提交 beb0a27a 编写于 作者: M Manish Vasani 提交者: GitHub

Merge pull request #22210 from mavasani/TryCatch

Add IOperation unit tests for try/catch statements and make the APIs …
......@@ -304,7 +304,7 @@ 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)
{
ILocalSymbol local = boundLocal.LocalSymbol;
bool isDeclaration = boundLocal.IsDeclaration;
......@@ -1112,8 +1112,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>();
......@@ -1300,15 +1299,17 @@ private ITryStatement CreateBoundTryStatementOperation(BoundTryStatement boundTr
private ICatchClause CreateBoundCatchBlockOperation(BoundCatchBlock boundCatchBlock)
{
Lazy<IBlockStatement> handler = new Lazy<IBlockStatement>(() => (IBlockStatement)Create(boundCatchBlock.Body));
ITypeSymbol caughtType = boundCatchBlock.ExceptionTypeOpt;
var exceptionSourceOpt = (BoundLocal)boundCatchBlock.ExceptionSourceOpt;
Lazy<IOperation> expressionDeclarationOrExpression = new Lazy<IOperation>(() => exceptionSourceOpt != null ? CreateVariableDeclaration(exceptionSourceOpt) : null);
ITypeSymbol exceptionType = boundCatchBlock.ExceptionTypeOpt;
ImmutableArray<ILocalSymbol> locals = boundCatchBlock.Locals.As<ILocalSymbol>();
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, locals, 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)')
......
......@@ -821,41 +821,49 @@ 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, ImmutableArray<ILocalSymbol> locals, 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;
Locals = locals;
}
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; }
protected abstract IOperation FilterImpl { get; }
public ITypeSymbol ExceptionType { get; }
/// <summary>
/// Symbol for the local catch variable bound to the caught exception.
/// Locals declared by the <see cref="ExceptionDeclarationOrExpression"/> and/or <see cref="Filter"/> clause.
/// </summary>
public ILocalSymbol ExceptionLocal { get; }
public ImmutableArray<ILocalSymbol> Locals { get; }
protected abstract IOperation ExceptionDeclarationOrExpressionImpl { get; }
protected abstract IOperation FilterImpl { 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);
......@@ -871,15 +879,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, ImmutableArray<ILocalSymbol> locals, IOperation filter, IBlockStatement handler, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit) :
base(exceptionType, locals, 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>
......@@ -887,18 +897,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, ImmutableArray<ILocalSymbol> locals, Lazy<IOperation> filter, Lazy<IBlockStatement> handler, SemanticModel semanticModel, SyntaxNode syntax, ITypeSymbol type, Optional<object> constantValue, bool isImplicit)
: base(exceptionType, locals, 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>
......@@ -4328,15 +4341,13 @@ 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)
{
}
protected abstract IBlockStatement BodyImpl { get; }
protected abstract ImmutableArray<ICatchClause> CatchesImpl { get; }
protected abstract IBlockStatement FinallyHandlerImpl { get; }
protected abstract IBlockStatement FinallyImpl { get; }
public override IEnumerable<IOperation> Children
{
get
......@@ -4346,7 +4357,7 @@ public override IEnumerable<IOperation> Children
{
yield return catche;
}
yield return FinallyHandler;
yield return Finally;
}
}
/// <summary>
......@@ -4360,7 +4371,7 @@ public override IEnumerable<IOperation> Children
/// <summary>
/// Finally handler of the try.
/// </summary>
public IBlockStatement FinallyHandler => Operation.SetParentOperation(FinallyHandlerImpl, this);
public IBlockStatement Finally => Operation.SetParentOperation(FinallyImpl, this);
public override void Accept(OperationVisitor visitor)
{
visitor.VisitTryStatement(this);
......@@ -4381,12 +4392,12 @@ internal sealed partial class TryStatement : BaseTryStatement, ITryStatement
{
BodyImpl = body;
CatchesImpl = catches;
FinallyHandlerImpl = finallyHandler;
FinallyImpl = finallyHandler;
}
protected override IBlockStatement BodyImpl { get; }
protected override ImmutableArray<ICatchClause> CatchesImpl { get; }
protected override IBlockStatement FinallyHandlerImpl { get; }
protected override IBlockStatement FinallyImpl { get; }
}
/// <summary>
......@@ -4409,7 +4420,7 @@ public LazyTryStatement(Lazy<IBlockStatement> body, Lazy<ImmutableArray<ICatchCl
protected override ImmutableArray<ICatchClause> CatchesImpl => _lazyCatches.Value;
protected override IBlockStatement FinallyHandlerImpl => _lazyFinallyHandler.Value;
protected override IBlockStatement FinallyImpl => _lazyFinallyHandler.Value;
}
/// <summary>
......
......@@ -11,24 +11,36 @@ 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.
/// Locals declared by the <see cref="ExceptionDeclarationOrExpression"/> and/or <see cref="Filter"/> clause.
/// </summary>
ITypeSymbol CaughtType { get; }
ImmutableArray<ILocalSymbol> Locals { get; }
/// <summary>
/// Filter expression to be executed to determine whether to handle the exception.
/// Type of the exception handled by the catch clause.
/// </summary>
IOperation Filter { get; }
ITypeSymbol ExceptionType { get; }
/// <summary>
/// Symbol for the local catch variable bound to the caught 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. Other expression for error scenarios (VB)
/// </summary>
ILocalSymbol ExceptionLocal { get; }
IOperation ExceptionDeclarationOrExpression { get; }
/// <summary>
/// Filter expression to be executed to determine whether to handle the exception.
/// </summary>
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.
......@@ -24,7 +24,7 @@ internal interface ITryStatement : IOperation // https://github.com/dotnet/rosly
/// <summary>
/// Finally handler of the try.
/// </summary>
IBlockStatement FinallyHandler { get; }
IBlockStatement Finally { get; }
}
}
......@@ -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);
return new TryStatement(Visit(operation.Body), VisitArray(operation.Catches), Visit(operation.Finally), ((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, operation.Locals, 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>
......@@ -205,9 +204,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);
}
......@@ -623,14 +621,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);
}
......
......@@ -63,6 +63,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
......@@ -122,6 +123,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
......@@ -230,6 +232,12 @@ 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.ICatchClause.Locals.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.ILocalSymbol>
Microsoft.CodeAnalysis.Semantics.ICoalesceExpression
Microsoft.CodeAnalysis.Semantics.ICoalesceExpression.Expression.get -> Microsoft.CodeAnalysis.IOperation
Microsoft.CodeAnalysis.Semantics.ICoalesceExpression.WhenNull.get -> Microsoft.CodeAnalysis.IOperation
......@@ -420,6 +428,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.Finally.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
......@@ -510,6 +522,7 @@ virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitAwaitExpression(M
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
......@@ -575,6 +588,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
......@@ -596,6 +610,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
......@@ -661,6 +676,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
......
......@@ -1165,7 +1165,6 @@ protected static string GetOperationTreeForTest(CSharpCompilation compilation, I
protected static string GetOperationTreeForTest<TSyntaxNode>(
string testSrc,
string expectedOperationTree,
CSharpCompilationOptions compilationOptions = null,
CSharpParseOptions parseOptions = null,
bool useLatestFrameworkReferences = false)
......@@ -1193,7 +1192,7 @@ protected static void VerifyOperationTreeForTest<TSyntaxNode>(CSharpCompilation
bool useLatestFrameworkReferences = false)
where TSyntaxNode : SyntaxNode
{
var actualOperationTree = GetOperationTreeForTest<TSyntaxNode>(testSrc, expectedOperationTree, compilationOptions, parseOptions, useLatestFrameworkReferences);
var actualOperationTree = GetOperationTreeForTest<TSyntaxNode>(testSrc, compilationOptions, parseOptions, useLatestFrameworkReferences);
OperationTreeVerifier.Verify(expectedOperationTree, actualOperationTree);
}
......
......@@ -818,7 +818,7 @@ 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
Dim local As ILocalSymbol = boundLocal.LocalSymbol
Dim isDeclaration As Boolean = False
Dim syntax As SyntaxNode = boundLocal.Syntax
......@@ -1096,15 +1096,27 @@ 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.LocalOpt IsNot Nothing AndAlso
boundCatchBlock.ExceptionSourceOpt?.Kind = BoundKind.Local AndAlso
boundCatchBlock.LocalOpt Is DirectCast(boundCatchBlock.ExceptionSourceOpt, BoundLocal).LocalSymbol Then
Return OperationFactory.CreateVariableDeclaration(boundCatchBlock.LocalOpt, initialValue:=Nothing, semanticModel:=_semanticModel, syntax:=boundCatchBlock.ExceptionSourceOpt.Syntax)
Else
Return Create(boundCatchBlock.ExceptionSourceOpt)
End If
End Function)
Dim exceptionType As ITypeSymbol = If(boundCatchBlock.ExceptionSourceOpt?.Type, DirectCast(_semanticModel.Compilation, VisualBasicCompilation).GetWellKnownType(WellKnownType.System_Exception))
Dim locals As ImmutableArray(Of ILocalSymbol) = If(boundCatchBlock.LocalOpt IsNot Nothing,
ImmutableArray.Create(Of ILocalSymbol)(boundCatchBlock.LocalOpt),
ImmutableArray(Of ILocalSymbol).Empty)
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, locals, filter, handler, _semanticModel, syntax, type, constantValue, isImplicit)
End Function
Private Function CreateBoundBlockOperation(boundBlock As BoundBlock) As IBlockStatement
......@@ -1114,7 +1126,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
......@@ -625,7 +625,11 @@ 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')
Locals: Local_1: ex As System.Exception
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,22 +557,25 @@ 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);
Visit(operation.Body, "Body");
VisitArray(operation.Catches, "Catch clauses", logElementCount: true);
Visit(operation.FinallyHandler, "Finally");
Visit(operation.Finally, "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()})");
var exceptionTypeStr = operation.ExceptionType != null ? operation.ExceptionType.ToTestDisplayString() : "null";
LogString($" (Exception type: {exceptionTypeStr})");
LogCommonPropertiesAndNewLine(operation);
LogLocals(operation.Locals);
Visit(operation.ExceptionDeclarationOrExpression, "ExceptionDeclarationOrExpression");
Visit(operation.Filter, "Filter");
Visit(operation.Handler, "Handler");
}
......
......@@ -180,15 +180,15 @@ 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;
var locals = operation.Locals;
base.VisitCatchClause(operation);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册