public async Task DetectFeaturesAsync_FindsNoFeatures() { // Arrange var source = @" using Microsoft.AspNetCore.Builder; namespace Microsoft.AspNetCore.Analyzers.TestFiles.CompilationFeatureDetectorTest { public class StartupWithNoFeatures { public void Configure(IApplicationBuilder app) { app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapFallbackToFile(""index.html""); }); } } }"; var compilation = TestCompilation.Create(source); var symbols = new StartupSymbols(compilation); var type = (INamedTypeSymbol)compilation.GetSymbolsWithName("StartupWithNoFeatures").Single(); Assert.True(StartupFacts.IsStartupClass(symbols, type)); // Act var features = await CompilationFeatureDetector.DetectFeaturesAsync(compilation); // Assert Assert.Empty(features); }
public void IsStartupClass_RejectsNotStartupClass(string source) { // Arrange var compilation = TestCompilation.Create(TestSources[source]); var symbols = new StartupSymbols(compilation); var type = (INamedTypeSymbol)compilation.GetSymbolsWithName(source).Single(); // Act var result = StartupFacts.IsStartupClass(symbols, type); // Assert Assert.False(result); }
public async Task DetectFeatureAsync_StartupWithMapHub_FindsSignalR() { var source = @" using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.SignalR; namespace Microsoft.AspNetCore.Analyzers.TestFiles.CompilationFeatureDetectorTest { public class StartupWithMapHub { public void Configure(IApplicationBuilder app) { app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapHub<MyHub>("" / test""); }); } } public class MyHub : Hub { } } "; var compilation = TestCompilation.Create(source); var symbols = new StartupSymbols(compilation); var type = (INamedTypeSymbol)compilation.GetSymbolsWithName("StartupWithMapHub").Single(); Assert.True(StartupFacts.IsStartupClass(symbols, type)); // Act var features = await CompilationFeatureDetector.DetectFeaturesAsync(compilation); // Assert Assert.Collection(features, f => Assert.Equal(WellKnownFeatures.SignalR, f)); }
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); }