예제 #1
0
 public void TestGetFlowGraphNullArgument()
 {
     Assert.Throws <ArgumentNullException>(() => SemanticModel.GetControlFlowGraph((IBlockOperation)null));
     Assert.Throws <ArgumentNullException>(() => SemanticModel.GetControlFlowGraph((IFieldInitializerOperation)null));
     Assert.Throws <ArgumentNullException>(() => SemanticModel.GetControlFlowGraph((IPropertyInitializerOperation)null));
     Assert.Throws <ArgumentNullException>(() => SemanticModel.GetControlFlowGraph((IParameterInitializerOperation)null));
     Assert.Throws <ArgumentNullException>(() => SemanticModel.GetControlFlowGraph((IConstructorBodyOperation)null));
     Assert.Throws <ArgumentNullException>(() => SemanticModel.GetControlFlowGraph((IMethodBodyOperation)null));
 }
예제 #2
0
        public static ControlFlowGraph GetTreeCFG(this Compilation compilation)
        {
            var tree = compilation.SyntaxTrees.Single();

            var root = tree.GetRoot();

            var semanticModel   = compilation.GetSemanticModel(tree);
            var firstMethod     = root.DescendantNodes().OfType <BaseMethodDeclarationSyntax>().First();
            var firstMethodOper = semanticModel.GetOperation(firstMethod) as IMethodBodyOperation;


            return(SemanticModel.GetControlFlowGraph(firstMethodOper));
        }
예제 #3
0
        public static ControlFlowGraph GetControlFlowGraph(SyntaxNode syntaxNode, SemanticModel model)
        {
            IOperation operationRoot = model.GetOperation(syntaxNode);

            // Workaround for unit tests designed to work on IBlockOperation with ConstructorBodyOperation/MethodBodyOperation parent.
            operationRoot = operationRoot.Kind == OperationKind.Block &&
                            (operationRoot.Parent?.Kind == OperationKind.ConstructorBodyOperation ||
                             operationRoot.Parent?.Kind == OperationKind.MethodBodyOperation) ?
                            operationRoot.Parent :
                            operationRoot;

            TestOperationVisitor.VerifySubTree(operationRoot);

            ControlFlowGraph graph;

            switch (operationRoot)
            {
            case IBlockOperation blockOperation:
                graph = SemanticModel.GetControlFlowGraph(blockOperation);
                break;

            case IMethodBodyOperation methodBodyOperation:
                graph = SemanticModel.GetControlFlowGraph(methodBodyOperation);
                break;

            case IConstructorBodyOperation constructorBodyOperation:
                graph = SemanticModel.GetControlFlowGraph(constructorBodyOperation);
                break;

            case IFieldInitializerOperation fieldInitializerOperation:
                graph = SemanticModel.GetControlFlowGraph(fieldInitializerOperation);
                break;

            case IPropertyInitializerOperation propertyInitializerOperation:
                graph = SemanticModel.GetControlFlowGraph(propertyInitializerOperation);
                break;

            case IParameterInitializerOperation parameterInitializerOperation:
                graph = SemanticModel.GetControlFlowGraph(parameterInitializerOperation);
                break;

            default:
                return(null);
            }

            Assert.NotNull(graph);
            Assert.Same(operationRoot, graph.OriginalOperation);
            return(graph);
        }
        public void LambdaFlow_04()
        {
            string source = @"
struct C
{
    void M(System.Action d1, System.Action<bool, bool> d2)
/*<bind>*/{
        d1 = () =>
        {
            d2 = (bool result1, bool input1) =>
            {
                result1 = input1;
            
            };
        };

        void local(bool result2, bool input2) => result2 = input2;
    }/*</bind>*/
}
";

            var compilation = CreateCompilation(source, parseOptions: TestOptions.Regular.WithFlowAnalysisFeature());

            var tree          = compilation.SyntaxTrees.Single();
            var semanticModel = compilation.GetSemanticModel(tree);
            var graphM        = SemanticModel.GetControlFlowGraph((IMethodBodyOperation)semanticModel.GetOperation(tree.GetRoot().DescendantNodes().OfType <MethodDeclarationSyntax>().Single()));

            Assert.NotNull(graphM);

            IFlowAnonymousFunctionOperation lambdaD1 = getLambda(graphM);

            Assert.Throws <ArgumentNullException>(() => graphM.GetLocalFunctionControlFlowGraph(null));
            Assert.Throws <ArgumentOutOfRangeException>(() => graphM.GetLocalFunctionControlFlowGraph(lambdaD1.Symbol));

            var graphD1 = graphM.GetAnonymousFunctionControlFlowGraph(lambdaD1);

            Assert.NotNull(graphD1);

            IFlowAnonymousFunctionOperation lambdaD2 = getLambda(graphD1);

            Assert.Throws <ArgumentNullException>(() => graphM.GetAnonymousFunctionControlFlowGraph(null));
            Assert.Throws <ArgumentOutOfRangeException>(() => graphM.GetAnonymousFunctionControlFlowGraph(lambdaD2));

            IFlowAnonymousFunctionOperation getLambda(ControlFlowGraph graph)
            {
                return(graph.Blocks.SelectMany(b => b.Operations.SelectMany(o => o.DescendantsAndSelf())).OfType <IFlowAnonymousFunctionOperation>().Single());
            }
        }
예제 #5
0
        public void TestFlowAnalysisFeatureFlag()
        {
            var source = @"
class C
{
    void M()
    {
    }
}";
            var tree   = CSharpSyntaxTree.ParseText(source);

            void testFlowAnalysisFeatureFlagCore(bool expectException)
            {
                var compilation      = CSharpCompilation.Create("c", new[] { tree });
                var model            = compilation.GetSemanticModel(tree, ignoreAccessibility: true);
                var methodBodySyntax = tree.GetCompilationUnitRoot().DescendantNodes().OfType <BaseMethodDeclarationSyntax>().Last();
                var operation        = (IMethodBodyOperation)model.GetOperation(methodBodySyntax);

                if (expectException)
                {
                    Assert.Throws <InvalidOperationException>(() => SemanticModel.GetControlFlowGraph(operation));
                }
                else
                {
                    ControlFlowGraph graph = SemanticModel.GetControlFlowGraph(operation);
                    Assert.NotNull(graph);
                    Assert.NotEmpty(graph.Blocks);
                }
            }

            // Test without feature flag.
            testFlowAnalysisFeatureFlagCore(expectException: true);

            // Test with feature flag.
            tree = CSharpSyntaxTree.ParseText(source);
            var options = tree.Options.WithFeatures(new[] { new KeyValuePair <string, string>("flow-analysis", "true") });

            tree = tree.WithRootAndOptions(tree.GetRoot(), options);
            testFlowAnalysisFeatureFlagCore(expectException: false);

            // Test with feature flag, case-insensitive.
            tree    = CSharpSyntaxTree.ParseText(source);
            options = tree.Options.WithFeatures(new[] { new KeyValuePair <string, string>("Flow-Analysis", "true") });
            tree    = tree.WithRootAndOptions(tree.GetRoot(), options);
            testFlowAnalysisFeatureFlagCore(expectException: false);
        }