Esempio n. 1
0
        public void Generate()
        {
            try
            {
                var settings    = GenerationSettings.FromContext(programContext.GeneratorExecutionContext);
                var syntaxTrees = programContext.GeneratorExecutionContext.Compilation.SyntaxTrees;
                var generations = from tree in syntaxTrees.AsParallel()
                                  let semanticModel = programContext.GeneratorExecutionContext.Compilation.GetSemanticModel(tree)

                                                      from node in tree.GetRoot().DescendantNodesAndSelf().OfType <ClassDeclarationSyntax>()
                                                      from attr in semanticModel.GetDeclaredSymbol(node)?.GetAttributes() ?? ImmutableArray.Create <AttributeData>()
                                                      where IsAssignableTo(attr.AttributeClass, nameof(LambdaAttribute))

                                                      let metadataAttributes = attr.AttributeClass?.GetAttributes() ?? ImmutableArray.Create <AttributeData>()
                                                                               let startupType = GetAttributeArgument <INamedTypeSymbol>(attr, "Startup") !
                                                                                                 let generationContext = new GenerationContext
                {
                    SourceGeneratorContext   = programContext.GeneratorExecutionContext,
                    Declaration              = node,
                    SyntaxTree               = tree,
                    Compilation              = programContext.GeneratorExecutionContext.Compilation,
                    SemanticModel            = semanticModel,
                    AttributeData            = attr,
                    LambdaHostAttribute      = GetMetadataAttribute <LambdaHostAttribute>(metadataAttributes),
                    LambdaInterfaceAttribute = GetMetadataAttribute <LambdaInterfaceAttribute>(metadataAttributes),
                    CancellationToken        = programContext.GeneratorExecutionContext.CancellationToken,
                    StartupType              = startupType,
                    SerializerType           = GetAttributeArgument <INamedTypeSymbol>(attr, "Serializer"),
                    ConfigFactoryType        = GetAttributeArgument <INamedTypeSymbol>(attr, "ConfigFactory"),
                    RunnerMethodName         = GetAttributeArgument <string>(attr, "RunnerMethod") ?? "Run",
                    StartupTypeName          = startupType.Name,
                    StartupTypeDisplayName   = startupType.ToDisplayString(),
                    Settings = settings,
                }

                let unit = GenerateUnit(generationContext)
                           let document                       = unit.NormalizeWhitespace().GetText(Encoding.UTF8)
                                                     let name = node.Identifier.Text
                                                                let lambdaInfo = GenerateLambdaInfo(generationContext).GetAwaiter().GetResult()
                                                                                 select(name, document, lambdaInfo);

                foreach (var(name, document, lambdaInfo) in generations)
                {
                    programContext.GeneratorExecutionContext.AddSource(name, document);
                    programContext.LambdaInfos.Add(lambdaInfo);
                }

                var templateGenerator = new TemplateGenerator(
                    settings.OutputPath,
                    settings.AssemblyName,
                    settings.OutputPath,
                    settings.TargetFrameworkVersion,
                    programContext.LambdaInfos
                    );

                templateGenerator.GenerateTemplates();
            }
            catch (AggregateException e)
            {
                var failureExceptions    = e.InnerExceptions.OfType <GenerationFailureException>();
                var nonFailureExceptions = e.InnerExceptions.Where(e => e is not GenerationFailureException);

                foreach (var failure in failureExceptions)
                {
                    programContext.GeneratorExecutionContext.ReportDiagnostic(failure.Diagnostic);
                }

                using var source = CancellationTokenSource.CreateLinkedTokenSource(programContext.GeneratorExecutionContext.CancellationToken);
                source.Cancel();

                if (nonFailureExceptions.Any())
                {
                    throw new AggregateException(nonFailureExceptions);
                }
            }
        }