示例#1
0
        public static async Task <LazinatorCompilationAnalyzer> CreateCompilationAnalyzer(Compilation compilation,
                                                                                          CancellationToken cancellationToken, ImmutableArray <TextDocument> additionalFiles)
        {
            // Check if the attribute type LazinatorAttribute is defined.
            INamedTypeSymbol lazinatorAttributeType = compilation.GetTypeByMetadataName(LazinatorAttributeName);

            if (lazinatorAttributeType == null)
            {
                return(null);
            }

            // Check if the interface type ILazinator is defined.
            INamedTypeSymbol lazinatorInterfaceType = compilation.GetTypeByMetadataName(LazinatorInterfaceName);

            if (lazinatorInterfaceType == null)
            {
                return(null);
            }

            (string configPath, string configString) = await LazinatorConfigLoader.GetConfigPathAndText(additionalFiles, cancellationToken);

            LazinatorConfig config = new LazinatorConfig(configPath, configString);

            // Initialize state in the start action.
            var analyzer = new LazinatorCompilationAnalyzer(lazinatorAttributeType, lazinatorInterfaceType, configPath, configString, config);

            return(analyzer);
        }
示例#2
0
        private static async Task AddDiagnosticsForDocument(ImmutableDictionary <Document, ImmutableArray <Diagnostic> > .Builder builder, Compilation compilation, IEnumerable <TextDocument> additionalDocuments, LazinatorCompilationAnalyzer analyzer, Document doc, CancellationToken cancellationToken, bool suppressRegenerate)
        {
            cancellationToken.ThrowIfCancellationRequested();
            if (analyzer == null)
            {
                analyzer = await
                           LazinatorCompilationAnalyzer.CreateCompilationAnalyzer(compilation, cancellationToken, additionalDocuments.ToImmutableArray());

                analyzer.DisableStartingFromInterface = true;
            }
            SyntaxNode root = await doc.GetSyntaxRootAsync(cancellationToken);

            var rootSyntaxTree = root.SyntaxTree;
            var model          = compilation.GetSemanticModel(rootSyntaxTree);

            var namedTypes = root.DescendantNodesAndSelf()
                             .OfType <TypeDeclarationSyntax>()
                             .Select(x => model.GetDeclaredSymbol(x))
                             .OfType <INamedTypeSymbol>()
                             .ToList();

            foreach (var symbol in namedTypes)
            {
                analyzer.AnalyzeNamedType(symbol, compilation);
            }
            ImmutableArray <Diagnostic> diagnostics = analyzer.GetDiagnosticsToReport(suppressRegenerate).ToImmutableArray();

            if (diagnostics.Any())
            {
                builder.Add(doc, diagnostics);
            }
            analyzer.ClearDiagnostics();
        }
示例#3
0
        public override void Initialize(AnalysisContext context)
        {
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);
            try
            {
                context.EnableConcurrentExecution();
                context.RegisterCompilationStartAction(compilationContext =>
                {
                    var additionalFiles   = compilationContext.Options.AdditionalFiles;
                    var compilation       = compilationContext.Compilation;
                    var cancellationToken = compilationContext.CancellationToken;
                    var analyzer          = LazinatorCompilationAnalyzer.CreateCompilationAnalyzer(compilation, cancellationToken, additionalFiles);
                    if (analyzer == null)
                    {
                        return;
                    }

                    // Register intermediate non-end actions that access and modify the state.
                    compilationContext.RegisterSyntaxNodeAction(analyzer.AnalyzeSyntaxNode, SyntaxKind.StructDeclaration, SyntaxKind.ClassDeclaration);
                    compilationContext.RegisterSymbolAction(analyzer.AnalyzeSymbol, SymbolKind.NamedType, SymbolKind.Method);

                    // Register an end action to report diagnostics based on the final state.
                    compilationContext.RegisterSyntaxTreeAction(analyzer.SyntaxTreeStartAction);
                    compilationContext.RegisterSemanticModelAction(analyzer.SemanticModelEndAction);

                    // NOTE: We could register a compilation end action, but this will not execute at all if full solution analysis is disabled.
                });
            }
            catch (Exception ex)
            { // catch exceptions so that we can get a more useful error in the Visual Studio consumer of this analyzer.
                throw new Exception($"Lazinator analyzer exception encountered. Message {ex.Message} Stack trace: {ex.StackTrace}");
            }
        }
示例#4
0
        public async Task AddDiagnosticsToBuilder(Document d, ImmutableDictionary <Document, ImmutableArray <Diagnostic> > .Builder builder, CancellationToken cancellationToken, bool suppressRegenerate)
        {
            if (d == null)
            {
                return;
            }
            Project     p           = d.Project;
            Compilation compilation = await p.GetCompilationAsync();

            var additionalDocuments = p.AdditionalDocuments;
            LazinatorCompilationAnalyzer analyzer = await
                                                    LazinatorCompilationAnalyzer.CreateCompilationAnalyzer(compilation, cancellationToken, additionalDocuments.ToImmutableArray());

            await AddDiagnosticsForDocument(builder, compilation, additionalDocuments, analyzer, d, cancellationToken, suppressRegenerate);
        }
示例#5
0
        public async Task AddDiagnosticsToBuilder(Project p, ImmutableDictionary <Document, ImmutableArray <Diagnostic> > .Builder builder, CancellationToken cancellationToken, bool suppressRegenerate)
        {
            if (p == null)
            {
                return;
            }
            Compilation compilation = await p.GetCompilationAsync();

            var additionalDocuments = p.AdditionalDocuments;
            LazinatorCompilationAnalyzer analyzer = await
                                                    LazinatorCompilationAnalyzer.CreateCompilationAnalyzer(compilation, cancellationToken, additionalDocuments?.ToImmutableArray() ?? new ImmutableArray <TextDocument>());

            if (analyzer == null)
            {
                return;
            }
            analyzer.DisableStartingFromInterface = true;
            var config = analyzer.Config;

            foreach (var doc in p.Documents.Where(x => x.SourceCodeKind == SourceCodeKind.Regular && !(x.FilePath ?? x.Name).EndsWith(config?.GeneratedCodeFileExtension ?? ".laz.cs")))
            {
                await AddDiagnosticsForDocument(builder, compilation, additionalDocuments, analyzer, doc, cancellationToken, suppressRegenerate);
            }
        }