Ejemplo n.º 1
0
        public void Execute(GeneratorExecutionContext context)
        {
            var cancellationToken = context.CancellationToken;
            var compilation       = context.Compilation;
            Action <Diagnostic> reportDiagnostic = context.ReportDiagnostic;

            if (!WellKnownTypes.TryCreate(compilation, reportDiagnostic, out var wellKnownTypes))
            {
                return;
            }

            var registrationCalculator =
                new RegistrationCalculator(compilation, wellKnownTypes, reportDiagnostic, cancellationToken);

            foreach (var syntaxTree in context.Compilation.SyntaxTrees)
            {
                cancellationToken.ThrowIfCancellationRequested();

                var semanticModel = context.Compilation.GetSemanticModel(syntaxTree);
                var modules       = syntaxTree.GetRoot(cancellationToken).DescendantNodesAndSelf()
                                    .OfType <ClassDeclarationSyntax>()
                                    .Select(x => semanticModel.GetDeclaredSymbol(x, cancellationToken))
                                    .Where(x => x != null)
                                    .Select(x =>
                {
                    var isContainer = x !.AllInterfaces.Any(x
                                                            => x.OriginalDefinition.Equals(wellKnownTypes.IContainer, SymbolEqualityComparer.Default) ||
                                                            x.OriginalDefinition.Equals(wellKnownTypes.IAsyncContainer,
                                                                                        SymbolEqualityComparer.Default));
                    return(type: x, isContainer);
                })
                                    .Where(x =>
                                           x.isContainer ||
                                           x.type.GetAttributes().Any(x =>
                                                                      x.AttributeClass is { } attribute&&
                                                                      (attribute.Equals(wellKnownTypes.RegisterAttribute, SymbolEqualityComparer.Default) ||
                                                                       attribute.Equals(wellKnownTypes.RegisterModuleAttribute, SymbolEqualityComparer.Default) ||
                                                                       attribute.Equals(wellKnownTypes.RegisterFactoryAttribute,
                                                                                        SymbolEqualityComparer.Default) ||
                                                                       attribute.Equals(wellKnownTypes.RegisterDecoratorAttribute,
                                                                                        SymbolEqualityComparer.Default))) ||
                                           x.type.GetMembers().Any(x => x.GetAttributes().Any(x =>
                                                                                              x.AttributeClass is { } attribute&&
                                                                                              (attribute.Equals(wellKnownTypes.FactoryAttribute, SymbolEqualityComparer.Default) ||
                                                                                               attribute.Equals(wellKnownTypes.InstanceAttribute, SymbolEqualityComparer.Default) ||
                                                                                               attribute.Equals(wellKnownTypes.DecoratorFactoryAttribute,
                                                                                                                SymbolEqualityComparer.Default) ||
                                                                                               attribute.Equals(wellKnownTypes.FactoryOfAttribute, SymbolEqualityComparer.Default)))));

                foreach (var module in modules)
                {
                    if (!module.type.IsInternal() && !module.type.IsPublic())
                    {
                        reportDiagnostic(ModuleNotPublicOrInternal(
                                             module.type,
                                             ((TypeDeclarationSyntax)module.type.DeclaringSyntaxReferences[0].GetSyntax()).Identifier
                                             .GetLocation()));
                    }

                    cancellationToken.ThrowIfCancellationRequested();
                    if (module.isContainer)
                    {
                        var file = ContainerGenerator.GenerateContainerImplementations(
                            module.type,
                            registrationCalculator.GetContainerRegistrations(module.type),
                            wellKnownTypes,
                            reportDiagnostic,
                            cancellationToken);

                        var source = CSharpSyntaxTree.ParseText(SourceText.From(file, Encoding.UTF8)).GetRoot()
                                     .NormalizeWhitespace().SyntaxTree.GetText();
                        context.AddSource(
                            GenerateNameHint(module.type),
                            source);
                    }
                    else
                    {
                        registrationCalculator.ValidateModuleRegistrations(module.type);
                    }
                }
            }
        }
Ejemplo n.º 2
0
        private void ExecuteInternal(SourceGeneratorContext context)
        {
            var cancellationToken = context.CancellationToken;
            var compilation       = context.Compilation;
            Action <Diagnostic> reportDiagnostic = context.ReportDiagnostic;

            if (!WellKnownTypes.TryCreate(compilation, reportDiagnostic, out var wellKnownTypes))
            {
                return;
            }

            var registrationCalculator = new RegistrationCalculator(compilation, reportDiagnostic, cancellationToken);

            foreach (var syntaxTree in context.Compilation.SyntaxTrees)
            {
                cancellationToken.ThrowIfCancellationRequested();

                var semanticModel = context.Compilation.GetSemanticModel(syntaxTree);
                var modules       = syntaxTree.GetRoot(cancellationToken).DescendantNodesAndSelf().OfType <ClassDeclarationSyntax>()
                                    .Select(x => semanticModel.GetDeclaredSymbol(x, cancellationToken))
                                    .OfType <INamedTypeSymbol>()
                                    .Select(x =>
                {
                    var isContainer = x.AllInterfaces.Any(x
                                                          => x.OriginalDefinition.Equals(wellKnownTypes.iContainer, SymbolEqualityComparer.Default) ||
                                                          x.OriginalDefinition.Equals(wellKnownTypes.iAsyncContainer, SymbolEqualityComparer.Default));
                    return(type: x, isContainer);
                })
                                    .Where(x =>
                                           x.isContainer ||
                                           x.type.GetAttributes().Any(x =>
                                                                      x.AttributeClass is { } attribute&&
                                                                      (attribute.Equals(wellKnownTypes.registrationAttribute, SymbolEqualityComparer.Default) ||
                                                                       attribute.Equals(wellKnownTypes.moduleRegistrationAttribute, SymbolEqualityComparer.Default) ||
                                                                       attribute.Equals(wellKnownTypes.factoryRegistrationAttribute, SymbolEqualityComparer.Default))));

                foreach (var module in modules)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    // do this even if not a container to report diagnostics
                    var registrations = registrationCalculator.GetRegistrations(module.type);

                    if (module.isContainer)
                    {
                        var file = ContainerGenerator.GenerateContainerImplementations(
                            compilation,
                            module.type,
                            registrations,
                            wellKnownTypes,
                            reportDiagnostic,
                            cancellationToken);

                        var source = CSharpSyntaxTree.ParseText(SourceText.From(file, Encoding.UTF8)).GetRoot().NormalizeWhitespace().SyntaxTree.GetText();
                        context.AddSource(
                            GenerateNameHint(module.type),
                            source);
                    }
                }
                ;
            }
        }