提交 ef007eb5 编写于 作者: M Manish Vasani

Add IOperation unit tests for try/catch statements and make the APIs public again

Fixes #22008

There might be some more API changes based on the open issues mentioned in #22008
上级 9064f0ab
......@@ -304,8 +304,13 @@ private IInvocationExpression CreateBoundCallOperation(BoundCall boundCall)
return new LazyInvocationExpression(targetMethod, instance, isVirtual, argumentsInEvaluationOrder, _semanticModel, syntax, type, constantValue, isImplicit);
}
private ILocalReferenceExpression CreateBoundLocalOperation(BoundLocal boundLocal)
private IOperation CreateBoundLocalOperation(BoundLocal boundLocal)
{
if (boundLocal.Syntax.Kind() == SyntaxKind.CatchDeclaration)
{
return CreateVariableDeclaration(boundLocal);
}
ILocalSymbol local = boundLocal.LocalSymbol;
bool isDeclaration = boundLocal.IsDeclaration;
SyntaxNode syntax = boundLocal.Syntax;
......@@ -1096,8 +1101,7 @@ private IBlockStatement CreateBoundBlockOperation(BoundBlock boundBlock)
// Filter out all OperationKind.None except fixed statements for now.
// https://github.com/dotnet/roslyn/issues/21776
.Where(s => s.operation.Kind != OperationKind.None ||
s.bound.Kind == BoundKind.FixedStatement ||
s.bound.Kind == BoundKind.TryStatement)
s.bound.Kind == BoundKind.FixedStatement)
.Select(s => s.operation).ToImmutableArray());
ImmutableArray<ILocalSymbol> locals = boundBlock.Locals.As<ILocalSymbol>();
......@@ -1284,15 +1288,15 @@ private ITryStatement CreateBoundTryStatementOperation(BoundTryStatement boundTr
private ICatchClause CreateBoundCatchBlockOperation(BoundCatchBlock boundCatchBlock)
{
Lazy<IBlockStatement> handler = new Lazy<IBlockStatement>(() => (IBlockStatement)Create(boundCatchBlock.Body));
ITypeSymbol caughtType = boundCatchBlock.ExceptionTypeOpt;
Lazy<IOperation> expressionDeclarationOrExpression = new Lazy<IOperation>(() => boundCatchBlock.ExceptionSourceOpt != null ? Create(boundCatchBlock.ExceptionSourceOpt) : null);
ITypeSymbol exceptionType = boundCatchBlock.ExceptionTypeOpt ?? ((CSharpCompilation)_semanticModel.Compilation).GetWellKnownType(WellKnownType.System_Exception);
Lazy<IOperation> filter = new Lazy<IOperation>(() => Create(boundCatchBlock.ExceptionFilterOpt));
ILocalSymbol exceptionLocal = (boundCatchBlock.Locals.FirstOrDefault()?.DeclarationKind == CSharp.Symbols.LocalDeclarationKind.CatchVariable) ? boundCatchBlock.Locals.FirstOrDefault() : null;
Lazy<IBlockStatement> handler = new Lazy<IBlockStatement>(() => (IBlockStatement)Create(boundCatchBlock.Body));
SyntaxNode syntax = boundCatchBlock.Syntax;
ITypeSymbol type = null;
Optional<object> constantValue = default(Optional<object>);
bool isImplicit = boundCatchBlock.WasCompilerGenerated;
return new LazyCatchClause(handler, caughtType, filter, exceptionLocal, _semanticModel, syntax, type, constantValue, isImplicit);
return new LazyCatchClause(expressionDeclarationOrExpression, exceptionType, filter, handler, _semanticModel, syntax, type, constantValue, isImplicit);
}
private IFixedStatement CreateBoundFixedStatementOperation(BoundFixedStatement boundFixedStatement)
......
......@@ -56,6 +56,11 @@ private IVariableDeclaration CreateVariableDeclaration(BoundLocalDeclaration bou
return OperationFactory.CreateVariableDeclaration(boundLocalDeclaration.LocalSymbol, Create(boundLocalDeclaration.InitializerOpt), _semanticModel, syntax);
}
private IVariableDeclaration CreateVariableDeclaration(BoundLocal boundLocal)
{
return OperationFactory.CreateVariableDeclaration(boundLocal.LocalSymbol, initialValue: null, semanticModel: _semanticModel, syntax: boundLocal.Syntax);
}
private IOperation CreateBoundCallInstanceOperation(BoundCall boundCall)
{
if (boundCall.Method == null || boundCall.Method.IsStatic)
......
......@@ -896,7 +896,7 @@ public void TryMethod()
Target: ILocalReferenceExpression: x (OperationKind.LocalReferenceExpression, Type: System.SByte) (Syntax: 'x')
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
Body: IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
ITryStatement (OperationKind.None) (Syntax: 'try ... }')
ITryStatement (OperationKind.TryStatement) (Syntax: 'try ... }')
Body: IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: 'y = (sbyte)(x / 2);')
Expression: ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.SByte) (Syntax: 'y = (sbyte)(x / 2)')
......
......@@ -827,41 +827,44 @@ internal abstract partial class CaseClause : Operation, ICaseClause
/// </summary>
internal abstract partial class BaseCatchClause : Operation, ICatchClause
{
protected BaseCatchClause(ITypeSymbol caughtType, ILocalSymbol exceptionLocal, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
// https://github.com/dotnet/roslyn/issues/22008
// base(OperationKind.CatchClause, semanticModel, syntax, type, constantValue, isImplicit)
base(OperationKind.None, semanticModel, syntax, type, constantValue, isImplicit)
protected BaseCatchClause(ITypeSymbol exceptionType, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
base(OperationKind.CatchClause, semanticModel, syntax, type, constantValue, isImplicit)
{
CaughtType = caughtType;
ExceptionLocal = exceptionLocal;
ExceptionType = exceptionType;
}
protected abstract IBlockStatement HandlerImpl { get; }
/// <summary>
/// Type of exception to be handled.
/// Type of the exception handled by the catch clause.
/// </summary>
public ITypeSymbol CaughtType { get; }
public ITypeSymbol ExceptionType { get; }
protected abstract IOperation ExceptionDeclarationOrExpressionImpl { get; }
protected abstract IOperation FilterImpl { get; }
/// <summary>
/// Symbol for the local catch variable bound to the caught exception.
/// </summary>
public ILocalSymbol ExceptionLocal { get; }
protected abstract IBlockStatement HandlerImpl { get; }
public override IEnumerable<IOperation> Children
{
get
{
yield return ExceptionDeclarationOrExpression;
yield return Filter;
yield return Handler;
}
}
/// <summary>
/// Body of the exception handler.
/// Optional source for exception. This could be any of the following operation:
/// 1. Declaration for the local catch variable bound to the caught exception (C# and VB) OR
/// 2. Type expression for the caught expression type (C#) OR
/// 3. Null, indicating no expression (C#)
/// 4. Reference to an existing local or parameter (VB) OR
/// 5. An error expression (VB)
/// </summary>
public IBlockStatement Handler => Operation.SetParentOperation(HandlerImpl, this);
public IOperation ExceptionDeclarationOrExpression => Operation.SetParentOperation(ExceptionDeclarationOrExpressionImpl, this);
/// <summary>
/// Filter expression to be executed to determine whether to handle the exception.
/// </summary>
public IOperation Filter => Operation.SetParentOperation(FilterImpl, this);
/// <summary>
/// Body of the exception handler.
/// </summary>
public IBlockStatement Handler => Operation.SetParentOperation(HandlerImpl, this);
public override void Accept(OperationVisitor visitor)
{
visitor.VisitCatchClause(this);
......@@ -877,15 +880,17 @@ public override void Accept(OperationVisitor visitor)
/// </summary>
internal sealed partial class CatchClause : BaseCatchClause, ICatchClause
{
public CatchClause(IBlockStatement handler, ITypeSymbol caughtType, IOperation filter, ILocalSymbol exceptionLocal, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
base(caughtType, exceptionLocal, semanticModel, syntax, type, constantValue, isImplicit)
public CatchClause(IOperation exceptionDeclarationOrExpression, ITypeSymbol exceptionType, IOperation filter, IBlockStatement handler, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
base(exceptionType, semanticModel, syntax, type, constantValue, isImplicit)
{
HandlerImpl = handler;
ExceptionDeclarationOrExpressionImpl = exceptionDeclarationOrExpression;
FilterImpl = filter;
HandlerImpl = handler;
}
protected override IBlockStatement HandlerImpl { get; }
protected override IOperation FilterImpl { get; }
protected override IOperation ExceptionDeclarationOrExpressionImpl { get; }
}
/// <summary>
......@@ -893,18 +898,21 @@ internal sealed partial class CatchClause : BaseCatchClause, ICatchClause
/// </summary>
internal sealed partial class LazyCatchClause : BaseCatchClause, ICatchClause
{
private readonly Lazy<IBlockStatement> _lazyHandler;
private readonly Lazy<IOperation> _lazyExceptionDeclarationOrExpression;
private readonly Lazy<IOperation> _lazyFilter;
private readonly Lazy<IBlockStatement> _lazyHandler;
public LazyCatchClause(Lazy<IBlockStatement> handler, ITypeSymbol caughtType, Lazy<IOperation> filter, ILocalSymbol exceptionLocal, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) : base(caughtType, exceptionLocal, semanticModel, syntax, type, constantValue, isImplicit)
public LazyCatchClause(Lazy<IOperation> exceptionDeclarationOrExpression, ITypeSymbol exceptionType, Lazy<IOperation> filter, Lazy<IBlockStatement> handler, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit)
: base(exceptionType, semanticModel, syntax, type, constantValue, isImplicit)
{
_lazyHandler = handler ?? throw new System.ArgumentNullException(nameof(handler));
_lazyExceptionDeclarationOrExpression = exceptionDeclarationOrExpression ?? throw new System.ArgumentNullException(nameof(exceptionDeclarationOrExpression));
_lazyFilter = filter ?? throw new System.ArgumentNullException(nameof(filter));
_lazyHandler = handler ?? throw new System.ArgumentNullException(nameof(handler));
}
protected override IBlockStatement HandlerImpl => _lazyHandler.Value;
protected override IOperation ExceptionDeclarationOrExpressionImpl => _lazyExceptionDeclarationOrExpression.Value;
protected override IOperation FilterImpl => _lazyFilter.Value;
protected override IBlockStatement HandlerImpl => _lazyHandler.Value;
}
/// <summary>
......@@ -4338,9 +4346,7 @@ internal abstract partial class SymbolInitializer : Operation, ISymbolInitialize
internal abstract partial class BaseTryStatement : Operation, ITryStatement
{
protected BaseTryStatement(SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
// https://github.com/dotnet/roslyn/issues/22008
// base(OperationKind.TryStatement, semanticModel, syntax, type, constantValue, isImplicit)
base(OperationKind.None, semanticModel, syntax, type, constantValue, isImplicit)
base(OperationKind.TryStatement, semanticModel, syntax, type, constantValue, isImplicit)
{
}
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Immutable;
namespace Microsoft.CodeAnalysis.Semantics
{
/// <summary>
......@@ -11,24 +9,31 @@ namespace Microsoft.CodeAnalysis.Semantics
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
/// </remarks>
internal interface ICatchClause : IOperation // https://github.com/dotnet/roslyn/issues/22008
public interface ICatchClause : IOperation
{
/// <summary>
/// Body of the exception handler.
/// </summary>
IBlockStatement Handler { get; }
/// <summary>
/// Type of exception to be handled.
/// Type of the exception handled by the catch clause.
/// </summary>
ITypeSymbol CaughtType { get; }
ITypeSymbol ExceptionType { get; }
/// <summary>
/// Filter expression to be executed to determine whether to handle the exception.
/// Optional source for exception. This could be any of the following operation:
/// 1. Declaration for the local catch variable bound to the caught exception (C# and VB) OR
/// 2. Null, indicating no declaration or expression (C# and VB)
/// 3. Reference to an existing local or parameter (VB) OR
/// 4. An error expression (VB)
/// </summary>
IOperation Filter { get; }
IOperation ExceptionDeclarationOrExpression { get; }
/// <summary>
/// Symbol for the local catch variable bound to the caught exception.
/// Filter expression to be executed to determine whether to handle the exception.
/// </summary>
ILocalSymbol ExceptionLocal { get; }
IOperation Filter { get; }
}
}
......@@ -11,7 +11,7 @@ namespace Microsoft.CodeAnalysis.Semantics
/// This interface is reserved for implementation by its associated APIs. We reserve the right to
/// change it in the future.
/// </remarks>
internal interface ITryStatement : IOperation // https://github.com/dotnet/roslyn/issues/22008
public interface ITryStatement : IOperation
{
/// <summary>
/// Body of the try, over which the handlers are active.
......
......@@ -139,14 +139,14 @@ public override IOperation VisitLockStatement(ILockStatement operation, object a
return new LockStatement(Visit(operation.Expression), Visit(operation.Body), ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
}
internal override IOperation VisitTryStatement(ITryStatement operation, object argument)
public override IOperation VisitTryStatement(ITryStatement operation, object argument)
{
return new TryStatement(Visit(operation.Body), VisitArray(operation.Catches), Visit(operation.FinallyHandler), ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
}
internal override IOperation VisitCatchClause(ICatchClause operation, object argument)
public override IOperation VisitCatchClause(ICatchClause operation, object argument)
{
return new CatchClause(Visit(operation.Handler), operation.CaughtType, Visit(operation.Filter), operation.ExceptionLocal, ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
return new CatchClause(Visit(operation.ExceptionDeclarationOrExpression), operation.ExceptionType, Visit(operation.Filter), Visit(operation.Handler), ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit);
}
public override IOperation VisitUsingStatement(IUsingStatement operation, object argument)
......
......@@ -38,9 +38,8 @@ public enum OperationKind
YieldBreakStatement = 0xc,
/// <summary>Indicates an <see cref="ILockStatement"/>.</summary>
LockStatement = 0xd,
// https://github.com/dotnet/roslyn/issues/22008
// /// <summary>Indicates an <see cref="ITryStatement"/>.</summary>
// TryStatement = 0xe,
/// <summary>Indicates an <see cref="ITryStatement"/>.</summary>
TryStatement = 0xe,
/// <summary>Indicates an <see cref="IUsingStatement"/>.</summary>
UsingStatement = 0xf,
/// <summary>Indicates an <see cref="IReturnStatement"/>.</summary>
......@@ -208,9 +207,8 @@ public enum OperationKind
/// <summary>Indicates an <see cref="IArgument"/>.</summary>
Argument = 0x407,
// https://github.com/dotnet/roslyn/issues/22008
// /// <summary>Indicates an <see cref="ICatchClause"/>.</summary>
// CatchClause = 0x408,
/// <summary>Indicates an <see cref="ICatchClause"/>.</summary>
CatchClause = 0x408,
/// <summary>Indicates an <see cref="ISwitchCase"/>.</summary>
SwitchCase = 0x409,
......
......@@ -130,14 +130,12 @@ public virtual void VisitLockStatement(ILockStatement operation)
DefaultVisit(operation);
}
// https://github.com/dotnet/roslyn/issues/22008
internal virtual void VisitTryStatement(ITryStatement operation)
public virtual void VisitTryStatement(ITryStatement operation)
{
DefaultVisit(operation);
}
// https://github.com/dotnet/roslyn/issues/22008
internal virtual void VisitCatchClause(ICatchClause operation)
public virtual void VisitCatchClause(ICatchClause operation)
{
DefaultVisit(operation);
}
......@@ -626,14 +624,12 @@ public virtual TResult VisitLockStatement(ILockStatement operation, TArgument ar
return DefaultVisit(operation, argument);
}
// https://github.com/dotnet/roslyn/issues/22008
internal virtual TResult VisitTryStatement(ITryStatement operation, TArgument argument)
public virtual TResult VisitTryStatement(ITryStatement operation, TArgument argument)
{
return DefaultVisit(operation, argument);
}
// https://github.com/dotnet/roslyn/issues/22008
internal virtual TResult VisitCatchClause(ICatchClause operation, TArgument argument)
public virtual TResult VisitCatchClause(ICatchClause operation, TArgument argument)
{
return DefaultVisit(operation, argument);
}
......
......@@ -60,6 +60,7 @@ Microsoft.CodeAnalysis.OperationKind.BinaryOperatorExpression = 270 -> Microsoft
Microsoft.CodeAnalysis.OperationKind.BlockStatement = 2 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.BranchStatement = 8 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.CaseClause = 1034 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.CatchClause = 1032 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.CoalesceExpression = 272 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.CollectionElementInitializerExpression = 290 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.CompoundAssignmentExpression = 281 -> Microsoft.CodeAnalysis.OperationKind
......@@ -117,6 +118,7 @@ Microsoft.CodeAnalysis.OperationKind.SwitchCase = 1033 -> Microsoft.CodeAnalysis
Microsoft.CodeAnalysis.OperationKind.SwitchStatement = 4 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.ThrowExpression = 519 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.TranslatedQueryExpression = 297 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.TryStatement = 14 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.TupleExpression = 292 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.TypeOfExpression = 513 -> Microsoft.CodeAnalysis.OperationKind
Microsoft.CodeAnalysis.OperationKind.TypeParameterObjectCreationExpression = 275 -> Microsoft.CodeAnalysis.OperationKind
......@@ -223,6 +225,11 @@ Microsoft.CodeAnalysis.Semantics.IBranchStatement.BranchKind.get -> Microsoft.Co
Microsoft.CodeAnalysis.Semantics.IBranchStatement.Target.get -> Microsoft.CodeAnalysis.ILabelSymbol
Microsoft.CodeAnalysis.Semantics.ICaseClause
Microsoft.CodeAnalysis.Semantics.ICaseClause.CaseKind.get -> Microsoft.CodeAnalysis.Semantics.CaseKind
Microsoft.CodeAnalysis.Semantics.ICatchClause
Microsoft.CodeAnalysis.Semantics.ICatchClause.ExceptionDeclarationOrExpression.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.ICatchClause.ExceptionType.get -> Microsoft.CodeAnalysis.ITypeSymbol
Microsoft.CodeAnalysis.Semantics.ICatchClause.Filter.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.ICatchClause.Handler.get -> Microsoft.CodeAnalysis.Semantics.IBlockStatement
Microsoft.CodeAnalysis.Semantics.ICoalesceExpression
Microsoft.CodeAnalysis.Semantics.ICoalesceExpression.Expression.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.ICoalesceExpression.WhenNull.get -> Microsoft.CodeAnalysis.IOperation
......@@ -411,6 +418,10 @@ Microsoft.CodeAnalysis.Semantics.IThrowExpression
Microsoft.CodeAnalysis.Semantics.IThrowExpression.Expression.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.ITranslatedQueryExpression
Microsoft.CodeAnalysis.Semantics.ITranslatedQueryExpression.Expression.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.ITryStatement
Microsoft.CodeAnalysis.Semantics.ITryStatement.Body.get -> Microsoft.CodeAnalysis.Semantics.IBlockStatement
Microsoft.CodeAnalysis.Semantics.ITryStatement.Catches.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Semantics.ICatchClause>
Microsoft.CodeAnalysis.Semantics.ITryStatement.FinallyHandler.get -> Microsoft.CodeAnalysis.Semantics.IBlockStatement
Microsoft.CodeAnalysis.Semantics.ITupleExpression
Microsoft.CodeAnalysis.Semantics.ITupleExpression.Elements.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.IOperation>
Microsoft.CodeAnalysis.Semantics.ITypeOfExpression
......@@ -500,6 +511,7 @@ virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitArrayInitializer(
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitBinaryOperatorExpression(Microsoft.CodeAnalysis.Semantics.IBinaryOperatorExpression operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitBlockStatement(Microsoft.CodeAnalysis.Semantics.IBlockStatement operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitBranchStatement(Microsoft.CodeAnalysis.Semantics.IBranchStatement operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitCatchClause(Microsoft.CodeAnalysis.Semantics.ICatchClause operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitCoalesceExpression(Microsoft.CodeAnalysis.Semantics.ICoalesceExpression operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitCollectionElementInitializerExpression(Microsoft.CodeAnalysis.Semantics.ICollectionElementInitializerExpression operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitCompoundAssignmentExpression(Microsoft.CodeAnalysis.Semantics.ICompoundAssignmentExpression operation) -> void
......@@ -563,6 +575,7 @@ virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitSwitchCase(Micros
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitSwitchStatement(Microsoft.CodeAnalysis.Semantics.ISwitchStatement operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitThrowExpression(Microsoft.CodeAnalysis.Semantics.IThrowExpression operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitTranslatedQueryExpression(Microsoft.CodeAnalysis.Semantics.ITranslatedQueryExpression operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitTryStatement(Microsoft.CodeAnalysis.Semantics.ITryStatement operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitTupleExpression(Microsoft.CodeAnalysis.Semantics.ITupleExpression operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitTypeOfExpression(Microsoft.CodeAnalysis.Semantics.ITypeOfExpression operation) -> void
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitTypeParameterObjectCreationExpression(Microsoft.CodeAnalysis.Semantics.ITypeParameterObjectCreationExpression operation) -> void
......@@ -583,6 +596,7 @@ virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.Vi
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitBinaryOperatorExpression(Microsoft.CodeAnalysis.Semantics.IBinaryOperatorExpression operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitBlockStatement(Microsoft.CodeAnalysis.Semantics.IBlockStatement operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitBranchStatement(Microsoft.CodeAnalysis.Semantics.IBranchStatement operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitCatchClause(Microsoft.CodeAnalysis.Semantics.ICatchClause operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitCoalesceExpression(Microsoft.CodeAnalysis.Semantics.ICoalesceExpression operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitCollectionElementInitializerExpression(Microsoft.CodeAnalysis.Semantics.ICollectionElementInitializerExpression operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitCompoundAssignmentExpression(Microsoft.CodeAnalysis.Semantics.ICompoundAssignmentExpression operation, TArgument argument) -> TResult
......@@ -646,6 +660,7 @@ virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.Vi
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitSwitchStatement(Microsoft.CodeAnalysis.Semantics.ISwitchStatement operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitThrowExpression(Microsoft.CodeAnalysis.Semantics.IThrowExpression operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitTranslatedQueryExpression(Microsoft.CodeAnalysis.Semantics.ITranslatedQueryExpression operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitTryStatement(Microsoft.CodeAnalysis.Semantics.ITryStatement operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitTupleExpression(Microsoft.CodeAnalysis.Semantics.ITupleExpression operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitTypeOfExpression(Microsoft.CodeAnalysis.Semantics.ITypeOfExpression operation, TArgument argument) -> TResult
virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor<TArgument, TResult>.VisitTypeParameterObjectCreationExpression(Microsoft.CodeAnalysis.Semantics.ITypeParameterObjectCreationExpression operation, TArgument argument) -> TResult
......
......@@ -799,7 +799,11 @@ Namespace Microsoft.CodeAnalysis.Semantics
Return New ParameterReferenceExpression(parameter, _semanticModel, syntax, type, constantValue, isImplicit)
End Function
Private Function CreateBoundLocalOperation(boundLocal As BoundLocal) As ILocalReferenceExpression
Private Function CreateBoundLocalOperation(boundLocal As BoundLocal) As IOperation
If boundLocal.Syntax.Kind = SyntaxKind.IdentifierName AndAlso boundLocal.Syntax.Parent?.Kind = SyntaxKind.CatchStatement Then
Return OperationFactory.CreateVariableDeclaration(boundLocal.LocalSymbol, initialValue:=Nothing, semanticModel:=_semanticModel, syntax:=boundLocal.Syntax)
End If
Dim local As ILocalSymbol = boundLocal.LocalSymbol
Dim isDeclaration As Boolean = False
Dim syntax As SyntaxNode = boundLocal.Syntax
......@@ -1077,15 +1081,16 @@ Namespace Microsoft.CodeAnalysis.Semantics
End Function
Private Function CreateBoundCatchBlockOperation(boundCatchBlock As BoundCatchBlock) As ICatchClause
Dim handler As Lazy(Of IBlockStatement) = New Lazy(Of IBlockStatement)(Function() DirectCast(Create(boundCatchBlock.Body), IBlockStatement))
Dim caughtType As ITypeSymbol = boundCatchBlock.ExceptionSourceOpt?.Type
Dim exceptionDeclarationOrExpression As Lazy(Of IOperation) = New Lazy(Of IOperation)(
Function() If(boundCatchBlock.ExceptionSourceOpt IsNot Nothing, Create(boundCatchBlock.ExceptionSourceOpt), Nothing))
Dim exceptionType As ITypeSymbol = If(boundCatchBlock.ExceptionSourceOpt?.Type, DirectCast(_semanticModel.Compilation, VisualBasicCompilation).GetWellKnownType(WellKnownType.System_Exception))
Dim filter As Lazy(Of IOperation) = New Lazy(Of IOperation)(Function() Create(boundCatchBlock.ExceptionFilterOpt))
Dim exceptionLocal As ILocalSymbol = boundCatchBlock.LocalOpt
Dim handler As Lazy(Of IBlockStatement) = New Lazy(Of IBlockStatement)(Function() DirectCast(Create(boundCatchBlock.Body), IBlockStatement))
Dim syntax As SyntaxNode = boundCatchBlock.Syntax
Dim type As ITypeSymbol = Nothing
Dim constantValue As [Optional](Of Object) = New [Optional](Of Object)()
Dim isImplicit As Boolean = boundCatchBlock.WasCompilerGenerated
Return New LazyCatchClause(handler, caughtType, filter, exceptionLocal, _semanticModel, syntax, type, constantValue, isImplicit)
Return New LazyCatchClause(exceptionDeclarationOrExpression, exceptionType, filter, handler, _semanticModel, syntax, type, constantValue, isImplicit)
End Function
Private Function CreateBoundBlockOperation(boundBlock As BoundBlock) As IBlockStatement
......@@ -1095,7 +1100,7 @@ Namespace Microsoft.CodeAnalysis.Semantics
' https://github.com/dotnet/roslyn/issues/21776
Return boundBlock.Statements.Select(Function(n) (s:=Create(n), bound:=n)).Where(
Function(tuple)
Return tuple.s.Kind <> OperationKind.None OrElse tuple.bound.Kind = BoundKind.TryStatement OrElse
Return tuple.s.Kind <> OperationKind.None OrElse
tuple.bound.Kind = BoundKind.WithStatement OrElse tuple.bound.Kind = BoundKind.StopStatement OrElse
tuple.bound.Kind = BoundKind.EndStatement
End Function).Select(Function(tuple) tuple.s).ToImmutableArray()
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports Microsoft.CodeAnalysis.Semantics
Imports Microsoft.CodeAnalysis.Test.Utilities
......@@ -624,7 +624,10 @@ Module Program
End Module]]>.Value
Dim expectedOperationTree = <![CDATA[
ICatchClause (Exception type: System.Exception, Exception local: ex As System.Exception) (OperationKind.None) (Syntax: 'Catch ex As ... Is Nothing')
ICatchClause (Exception type: System.Exception) (OperationKind.CatchClause) (Syntax: 'Catch ex As ... Is Nothing')
ExceptionDeclarationOrExpression: IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'ex')
Variables: Local_1: ex As System.Exception
Initializer: null
Filter: IBinaryOperatorExpression (BinaryOperatorKind.Equals) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: 'ex Is Nothing')
Left: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Object) (Syntax: 'ex')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports Microsoft.CodeAnalysis.Semantics
Imports Microsoft.CodeAnalysis.Test.Utilities
......@@ -927,7 +927,7 @@ IWhileLoopStatement (LoopKind.While) (OperationKind.LoopStatement, IsInvalid) (S
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: '1')
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
Body: IBlockStatement (1 statements) (OperationKind.BlockStatement, IsInvalid) (Syntax: 'While Syste ... End While')
ITryStatement (OperationKind.None) (Syntax: 'Try ... End Try')
ITryStatement (OperationKind.TryStatement) (Syntax: 'Try ... End Try')
Body: IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'Try ... End Try')
IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: 'y = CSByte(x / 2)')
Expression: ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.SByte) (Syntax: 'y = CSByte(x / 2)')
......
......@@ -557,7 +557,7 @@ public override void VisitLockStatement(ILockStatement operation)
Visit(operation.Body, "Body");
}
internal override void VisitTryStatement(ITryStatement operation)
public override void VisitTryStatement(ITryStatement operation)
{
LogString(nameof(ITryStatement));
LogCommonPropertiesAndNewLine(operation);
......@@ -567,12 +567,13 @@ internal override void VisitTryStatement(ITryStatement operation)
Visit(operation.FinallyHandler, "Finally");
}
internal override void VisitCatchClause(ICatchClause operation)
public override void VisitCatchClause(ICatchClause operation)
{
LogString(nameof(ICatchClause));
LogString($" (Exception type: {operation.CaughtType?.ToTestDisplayString()}, Exception local: {operation.ExceptionLocal?.ToTestDisplayString()})");
LogString($" (Exception type: {operation.ExceptionType?.ToTestDisplayString()})");
LogCommonPropertiesAndNewLine(operation);
Visit(operation.ExceptionDeclarationOrExpression, "ExceptionDeclarationOrExpression");
Visit(operation.Filter, "Filter");
Visit(operation.Handler, "Handler");
}
......
......@@ -180,15 +180,14 @@ public override void VisitLockStatement(ILockStatement operation)
base.VisitLockStatement(operation);
}
internal override void VisitTryStatement(ITryStatement operation)
public override void VisitTryStatement(ITryStatement operation)
{
base.VisitTryStatement(operation);
}
internal override void VisitCatchClause(ICatchClause operation)
public override void VisitCatchClause(ICatchClause operation)
{
var caughtType = operation.CaughtType;
var exceptionLocal = operation.ExceptionLocal;
var exceptionType = operation.ExceptionType;
base.VisitCatchClause(operation);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册