public void Setup()
		{
			ccu = new CodeCompileUnit();
			mocks = new MockRepository();
			engine = Engine.GlobalEngine;
			engine.BinPath = @"C:\Program Files (x86)\MSBuild";
			project = new Project();
			buildEngine = mocks.DynamicMock<MockBuildEngine>(project);

			logger = new NullLogger();
			parserService = mocks.DynamicMock<ISiteTreeGeneratorService>();
			naming = mocks.DynamicMock<INamingService>();
			sourceStorage = mocks.DynamicMock<IParsedSourceStorageService>();
			source = mocks.DynamicMock<ISourceGenerator>();
			typeResolver = mocks.DynamicMock<ITypeResolver>();
			treeService = mocks.DynamicMock<ITreeCreationService>();
			viewSourceMapper = mocks.DynamicMock<IViewSourceMapper>();
			generator = mocks.DynamicMock<IGenerator>();

			task = new GenerateMonoRailSiteTreeTask(logger, parserService, naming, source, sourceStorage, typeResolver,
			                                         treeService, viewSourceMapper, generator);

			item = mocks.DynamicMock<ITaskItem>();
			parsedSource = mocks.DynamicMock<IParser>();
		}
		public virtual void Setup()
		{
			naming = new DefaultNamingService();
			source = new DefaultSourceGenerator();
			logging = new NullLogger();
			generator = new RouteMapGenerator(logging, source, naming, "TargetNamespace", typeof (IServiceProvider).FullName);
		}
		public virtual void Setup()
		{
			mocks = new MockRepository();
			naming = new DefaultNamingService();
			source = new DefaultSourceGenerator();
			logging = new NullLogger();
			generator = new ActionMapGenerator(logging, source, naming, "TargetNamespace", typeof (IServiceProvider).FullName);
		}
 	public virtual void Setup()
 	{
 		_mocks = new MockRepository();
     _naming = new DefaultNamingService();
     _source = new DefaultSourceGenerator();
     _logging = new NullLogger();
     _generator = new ControllerMapGenerator(_logging, _source, _naming, "TargetNamespace", typeof(IServiceProvider).FullName);
 	}
		public virtual void Setup()
		{
			naming = new DefaultNamingService();
			source = new DefaultSourceGenerator(); // I found a more integration style of testing was better, I started off
			// mocking calls to ISourceGenerator, and that was just stupid, we want the classes and types and members.
			// and the assertions here ensure that.
			logging = new NullLogger();
			generator = new ActionMapGenerator(logging, source, naming, "TargetNamespace", typeof (IServiceProvider).FullName);
		}
Exemplo n.º 6
0
		public AbstractGenerator(ILogger logger, ISourceGenerator source, INamingService naming, string targetNamespace, string serviceType)
		{
			_logger = logger;
			_source = source;
			_naming = naming;
			_namespace = targetNamespace;
			_serviceType = serviceType;
			_serviceIdentifier = "services";
		}
Exemplo n.º 7
0
		public Generator(string nameSpace, string outputFile, string serviceTypeName, ILogger logger, INamingService namingService, ISourceGenerator sourceGenerator, ITreeCreationService treeCreationService)
		{
			this.nameSpace = nameSpace;
			this.outputFile = outputFile;
			this.serviceTypeName = serviceTypeName;
			this.logger = logger;
			this.namingService = namingService;
			this.sourceGenerator = sourceGenerator;
			this.treeCreationService = treeCreationService;
		}
		public virtual void Setup()
		{
			_mocks = new MockRepository();
			_naming = new DefaultNamingService();
			_source = new DefaultSourceGenerator(); // I found a more integration style of testing was better, I started off
			// mocking calls to ISourceGenerator, and that was just stupid, we want the classes and types and members.
			// and the assertions here ensure that.
			_logging = new NullLogger();
			_generator =
				new ControllerPartialsGenerator(_logging, _source, _naming, "TargetNamespace", typeof (IServiceProvider).FullName);
		}
		public GenerateMonoRailSiteTreeTask()
		{
			logger = new MsBuildLogger(Log);
			naming = new DefaultNamingService();
			treeService = new DefaultTreeCreationService();
			source = new DefaultSourceGenerator();
			viewSourceMapper = new ViewSourceMapper(logger, treeService);
			sourceStorage = new DefaultSourceStorageService();
			typeResolver = new TypeResolver();
			service = new SiteTreeGeneratorService(logger, typeResolver, sourceStorage, new NRefactoryParserFactory());
			ServiceTypeName = typeof(ICodeGeneratorServices).FullName;
			ViewComponentSources = new ITaskItem[0];
			AssemblyReferences = new ITaskItem[0];
		}
		public GenerateMonoRailSiteTreeTask(ILogger logger, ISiteTreeGeneratorService service, INamingService naming,
											ISourceGenerator source, IParsedSourceStorageService sourceStorage,
											ITypeResolver typeResolver, ITreeCreationService treeService,
											IViewSourceMapper viewSourceMapper, IGenerator generator)
		{
			this.service = service;
			this.logger = logger;
			this.naming = naming;
			this.source = source;
			this.sourceStorage = sourceStorage;
			this.typeResolver = typeResolver;
			this.treeService = treeService;
			this.viewSourceMapper = viewSourceMapper;
			generators.Add(generator);
			ServiceTypeName = typeof(ICodeGeneratorServices).FullName;
			ViewComponentSources = new ITaskItem[0];
			AssemblyReferences = new ITaskItem[0];
		}
Exemplo n.º 11
0
 /// <summary>
 /// Initializes a new instance of the <see cref="GeneratorTest"/> class.
 /// </summary>
 protected GeneratorTest()
 {
     Generator = CreateGenerator();
 }
 public GenerateMonoRailSiteTreeTask(ILogger logger, ISiteTreeGeneratorService service, INamingService naming, ISourceGenerator source, IParsedSourceStorageService sourceStorage, ITypeResolver typeResolver, ITreeCreationService treeService, IViewSourceMapper viewSourceMapper, IGenerator generator)
 {
     _service = service;
     _logger = logger;
     _naming = naming;
     _source = source;
     _sourceStorage = sourceStorage;
     _typeResolver = typeResolver;
     _treeService = treeService;
     _viewSourceMapper = viewSourceMapper;
     _generators.Add(generator);
     this.ServiceTypeName = typeof(ICodeGeneratorServices).FullName;
 }
Exemplo n.º 13
0
 public StaticRouteCreator(string @namespace, ISourceGenerator sourceGenerator, INamingService namingService, StaticRouteTreeNode node, CodeTypeDeclaration routeDefinitions, CodeTypeDeclaration routes) : base(@namespace, sourceGenerator, namingService, node, routeDefinitions, routes)
 {
 }
 public TestGeneratorReference(ISourceGenerator generator)
 {
     _generator = generator;
 }
Exemplo n.º 15
0
 public Generator(string nameSpace, string outputFile, string serviceTypeName, ILogger logger, INamingService namingService, ISourceGenerator sourceGenerator, ITreeCreationService treeCreationService)
 {
     this.nameSpace           = nameSpace;
     this.outputFile          = outputFile;
     this.serviceTypeName     = serviceTypeName;
     this.logger              = logger;
     this.namingService       = namingService;
     this.sourceGenerator     = sourceGenerator;
     this.treeCreationService = treeCreationService;
 }
Exemplo n.º 16
0
 public override GeneratorDriver CreateGeneratorDriver(ISourceGenerator generator)
 => CSharpGeneratorDriver.Create(generator);
Exemplo n.º 17
0
 public static RunTimer CreateSingleGeneratorRunTimer(this CodeAnalysisEventSource eventSource, ISourceGenerator generator)
 {
     if (eventSource.IsEnabled(EventLevel.Informational, Keywords.Performance))
     {
         var id   = Guid.NewGuid().ToString();
         var type = generator.GetGeneratorType();
         eventSource.StartSingleGeneratorRunTime(type.FullName !, type.Assembly.Location, id);
         return(new RunTimer(t => eventSource.StopSingleGeneratorRunTime(type.FullName !, type.Assembly.Location, t.Ticks, id)));
     }
     else
     {
         return(new RunTimer());
     }
 }
Exemplo n.º 18
0
        // Generation
        public static async Task <GeneratorRunResult> GenerateAsync(ISourceGenerator generator, Compilation compilation, CancellationToken cancellationToken)
        {
            var driver = GetGeneratorDriver(generator, null, null, null);

            return(driver.RunGenerators(compilation, cancellationToken).GetRunResult().Results.Single());
        }
Exemplo n.º 19
0
        private static GeneratorState SetGeneratorException(CommonMessageProvider provider, GeneratorState generatorState, ISourceGenerator generator, Exception e, DiagnosticBag?diagnosticBag, bool isInit = false)
        {
            var message    = isInit ? provider.WRN_GeneratorFailedDuringInitialization : provider.WRN_GeneratorFailedDuringGeneration;
            var diagnostic = Diagnostic.Create(provider, message, generator.GetType().Name);

            diagnosticBag?.Add(diagnostic);
            return(new GeneratorState(generatorState.Info, e, diagnostic));
        }
 public abstract GeneratorDriver CreateGeneratorDriver(ISourceGenerator generator);
Exemplo n.º 21
0
        public static SourceGeneratedDocumentState Create(
            string hintName,
            SourceText generatedSourceText,
            SyntaxTree generatedSyntaxTree,
            DocumentId documentId,
            ISourceGenerator sourceGenerator,
            HostLanguageServices languageServices,
            SolutionServices solutionServices,
            CancellationToken cancellationToken
            )
        {
            var options  = generatedSyntaxTree.Options;
            var filePath = generatedSyntaxTree.FilePath;

            var textAndVersion = TextAndVersion.Create(generatedSourceText, VersionStamp.Create());
            ValueSource <TextAndVersion> textSource = new ConstantValueSource <TextAndVersion>(
                textAndVersion
                );

            var root = generatedSyntaxTree.GetRoot(cancellationToken);

            Contract.ThrowIfNull(
                languageServices.SyntaxTreeFactory,
                "We should not have a generated syntax tree for a language that doesn't support trees."
                );

            if (languageServices.SyntaxTreeFactory.CanCreateRecoverableTree(root))
            {
                // We will only create recoverable text if we can create a recoverable tree; if we created a
                // recoverable text but not a new tree, it would mean tree.GetText() could still potentially return
                // the non-recoverable text, but asking the document directly for it's text would give a recoverable
                // text with a different object identity.
                textSource = CreateRecoverableText(textAndVersion, solutionServices);

                generatedSyntaxTree = languageServices.SyntaxTreeFactory.CreateRecoverableTree(
                    documentId.ProjectId,
                    filePath: generatedSyntaxTree.FilePath,
                    options,
                    textSource,
                    generatedSourceText.Encoding,
                    root
                    );
            }

            var treeAndVersion = TreeAndVersion.Create(generatedSyntaxTree, textAndVersion.Version);

            return(new SourceGeneratedDocumentState(
                       languageServices,
                       solutionServices,
                       documentServiceProvider: null,
                       new DocumentInfo.DocumentAttributes(
                           documentId,
                           name: hintName,
                           folders: SpecializedCollections.EmptyReadOnlyList <string>(),
                           options.Kind,
                           filePath: filePath,
                           isGenerated: true,
                           designTimeOnly: false
                           ),
                       options,
                       sourceText: null, // don't strongly hold the text
                       textSource,
                       treeAndVersion,
                       sourceGenerator,
                       hintName
                       ));
        }
Exemplo n.º 22
0
 public SourceGeneratorAdaptor(ISourceGenerator generator)
 {
     SourceGenerator = generator;
 }
Exemplo n.º 23
0
 public RestRouteCreator(string @namespace, ISourceGenerator sourceGenerator, INamingService namingService, RestRouteTreeNode node, CodeTypeDeclaration routeDefinitions, CodeTypeDeclaration routes) : base(@namespace, sourceGenerator, namingService, node, routeDefinitions, routes)
 {
     OptionalRouteParameters.Add(FormatKey, new StringRouteParameterType());
 }
Exemplo n.º 24
0
 public PatternRouteCreator(string @namespace, ISourceGenerator sourceGenerator, INamingService namingService, PatternRouteTreeNode node, CodeTypeDeclaration routeDefinitions, CodeTypeDeclaration routes) : base(@namespace, sourceGenerator, namingService, node, routeDefinitions, routes)
 {
     requiredRouteParameters = new RequiredRouteParameters().GetFrom(node.Pattern);
     optionalRouteParameters = new OptionalRouteParameters().GetFrom(node.Pattern);
     routeParameterDefaults  = new RouteParameterDefaults().GetFrom(node.Defaults);
 }
        public static SourceGeneratedDocumentIdentity Generate(ProjectId projectId, string hintName, ISourceGenerator generator, string filePath)
        {
            // We want the DocumentId generated for a generated output to be stable between Compilations; this is so features that track
            // a document by DocumentId can find it after some change has happened that requires generators to run again.
            // To achieve this we'll just do a crytographic hash of the generator name and hint name; the choice of a cryptographic hash
            // as opposed to a more generic string hash is we actually want to ensure we don't have collisions.
            var generatorAssemblyName = GetGeneratorAssemblyName(generator);
            var generatorTypeName     = GetGeneratorTypeName(generator);

            // Combine the strings together; we'll use Encoding.Unicode since that'll match the underlying format; this can be made much
            // faster once we're on .NET Core since we could directly treat the strings as ReadOnlySpan<char>.
            var projectIdBytes = projectId.Id.ToByteArray();

            using var _ = ArrayBuilder <byte> .GetInstance(capacity : (generatorAssemblyName.Length + 1 + generatorTypeName.Length + 1 + hintName.Length) * 2 + projectIdBytes.Length, out var hashInput);

            hashInput.AddRange(projectIdBytes);

            // Add a null to separate the generator name and hint name; since this is effectively a joining of UTF-16 bytes
            // we'll use a UTF-16 null just to make sure there's absolutely no risk of collision.
            hashInput.AddRange(Encoding.Unicode.GetBytes(generatorAssemblyName));
            hashInput.AddRange(0, 0);
            hashInput.AddRange(Encoding.Unicode.GetBytes(generatorTypeName));
            hashInput.AddRange(0, 0);
            hashInput.AddRange(Encoding.Unicode.GetBytes(hintName));

            // The particular choice of crypto algorithm here is arbitrary and can be always changed as necessary. The only requirement
            // is it must be collision resistant, and provide enough bits to fill a GUID.
            using var crytpoAlgorithm = System.Security.Cryptography.SHA256.Create();
            var hash = crytpoAlgorithm.ComputeHash(hashInput.ToArray());

            Array.Resize(ref hash, 16);
            var guid = new Guid(hash);

            var documentId = DocumentId.CreateFromSerialized(projectId, guid, hintName);

            return(new SourceGeneratedDocumentIdentity(documentId, hintName, generatorAssemblyName, generatorTypeName, filePath));
        }
        protected static Assembly?RunGeneratorAndGenerateAssembly(
            ISourceGenerator generator,
            string source,
            out ImmutableArray <Diagnostic> diagnostics,
            CSharpParseOptions?parseOptions     = null,
            AnalyzerConfigOptions?configOptions = null,
            IEnumerable <MetadataReference>?additionalReferences = null,
            CSharpCompilationOptions?compilationOptions          = null,
            EmitOptions?emitOptions  = null,
            bool printDiagnostics    = true,
            bool makeTestFailIfError = true)
        {
            if (generator is null)
            {
                throw new ArgumentNullException(nameof(generator));
            }

            if (source is null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            parseOptions ??= CSharpParseOptions.Default
            .WithLanguageVersion(LanguageVersion.CSharp9);

            configOptions ??= TestAnalyzerConfigOptions.Empty;

            compilationOptions ??= new CSharpCompilationOptions(
                OutputKind.DynamicallyLinkedLibrary,
                nullableContextOptions: NullableContextOptions.Enable);

            emitOptions ??= new EmitOptions(
                debugInformationFormat: DebugInformationFormat.PortablePdb);

            var optionsProvider = new TestAnalyzerConfigOptionsProvider(configOptions);

            var driver = CSharpGeneratorDriver.Create(
                new[] { generator },
                parseOptions: parseOptions,
                optionsProvider: optionsProvider);

            string assemblyName = Guid.NewGuid().ToString("D");

            var syntaxTree = CSharpSyntaxTree.ParseText(
                source,
                parseOptions,
                "Main.cs",
                Encoding.UTF8);

            var references = new List <MetadataReference> {
                MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
                MetadataReference.CreateFromFile(typeof(ITestHooks).Assembly.Location)
            };

            if (additionalReferences is not null)
            {
                references.AddRange(additionalReferences);
            }

            var compilation = CSharpCompilation.Create(
                assemblyName,
                new[] { syntaxTree },
                references,
                compilationOptions);

            var driver2 = driver.RunGeneratorsAndUpdateCompilation(
                compilation,
                out var outputCompilation,
                out _);

            var runResult = driver2.GetRunResult();

            var exceptions = runResult.Results
                             .Select(x => x.Exception)
                             .Where(x => x is not null)
                             .Select(x => x !)
                             .ToArray();

            var exception = exceptions.Length switch {
                0 => null,
                1 => exceptions[0],
                > 1 => new AggregateException(exceptions)
            };

            if (exception is not null)
            {
                ExceptionDispatchInfo.Capture(exception).Throw();
            }

            var embeddedTexts = outputCompilation.SyntaxTrees
                                .Select(x => EmbeddedText.FromSource(x.FilePath, x.GetText())).ToArray();

            using var peStream  = new MemoryStream();
            using var pdbStream = new MemoryStream();

            var emitResult = outputCompilation.Emit(
                peStream,
                pdbStream,
                options: emitOptions,
                embeddedTexts: embeddedTexts);

            diagnostics = emitResult.Diagnostics;

            if (printDiagnostics)
            {
                foreach (var d in diagnostics
                         .OrderByDescending(x => x.Severity))
                {
                    TestContext.WriteLine(d.ToString());
                }
            }

            if (!emitResult.Success)
            {
                if (makeTestFailIfError)
                {
                    Assert.Fail();
                }

                return(null);
            }

            if (makeTestFailIfError)
            {
                if (diagnostics.Any(d => d.Severity == DiagnosticSeverity.Error))
                {
                    Assert.Fail();
                    return(null);
                }
            }

            peStream.Seek(0, SeekOrigin.Begin);
            pdbStream.Seek(0, SeekOrigin.Begin);

            var assembly =
                AssemblyLoadContext.Default.LoadFromStream(
                    peStream, pdbStream);

            return(assembly);
        }
 private static string GetGeneratedCode(ISourceGenerator generators, Compilation outputCompilation)
 {
     return(outputCompilation.SyntaxTrees.FirstOrDefault(file => file.FilePath.IndexOf(generators.GetType().Name) > -1)?.ToString());
 }
		public ControllerPartialsGenerator(ILogger logger, ISourceGenerator source, INamingService naming,
		                                   string targetNamespace, string serviceType)
			: base(logger, source, naming, targetNamespace, serviceType)
		{
		}
    public void Setup()
    {
      _ccu = new CodeCompileUnit();
      _mocks = new MockRepository();
      _engine = Engine.GlobalEngine;
      _engine.BinPath = @"C:\Program Files (x86)\MSBuild";
      _project = new Project();
      _buildEngine = _mocks.DynamicMock<MockBuildEngine>(_project);

      _logger = new NullLogger();
      _parserService = _mocks.DynamicMock<ISiteTreeGeneratorService>();
      _naming = _mocks.DynamicMock<INamingService>();
      _sourceStorage = _mocks.DynamicMock<IParsedSourceStorageService>();
      _source = _mocks.DynamicMock<ISourceGenerator>();
      _typeResolver = _mocks.DynamicMock<ITypeResolver>();
      _treeService = _mocks.DynamicMock<ITreeCreationService>();
      _viewSourceMapper = _mocks.DynamicMock<IViewSourceMapper>();
      _generator = _mocks.DynamicMock<IGenerator>();

      _task = new GenerateMonoRailSiteTreeTask(_logger, _parserService, _naming, _source, _sourceStorage, _typeResolver, _treeService, _viewSourceMapper, _generator);

      _item = _mocks.DynamicMock<ITaskItem>();
      _parsedSource = _mocks.DynamicMock<IParser>();
    }
Exemplo n.º 30
0
        private ImmutableDictionary <GeneratedSourceText, SyntaxTree> ParseAdditionalSources(ISourceGenerator generator, ImmutableArray <GeneratedSourceText> generatedSources, CancellationToken cancellationToken)
        {
            var trees = PooledDictionary <GeneratedSourceText, SyntaxTree> .GetInstance();

            var type   = generator.GetType();
            var prefix = $"{type.Module.ModuleVersionId}_{type.FullName}";

            foreach (var source in generatedSources)
            {
                trees.Add(source, ParseGeneratedSourceText(source, $"{prefix}_{source.HintName}", cancellationToken));
            }
            return(trees.ToImmutableDictionaryAndFree());
        }
Exemplo n.º 31
0
 public GenerateMonoRailSiteTreeTask(ILogger logger, ISiteTreeGeneratorService service, INamingService naming, ISourceGenerator source, IParsedSourceStorageService sourceStorage, ITypeResolver typeResolver, ITreeCreationService treeService, IViewSourceMapper viewSourceMapper, IGenerator generator)
 {
     _service          = service;
     _logger           = logger;
     _naming           = naming;
     _source           = source;
     _sourceStorage    = sourceStorage;
     _typeResolver     = typeResolver;
     _treeService      = treeService;
     _viewSourceMapper = viewSourceMapper;
     _generators.Add(generator);
     this.ServiceTypeName = typeof(ICodeGeneratorServices).FullName;
 }
 public static string GetGeneratorTypeName(ISourceGenerator generator)
 {
     return(generator.GetType().FullName !);
 }
Exemplo n.º 33
0
		public RouteMapGenerator(ILogger logger, ISourceGenerator source, INamingService naming, string targetNamespace,
		                         string serviceType) : base(logger, source, naming, targetNamespace, serviceType)
		{
		}
 public GenerateMonoRailSiteTreeTask()
 {
     _logger = new MsBuildLogger(this.Log);
     _naming = new DefaultNamingService();
     _treeService = new DefaultTreeCreationService();
     _source = new DefaultSourceGenerator();
     _viewSourceMapper = new ViewSourceMapper(_logger, _treeService, _naming);
     _sourceStorage = new DefaultSourceStorageService();
     _typeResolver = new TypeResolver();
     _service = new SiteTreeGeneratorService(_logger, _typeResolver, _sourceStorage, new NRefactoryParserFactory());
     this.ServiceTypeName = typeof(ICodeGeneratorServices).FullName;
 }
Exemplo n.º 35
0
 public SourceGeneratorAdaptor(ISourceGenerator generator, string sourceExtension)
 {
     SourceGenerator  = generator;
     _sourceExtension = sourceExtension;
 }
 public override GeneratorDriver CreateGeneratorDriver(ISourceGenerator generator)
 => VisualBasicGeneratorDriver.Create(ImmutableArray.Create(generator));
Exemplo n.º 37
0
 public ControllerMapGenerator(ILogger logger, ISourceGenerator source, INamingService naming, string targetNamespace,
                               string serviceType)
     : base(logger, source, naming, targetNamespace, serviceType)
 {
 }
Exemplo n.º 38
0
        internal static string GetFilePathPrefixForGenerator(ISourceGenerator generator)
        {
            var type = generator.GetType();

            return(Path.Combine(type.Assembly.GetName().Name ?? string.Empty, type.FullName !));
        }
Exemplo n.º 39
0
 /// <summary>
 /// Returns a <see cref="SingletonGeneratorTestResult"/> created by performing a test on the target <paramref name="sourceGenerator"/>.
 /// </summary>
 /// <param name="input">Input for the generator.</param>
 /// <param name="sourceGenerator"><see cref="ISourceGenerator"/> to perform the test on.</param>
 public static SingletonGeneratorTestResult RunGenerator(string?input, ISourceGenerator sourceGenerator)
 {
     if (sourceGenerator is null)
     {
         return(default);
Exemplo n.º 40
0
 internal GeneratorTimingInfo(ISourceGenerator generator, TimeSpan elapsedTime)
 {
     Generator   = generator;
     ElapsedTime = elapsedTime;
 }
Exemplo n.º 41
0
        private static GeneratorState SetGeneratorException(CommonMessageProvider provider, GeneratorState generatorState, ISourceGenerator generator, Exception e, DiagnosticBag?diagnosticBag, bool isInit = false)
        {
            var errorCode = isInit ? provider.WRN_GeneratorFailedDuringInitialization : provider.WRN_GeneratorFailedDuringGeneration;

            // ISSUE: Diagnostics don't currently allow descriptions with arguments, so we have to manually create the diagnostic description
            // ISSUE: Exceptions also don't support IFormattable, so will always be in the current UI Culture.
            // ISSUE: See https://github.com/dotnet/roslyn/issues/46939

            var description = string.Format(provider.GetDescription(errorCode).ToString(CultureInfo.CurrentUICulture), e);

            var descriptor = new DiagnosticDescriptor(
                provider.GetIdForErrorCode(errorCode),
                provider.GetTitle(errorCode),
                provider.GetMessageFormat(errorCode),
                description: description,
                category: "Compiler",
                defaultSeverity: DiagnosticSeverity.Warning,
                isEnabledByDefault: true,
                customTags: WellKnownDiagnosticTags.AnalyzerException);

            var diagnostic = Diagnostic.Create(descriptor, Location.None, generator.GetType().Name, e.GetType().Name, e.Message);

            diagnosticBag?.Add(diagnostic);
            return(new GeneratorState(generatorState.Info, e, diagnostic));
        }
 public static string GetGeneratorAssemblyName(ISourceGenerator generator)
 {
     return(generator.GetGeneratorType().Assembly.FullName !);
 }