Esempio n. 1
0
        public static List <IMethodSymbol> FindConfigureMethods(StartupSymbols symbols, IAssemblySymbol assembly)
        {
            var visitor = new ConfigureMethodVisitor(symbols);

            visitor.Visit(assembly);
            return(visitor._methods);
        }
Esempio n. 2
0
        public async Task FindConfigureMethods_AtDifferentScopes()
        {
            // Arrange
            var expected = new string[]
            {
                "global::ANamespace.Nested.Startup.Configure",
                "global::ANamespace.Nested.Startup.NestedStartup.Configure",
                "global::ANamespace.Startup.ConfigureDevelopment",
                "global::ANamespace.Startup.NestedStartup.ConfigureTest",
                "global::Another.AnotherStartup.Configure",
                "global::GlobalStartup.Configure",
            };

            var compilation = await CreateCompilationAsync("Startup");

            var symbols = new StartupSymbols(compilation);

            // Act
            var results = ConfigureMethodVisitor.FindConfigureMethods(symbols, compilation.Assembly);

            // Assert
            var actual = results
                         .Select(m => m.ContainingType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + "." + m.Name)
                         .OrderBy(s => s)
                         .ToArray();

            Assert.Equal(expected, actual);
        }
        public static async Task <IImmutableSet <string> > DetectFeaturesAsync(
            Compilation compilation,
            CancellationToken cancellationToken = default)
        {
            var symbols = new StartupSymbols(compilation);

            if (!symbols.HasRequiredSymbols)
            {
                // Cannot find ASP.NET Core types.
                return(ImmutableHashSet <string> .Empty);
            }

            var features = ImmutableHashSet.CreateBuilder <string>();

            // Find configure methods in the project's assembly
            var configureMethods = ConfigureMethodVisitor.FindConfigureMethods(symbols, compilation.Assembly);

            for (var i = 0; i < configureMethods.Count; i++)
            {
                var configureMethod = configureMethods[i];

                // Handles the case where a method is using partial definitions. We don't expect this to occur, but still handle it correctly.
                var syntaxReferences = configureMethod.DeclaringSyntaxReferences;
                for (var j = 0; j < syntaxReferences.Length; j++)
                {
                    var semanticModel = compilation.GetSemanticModel(syntaxReferences[j].SyntaxTree);

                    var syntax    = await syntaxReferences[j].GetSyntaxAsync(cancellationToken).ConfigureAwait(false);
                    var operation = semanticModel.GetOperation(syntax);

                    // Look for a call to one of the SignalR gestures that applies to the Configure method.
                    if (operation
                        .Descendants()
                        .OfType <IInvocationOperation>()
                        .Any(op => StartupFacts.IsSignalRConfigureMethodGesture(op.TargetMethod)))
                    {
                        features.Add(WellKnownFeatures.SignalR);
                    }
                }
            }

            return(features.ToImmutable());
        }
        public void FindConfigureMethods_AtDifferentScopes()
        {
            // Arrange
            var source = @"
using Microsoft.AspNetCore.Builder;

public class GlobalStartup
{
    public void Configure(IApplicationBuilder app)
    {
    }
}

namespace Another
{
    public class AnotherStartup
    {
        public void Configure(IApplicationBuilder app)
        {
        }
    }
}

namespace ANamespace
{
    public class Startup
    {
        public void ConfigureDevelopment(IApplicationBuilder app)
        {
        }

        public class NestedStartup
        {
            public void ConfigureTest(IApplicationBuilder app)
            {
            }
        }
    }
}

namespace ANamespace.Nested
{
    public class Startup
    {
        public void Configure(IApplicationBuilder app)
        {
        }

        public class NestedStartup
        {
            public void Configure(IApplicationBuilder app)
            {
            }
        }
    }
}";

            var expected = new string[]
            {
                "global::ANamespace.Nested.Startup.Configure",
                "global::ANamespace.Nested.Startup.NestedStartup.Configure",
                "global::ANamespace.Startup.ConfigureDevelopment",
                "global::ANamespace.Startup.NestedStartup.ConfigureTest",
                "global::Another.AnotherStartup.Configure",
                "global::GlobalStartup.Configure",
            };

            var compilation = TestCompilation.Create(source);
            var symbols     = new StartupSymbols(compilation);

            // Act
            var results = ConfigureMethodVisitor.FindConfigureMethods(symbols, compilation.Assembly);

            // Assert
            var actual = results
                         .Select(m => m.ContainingType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + "." + m.Name)
                         .OrderBy(s => s)
                         .ToArray();

            Assert.Equal(expected, actual);
        }