private void OnCompilationStart(CompilationStartAnalysisContext context) { var symbols = new StartupSymbols(context.Compilation); // Don't run analyzer if ASP.NET Core types cannot be found if (!symbols.HasRequiredSymbols) { return; } context.RegisterSymbolStartAction(context => { var type = (INamedTypeSymbol)context.Symbol; if (!StartupFacts.IsStartupClass(symbols, type)) { // Not a startup class, nothing to do. return; } // This analyzer fans out a bunch of jobs. The context will capture the results of doing analysis // on the startup code, so that other analyzers that run later can examine them. var builder = new StartupAnalysisBuilder(this, symbols); var services = new ServicesAnalyzer(builder); var options = new OptionsAnalyzer(builder); var middleware = new MiddlewareAnalyzer(builder); context.RegisterOperationBlockStartAction(context => { if (context.OwningSymbol.Kind != SymbolKind.Method) { return; } var method = (IMethodSymbol)context.OwningSymbol; if (StartupFacts.IsConfigureServices(symbols, method)) { OnConfigureServicesMethodFound(method); services.AnalyzeConfigureServices(context); options.AnalyzeConfigureServices(context); } if (StartupFacts.IsConfigure(symbols, method)) { OnConfigureMethodFound(method); middleware.AnalyzeConfigureMethod(context); } }); // Run after analyses have had a chance to finish to add diagnostics. context.RegisterSymbolEndAction(context => { var analysis = builder.Build(); new UseMvcAnalyzer(analysis).AnalyzeSymbol(context); new BuildServiceProviderValidator(analysis).AnalyzeSymbol(context); }); }, SymbolKind.NamedType); }
private void OnCompilationStart(CompilationStartAnalysisContext context) { var symbols = new StartupSymbols(context.Compilation); // Don't run analyzer if ASP.NET Core types cannot be found if (!symbols.HasRequiredSymbols) { return; } var entryPoint = context.Compilation.GetEntryPoint(context.CancellationToken); context.RegisterSymbolStartAction(context => { var type = (INamedTypeSymbol)context.Symbol; if (!StartupFacts.IsStartupClass(symbols, type) && !SymbolEqualityComparer.Default.Equals(entryPoint?.ContainingType, type)) { // Not a startup class, nothing to do. return; } // This analyzer fans out a bunch of jobs. The context will capture the results of doing analysis // on the startup code, so that other analyzers that run later can examine them. var builder = new StartupAnalysisBuilder(this, symbols); var services = new ServicesAnalyzer(builder); var options = new OptionsAnalyzer(builder); var middleware = new MiddlewareAnalyzer(builder); context.RegisterOperationBlockStartAction(context => { if (context.OwningSymbol.Kind != SymbolKind.Method) { return; } var method = (IMethodSymbol)context.OwningSymbol; var isConfigureServices = StartupFacts.IsConfigureServices(symbols, method); if (isConfigureServices) { OnConfigureServicesMethodFound(method); } // In the future we can consider looking at more methods, but for now limit to Main, implicit Main, and Configure* methods var isMain = SymbolEqualityComparer.Default.Equals(entryPoint, context.OwningSymbol); if (isConfigureServices || isMain) { services.AnalyzeConfigureServices(context); options.AnalyzeConfigureServices(context); } var isConfigure = StartupFacts.IsConfigure(symbols, method); if (isConfigure) { OnConfigureMethodFound(method); } if (isConfigure || isMain) { middleware.AnalyzeConfigureMethod(context); } }); // Run after analyses have had a chance to finish to add diagnostics. context.RegisterSymbolEndAction(context => { var analysis = builder.Build(); new UseMvcAnalyzer(analysis).AnalyzeSymbol(context); new BuildServiceProviderAnalyzer(analysis).AnalyzeSymbol(context); new UseAuthorizationAnalyzer(analysis).AnalyzeSymbol(context); }); }, SymbolKind.NamedType); }