未验证 提交 a250209f 编写于 作者: A AlekseyTs 提交者: GitHub

Handle lock statement in control flow graph (#25916)

* Handle lock statement in control flow graph
* Improve handling of IConditionalAccessOperation used at the statement level.
上级 6e2f0574
......@@ -1277,6 +1277,11 @@ internal Symbol GetSpecialTypeMember(SpecialMember specialMember)
return Assembly.GetSpecialTypeMember(specialMember);
}
internal override ISymbol CommonGetSpecialTypeMember(SpecialMember specialMember)
{
return GetSpecialTypeMember(specialMember);
}
internal TypeSymbol GetTypeByReflectionType(Type type, DiagnosticBag diagnostics)
{
var result = Assembly.GetTypeByReflectionType(type, includeReferences: true);
......
......@@ -2372,5 +2372,101 @@ void M(dynamic input1, dynamic input2, bool b)
VerifyFlowGraphAndDiagnosticsForTest<BlockSyntax>(source, expectedGraph, expectedDiagnostics);
}
[CompilerTrait(CompilerFeature.IOperation, CompilerFeature.Dataflow)]
[Fact]
public void UsingFlow_13()
{
string source = @"
class P
{
void M(System.IDisposable input, object o)
/*<bind>*/{
using (input)
{
o?.ToString();
}
}/*</bind>*/
}
";
string expectedGraph = @"
Block[B0] - Entry
Statements (0)
Next (Regular) Block[B1]
Block[B1] - Block
Predecessors: [B0]
Statements (1)
IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'input')
Value:
IParameterReferenceOperation: input (OperationKind.ParameterReference, Type: System.IDisposable) (Syntax: 'input')
Next (Regular) Block[B2]
Entering: {R1} {R2}
.try {R1, R2}
{
Block[B2] - Block
Predecessors: [B1]
Statements (1)
IFlowCaptureOperation: 1 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'o')
Value:
IParameterReferenceOperation: o (OperationKind.ParameterReference, Type: System.Object) (Syntax: 'o')
Jump if True (Regular) to Block[B7]
IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 'o')
Operand:
IFlowCaptureReferenceOperation: 1 (OperationKind.FlowCaptureReference, Type: System.Object, IsImplicit) (Syntax: 'o')
Finalizing: {R3}
Leaving: {R2} {R1}
Next (Regular) Block[B3]
Block[B3] - Block
Predecessors: [B2]
Statements (1)
IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'o?.ToString();')
Expression:
IInvocationOperation (virtual System.String System.Object.ToString()) (OperationKind.Invocation, Type: System.String) (Syntax: '.ToString()')
Instance Receiver:
IFlowCaptureReferenceOperation: 1 (OperationKind.FlowCaptureReference, Type: System.Object, IsImplicit) (Syntax: 'o')
Arguments(0)
Next (Regular) Block[B7]
Finalizing: {R3}
Leaving: {R2} {R1}
}
.finally {R3}
{
Block[B4] - Block
Predecessors (0)
Statements (0)
Jump if True (Regular) to Block[B6]
IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 'input')
Operand:
IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.IDisposable, IsImplicit) (Syntax: 'input')
Next (Regular) Block[B5]
Block[B5] - Block
Predecessors: [B4]
Statements (1)
IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 'input')
Instance Receiver:
IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.IDisposable, IsImplicit) (Syntax: 'input')
Arguments(0)
Next (Regular) Block[B6]
Block[B6] - Block
Predecessors: [B4] [B5]
Statements (0)
Next (StructuredExceptionHandling) Block[null]
}
Block[B7] - Exit
Predecessors: [B2] [B3]
Statements (0)
";
var expectedDiagnostics = DiagnosticDescription.None;
VerifyFlowGraphAndDiagnosticsForTest<BlockSyntax>(source, expectedGraph, expectedDiagnostics);
}
}
}
......@@ -791,6 +791,11 @@ public INamedTypeSymbol GetSpecialType(SpecialType specialType)
return CommonGetSpecialType(specialType);
}
/// <summary>
/// Get the symbol for the predefined type member from the COR Library referenced by this compilation.
/// </summary>
internal abstract ISymbol CommonGetSpecialTypeMember(SpecialMember specialMember);
/// <summary>
/// Returns true if the type is System.Type.
/// </summary>
......@@ -798,6 +803,9 @@ public INamedTypeSymbol GetSpecialType(SpecialType specialType)
protected abstract INamedTypeSymbol CommonGetSpecialType(SpecialType specialType);
/// <summary>
/// Lookup member declaration in well known type used by this Compilation.
/// </summary>
internal abstract ISymbol CommonGetWellKnownTypeMember(WellKnownMember member);
/// <summary>
......
......@@ -1093,13 +1093,33 @@ protected static void VerifyFlowGraphForTest<TSyntaxNode>(CSharpCompilation comp
MetadataReference[] references = null,
bool useLatestFrameworkReferences = false)
where TSyntaxNode : SyntaxNode
{
VerifyFlowGraphAndDiagnosticsForTest<TSyntaxNode>(
testSrc,
expectedFlowGraph,
expectedDiagnostics,
targetFramework: useLatestFrameworkReferences ? TargetFramework.Mscorlib46Extended : TargetFramework.Standard,
compilationOptions,
parseOptions,
references);
}
protected static void VerifyFlowGraphAndDiagnosticsForTest<TSyntaxNode>(
string testSrc,
string expectedFlowGraph,
DiagnosticDescription[] expectedDiagnostics,
TargetFramework targetFramework,
CSharpCompilationOptions compilationOptions = null,
CSharpParseOptions parseOptions = null,
MetadataReference[] references = null)
where TSyntaxNode : SyntaxNode
{
parseOptions = parseOptions?.WithFlowAnalysisFeature() ?? TestOptions.RegularWithFlowAnalysisFeature;
var compilation = CreateCompilation(
new[] { Parse(testSrc, filename: "file.cs", options: parseOptions) },
references,
options: compilationOptions ?? TestOptions.ReleaseDll,
targetFramework: useLatestFrameworkReferences ? TargetFramework.Mscorlib46Extended : TargetFramework.Standard);
targetFramework: targetFramework);
VerifyFlowGraphAndDiagnosticsForTest<TSyntaxNode>(compilation, expectedFlowGraph, expectedDiagnostics);
}
......
......@@ -1798,6 +1798,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return Assembly.GetSpecialTypeMember(memberId)
End Function
Friend Overrides Function CommonGetSpecialTypeMember(specialMember As SpecialMember) As ISymbol
Return GetSpecialTypeMember(specialMember)
End Function
Friend Function GetTypeByReflectionType(type As Type, diagnostics As DiagnosticBag) As TypeSymbol
' TODO: See CSharpCompilation.GetTypeByReflectionType
Return GetSpecialType(SpecialType.System_Object)
......
......@@ -359,5 +359,8 @@ ILockOperation (OperationKind.Lock, Type: null) (Syntax: 'SyncLock o' ... nd Syn
VerifyOperationTreeAndDiagnosticsForTest(Of SyncLockBlockSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
' PROTOTYPE(dataflow): Port applicable LockFlow_** test scenarios from C#.
End Class
End Namespace
......@@ -982,11 +982,11 @@ IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (S
VerifyOperationTreeAndDiagnosticsForTest(Of ExpressionStatementSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
' PROTOTYPE(dataflow): Port applicable UsingFlow_01 - UsingFlow_12 test scenarios from C#.
' PROTOTYPE(dataflow): Port applicable UsingFlow_01 - UsingFlow_13 test scenarios from C#.
<CompilerTrait(CompilerFeature.IOperation, CompilerFeature.Dataflow)>
<Fact()>
Public Sub UsingFlow_13()
Public Sub UsingFlow_14()
Dim source = <![CDATA[
Imports System
Public Class C
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册