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); } } } }
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); } } ; } }