提交 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)')
......
// 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 Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Semantics;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests
......@@ -37,14 +35,18 @@ void M(int i)
}
";
string expectedOperationTree = @"
ITryStatement (OperationKind.None) (Syntax: 'try ... }')
ITryStatement (OperationKind.TryStatement) (Syntax: 'try ... }')
Body: IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: 'i = 0;')
Expression: ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32) (Syntax: 'i = 0')
Left: IParameterReferenceExpression: i (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'i')
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
Catch clauses(1):
ICatchClause (Exception type: System.Exception, Exception local: System.Exception ex) (OperationKind.None) (Syntax: 'catch (Exce ... }')
ICatchClause (Exception type: System.Exception) (OperationKind.CatchClause) (Syntax: 'catch (Exce ... }')
Locals: Local_1: System.Exception ex
ExceptionDeclarationOrExpression: IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: '(Exception ex)')
Variables: Local_1: System.Exception ex
Initializer: null
Filter: IBinaryOperatorExpression (BinaryOperatorKind.GreaterThan) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: 'i > 0')
Left: IParameterReferenceExpression: i (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'i')
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
......@@ -91,14 +93,18 @@ void M(int i)
";
string expectedOperationTree = @"
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: 'i = 0;')
Expression: ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32) (Syntax: 'i = 0')
Left: IParameterReferenceExpression: i (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'i')
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
Catch clauses(1):
ICatchClause (Exception type: System.Exception, Exception local: System.Exception ex) (OperationKind.None) (Syntax: 'catch (Exce ... }')
ICatchClause (Exception type: System.Exception) (OperationKind.CatchClause) (Syntax: 'catch (Exce ... }')
Locals: Local_1: System.Exception ex
ExceptionDeclarationOrExpression: IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: '(Exception ex)')
Variables: Local_1: System.Exception ex
Initializer: null
Filter: IBinaryOperatorExpression (BinaryOperatorKind.GreaterThan) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: 'i > 0')
Left: IParameterReferenceExpression: i (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'i')
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
......@@ -116,5 +122,704 @@ void M(int i)
VerifyOperationTreeAndDiagnosticsForTest<BlockSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
[CompilerTrait(CompilerFeature.IOperation)]
[Fact]
public void TryCatch_SingleCatchClause()
{
string source = @"
class C
{
static void Main()
{
/*<bind>*/try
{
}
catch (System.IO.IOException e)
{
}/*</bind>*/
}
}
";
string expectedOperationTree = @"
ITryStatement (OperationKind.TryStatement) (Syntax: 'try ... }')
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
Catch clauses(1):
ICatchClause (Exception type: System.IO.IOException) (OperationKind.CatchClause) (Syntax: 'catch (Syst ... }')
Locals: Local_1: System.IO.IOException e
ExceptionDeclarationOrExpression: IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: '(System.IO. ... xception e)')
Variables: Local_1: System.IO.IOException e
Initializer: null
Filter: null
Handler: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
Finally: null
";
var expectedDiagnostics = new DiagnosticDescription[] {
// CS0168: The variable 'e' is declared but never used
// catch (System.IO.IOException e)
Diagnostic(ErrorCode.WRN_UnreferencedVar, "e").WithArguments("e").WithLocation(9, 38)
};
VerifyOperationTreeAndDiagnosticsForTest<TryStatementSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
[CompilerTrait(CompilerFeature.IOperation)]
[Fact]
public void TryCatch_SingleCatchClauseAndFilter()
{
string source = @"
class C
{
static void Main()
{
/*<bind>*/try
{
}
catch (System.IO.IOException e) when (e.Message != null)
{
}/*</bind>*/
}
}
";
string expectedOperationTree = @"
ITryStatement (OperationKind.TryStatement) (Syntax: 'try ... }')
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
Catch clauses(1):
ICatchClause (Exception type: System.IO.IOException) (OperationKind.CatchClause) (Syntax: 'catch (Syst ... }')
Locals: Local_1: System.IO.IOException e
ExceptionDeclarationOrExpression: IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: '(System.IO. ... xception e)')
Variables: Local_1: System.IO.IOException e
Initializer: null
Filter: IBinaryOperatorExpression (BinaryOperatorKind.NotEquals) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: 'e.Message != null')
Left: IPropertyReferenceExpression: System.String System.Exception.Message { get; } (OperationKind.PropertyReferenceExpression, Type: System.String) (Syntax: 'e.Message')
Instance Receiver: ILocalReferenceExpression: e (OperationKind.LocalReferenceExpression, Type: System.IO.IOException) (Syntax: 'e')
Right: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.String, Constant: null) (Syntax: 'null')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
Operand: ILiteralExpression (OperationKind.LiteralExpression, Type: null, Constant: null) (Syntax: 'null')
Handler: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
Finally: null
";
var expectedDiagnostics = DiagnosticDescription.None;
VerifyOperationTreeAndDiagnosticsForTest<TryStatementSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
[CompilerTrait(CompilerFeature.IOperation)]
[Fact]
public void TryCatch_MultipleCatchClausesWithDifferentCaughtTypes()
{
string source = @"
class C
{
static void Main()
{
/*<bind>*/try
{
}
catch (System.IO.IOException e)
{
}
catch (System.Exception e) when (e.Message != null)
{
}/*</bind>*/
}
}
";
string expectedOperationTree = @"
ITryStatement (OperationKind.TryStatement) (Syntax: 'try ... }')
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
Catch clauses(2):
ICatchClause (Exception type: System.IO.IOException) (OperationKind.CatchClause) (Syntax: 'catch (Syst ... }')
Locals: Local_1: System.IO.IOException e
ExceptionDeclarationOrExpression: IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: '(System.IO. ... xception e)')
Variables: Local_1: System.IO.IOException e
Initializer: null
Filter: null
Handler: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
ICatchClause (Exception type: System.Exception) (OperationKind.CatchClause) (Syntax: 'catch (Syst ... }')
Locals: Local_1: System.Exception e
ExceptionDeclarationOrExpression: IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: '(System.Exception e)')
Variables: Local_1: System.Exception e
Initializer: null
Filter: IBinaryOperatorExpression (BinaryOperatorKind.NotEquals) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: 'e.Message != null')
Left: IPropertyReferenceExpression: System.String System.Exception.Message { get; } (OperationKind.PropertyReferenceExpression, Type: System.String) (Syntax: 'e.Message')
Instance Receiver: ILocalReferenceExpression: e (OperationKind.LocalReferenceExpression, Type: System.Exception) (Syntax: 'e')
Right: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.String, Constant: null) (Syntax: 'null')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
Operand: ILiteralExpression (OperationKind.LiteralExpression, Type: null, Constant: null) (Syntax: 'null')
Handler: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
Finally: null
";
var expectedDiagnostics = new DiagnosticDescription[] {
// CS0168: The variable 'e' is declared but never used
// catch (System.IO.IOException e)
Diagnostic(ErrorCode.WRN_UnreferencedVar, "e").WithArguments("e").WithLocation(9, 38)
};
VerifyOperationTreeAndDiagnosticsForTest<TryStatementSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
[CompilerTrait(CompilerFeature.IOperation)]
[Fact]
public void TryCatch_MultipleCatchClausesWithDuplicateCaughtTypes()
{
string source = @"
class C
{
static void Main()
{
/*<bind>*/try
{
}
catch (System.IO.IOException e)
{
}
catch (System.IO.IOException e) when (e.Message != null)
{
}/*</bind>*/
}
}
";
string expectedOperationTree = @"
ITryStatement (OperationKind.TryStatement, IsInvalid) (Syntax: 'try ... }')
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
Catch clauses(2):
ICatchClause (Exception type: System.IO.IOException) (OperationKind.CatchClause) (Syntax: 'catch (Syst ... }')
Locals: Local_1: System.IO.IOException e
ExceptionDeclarationOrExpression: IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: '(System.IO. ... xception e)')
Variables: Local_1: System.IO.IOException e
Initializer: null
Filter: null
Handler: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
ICatchClause (Exception type: System.IO.IOException) (OperationKind.CatchClause, IsInvalid) (Syntax: 'catch (Syst ... }')
Locals: Local_1: System.IO.IOException e
ExceptionDeclarationOrExpression: IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration, IsInvalid) (Syntax: '(System.IO. ... xception e)')
Variables: Local_1: System.IO.IOException e
Initializer: null
Filter: IBinaryOperatorExpression (BinaryOperatorKind.NotEquals) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: 'e.Message != null')
Left: IPropertyReferenceExpression: System.String System.Exception.Message { get; } (OperationKind.PropertyReferenceExpression, Type: System.String) (Syntax: 'e.Message')
Instance Receiver: ILocalReferenceExpression: e (OperationKind.LocalReferenceExpression, Type: System.IO.IOException) (Syntax: 'e')
Right: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.String, Constant: null) (Syntax: 'null')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
Operand: ILiteralExpression (OperationKind.LiteralExpression, Type: null, Constant: null) (Syntax: 'null')
Handler: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
Finally: null
";
var expectedDiagnostics = new DiagnosticDescription[] {
// CS0160: A previous catch clause already catches all exceptions of this or of a super type ('IOException')
// catch (System.IO.IOException e) when (e.Message != null)
Diagnostic(ErrorCode.ERR_UnreachableCatch, "System.IO.IOException").WithArguments("System.IO.IOException").WithLocation(12, 16),
// CS0168: The variable 'e' is declared but never used
// catch (System.IO.IOException e)
Diagnostic(ErrorCode.WRN_UnreferencedVar, "e").WithArguments("e").WithLocation(9, 38)
};
VerifyOperationTreeAndDiagnosticsForTest<TryStatementSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
[CompilerTrait(CompilerFeature.IOperation)]
[Fact]
public void TryCatch_CatchClauseWithoutExceptionLocal()
{
string source = @"
using System;
class C
{
static void M(string s)
{
/*<bind>*/try
{
}
catch (Exception)
{
}/*</bind>*/
}
}
";
string expectedOperationTree = @"
ITryStatement (OperationKind.TryStatement) (Syntax: 'try ... }')
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
Catch clauses(1):
ICatchClause (Exception type: System.Exception) (OperationKind.CatchClause) (Syntax: 'catch (Exce ... }')
ExceptionDeclarationOrExpression: null
Filter: null
Handler: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
Finally: null
";
var expectedDiagnostics = DiagnosticDescription.None;
VerifyOperationTreeAndDiagnosticsForTest<TryStatementSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
[CompilerTrait(CompilerFeature.IOperation)]
[Fact]
public void TryCatch_CatchClauseWithoutCaughtTypeOrExceptionLocal()
{
string source = @"
class C
{
static void M(object o)
{
/*<bind>*/try
{
}
catch
{
}/*</bind>*/
}
}
";
string expectedOperationTree = @"
ITryStatement (OperationKind.TryStatement) (Syntax: 'try ... }')
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
Catch clauses(1):
ICatchClause (Exception type: null) (OperationKind.CatchClause) (Syntax: 'catch ... }')
ExceptionDeclarationOrExpression: null
Filter: null
Handler: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
Finally: null
";
var expectedDiagnostics = DiagnosticDescription.None;
VerifyOperationTreeAndDiagnosticsForTest<TryStatementSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
[CompilerTrait(CompilerFeature.IOperation)]
[Fact]
public void TryCatch_FinallyWithoutCatchClause()
{
string source = @"
using System;
class C
{
static void M(string s)
{
/*<bind>*/try
{
}
finally
{
Console.WriteLine(s);
}/*</bind>*/
}
}
";
string expectedOperationTree = @"
ITryStatement (OperationKind.TryStatement) (Syntax: 'try ... }')
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
Catch clauses(0)
Finally: IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: 'Console.WriteLine(s);')
Expression: IInvocationExpression (void System.Console.WriteLine(System.String value)) (OperationKind.InvocationExpression, Type: System.Void) (Syntax: 'Console.WriteLine(s)')
Instance Receiver: null
Arguments(1):
IArgument (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument) (Syntax: 's')
IParameterReferenceExpression: s (OperationKind.ParameterReferenceExpression, Type: System.String) (Syntax: 's')
InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
";
var expectedDiagnostics = DiagnosticDescription.None;
VerifyOperationTreeAndDiagnosticsForTest<TryStatementSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
[CompilerTrait(CompilerFeature.IOperation)]
[Fact]
public void TryCatch_TryBlockWithLocalDeclaration()
{
string source = @"
using System;
class C
{
static void M(string s)
{
/*<bind>*/try
{
int i = 0;
}
catch (Exception)
{
}/*</bind>*/
}
}
";
string expectedOperationTree = @"
ITryStatement (OperationKind.TryStatement) (Syntax: 'try ... }')
Body: IBlockStatement (1 statements, 1 locals) (OperationKind.BlockStatement) (Syntax: '{ ... }')
Locals: Local_1: System.Int32 i
IVariableDeclarationStatement (1 declarations) (OperationKind.VariableDeclarationStatement) (Syntax: 'int i = 0;')
IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'i = 0')
Variables: Local_1: System.Int32 i
Initializer: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
Catch clauses(1):
ICatchClause (Exception type: System.Exception) (OperationKind.CatchClause) (Syntax: 'catch (Exce ... }')
ExceptionDeclarationOrExpression: null
Filter: null
Handler: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
Finally: null
";
var expectedDiagnostics = new DiagnosticDescription[] {
// CS0219: The variable 'i' is assigned but its value is never used
// int i = 0;
Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "i").WithArguments("i").WithLocation(10, 17)
};
VerifyOperationTreeAndDiagnosticsForTest<TryStatementSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
[CompilerTrait(CompilerFeature.IOperation)]
[Fact]
public void TryCatch_CatchClauseWithLocalDeclaration()
{
string source = @"
using System;
class C
{
static void M(string s)
{
/*<bind>*/try
{
}
catch (Exception)
{
int i = 0;
}/*</bind>*/
}
}
";
string expectedOperationTree = @"
ITryStatement (OperationKind.TryStatement) (Syntax: 'try ... }')
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
Catch clauses(1):
ICatchClause (Exception type: System.Exception) (OperationKind.CatchClause) (Syntax: 'catch (Exce ... }')
ExceptionDeclarationOrExpression: null
Filter: null
Handler: IBlockStatement (1 statements, 1 locals) (OperationKind.BlockStatement) (Syntax: '{ ... }')
Locals: Local_1: System.Int32 i
IVariableDeclarationStatement (1 declarations) (OperationKind.VariableDeclarationStatement) (Syntax: 'int i = 0;')
IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'i = 0')
Variables: Local_1: System.Int32 i
Initializer: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
Finally: null
";
var expectedDiagnostics = new DiagnosticDescription[] {
// CS0219: The variable 'i' is assigned but its value is never used
// int i = 0;
Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "i").WithArguments("i").WithLocation(13, 17)
};
VerifyOperationTreeAndDiagnosticsForTest<TryStatementSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
[CompilerTrait(CompilerFeature.IOperation)]
[Fact]
public void TryCatch_CatchFilterWithLocalDeclaration()
{
string source = @"
using System;
class C
{
static void M(object o)
{
/*<bind>*/try
{
}
catch (Exception) when (o is string s)
{
}/*</bind>*/
}
}
";
string expectedOperationTree = @"
ITryStatement (OperationKind.TryStatement) (Syntax: 'try ... }')
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
Catch clauses(1):
ICatchClause (Exception type: System.Exception) (OperationKind.CatchClause) (Syntax: 'catch (Exce ... }')
Locals: Local_1: System.String s
ExceptionDeclarationOrExpression: null
Filter: IIsPatternExpression (OperationKind.IsPatternExpression, Type: System.Boolean) (Syntax: 'o is string s')
Expression: IParameterReferenceExpression: o (OperationKind.ParameterReferenceExpression, Type: System.Object) (Syntax: 'o')
Pattern: IDeclarationPattern (Declared Symbol: System.String s) (OperationKind.DeclarationPattern) (Syntax: 'string s')
Handler: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
Finally: null
";
var expectedDiagnostics = DiagnosticDescription.None;
VerifyOperationTreeAndDiagnosticsForTest<TryStatementSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
[CompilerTrait(CompilerFeature.IOperation)]
[Fact]
public void TryCatch_CatchFilterAndSourceWithLocalDeclaration()
{
string source = @"
using System;
class C
{
static void M(object o)
{
/*<bind>*/try
{
}
catch (Exception e) when (o is string s)
{
}/*</bind>*/
}
}
";
string expectedOperationTree = @"
ITryStatement (OperationKind.TryStatement) (Syntax: 'try ... }')
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
Catch clauses(1):
ICatchClause (Exception type: System.Exception) (OperationKind.CatchClause) (Syntax: 'catch (Exce ... }')
Locals: Local_1: System.Exception e
Local_2: System.String s
ExceptionDeclarationOrExpression: IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: '(Exception e)')
Variables: Local_1: System.Exception e
Initializer: null
Filter: IIsPatternExpression (OperationKind.IsPatternExpression, Type: System.Boolean) (Syntax: 'o is string s')
Expression: IParameterReferenceExpression: o (OperationKind.ParameterReferenceExpression, Type: System.Object) (Syntax: 'o')
Pattern: IDeclarationPattern (Declared Symbol: System.String s) (OperationKind.DeclarationPattern) (Syntax: 'string s')
Handler: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
Finally: null
";
var expectedDiagnostics = new DiagnosticDescription[] {
// file.cs(11,26): warning CS0168: The variable 'e' is declared but never used
// catch (Exception e) when (o is string s)
Diagnostic(ErrorCode.WRN_UnreferencedVar, "e").WithArguments("e").WithLocation(11, 26)
};
VerifyOperationTreeAndDiagnosticsForTest<TryStatementSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
[CompilerTrait(CompilerFeature.IOperation)]
[Fact]
public void TryCatch_FinallyWithLocalDeclaration()
{
string source = @"
class C
{
static void Main()
{
/*<bind>*/try
{
}
finally
{
int i = 0;
}/*</bind>*/
}
}
";
string expectedOperationTree = @"
ITryStatement (OperationKind.TryStatement) (Syntax: 'try ... }')
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
Catch clauses(0)
Finally: IBlockStatement (1 statements, 1 locals) (OperationKind.BlockStatement) (Syntax: '{ ... }')
Locals: Local_1: System.Int32 i
IVariableDeclarationStatement (1 declarations) (OperationKind.VariableDeclarationStatement) (Syntax: 'int i = 0;')
IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'i = 0')
Variables: Local_1: System.Int32 i
Initializer: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
";
var expectedDiagnostics = new DiagnosticDescription[] {
// CS0219: The variable 'i' is assigned but its value is never used
// int i = 0;
Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "i").WithArguments("i").WithLocation(11, 17)
};
VerifyOperationTreeAndDiagnosticsForTest<TryStatementSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
[CompilerTrait(CompilerFeature.IOperation)]
[Fact]
public void TryCatch_InvalidCaughtType()
{
string source = @"
class C
{
static void Main()
{
try
{
}
/*<bind>*/catch (int e)
{
}/*</bind>*/
}
}
";
string expectedOperationTree = @"
ICatchClause (Exception type: System.Int32) (OperationKind.CatchClause, IsInvalid) (Syntax: 'catch (int ... }')
Locals: Local_1: System.Int32 e
ExceptionDeclarationOrExpression: IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration, IsInvalid) (Syntax: '(int e)')
Variables: Local_1: System.Int32 e
Initializer: null
Filter: null
Handler: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
";
var expectedDiagnostics = new DiagnosticDescription[] {
// CS0155: The type caught or thrown must be derived from System.Exception
// /*<bind>*/catch (int e)
Diagnostic(ErrorCode.ERR_BadExceptionType, "int").WithLocation(9, 26),
// CS0168: The variable 'e' is declared but never used
// /*<bind>*/catch (int e)
Diagnostic(ErrorCode.WRN_UnreferencedVar, "e").WithArguments("e").WithLocation(9, 30)
};
VerifyOperationTreeAndDiagnosticsForTest<CatchClauseSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
[CompilerTrait(CompilerFeature.IOperation)]
[Fact]
public void TryCatch_GetOperationForCatchClause()
{
string source = @"
class C
{
static void Main()
{
try
{
}
/*<bind>*/catch (System.IO.IOException e) when (e.Message != null)
{
}/*</bind>*/
}
}
";
string expectedOperationTree = @"
ICatchClause (Exception type: System.IO.IOException) (OperationKind.CatchClause) (Syntax: 'catch (Syst ... }')
Locals: Local_1: System.IO.IOException e
ExceptionDeclarationOrExpression: IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: '(System.IO. ... xception e)')
Variables: Local_1: System.IO.IOException e
Initializer: null
Filter: IBinaryOperatorExpression (BinaryOperatorKind.NotEquals) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: 'e.Message != null')
Left: IPropertyReferenceExpression: System.String System.Exception.Message { get; } (OperationKind.PropertyReferenceExpression, Type: System.String) (Syntax: 'e.Message')
Instance Receiver: ILocalReferenceExpression: e (OperationKind.LocalReferenceExpression, Type: System.IO.IOException) (Syntax: 'e')
Right: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.String, Constant: null) (Syntax: 'null')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
Operand: ILiteralExpression (OperationKind.LiteralExpression, Type: null, Constant: null) (Syntax: 'null')
Handler: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
";
var expectedDiagnostics = DiagnosticDescription.None;
VerifyOperationTreeAndDiagnosticsForTest<CatchClauseSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
[CompilerTrait(CompilerFeature.IOperation)]
[Fact]
public void TryCatch_GetOperationForCatchDeclaration()
{
string source = @"
class C
{
static void Main()
{
try
{
}
catch /*<bind>*/(System.IO.IOException e)/*</bind>*/ when (e.Message != null)
{
}
}
}
";
string expectedOperationTree = @"
IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: '(System.IO. ... xception e)')
Variables: Local_1: System.IO.IOException e
Initializer: null
";
var expectedDiagnostics = DiagnosticDescription.None;
VerifyOperationTreeAndDiagnosticsForTest<CatchDeclarationSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
[CompilerTrait(CompilerFeature.IOperation)]
[Fact]
public void TryCatch_GetOperationForCatchFilterClause()
{
string source = @"
using System;
class C
{
static void M(string s)
{
try
{
}
catch (Exception) /*<bind>*/when (s != null)/*</bind>*/
{
}
}
}
";
// GetOperation returns null for CatchFilterClauseSyntax
Assert.Null(GetOperationTreeForTest<CatchFilterClauseSyntax>(source));
}
[CompilerTrait(CompilerFeature.IOperation)]
[Fact]
public void TryCatch_GetOperationForCatchFilterClauseExpression()
{
string source = @"
using System;
class C
{
static void M(string s)
{
try
{
}
catch (Exception) when (/*<bind>*/s != null/*</bind>*/)
{
}
}
}
";
string expectedOperationTree = @"
IBinaryOperatorExpression (BinaryOperatorKind.NotEquals) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: 's != null')
Left: IParameterReferenceExpression: s (OperationKind.ParameterReferenceExpression, Type: System.String) (Syntax: 's')
Right: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.String, Constant: null) (Syntax: 'null')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
Operand: ILiteralExpression (OperationKind.LiteralExpression, Type: null, Constant: null) (Syntax: 'null')
";
var expectedDiagnostics = DiagnosticDescription.None;
VerifyOperationTreeAndDiagnosticsForTest<BinaryExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
[CompilerTrait(CompilerFeature.IOperation)]
[Fact]
public void TryCatch_GetOperationForFinallyClause()
{
string source = @"
using System;
class C
{
static void M(string s)
{
try
{
}
/*<bind>*/finally
{
Console.WriteLine(s);
}/*</bind>*/
}
}
";
// GetOperation returns null for FinallyClauseSyntax
Assert.Null(GetOperationTreeForTest<FinallyClauseSyntax>(source));
}
}
}
......@@ -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)')
......
......@@ -27,14 +27,18 @@ Class C
End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
ITryStatement (OperationKind.None) (Syntax: 'Try'BIND:"T ... End Try')
ITryStatement (OperationKind.TryStatement) (Syntax: 'Try'BIND:"T ... End Try')
Body: IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'Try'BIND:"T ... End Try')
IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: 'i = 0')
Expression: ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32) (Syntax: 'i = 0')
Left: IParameterReferenceExpression: i (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'i')
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
Catch clauses(1):
ICatchClause (Exception type: System.Exception, Exception local: ex As System.Exception) (OperationKind.None) (Syntax: 'Catch ex As ... Throw ex')
ICatchClause (Exception type: System.Exception) (OperationKind.CatchClause) (Syntax: 'Catch ex As ... Throw ex')
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.GreaterThan, Checked) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: 'i > 0')
Left: IParameterReferenceExpression: i (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'i')
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
......@@ -74,14 +78,18 @@ End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
IBlockStatement (3 statements) (OperationKind.BlockStatement) (Syntax: 'Private Sub ... End Sub')
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: 'i = 0')
Expression: ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32) (Syntax: 'i = 0')
Left: IParameterReferenceExpression: i (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'i')
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
Catch clauses(1):
ICatchClause (Exception type: System.Exception, Exception local: ex As System.Exception) (OperationKind.None) (Syntax: 'Catch ex As ... Throw ex')
ICatchClause (Exception type: System.Exception) (OperationKind.CatchClause) (Syntax: 'Catch ex As ... Throw ex')
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.GreaterThan, Checked) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: 'i > 0')
Left: IParameterReferenceExpression: i (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'i')
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
......@@ -104,5 +112,907 @@ IBlockStatement (3 statements) (OperationKind.BlockStatement) (Syntax: 'Private
VerifyOperationTreeAndDiagnosticsForTest(Of MethodBlockSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact>
Public Sub TryCatch_SingleCatchClause()
Dim source = <![CDATA[
Class C
Private Shared Sub M()
Try'BIND:"Try"
Catch e As System.IO.IOException
End Try
End Sub
End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
ITryStatement (OperationKind.TryStatement) (Syntax: 'Try'BIND:"T ... End Try')
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: 'Try'BIND:"T ... End Try')
Catch clauses(1):
ICatchClause (Exception type: System.IO.IOException) (OperationKind.CatchClause) (Syntax: 'Catch e As ... IOException')
Locals: Local_1: e As System.IO.IOException
ExceptionDeclarationOrExpression: IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'e')
Variables: Local_1: e As System.IO.IOException
Initializer: null
Filter: null
Handler: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: 'Catch e As ... IOException')
Finally: null
]]>.Value
Dim expectedDiagnostics = String.Empty
VerifyOperationTreeAndDiagnosticsForTest(Of TryBlockSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact>
Public Sub TryCatch_SingleCatchClauseAndFilter()
Dim source = <![CDATA[
Class C
Private Shared Sub M()
Try'BIND:"Try"
Catch e As System.IO.IOException When e.Message IsNot Nothing
End Try
End Sub
End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
ITryStatement (OperationKind.TryStatement) (Syntax: 'Try'BIND:"T ... End Try')
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: 'Try'BIND:"T ... End Try')
Catch clauses(1):
ICatchClause (Exception type: System.IO.IOException) (OperationKind.CatchClause) (Syntax: 'Catch e As ... Not Nothing')
Locals: Local_1: e As System.IO.IOException
ExceptionDeclarationOrExpression: IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'e')
Variables: Local_1: e As System.IO.IOException
Initializer: null
Filter: IBinaryOperatorExpression (BinaryOperatorKind.NotEquals) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: 'e.Message IsNot Nothing')
Left: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Object) (Syntax: 'e.Message')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
Operand: IPropertyReferenceExpression: ReadOnly Property System.Exception.Message As System.String (OperationKind.PropertyReferenceExpression, Type: System.String) (Syntax: 'e.Message')
Instance Receiver: ILocalReferenceExpression: e (OperationKind.LocalReferenceExpression, Type: System.IO.IOException) (Syntax: 'e')
Right: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Object, Constant: null) (Syntax: 'Nothing')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand: ILiteralExpression (OperationKind.LiteralExpression, Type: null, Constant: null) (Syntax: 'Nothing')
Handler: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: 'Catch e As ... Not Nothing')
Finally: null
]]>.Value
Dim expectedDiagnostics = String.Empty
VerifyOperationTreeAndDiagnosticsForTest(Of TryBlockSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact>
Public Sub TryCatch_MultipleCatchClausesWithDifferentCaughtTypes()
Dim source = <![CDATA[
Class C
Private Shared Sub M()
Try'BIND:"Try"
Catch e As System.IO.IOException
Catch e As System.Exception When e.Message IsNot Nothing
End Try
End Sub
End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
ITryStatement (OperationKind.TryStatement) (Syntax: 'Try'BIND:"T ... End Try')
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: 'Try'BIND:"T ... End Try')
Catch clauses(2):
ICatchClause (Exception type: System.IO.IOException) (OperationKind.CatchClause) (Syntax: 'Catch e As ... IOException')
Locals: Local_1: e As System.IO.IOException
ExceptionDeclarationOrExpression: IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'e')
Variables: Local_1: e As System.IO.IOException
Initializer: null
Filter: null
Handler: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: 'Catch e As ... IOException')
ICatchClause (Exception type: System.Exception) (OperationKind.CatchClause) (Syntax: 'Catch e As ... Not Nothing')
Locals: Local_1: e As System.Exception
ExceptionDeclarationOrExpression: IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'e')
Variables: Local_1: e As System.Exception
Initializer: null
Filter: IBinaryOperatorExpression (BinaryOperatorKind.NotEquals) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: 'e.Message IsNot Nothing')
Left: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Object) (Syntax: 'e.Message')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
Operand: IPropertyReferenceExpression: ReadOnly Property System.Exception.Message As System.String (OperationKind.PropertyReferenceExpression, Type: System.String) (Syntax: 'e.Message')
Instance Receiver: ILocalReferenceExpression: e (OperationKind.LocalReferenceExpression, Type: System.Exception) (Syntax: 'e')
Right: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Object, Constant: null) (Syntax: 'Nothing')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand: ILiteralExpression (OperationKind.LiteralExpression, Type: null, Constant: null) (Syntax: 'Nothing')
Handler: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: 'Catch e As ... Not Nothing')
Finally: null
]]>.Value
Dim expectedDiagnostics = String.Empty
VerifyOperationTreeAndDiagnosticsForTest(Of TryBlockSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact>
Public Sub TryCatch_MultipleCatchClausesWithDuplicateCaughtTypes()
Dim source = <![CDATA[
Class C
Private Shared Sub M()
Try'BIND:"Try"
Catch e As System.IO.IOException
Catch e As System.IO.IOException When e.Message IsNot Nothing
End Try
End Sub
End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
ITryStatement (OperationKind.TryStatement) (Syntax: 'Try'BIND:"T ... End Try')
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: 'Try'BIND:"T ... End Try')
Catch clauses(2):
ICatchClause (Exception type: System.IO.IOException) (OperationKind.CatchClause) (Syntax: 'Catch e As ... IOException')
Locals: Local_1: e As System.IO.IOException
ExceptionDeclarationOrExpression: IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'e')
Variables: Local_1: e As System.IO.IOException
Initializer: null
Filter: null
Handler: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: 'Catch e As ... IOException')
ICatchClause (Exception type: System.IO.IOException) (OperationKind.CatchClause) (Syntax: 'Catch e As ... Not Nothing')
Locals: Local_1: e As System.IO.IOException
ExceptionDeclarationOrExpression: IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'e')
Variables: Local_1: e As System.IO.IOException
Initializer: null
Filter: IBinaryOperatorExpression (BinaryOperatorKind.NotEquals) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: 'e.Message IsNot Nothing')
Left: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Object) (Syntax: 'e.Message')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
Operand: IPropertyReferenceExpression: ReadOnly Property System.Exception.Message As System.String (OperationKind.PropertyReferenceExpression, Type: System.String) (Syntax: 'e.Message')
Instance Receiver: ILocalReferenceExpression: e (OperationKind.LocalReferenceExpression, Type: System.IO.IOException) (Syntax: 'e')
Right: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Object, Constant: null) (Syntax: 'Nothing')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand: ILiteralExpression (OperationKind.LiteralExpression, Type: null, Constant: null) (Syntax: 'Nothing')
Handler: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: 'Catch e As ... Not Nothing')
Finally: null
]]>.Value
Dim expectedDiagnostics = <![CDATA[
BC42031: 'Catch' block never reached; 'IOException' handled above in the same Try statement.
Catch e As System.IO.IOException When e.Message IsNot Nothing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
]]>.Value
VerifyOperationTreeAndDiagnosticsForTest(Of TryBlockSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact>
Public Sub TryCatch_CatchClauseWithTypeExpression()
Dim source = <![CDATA[
Class C
Private Shared Sub M()
Try'BIND:"Try"
Catch System.Exception
End Try
End Sub
End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
ITryStatement (OperationKind.TryStatement, IsInvalid) (Syntax: 'Try'BIND:"T ... End Try')
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement, IsInvalid) (Syntax: 'Try'BIND:"T ... End Try')
Catch clauses(1):
ICatchClause (Exception type: ?) (OperationKind.CatchClause, IsInvalid) (Syntax: 'Catch System')
ExceptionDeclarationOrExpression: IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: 'System')
Children(1):
IOperation: (OperationKind.None, IsInvalid) (Syntax: 'System')
Filter: null
Handler: IBlockStatement (0 statements) (OperationKind.BlockStatement, IsInvalid) (Syntax: 'Catch System')
Finally: null
]]>.Value
Dim expectedDiagnostics = <![CDATA[
BC31082: 'System' is not a local variable or parameter, and so cannot be used as a 'Catch' variable.
Catch System.Exception
~~~~~~
BC30205: End of statement expected.
Catch System.Exception
~
]]>.Value
VerifyOperationTreeAndDiagnosticsForTest(Of TryBlockSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact>
Public Sub TryCatch_CatchClauseWithLocalReferenceExpression()
Dim source = <![CDATA[
Imports System
Class C
Private Shared Sub M()
Dim e As IO.IOException = Nothing
Try'BIND:"Try"
Catch e
End Try
End Sub
End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
ITryStatement (OperationKind.TryStatement) (Syntax: 'Try'BIND:"T ... End Try')
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: 'Try'BIND:"T ... End Try')
Catch clauses(1):
ICatchClause (Exception type: System.IO.IOException) (OperationKind.CatchClause) (Syntax: 'Catch e')
ExceptionDeclarationOrExpression: ILocalReferenceExpression: e (OperationKind.LocalReferenceExpression, Type: System.IO.IOException) (Syntax: 'e')
Filter: null
Handler: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: 'Catch e')
Finally: null
]]>.Value
Dim expectedDiagnostics = String.Empty
VerifyOperationTreeAndDiagnosticsForTest(Of TryBlockSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact>
Public Sub TryCatch_CatchClauseWithParameterReferenceExpression()
Dim source = <![CDATA[
Imports System
Class C
Private Shared Sub M(e As IO.IOException)
Try'BIND:"Try"
Catch e
End Try
End Sub
End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
ITryStatement (OperationKind.TryStatement) (Syntax: 'Try'BIND:"T ... End Try')
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: 'Try'BIND:"T ... End Try')
Catch clauses(1):
ICatchClause (Exception type: System.IO.IOException) (OperationKind.CatchClause) (Syntax: 'Catch e')
ExceptionDeclarationOrExpression: IParameterReferenceExpression: e (OperationKind.ParameterReferenceExpression, Type: System.IO.IOException) (Syntax: 'e')
Filter: null
Handler: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: 'Catch e')
Finally: null
]]>.Value
Dim expectedDiagnostics = String.Empty
VerifyOperationTreeAndDiagnosticsForTest(Of TryBlockSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact>
Public Sub TryCatch_CatchClauseWithFieldReferenceExpression()
Dim source = <![CDATA[
Imports System
Class C
Private e As IO.IOException = Nothing
Private Sub M()
Try 'BIND:"Try"'BIND:"Try 'BIND:"Try""
Catch e
End Try
End Sub
End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
ITryStatement (OperationKind.TryStatement, IsInvalid) (Syntax: 'Try 'BIND:" ... End Try')
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement, IsInvalid) (Syntax: 'Try 'BIND:" ... End Try')
Catch clauses(1):
ICatchClause (Exception type: System.IO.IOException) (OperationKind.CatchClause, IsInvalid) (Syntax: 'Catch e')
ExceptionDeclarationOrExpression: IFieldReferenceExpression: C.e As System.IO.IOException (OperationKind.FieldReferenceExpression, Type: System.IO.IOException, IsInvalid) (Syntax: 'e')
Instance Receiver: IInstanceReferenceExpression (OperationKind.InstanceReferenceExpression, Type: C, IsInvalid) (Syntax: 'e')
Filter: null
Handler: IBlockStatement (0 statements) (OperationKind.BlockStatement, IsInvalid) (Syntax: 'Catch e')
Finally: null
]]>.Value
Dim expectedDiagnostics = <![CDATA[
BC31082: 'e' is not a local variable or parameter, and so cannot be used as a 'Catch' variable.
Catch e
~
]]>.Value
VerifyOperationTreeAndDiagnosticsForTest(Of TryBlockSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact>
Public Sub TryCatch_CatchClauseWithErrorExpression()
Dim source = <![CDATA[
Imports System
Class C
Private Shared Sub M()
Try'BIND:"Try"
Catch e
End Try
End Sub
End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
ITryStatement (OperationKind.TryStatement, IsInvalid) (Syntax: 'Try'BIND:"T ... End Try')
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement, IsInvalid) (Syntax: 'Try'BIND:"T ... End Try')
Catch clauses(1):
ICatchClause (Exception type: ?) (OperationKind.CatchClause, IsInvalid) (Syntax: 'Catch e')
ExceptionDeclarationOrExpression: IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: 'e')
Children(0)
Filter: null
Handler: IBlockStatement (0 statements) (OperationKind.BlockStatement, IsInvalid) (Syntax: 'Catch e')
Finally: null
]]>.Value
Dim expectedDiagnostics = <![CDATA[
BC30451: 'e' is not declared. It may be inaccessible due to its protection level.
Catch e
~
]]>.Value
VerifyOperationTreeAndDiagnosticsForTest(Of TryBlockSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact>
Public Sub TryCatch_CatchClauseWithInvalidExpression()
Dim source = <![CDATA[
Imports System
Class C
Private Shared Sub M()
Try'BIND:"Try"
Catch M2(e)
End Try
End Sub
Private Shared Function M2(e As Exception) As Exception
Return e
End Function
End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
ITryStatement (OperationKind.TryStatement, IsInvalid) (Syntax: 'Try'BIND:"T ... End Try')
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement, IsInvalid) (Syntax: 'Try'BIND:"T ... End Try')
Catch clauses(1):
ICatchClause (Exception type: ?) (OperationKind.CatchClause, IsInvalid) (Syntax: 'Catch M2')
ExceptionDeclarationOrExpression: IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: 'M2')
Children(1):
IOperation: (OperationKind.None, IsInvalid) (Syntax: 'M2')
Children(1):
IInstanceReferenceExpression (OperationKind.InstanceReferenceExpression, Type: C, IsInvalid) (Syntax: 'M2')
Filter: null
Handler: IBlockStatement (0 statements) (OperationKind.BlockStatement, IsInvalid) (Syntax: 'Catch M2')
Finally: null
]]>.Value
Dim expectedDiagnostics = <![CDATA[
BC31082: 'M2' is not a local variable or parameter, and so cannot be used as a 'Catch' variable.
Catch M2(e)
~~
BC30205: End of statement expected.
Catch M2(e)
~
]]>.Value
VerifyOperationTreeAndDiagnosticsForTest(Of TryBlockSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact>
Public Sub TryCatch_CatchClauseWithoutCaughtTypeOrExceptionLocal()
Dim source = <![CDATA[
Class C
Private Shared Sub M()
Try'BIND:"Try"
Catch
End Try
End Sub
End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
ITryStatement (OperationKind.TryStatement) (Syntax: 'Try'BIND:"T ... End Try')
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: 'Try'BIND:"T ... End Try')
Catch clauses(1):
ICatchClause (Exception type: System.Exception) (OperationKind.CatchClause) (Syntax: 'Catch')
ExceptionDeclarationOrExpression: null
Filter: null
Handler: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: 'Catch')
Finally: null
]]>.Value
Dim expectedDiagnostics = String.Empty
VerifyOperationTreeAndDiagnosticsForTest(Of TryBlockSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact>
Public Sub TryCatch_FinallyWithoutCatchClause()
Dim source = <![CDATA[
Imports System
Class C
Private Shared Sub M(s As String)
Try'BIND:"Try"
Finally
Console.WriteLine(s)
End Try
End Sub
End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
ITryStatement (OperationKind.TryStatement) (Syntax: 'Try'BIND:"T ... End Try')
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: 'Try'BIND:"T ... End Try')
Catch clauses(0)
Finally: IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'Finally ... riteLine(s)')
IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: 'Console.WriteLine(s)')
Expression: IInvocationExpression (Sub System.Console.WriteLine(value As System.String)) (OperationKind.InvocationExpression, Type: System.Void) (Syntax: 'Console.WriteLine(s)')
Instance Receiver: null
Arguments(1):
IArgument (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument) (Syntax: 's')
IParameterReferenceExpression: s (OperationKind.ParameterReferenceExpression, Type: System.String) (Syntax: 's')
InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
]]>.Value
Dim expectedDiagnostics = String.Empty
VerifyOperationTreeAndDiagnosticsForTest(Of TryBlockSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact>
Public Sub TryCatch_TryBlockWithLocalDeclaration()
Dim source = <![CDATA[
Imports System
Class C
Private Shared Sub M(s As String)
Try'BIND:"Try"
Dim i As Integer = 0
Finally
End Try
End Sub
End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
ITryStatement (OperationKind.TryStatement) (Syntax: 'Try'BIND:"T ... End Try')
Body: IBlockStatement (1 statements, 1 locals) (OperationKind.BlockStatement) (Syntax: 'Try'BIND:"T ... End Try')
Locals: Local_1: i As System.Int32
IVariableDeclarationStatement (1 declarations) (OperationKind.VariableDeclarationStatement) (Syntax: 'Dim i As Integer = 0')
IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'i')
Variables: Local_1: i As System.Int32
Initializer: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
Catch clauses(0)
Finally: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: 'Finally')
]]>.Value
Dim expectedDiagnostics = String.Empty
VerifyOperationTreeAndDiagnosticsForTest(Of TryBlockSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact>
Public Sub TryCatch_CatchBlockWithLocalDeclaration()
Dim source = <![CDATA[
Imports System
Class C
Private Shared Sub M(s As String)
Try'BIND:"Try"
Catch ex As Exception
Dim i As Integer = 0
End Try
End Sub
End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
ITryStatement (OperationKind.TryStatement) (Syntax: 'Try'BIND:"T ... End Try')
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: 'Try'BIND:"T ... End Try')
Catch clauses(1):
ICatchClause (Exception type: System.Exception) (OperationKind.CatchClause) (Syntax: 'Catch ex As ... Integer = 0')
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: null
Handler: IBlockStatement (1 statements, 1 locals) (OperationKind.BlockStatement) (Syntax: 'Catch ex As ... Integer = 0')
Locals: Local_1: i As System.Int32
IVariableDeclarationStatement (1 declarations) (OperationKind.VariableDeclarationStatement) (Syntax: 'Dim i As Integer = 0')
IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'i')
Variables: Local_1: i As System.Int32
Initializer: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
Finally: null
]]>.Value
Dim expectedDiagnostics = String.Empty
VerifyOperationTreeAndDiagnosticsForTest(Of TryBlockSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact>
Public Sub TryCatch_FinallyWithLocalDeclaration()
Dim source = <![CDATA[
Imports System
Class C
Private Shared Sub M(s As String)
Try'BIND:"Try"
Finally
Dim i As Integer = 0
End Try
End Sub
End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
ITryStatement (OperationKind.TryStatement) (Syntax: 'Try'BIND:"T ... End Try')
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: 'Try'BIND:"T ... End Try')
Catch clauses(0)
Finally: IBlockStatement (1 statements, 1 locals) (OperationKind.BlockStatement) (Syntax: 'Finally ... Integer = 0')
Locals: Local_1: i As System.Int32
IVariableDeclarationStatement (1 declarations) (OperationKind.VariableDeclarationStatement) (Syntax: 'Dim i As Integer = 0')
IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'i')
Variables: Local_1: i As System.Int32
Initializer: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
]]>.Value
Dim expectedDiagnostics = String.Empty
VerifyOperationTreeAndDiagnosticsForTest(Of TryBlockSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact>
Public Sub TryCatch_InvalidCaughtType()
Dim source = <![CDATA[
Imports System
Class C
Private Shared Sub M(s As String)
Try'BIND:"Try"
Catch i As Integer
End Try
End Sub
End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
ITryStatement (OperationKind.TryStatement, IsInvalid) (Syntax: 'Try'BIND:"T ... End Try')
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement, IsInvalid) (Syntax: 'Try'BIND:"T ... End Try')
Catch clauses(1):
ICatchClause (Exception type: System.Int32) (OperationKind.CatchClause, IsInvalid) (Syntax: 'Catch i As Integer')
Locals: Local_1: i As System.Int32
ExceptionDeclarationOrExpression: IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'i')
Variables: Local_1: i As System.Int32
Initializer: null
Filter: null
Handler: IBlockStatement (0 statements) (OperationKind.BlockStatement, IsInvalid) (Syntax: 'Catch i As Integer')
Finally: null
]]>.Value
Dim expectedDiagnostics = <![CDATA[
BC30392: 'Catch' cannot catch type 'Integer' because it is not 'System.Exception' or a class that inherits from 'System.Exception'.
Catch i As Integer
~~~~~~~
]]>.Value
VerifyOperationTreeAndDiagnosticsForTest(Of TryBlockSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact>
Public Sub TryCatch_GetOperationForCatchBlock()
Dim source = <![CDATA[
Imports System
Class C
Private Shared Sub M()
Try
Catch e As IO.IOException When e.Message IsNot Nothing'BIND:"Catch e As IO.IOException When e.Message IsNot Nothing"
End Try
End Sub
End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
ICatchClause (Exception type: System.IO.IOException) (OperationKind.CatchClause) (Syntax: 'Catch e As ... Not Nothing')
Locals: Local_1: e As System.IO.IOException
ExceptionDeclarationOrExpression: IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'e')
Variables: Local_1: e As System.IO.IOException
Initializer: null
Filter: IBinaryOperatorExpression (BinaryOperatorKind.NotEquals) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: 'e.Message IsNot Nothing')
Left: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Object) (Syntax: 'e.Message')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
Operand: IPropertyReferenceExpression: ReadOnly Property System.Exception.Message As System.String (OperationKind.PropertyReferenceExpression, Type: System.String) (Syntax: 'e.Message')
Instance Receiver: ILocalReferenceExpression: e (OperationKind.LocalReferenceExpression, Type: System.IO.IOException) (Syntax: 'e')
Right: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Object, Constant: null) (Syntax: 'Nothing')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand: ILiteralExpression (OperationKind.LiteralExpression, Type: null, Constant: null) (Syntax: 'Nothing')
Handler: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: 'Catch e As ... Not Nothing')
]]>.Value
Dim expectedDiagnostics = String.Empty
VerifyOperationTreeAndDiagnosticsForTest(Of CatchBlockSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact>
Public Sub TryCatch_GetOperationForFinallyBlock()
Dim source = <![CDATA[
Imports System
Class C
Private Shared Sub M(s As String)
Try
Finally'BIND:"Finally"
Console.WriteLine(s)
End Try
End Sub
End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'Finally'BIN ... riteLine(s)')
IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: 'Console.WriteLine(s)')
Expression: IInvocationExpression (Sub System.Console.WriteLine(value As System.String)) (OperationKind.InvocationExpression, Type: System.Void) (Syntax: 'Console.WriteLine(s)')
Instance Receiver: null
Arguments(1):
IArgument (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument) (Syntax: 's')
IParameterReferenceExpression: s (OperationKind.ParameterReferenceExpression, Type: System.String) (Syntax: 's')
InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
]]>.Value
Dim expectedDiagnostics = String.Empty
VerifyOperationTreeAndDiagnosticsForTest(Of FinallyBlockSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact>
Public Sub TryCatch_GetOperationForCatchExceptionIdentifier()
Dim source = <![CDATA[
Imports System
Class C
Private Sub M(e As Exception)
Try
Catch e'BIND:"e"
End Try
End Sub
End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
IParameterReferenceExpression: e (OperationKind.ParameterReferenceExpression, Type: System.Exception) (Syntax: 'e')
]]>.Value
Dim expectedDiagnostics = String.Empty
VerifyOperationTreeAndDiagnosticsForTest(Of IdentifierNameSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact(Skip:="https://github.com/dotnet/roslyn/issues/22299")>
Public Sub TryCatch_GetOperationForCatchExceptionDeclaration()
Dim source = <![CDATA[
Imports System
Class C
Private Sub M()
Try
Catch e As Exception'BIND:"e"
End Try
End Sub
End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'e')
Variables: Local_1: e As System.Exception
Initializer: null
]]>.Value
Dim expectedDiagnostics = String.Empty
VerifyOperationTreeAndDiagnosticsForTest(Of IdentifierNameSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact>
Public Sub TryCatch_GetOperationForCatchFilterClause()
Dim source = <![CDATA[
Imports System
Class C
Private Shared Sub M()
Try
Catch e As IO.IOException When e.Message IsNot Nothing'BIND:"When e.Message IsNot Nothing"
End Try
End Sub
End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
]]>.Value
' GetOperation return Nothing for CatchFilterClauseSyntax
Assert.Null(GetOperationTreeForTest(Of CatchFilterClauseSyntax)(source).operation)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact>
Public Sub TryCatch_GetOperationForCatchFilterClauseExpression()
Dim source = <![CDATA[
Imports System
Class C
Private Shared Sub M()
Try
Catch e As IO.IOException When e.Message IsNot Nothing'BIND:"e.Message IsNot Nothing"
End Try
End Sub
End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
IBinaryOperatorExpression (BinaryOperatorKind.NotEquals) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: 'e.Message IsNot Nothing')
Left: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Object) (Syntax: 'e.Message')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
Operand: IPropertyReferenceExpression: ReadOnly Property System.Exception.Message As System.String (OperationKind.PropertyReferenceExpression, Type: System.String) (Syntax: 'e.Message')
Instance Receiver: ILocalReferenceExpression: e (OperationKind.LocalReferenceExpression, Type: System.IO.IOException) (Syntax: 'e')
Right: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Object, Constant: null) (Syntax: 'Nothing')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand: ILiteralExpression (OperationKind.LiteralExpression, Type: null, Constant: null) (Syntax: 'Nothing')
]]>.Value
Dim expectedDiagnostics = String.Empty
VerifyOperationTreeAndDiagnosticsForTest(Of BinaryExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact>
Public Sub TryCatch_GetOperationForCatchStatement()
Dim source = <![CDATA[
Imports System
Class C
Private Shared Sub M()
Try
Catch e As IO.IOException When e.Message IsNot Nothing'BIND:"Catch e As IO.IOException When e.Message IsNot Nothing"
End Try
End Sub
End Class]]>.Value
' GetOperation returns Nothing for CatchStatementSyntax
Assert.Null(GetOperationTreeForTest(Of CatchStatementSyntax)(source).operation)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact>
Public Sub TryCatch_GetOperationForTryStatement()
Dim source = <![CDATA[
Imports System
Class C
Private Shared Sub M()
Try'BIND:"Try"
Catch e As IO.IOException When e.Message IsNot Nothing
End Try
End Sub
End Class]]>.Value
' GetOperation returns Nothing for TryStatementSyntax
Assert.Null(GetOperationTreeForTest(Of TryStatementSyntax)(source).operation)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact>
Public Sub TryCatch_GetOperationForEndTryStatement()
Dim source = <![CDATA[
Imports System
Class C
Private Shared Sub M()
Try
Catch e As IO.IOException When e.Message IsNot Nothing
End Try'BIND:"End Try"
End Sub
End Class]]>.Value
' GetOperation returns Nothing for End Try statement
Assert.Null(GetOperationTreeForTest(Of EndBlockStatementSyntax)(source).operation)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact>
Public Sub TryCatch_GetOperationForFinallyStatement()
Dim source = <![CDATA[
Imports System
Class C
Private Shared Sub M(s As String)
Try
Finally'BIND:"Finally"
Console.WriteLine(s)
End Try
End Sub
End Class]]>.Value
' GetOperation returns Nothing for FinallyStatementSyntax
Assert.Null(GetOperationTreeForTest(Of FinallyStatementSyntax)(source).operation)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact>
Public Sub TryCatch_GetOperationForStatementInTryBlock()
Dim source = <![CDATA[
Imports System
Class C
Private Shared Sub M(s As String)
Try
Console.WriteLine(s)'BIND:"Console.WriteLine(s)"
Catch e As IO.IOException
End Try
End Sub
End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: 'Console.WriteLine(s)')
Expression: IInvocationExpression (Sub System.Console.WriteLine(value As System.String)) (OperationKind.InvocationExpression, Type: System.Void) (Syntax: 'Console.WriteLine(s)')
Instance Receiver: null
Arguments(1):
IArgument (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument) (Syntax: 's')
IParameterReferenceExpression: s (OperationKind.ParameterReferenceExpression, Type: System.String) (Syntax: 's')
InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
]]>.Value
Dim expectedDiagnostics = String.Empty
VerifyOperationTreeAndDiagnosticsForTest(Of ExpressionStatementSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact>
Public Sub TryCatch_GetOperationForStatementInCatchBlock()
Dim source = <![CDATA[
Imports System
Class C
Private Shared Sub M()
Try
Catch e As IO.IOException
Console.WriteLine(e)'BIND:"Console.WriteLine(e)"
End Try
End Sub
End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: 'Console.WriteLine(e)')
Expression: IInvocationExpression (Sub System.Console.WriteLine(value As System.Object)) (OperationKind.InvocationExpression, Type: System.Void) (Syntax: 'Console.WriteLine(e)')
Instance Receiver: null
Arguments(1):
IArgument (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument) (Syntax: 'e')
IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Object) (Syntax: 'e')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
Operand: ILocalReferenceExpression: e (OperationKind.LocalReferenceExpression, Type: System.IO.IOException) (Syntax: 'e')
InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
]]>.Value
Dim expectedDiagnostics = String.Empty
VerifyOperationTreeAndDiagnosticsForTest(Of ExpressionStatementSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact>
Public Sub TryCatch_GetOperationForStatementInFinallyBlock()
Dim source = <![CDATA[
Imports System
Class C
Private Shared Sub M(s As String)
Try
Finally
Console.WriteLine(s)'BIND:"Console.WriteLine(s)"
End Try
End Sub
End Class]]>.Value
Dim expectedOperationTree = <![CDATA[
IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: 'Console.WriteLine(s)')
Expression: IInvocationExpression (Sub System.Console.WriteLine(value As System.String)) (OperationKind.InvocationExpression, Type: System.Void) (Syntax: 'Console.WriteLine(s)')
Instance Receiver: null
Arguments(1):
IArgument (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument) (Syntax: 's')
IParameterReferenceExpression: s (OperationKind.ParameterReferenceExpression, Type: System.String) (Syntax: 's')
InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
]]>.Value
Dim expectedDiagnostics = String.Empty
VerifyOperationTreeAndDiagnosticsForTest(Of ExpressionStatementSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
End Class
End Namespace
......@@ -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.
先完成此消息的编辑!
想要评论请 注册