예제 #1
0
        public void Execute(SourceGeneratorContext context)
        {
            string attributeSource = @"
    [System.AttributeUsage(System.AttributeTargets.Assembly, AllowMultiple=true)]
    public class MustacheAttribute: System.Attribute
    {
        public string Name { get; }
        public string Template { get; }
        public string Hash { get; }
        public MustacheAttribute(string name, string template, string hash)
            => (Name, Template, Hash) = (name, template, hash);
    }
";

            context.AddSource("Mustache_MainAttributes__", SourceText.From(attributeSource, Encoding.UTF8));

            Compilation compilation = context.Compilation;

            IEnumerable <(string, string, string)> options      = GetMustacheOptions(compilation);
            IEnumerable <(string, string)>         namesSources = SourceFilesFromMustachePaths(options);

            foreach ((string name, string source) in namesSources)
            {
                context.AddSource($"Mustache{name}", SourceText.From(source, Encoding.UTF8));
            }
        }
예제 #2
0
        public void Execute(SourceGeneratorContext context)
        {
            // retreive the populated receiver
            if (!(context.SyntaxReceiver is SyntaxReceiver receiver))
            {
                return;
            }
            try
            {
                // 简单测试aop 生成
                Action <StringBuilder, IMethodSymbol> beforeCall = (sb, method) => { };
                Action <StringBuilder, IMethodSymbol> afterCall  = (sb, method) => { sb.Append("r++;"); };

                // 获取生成结果
                var code = receiver.SyntaxNodes
                           .Select(i => context.Compilation.GetSemanticModel(i.SyntaxTree).GetDeclaredSymbol(i) as INamedTypeSymbol)
                           .Where(i => i != null && !i.IsStatic)
                           .Select(i => ProxyCodeGenerator.GenerateProxyCode(i, beforeCall, afterCall))
                           .First();

                context.AddSource("code.cs", SourceText.From(code, Encoding.UTF8));
            }
            catch (Exception ex)
            {
                // 失败汇报
                context.ReportDiagnostic(Diagnostic.Create(new DiagnosticDescriptor("n001", ex.ToString(), ex.ToString(), "AOP.Generate", DiagnosticSeverity.Warning, true), Location.Create("code.cs", TextSpan.FromBounds(0, 0), new LinePositionSpan())));
            }
        }
 public void Output(string content, string fileName, bool overwriteExisting)
 {
     if (overwriteExisting)
     {
         _context.AddSource(fileName, SourceText.From(content, Encoding.UTF8));
     }
 }
예제 #4
0
        public void Execute(SourceGeneratorContext context)
        {
            var sourceBuilder = new StringBuilder(@"
using System;
namespace ShowSyntaxTrees
{
  public static class SyntaxTrees
  {
    public static void Show()
    {

");


            var syntaxTrees = context.Compilation.SyntaxTrees;

            foreach (var syntaxTree in syntaxTrees)
            {
                sourceBuilder.Append($@"Console.WriteLine(@""{syntaxTree.FilePath}"");");
            }

            sourceBuilder.Append(@"
    }
  }
}");

            context.AddSource("syntaxtrees", SourceText.From(sourceBuilder.ToString(), Encoding.UTF8));
        }
        private void GenerateDictionaty(SourceGeneratorContext context, INamedTypeSymbol type)
        {
            var structure = new JsonDictionary(type);
            var code      = DictionaryGenerator.Generate(structure);

            context.AddSource($"{type.Name}.Generated.cs", SourceText.From(code, Encoding.UTF8));
        }
예제 #6
0
 public void Execute(SourceGeneratorContext context)
 {
     foreach (var file in context.AdditionalFiles)
     {
         context.AddSource(GetGeneratedFileName(file.Path), SourceText.From("", Encoding.UTF8));
     }
 }
예제 #7
0
        public void Execute(SourceGeneratorContext context)
        {
            IEnumerable <AdditionalText> settingsFiles = context.AdditionalFiles.Where(at => at.Path.EndsWith(".json"));

            foreach (var file in settingsFiles)
            {
                var fileName     = Path.GetFileNameWithoutExtension(file.Path);
                var jsonDocument = JsonDocument.Parse(file.GetText().ToString());
                var sb           = new StringBuilder($@"
namespace MyGenerated 
{{
    public class {fileName} 
    {{
        ");
                foreach (var prop in jsonDocument.RootElement.EnumerateObject())
                {
                    sb.AppendLine($"public {GetPropertyType(prop.Value.ValueKind)} {prop.Name} {{ get; set; }}");
                }

                sb.AppendLine("} }");

                var content = sb.ToString();

                context.AddSource($"Json_{fileName}.cs", SourceText.From(content, Encoding.UTF8));
            }
        }
        public void Execute(SourceGeneratorContext context)
        {
            // begin creating the source we'll inject into the users compilation
            StringBuilder sourceBuilder = new StringBuilder();

            // we need to somehow discover the views in a project automatically - for now they listed here
            var views = new List <string>();

            views.Add("MainPage");
            views.Add("SecondPage");

            foreach (var view in views)
            {
                sourceBuilder.Append($@"
        
        using Xamarin.Forms;
        namespace PrismExample.Views
        {{
          public partial class {view}
          {{
            public {view}()
            {{
              InitializeComponent();
            }}
          }}
        }}

        ");
            }


            // inject the created source into the users compilation
            context.AddSource("viewGenerated", SourceText.From(sourceBuilder.ToString(), Encoding.UTF8));
        }
예제 #9
0
        public void Execute(SourceGeneratorContext context)
        {
            // begin creating the source we'll inject into the users compilation
            var sourceBuilder = new StringBuilder(@"
using System;
namespace HelloWorldGenerated
{
    public static class HelloWorld
    {
        public static void SayHello() 
        {
            Console.WriteLine(""Hello from generated code!"");
            Console.WriteLine(""The following syntax trees existed in the compilation that created this program:"");
");

            // using the context, get a list of syntax trees in the users compilation
            var syntaxTrees = context.Compilation.SyntaxTrees;

            // add the filepath of each tree to the class we're building
            foreach (SyntaxTree tree in syntaxTrees)
            {
                sourceBuilder.AppendLine($@"Console.WriteLine(@"" - {tree.FilePath}"");");
            }

            // finish creating the source to inject
            sourceBuilder.Append(@"
        }
    }
}");

            // inject the created source into the users compilation
            context.AddSource("helloWorldGenerator", SourceText.From(sourceBuilder.ToString(), Encoding.UTF8));
        }
예제 #10
0
        public void Execute(SourceGeneratorContext context)
        {
            foreach (AdditionalText bfFile in context.AdditionalFiles.Where(x => x.Path.EndsWith(".bf")))
            {
                try
                {
                    (IEnumerable <BFOp> operations, BFTranspilerOptions options) = BFParser.Parse(bfFile);

                    if (!operations.Any())
                    {
                        continue;
                    }

                    BFTranspiler btf = new BFTranspiler(options);

                    string csFile = btf.Transpile(operations);

                    context.AddSource(options.ClassName + ".cs", SourceText.From(csFile, Encoding.UTF8));
                }
                catch (Exception e)
                {
                    context.ReportDiagnostic(
                        Diagnostic.Create(
                            new DiagnosticDescriptor("P0T4T0", "BFError", "Error when transpiling BF: {0}", "BF.Transpile", DiagnosticSeverity.Error, true),
                            Location.Create(Path.GetFileName(bfFile.Path), new TextSpan(), new LinePositionSpan()),
                            e.Message));
                }
            }
        }
예제 #11
0
        public void Execute(SourceGeneratorContext context)
        {
            try
            {
                var registrationSymbols = RegistrationSymbols.FromCompilation(context.Compilation);
                var containerClasses    = context.LocateContainerSymbols(registrationSymbols.ContainerSymbol);
                var generator           = new ContainerClassContentGenerator(context, registrationSymbols);

                foreach (var containerClass in containerClasses)
                {
                    var hintName = $"Generated.{containerClass.FullyQualifiedName}";
                    var content  = generator.GenerateClassString(containerClass);

                    WriteOutDebugFile(hintName, content, context);
                    context.AddSource(hintName, SourceText.From(content, Encoding.UTF8));
                }
            }
            catch (DiagnosticException ex)
            {
                context.ReportDiagnostic(ex.Diagnostic);
            }
            catch (Exception ex)
            {
                var descriptor = new DiagnosticDescriptor(DiagnosticConstants.UnknownExceptionId, "Unexpected error", $"Unknown error during generation: {ex.GetType()} {ex.Message}", DiagnosticConstants.Category, DiagnosticSeverity.Error, true);
                context.ReportDiagnostic(Diagnostic.Create(descriptor, Location.None));
            }
        }
예제 #12
0
        protected override void Generate(SourceGeneratorContext context, INamedTypeSymbol symbol)
        {
            var equalsCandidates = symbol.GetMembers(nameof(Equals))
                                   .Where(member => member is IMethodSymbol method &&
                                          SymbolEqualityComparer.Default.Equals(method.ReturnType, context.Compilation.GetSpecialType(SpecialType.System_Boolean)) &&
                                          method.Parameters.Length == 1 &&
                                          SymbolEqualityComparer.Default.Equals(method.Parameters[0], symbol));

            var ghcCandidates = symbol.GetMembers(nameof(GetHashCode))
                                .Where(member => member is IMethodSymbol method &&
                                       SymbolEqualityComparer.Default.Equals(method.ReturnType, context.Compilation.GetSpecialType(SpecialType.System_Int32)) &&
                                       method.Parameters.Length == 0);

            var builder = new StringBuilder();

            if (equalsCandidates.Count() == 0)
            {
                var compString = GenerateComparisonOfAllFields(context, symbol);
                builder.AppendLine(string.Format(symbol.IsValueType ? ValueTypeStandardEqualsTemplate : RefTypeStandardEqualsTemplate, symbol.Name, compString));
            }

            if (ghcCandidates.Count() == 0)
            {
                var ghcString = GenerateHashCodeOfAllFields(context, symbol);
                builder.AppendLine(string.Format(GetHashCodeTemplate, ghcString));
            }

            builder.AppendLine(string.Format(symbol.IsValueType ? ValueTypeEqualsTemplate : RefTypeEqualsTemplate, symbol.Name));

            builder.AppendLine(string.Format(EquatableTemplate, symbol.Name));

            var source = string.Format(TypeTemplate, symbol.ContainingNamespace, symbol.IsValueType ? "struct" : "class", symbol.Name, builder.ToString());

            context.AddSource($"{symbol.Name}.EqualityMembers.cs", SourceText.From(source, Encoding.UTF8));
        }
예제 #13
0
        public void Execute(SourceGeneratorContext context)
        {
            var resources = context.GetMSBuildItems("PRIResource");

            if (resources.Any())
            {
                var sb = new IndentedStringBuilder();

                using (sb.BlockInvariant($"namespace {context.GetMSBuildProperty("RootNamespace")}"))
                {
                    using (sb.BlockInvariant($"internal enum PriResources"))
                    {
                        foreach (var item in resources)
                        {
                            //load document
                            XmlDocument doc = new XmlDocument();
                            doc.Load(item);

                            //extract all localization keys from Win10 resource file
                            var nodes = doc.SelectNodes("//data")
                                        .Cast <XmlElement>()
                                        .Select(node => node.GetAttribute("name"))
                                        .ToArray();

                            foreach (var node in nodes)
                            {
                                sb.AppendLineInvariant($"{node},");
                            }
                        }
                    }
                }

                context.AddSource("PriResources", SourceText.From(sb.ToString(), Encoding.UTF8));
            }
        }
        public void Execute(SourceGeneratorContext context)
        {
            context.AddCompiledOnMetadataAttribute();

            var compilation = context.Compilation;
            var types       = CompilationHelper.GetAllTypes(context.Compilation.Assembly);

            using (var stringWriter = new StringWriter())
                using (var indentedTextWriter = new IndentedTextWriter(stringWriter, "    "))
                {
                    var defaultToStringGenerator = new DefaultToStringGenerator(context);
                    foreach (var type in types)
                    {
                        if (DefaultToStringGenerator.ShouldUseGenerator(type))
                        {
                            defaultToStringGenerator.WriteType(type, indentedTextWriter);
                        }
                    }

                    indentedTextWriter.Flush();
                    stringWriter.Flush();

                    var sourceText = SourceText.From(stringWriter.ToString(), Encoding.UTF8);
                    var hintName   = $"AutoToString_{compilation.Assembly.Name}.g.cs";

                    context.AddSource(hintName, sourceText);
                }
        }
예제 #15
0
        public void Execute(SourceGeneratorContext context)
        {
            StringBuilder sourceBuilder = new StringBuilder(@"
using System;

namespace SyntaxTreesGenerated
{
    public static class SyntaxTrees
    {
        public static void PrintSyntaxTrees() 
        {
            Console.WriteLine(""The following syntax trees existed in the compilation that created this program:"");
");

            foreach (SyntaxTree tree in context.Compilation.SyntaxTrees)
            {
                sourceBuilder.AppendLine($@"Console.WriteLine(@""{tree.FilePath}"");");
            }

            sourceBuilder.Append(@"
        }
    }
}");

            context.AddSource("syntaxTreesGenerator", SourceText.From(sourceBuilder.ToString(), Encoding.UTF8));
        }
        private void GenerateLazyLoader(SourceGeneratorContext context, INamedTypeSymbol type)
        {
            var structure = new JsonLazyLoader(type);
            var code      = LazyLoaderGenerator.Generate(structure);

            context.AddSource($"{type.Name}.Generated.cs", SourceText.From(code, Encoding.UTF8));
        }
        public void Execute(SourceGeneratorContext context)
        {
            // the generator infrastructure will create a receiver and populate it
            // we can retrieve the populated instance via the context
            MySyntaxReceiver syntaxReceiver = (MySyntaxReceiver)context.SyntaxReceiver;

            // get the recorded user class
            ClassDeclarationSyntax userClass = syntaxReceiver.ClassToAugment;

            if (userClass is null)
            {
                // if we didn't find the user class, there is nothing to do
                return;
            }

            // add the generated implementation to the compilation
            SourceText sourceText = SourceText.From($@"
public partial class {userClass.Identifier}
{{
    public void GeneratedMethod()
    {{
        // generated code
    }}
}}", Encoding.UTF8);

            context.AddSource("ExpressionHolder.Generated.cs", sourceText);
        }
예제 #18
0
        public void WritePrimitivesSerializerClass(SourceGeneratorContext context)
        {
            // Write out some functions that are  missing from the BinaryPrimitives class.
            var sourceBuilder = new StringBuilder();

            sourceBuilder.Append(@"
namespace BitSerialization.Generated
{
    internal static class BitPrimitivesSerializer
    {
        public static bool TryWriteByte(global::System.Span<byte> destination, byte value)
        {
            if (destination.Length < 1)
            {
                return false;
            }
            destination[0] = value;
            return true;
        }

        public static bool TryWriteSByte(global::System.Span<byte> destination, sbyte value)
        {
            if (destination.Length < 1)
            {
                return false;
            }
            destination[0] = (byte)value;
            return true;
        }

        public static bool TryReadByte(global::System.ReadOnlySpan<byte> source, out byte value)
        {
            if (source.Length < 1)
            {
                value = default;
                return false;
            }
            value = source[0];
            return true;
        }

        public static bool TryReadSByte(global::System.ReadOnlySpan<byte> source, out sbyte value)
        {
            if (source.Length < 1)
            {
                value = default;
                return false;
            }
            value = (sbyte)source[0];
            return true;
        }
    }
}
");

            string sourceCode = sourceBuilder.ToString();

            context.AddSource("BitPrimitivesSerializer.cs", SourceText.From(sourceCode, Encoding.UTF8));
        }
예제 #19
0
        private void Execute(SourceGeneratorContext context, INamedTypeSymbol typeSymbol)
        {
            var writer     = new TypeBuilderWriter();
            var source     = writer.Write(typeSymbol);
            var sourceText = SourceText.From(source, Encoding.UTF8);

            context.AddSource($"{typeSymbol.Name}Builder.cs", sourceText);
        }
예제 #20
0
        protected override void Generate(SourceGeneratorContext context, INamedTypeSymbol typeSymbol)
        {
            var builder = new IAInputDescBuilder();

            ResolveType(builder, (typeSymbol.Name, typeSymbol));

            context.AddSource($"{typeSymbol.Name}.IAInputLayout.cs", SourceText.From(builder.ToString(typeSymbol) !, Encoding.UTF8));
        }
예제 #21
0
 public void Execute(SourceGeneratorContext context)
 {
     _onExecute(context);
     if (!string.IsNullOrWhiteSpace(_source))
     {
         context.AddSource("source.cs", SourceText.From(_source, Encoding.UTF8));
     }
 }
예제 #22
0
        public void Execute(SourceGeneratorContext context)
        {
            Compilation?compilation = context.Compilation;

            string sourceBuilder = Generate(compilation);

            context.AddSource("ServiceLocator.cs", SourceText.From(sourceBuilder, Encoding.UTF8));
        }
예제 #23
0
        public void Execute(SourceGeneratorContext context)
        {
            // Always add the attribute itself to the compilation
            context.AddSource("CompileTimeExecutorAttribute", SourceText.From(attributeText, Encoding.UTF8));

            // retreive the populated receiver
            if (!(context.SyntaxReceiver is SyntaxReceiver receiver))
            {
                return;
            }

            // we're going to create a new compilation that contains the attribute.
            // TODO: we should allow source generators to provide source during initialize, so that this step isn't required.
            CSharpParseOptions options     = (context.Compilation as CSharpCompilation).SyntaxTrees[0].Options as CSharpParseOptions;
            Compilation        compilation = context.Compilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(SourceText.From(attributeText, Encoding.UTF8), options));

            // get the newly bound attribute, and INotifyPropertyChanged
            INamedTypeSymbol attributeSymbol = compilation.GetTypeByMetadataName("CompileTimeMethodExecutionGenerator.CompileTimeExecutorAttribute");

            foreach (MethodDeclarationSyntax method in receiver.CandidateMethods)
            {
                SemanticModel model = compilation.GetSemanticModel(method.SyntaxTree);

                var methodSymbol = model.GetDeclaredSymbol(method) as IMethodSymbol;

                foreach (AttributeSyntax attribute in method.AttributeLists
                         .SelectMany(al => al.Attributes)
                         .Where(at => string.Equals("CompileTimeExecutor", at.Name.ToString())))
                {
                    string calculatedResult = CalculateResult(method, methodSymbol);

                    context.AddSource($"{methodSymbol.ContainingNamespace.ToDisplayString()}_{methodSymbol.ContainingType.Name}_{method.Identifier.Text}.gen.cs",
                                      SourceText.From($@"namespace {methodSymbol.ContainingNamespace.ToDisplayString()}
{{
    public partial class {methodSymbol.ContainingType.Name}
    {{
        public string {method.Identifier.Text}CompileTime()
        {{
            return ""{calculatedResult}"";
        }}
    }}
}}", Encoding.UTF8));
                }
            }
        }
        public void Execute(SourceGeneratorContext context)
        {
            var source = GetGeneratedSource(context.Compilation);

            if (source != null)
            {
                context.AddSource("generated.cs", SourceText.From(source, Encoding.UTF8));
            }
        }
        public void Execute(SourceGeneratorContext context)
        {
            // add the attribute text
            context.AddSource("AutoNotifyAttribute", SourceText.From(attributeText, Encoding.UTF8));

            // retreive the populated receiver
            if (!(context.SyntaxReceiver is SyntaxReceiver receiver))
            {
                return;
            }

            // we're going to create a new compilation that contains the attribute.
            // TODO: we should allow source generators to provide source during initialize, so that this step isn't required.
            CSharpParseOptions options     = (context.Compilation as CSharpCompilation).SyntaxTrees[0].Options as CSharpParseOptions;
            Compilation        compilation = context.Compilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(SourceText.From(attributeText, Encoding.UTF8), options));

            // get the newly bound attribute, and INotifyPropertyChanged
            INamedTypeSymbol attributeSymbol = compilation.GetTypeByMetadataName("AutoNotify.AutoNotifyAttribute");
            INamedTypeSymbol notifySymbol    = compilation.GetTypeByMetadataName("System.ComponentModel.INotifyPropertyChanged");

            // loop over the candidate fields, and keep the ones that are actually annotated
            List <IFieldSymbol> fieldSymbols = new List <IFieldSymbol>();

            foreach (FieldDeclarationSyntax field in receiver.CandidateFields)
            {
                SemanticModel model = compilation.GetSemanticModel(field.SyntaxTree);
                foreach (VariableDeclaratorSyntax variable in field.Declaration.Variables)
                {
                    // Get the symbol being decleared by the field, and keep it if its annotated
                    IFieldSymbol fieldSymbol = model.GetDeclaredSymbol(variable) as IFieldSymbol;
                    if (fieldSymbol.GetAttributes().Any(ad => ad.AttributeClass.Equals(attributeSymbol, SymbolEqualityComparer.Default)))
                    {
                        fieldSymbols.Add(fieldSymbol);
                    }
                }
            }

            // group the fields by class, and generate the source
            foreach (IGrouping <INamedTypeSymbol, IFieldSymbol> group in fieldSymbols.GroupBy(f => f.ContainingType))
            {
                string classSource = ProcessClass(group.Key, group.ToList(), attributeSymbol, notifySymbol, context);
                context.AddSource($"{group.Key.Name}_autoNotify.cs", SourceText.From(classSource, Encoding.UTF8));
            }
        }
예제 #26
0
        public void Execute(SourceGeneratorContext context)
        {
            SyntaxReceiver receiver = context.SyntaxReceiver as SyntaxReceiver;

            foreach (string name in receiver.Namespaces)
            {
                string code = GetCodeForNamespace(name);
                context.AddSource($"{name}.Console.Generated", SourceText.From(code, Encoding.UTF8));
            }
        }
        public void Execute(SourceGeneratorContext context)
        {
            context.AddSource(AttributeFullName, SourceText.From(AttributeText, Encoding.UTF8));

            // TODO : Improve
            CSharpParseOptions options     = (context.Compilation as CSharpCompilation)?.SyntaxTrees[0]?.Options as CSharpParseOptions ?? throw new InvalidOperationException();
            Compilation        compilation = context.Compilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(SourceText.From(AttributeText, Encoding.UTF8), options));

            if (!(context.SyntaxReceiver is EnumSyntaxReceiver receiver))
            {
                return;
            }

            var attributeSymbol = compilation.GetTypeByMetadataName(AttributeFullName)
                                  ?? throw new NullReferenceException($@"[{AttributeFullName}] is missing from the compilation");

            var eligibleEnums = receiver.EnumCandidates
                                .Where(enumItem =>
            {
                var model = compilation.GetSemanticModel(enumItem.SyntaxTree);
                var symb  = model.GetDeclaredSymbol(enumItem);
                return(symb is not null && symb.GetAttributes().Any(x =>
                                                                    x.AttributeClass?.Equals(attributeSymbol, SymbolEqualityComparer.Default) == true));
            });

            var preProcessedEnums = eligibleEnums
                                    .Select(x => (EnumDeclaration: x, Processor: new EnumProcessor(x, compilation)))
                                    .ToList();

            //foreach (var (enumItem, _) in preProcessedEnums)
            //{
            //    var proc = new EnumProcessor(enumItem, compilation);
            //    var src = GenerateEnumExtension(proc);
            //    context.AddSource(proc.EnumType.Name, src);
            //}


            context.AddSource(nameof(GenerateAllEnumValues), GenerateAllEnumValues(preProcessedEnums));
            context.AddSource(nameof(GenerateAllEnumNames), GenerateAllEnumNames(preProcessedEnums));
            context.AddSource(nameof(GenerateTryParseEnum), GenerateTryParseEnum(preProcessedEnums));
        }
예제 #28
0
        private static Compilation GenerateHelperClasses(SourceGeneratorContext context)
        {
            var compilation = context.Compilation;

            var options         = (compilation as CSharpCompilation)?.SyntaxTrees[0].Options as CSharpParseOptions;
            var tempCompilation = compilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(SourceText.From(ServiceLocatorStub, Encoding.UTF8), options))
                                  .AddSyntaxTrees(CSharpSyntaxTree.ParseText(SourceText.From(TransientAttribute, Encoding.UTF8), options));

            context.AddSource("TransientAttribute.cs", SourceText.From(TransientAttribute, Encoding.UTF8));

            return(tempCompilation);
        }
예제 #29
0
        public void RunGeneration()
        {
            using var scope = CreateServiceProvider().CreateScope();
            var serviceProvider         = scope.ServiceProvider;
            var externalContextProvider = serviceProvider.GetRequiredService <IContextCollectionProvider>();

            // First we validate all the captured syntax are valid
            foreach (var syntaxNode in _capture.CapturedNodes)
            {
                // We rely on lazy evaluation so that if the first group fails, we just short cut out
                var diagnosticsGroup = RunSyntaxAnalyzerGroup(serviceProvider, syntaxNode, externalContextProvider);
                diagnosticsGroup = diagnosticsGroup.Concat(RunSymbolAnalyzerGroup(serviceProvider, syntaxNode, externalContextProvider));

                foreach (var diagnostics in diagnosticsGroup)
                {
                    if (ReportDiagnostics(diagnostics))
                    {
                        return;
                    }
                }
            }

            // Then finally we run the generation
            // TODO : Handle Exceptions
            try {
                var generators = serviceProvider.GetServices <SourceGenerator>();
                foreach (var generator in generators)
                {
                    generator.Context = new InternalGeneratingContext {
                        ContextCollectionSource = externalContextProvider,
                        SourceAddition          = serviceProvider.GetRequiredService <ISourceAddition>(),
                        SymbolProvider          = serviceProvider.GetRequiredService <ITypeSymbolProvider>()
                    };
                    foreach (var syntaxNode in _capture.CapturedNodes)
                    {
                        var context = new GenerationContext(syntaxNode,
                                                            GetSemanticModel(syntaxNode),
                                                            _generatorContext.AdditionalFiles,
                                                            _generatorContext.AnalyzerConfigOptions,
                                                            _generatorContext.CancellationToken);
                        generator.GenerateContext(context);
                    }
                    foreach (var source in generator.GeneratedSource)
                    {
                        _generatorContext.AddSource(source.HintName, source.SourceText);
                    }
                }
            }
            catch (Exception e) {
                GetExceptionDiagnostic(e);
                // should we rethrow?
            }
        }
        public void Execute(SourceGeneratorContext context)
        {
            context.AddSource(GeneratedClassName, SourceText.From(@"
internal class " + GeneratedClassName + @"
{
    public static string GetMessage()
    {
        return ""Hello, World!"";
    }
}
", encoding: Encoding.UTF8));
        }