public static async Task <List <InvocationExpressionSyntax> > GetMethodCallsAsync(
            CSharpCompilation compilation,
            CSharpSyntaxTree syntaxTree,
            CSharpSyntaxNode node,
            string methodName)
        {
            if (compilation == null)
            {
                throw new ArgumentNullException(nameof(compilation));
            }

            if (syntaxTree == null)
            {
                throw new ArgumentNullException(nameof(syntaxTree));
            }

            if (methodName == null)
            {
                throw new ArgumentNullException(nameof(methodName));
            }

            node = node ?? await syntaxTree.GetRootAsync().ConfigureAwait(false);

            var semanticModel = compilation.GetSemanticModel(syntaxTree);
            var visitor       = new FindInvocationExpressionVisitor(semanticModel, methodName);

            visitor.Visit(node);

            return(visitor.Results);
        }
예제 #2
0
        public override async Task AnalyzeAsync(
            AnalysisContext context,
            CSharpCompilation compilation,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (compilation == null)
            {
                throw new ArgumentNullException(nameof(compilation));
            }

            var configureServicesMethods = new List <MethodDeclarationSyntax>();
            var results = new List <ServiceDependencyItem>();

            foreach (var syntaxTree in compilation.SyntaxTrees.OfType <CSharpSyntaxTree>().Where(t => IsStartup(t)))
            {
                var methods = await FindMethodDeclarationVisitor.GetMethodsAsync(compilation, syntaxTree, null, "ConfigureServices").ConfigureAwait(false);

                if (methods.Count == 0)
                {
                    continue;
                }

                for (var i = 0; i < methods.Count; i++)
                {
                    var calls = await FindInvocationExpressionVisitor.GetMethodCallsAsync(compilation, syntaxTree, methods[i], ServiceCollectionFullTypeName).ConfigureAwait(false);

                    for (var j = 0; j < calls.Count; j++)
                    {
                        results.Add(new ServiceDependencyItem(compilation, calls[j]));
                    }
                }

                configureServicesMethods.AddRange(methods);

                // Track nodes so we can find them later.
                var root = await syntaxTree.GetRootAsync().ConfigureAwait(false);

                var tracked = root.TrackNodes(methods);
                compilation = compilation.ReplaceSyntaxTree(syntaxTree, syntaxTree.WithRootAndOptions(tracked, syntaxTree.Options));
            }

            context.SetData(new ServiceDependencySet(configureServicesMethods, results));
            context.SetData <CSharpCompilation>(compilation);
        }