public void CompilationStartAnalysisContext_Simple()
        {     
            var context = new RoslynCompilationStartAnalysisContext(null, null, CancellationToken.None);
            int invocationCount = 0;

            // The relevant work
            context.RegisterSymbolAction((c) => { invocationCount++; }, SymbolKind.NamedType);

            // No-ops
            context.RegisterCodeBlockAction(null);
            context.RegisterCodeBlockStartAction<int>(null);
            context.RegisterCompilationEndAction(null);
            context.RegisterSemanticModelAction(null);
            context.RegisterSyntaxNodeAction<int>(null);
            context.RegisterSyntaxTreeAction(null);

            Assert.NotNull(context.SymbolActions);

            context.SymbolActions.Invoke(SymbolKind.NamedType, new SymbolAnalysisContext());

            Assert.Equal(1, invocationCount);           
        }
Ejemplo n.º 2
0
        public void Analyze(
            string targetPath, 
            Action<Diagnostic> reportDiagnostic, 
            CancellationToken cancellationToken = default(CancellationToken))
        {
            // Create a Roslyn representation of the IL by constructing a MetadataReference against
            // the target path (as if we intended to reference this binary during compilation, instead
            // of analyzing it). Using this mechanism, we can scan types/members contained in the 
            // binary. We cannot currently retrieve IL from method bodies.
            var reference = MetadataReference.CreateFromFile(targetPath);
            var compilation = CSharpCompilation.Create("_", references: new[] { reference });
            var target = compilation.GetAssemblyOrModuleSymbol(reference);

            // For each analysis target, we create a compilation start context, which may result
            // in symbol action registration. We need to capture and throw these registrations 
            // away for each binary we inspect. 
            var compilationStartAnalysisContext = new RoslynCompilationStartAnalysisContext(compilation, _options, cancellationToken);

            GlobalRoslynAnalysisContext.CompilationStartActions?.Invoke(compilationStartAnalysisContext);

            var visitor = new RoslynSymbolVisitor(symbol => Analyze(
                symbol,
                compilation,
                compilationStartAnalysisContext.SymbolActions,
                reportDiagnostic, 
                cancellationToken));

            visitor.Visit(target);

            // Having finished analysis, we'll invoke any compilation end actions registered previously.
            // We also discard the per-compilation symbol actions we collected.
            var compilationAnalysisContext = new CompilationAnalysisContext(compilation, _options, reportDiagnostic, _isSupportedDiagnostic, cancellationToken);

            GlobalRoslynAnalysisContext.CompilationActions?.Invoke(compilationAnalysisContext);
            compilationStartAnalysisContext.CompilationEndActions?.Invoke(compilationAnalysisContext);
        }