diff --git a/src/Compilers/CSharp/Portable/SourceGeneration/CSharpGeneratorDriver.cs b/src/Compilers/CSharp/Portable/SourceGeneration/CSharpGeneratorDriver.cs index 9929e6a4a61bf..8a17671c8dfb9 100644 --- a/src/Compilers/CSharp/Portable/SourceGeneration/CSharpGeneratorDriver.cs +++ b/src/Compilers/CSharp/Portable/SourceGeneration/CSharpGeneratorDriver.cs @@ -62,5 +62,7 @@ internal override SyntaxTree ParseGeneratedSourceText(GeneratedSourceText input, internal override GeneratorDriver FromState(GeneratorDriverState state) => new CSharpGeneratorDriver(state); internal override CommonMessageProvider MessageProvider => CSharp.MessageProvider.Instance; + + internal override AdditionalSourcesCollection CreateSourcesCollection() => new AdditionalSourcesCollection(".cs"); } } diff --git a/src/Compilers/CSharp/Test/Semantic/SourceGeneration/AdditionalSourcesCollectionTests.cs b/src/Compilers/CSharp/Test/Semantic/SourceGeneration/AdditionalSourcesCollectionTests.cs index 45dc947fe47e9..f03278aa32e22 100644 --- a/src/Compilers/CSharp/Test/Semantic/SourceGeneration/AdditionalSourcesCollectionTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/SourceGeneration/AdditionalSourcesCollectionTests.cs @@ -34,7 +34,7 @@ public class AdditionalSourcesCollectionTests [InlineData("abc{1}.cs")] public void HintName_ValidValues(string hintName) { - AdditionalSourcesCollection asc = new AdditionalSourcesCollection(); + AdditionalSourcesCollection asc = new AdditionalSourcesCollection(".cs"); asc.Add(hintName, SourceText.From("public class D{}", Encoding.UTF8)); Assert.True(asc.Contains(hintName)); @@ -43,6 +43,21 @@ public void HintName_ValidValues(string hintName) } + [Theory] + [InlineData("abc")] // abc.vb + [InlineData("abc.cs")] //abc.cs.vb + [InlineData("abc.vb")] // abc.vb + public void HintName_WithExtension(string hintName) + { + AdditionalSourcesCollection asc = new AdditionalSourcesCollection(".vb"); + asc.Add(hintName, SourceText.From("public class D{}", Encoding.UTF8)); + Assert.True(asc.Contains(hintName)); + + var sources = asc.ToImmutableAndFree(); + Assert.True(sources[0].HintName.EndsWith(".vb")); + + } + [Theory] [InlineData("/abc/def.cs")] [InlineData("\\")] @@ -57,7 +72,7 @@ public void HintName_ValidValues(string hintName) [InlineData("abc\u00A0.cs")] // unicode non-breaking space public void HintName_InvalidValues(string hintName) { - AdditionalSourcesCollection asc = new AdditionalSourcesCollection(); + AdditionalSourcesCollection asc = new AdditionalSourcesCollection(".cs"); Assert.Throws(nameof(hintName), () => asc.Add(hintName, SourceText.From("public class D{}", Encoding.UTF8))); } @@ -65,7 +80,7 @@ public void HintName_InvalidValues(string hintName) public void AddedSources_Are_Deterministic() { // a few manual simple ones - AdditionalSourcesCollection asc = new AdditionalSourcesCollection(); + AdditionalSourcesCollection asc = new AdditionalSourcesCollection(".cs"); asc.Add("file3.cs", SourceText.From("", Encoding.UTF8)); asc.Add("file1.cs", SourceText.From("", Encoding.UTF8)); asc.Add("file2.cs", SourceText.From("", Encoding.UTF8)); @@ -87,7 +102,7 @@ public void AddedSources_Are_Deterministic() // generate a long random list, remembering the order we added them Random r = new Random(); string[] names = new string[1000]; - asc = new AdditionalSourcesCollection(); + asc = new AdditionalSourcesCollection(".cs"); for (int i = 0; i < 1000; i++) { names[i] = r.NextDouble().ToString() + ".cs"; @@ -112,7 +127,7 @@ public void AddedSources_Are_Deterministic() [InlineData("file", "File")] public void Hint_Name_Must_Be_Unique(string hintName1, string hintName2) { - AdditionalSourcesCollection asc = new AdditionalSourcesCollection(); + AdditionalSourcesCollection asc = new AdditionalSourcesCollection(".cs"); asc.Add(hintName1, SourceText.From("", Encoding.UTF8)); Assert.Throws("hintName", () => asc.Add(hintName2, SourceText.From("", Encoding.UTF8))); } @@ -129,7 +144,7 @@ public void Hint_Name_Must_Be_Unique(string hintName1, string hintName2) [InlineData("File.cs", "file.CS")] public void Contains(string addHintName, string checkHintName) { - AdditionalSourcesCollection asc = new AdditionalSourcesCollection(); + AdditionalSourcesCollection asc = new AdditionalSourcesCollection(".cs"); asc.Add(addHintName, SourceText.From("", Encoding.UTF8)); Assert.True(asc.Contains(checkHintName)); } @@ -141,7 +156,7 @@ public void Contains(string addHintName, string checkHintName) [InlineData("file.cs", "file")] public void Remove(string addHintName, string removeHintName) { - AdditionalSourcesCollection asc = new AdditionalSourcesCollection(); + AdditionalSourcesCollection asc = new AdditionalSourcesCollection(".cs"); asc.Add(addHintName, SourceText.From("", Encoding.UTF8)); asc.RemoveSource(removeHintName); var sources = asc.ToImmutableAndFree(); @@ -151,7 +166,7 @@ public void Remove(string addHintName, string removeHintName) [Fact] public void SourceTextRequiresEncoding() { - AdditionalSourcesCollection asc = new AdditionalSourcesCollection(); + AdditionalSourcesCollection asc = new AdditionalSourcesCollection(".cs"); // fine asc.Add("file1.cs", SourceText.From("", Encoding.UTF8)); diff --git a/src/Compilers/Core/CodeAnalysisTest/Analyzers/AnalyzerFileReferenceTests.cs b/src/Compilers/Core/CodeAnalysisTest/Analyzers/AnalyzerFileReferenceTests.cs index 7452b4980fd94..60ca14e2cad47 100644 --- a/src/Compilers/Core/CodeAnalysisTest/Analyzers/AnalyzerFileReferenceTests.cs +++ b/src/Compilers/Core/CodeAnalysisTest/Analyzers/AnalyzerFileReferenceTests.cs @@ -248,13 +248,12 @@ public void TestFailedLoadDoesntCauseNoAnalyzersWarning() Assert.Equal(AnalyzerLoadFailureEventArgs.FailureErrorCode.UnableToCreateAnalyzer, errors.First().ErrorCode); } - // can't load a framework targeting generator, which these are in desktop [ConditionalFact(typeof(CoreClrOnly))] public void TestLoadGenerators() { AnalyzerFileReference reference = CreateAnalyzerFileReference(Assembly.GetExecutingAssembly().Location); - var generators = reference.GetGenerators(); - Assert.Equal(5, generators.Length); + var generators = reference.GetGeneratorsForAllLanguages(); + Assert.Equal(10, generators.Length); var typeNames = generators.Select(g => g.GetType().FullName); Assert.Contains("Microsoft.CodeAnalysis.UnitTests.AnalyzerFileReferenceTests+TestGenerator", typeNames); @@ -262,11 +261,61 @@ public void TestLoadGenerators() Assert.Contains("Microsoft.CodeAnalysis.UnitTests.TestGenerator", typeNames); Assert.Contains("Microsoft.CodeAnalysis.UnitTests.BaseGenerator", typeNames); Assert.Contains("Microsoft.CodeAnalysis.UnitTests.SubClassedGenerator", typeNames); + Assert.Contains("Microsoft.CodeAnalysis.UnitTests.ExplicitCSharpOnlyGenerator", typeNames); + Assert.Contains("Microsoft.CodeAnalysis.UnitTests.VisualBasicOnlyGenerator", typeNames); + Assert.Contains("Microsoft.CodeAnalysis.UnitTests.CSharpAndVisualBasicGenerator", typeNames); + Assert.Contains("Microsoft.CodeAnalysis.UnitTests.VisualBasicAndCSharpGenerator", typeNames); + Assert.Contains("Microsoft.CodeAnalysis.UnitTests.FSharpGenerator", typeNames); + Assert.DoesNotContain("Microsoft.CodeAnalysis.UnitTests.TestGeneratorNoAttrib", typeNames); Assert.DoesNotContain("Microsoft.CodeAnalysis.UnitTests.Test.NotAGenerator", typeNames); Assert.DoesNotContain("Microsoft.CodeAnalysis.UnitTests.NotAGenerator", typeNames); } + [ConditionalFact(typeof(CoreClrOnly))] + public void TestLoadGeneratorsWithoutArgumentOnlyLoadsCSharp() + { + AnalyzerFileReference reference = CreateAnalyzerFileReference(Assembly.GetExecutingAssembly().Location); + var generators = reference.GetGenerators(LanguageNames.CSharp); + +#pragma warning disable CS0618 // Type or member is obsolete + var generators2 = reference.GetGenerators(); +#pragma warning restore CS0618 // Type or member is obsolete + + Assert.Equal(generators, generators2); + } + + [ConditionalFact(typeof(CoreClrOnly))] + public void TestLoadCSharpGenerators() + { + AnalyzerFileReference reference = CreateAnalyzerFileReference(Assembly.GetExecutingAssembly().Location); + var generators = reference.GetGenerators(LanguageNames.CSharp); + Assert.Equal(8, generators.Length); + + var typeNames = generators.Select(g => g.GetType().FullName); + Assert.Contains("Microsoft.CodeAnalysis.UnitTests.AnalyzerFileReferenceTests+TestGenerator", typeNames); + Assert.Contains("Microsoft.CodeAnalysis.UnitTests.AnalyzerFileReferenceTests+SomeType+NestedGenerator", typeNames); + Assert.Contains("Microsoft.CodeAnalysis.UnitTests.TestGenerator", typeNames); + Assert.Contains("Microsoft.CodeAnalysis.UnitTests.BaseGenerator", typeNames); + Assert.Contains("Microsoft.CodeAnalysis.UnitTests.SubClassedGenerator", typeNames); + Assert.Contains("Microsoft.CodeAnalysis.UnitTests.ExplicitCSharpOnlyGenerator", typeNames); + Assert.Contains("Microsoft.CodeAnalysis.UnitTests.CSharpAndVisualBasicGenerator", typeNames); + Assert.Contains("Microsoft.CodeAnalysis.UnitTests.VisualBasicAndCSharpGenerator", typeNames); + } + + [ConditionalFact(typeof(CoreClrOnly))] + public void TestLoadVisualBasicGenerators() + { + AnalyzerFileReference reference = CreateAnalyzerFileReference(Assembly.GetExecutingAssembly().Location); + var generators = reference.GetGenerators(LanguageNames.VisualBasic); + Assert.Equal(3, generators.Length); + + var typeNames = generators.Select(g => g.GetType().FullName); + Assert.Contains("Microsoft.CodeAnalysis.UnitTests.VisualBasicOnlyGenerator", typeNames); + Assert.Contains("Microsoft.CodeAnalysis.UnitTests.CSharpAndVisualBasicGenerator", typeNames); + Assert.Contains("Microsoft.CodeAnalysis.UnitTests.VisualBasicAndCSharpGenerator", typeNames); + } + // can't load a coreclr targeting generator on net framework / mono [ConditionalFact(typeof(CoreClrOnly))] public void TestGeneratorsCantTargetNetFramework() @@ -455,4 +504,19 @@ public class SubClassedGenerator : BaseGenerator [Generator] public class NotAGenerator { } + + [Generator(LanguageNames.CSharp)] + public class ExplicitCSharpOnlyGenerator : TestGenerator { } + + [Generator(LanguageNames.VisualBasic)] + public class VisualBasicOnlyGenerator : TestGenerator { } + + [Generator(LanguageNames.CSharp, LanguageNames.VisualBasic)] + public class CSharpAndVisualBasicGenerator : TestGenerator { } + + [Generator(LanguageNames.CSharp, LanguageNames.VisualBasic)] + public class VisualBasicAndCSharpGenerator : TestGenerator { } + + [Generator(LanguageNames.FSharp)] + public class FSharpGenerator : TestGenerator { } } diff --git a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerFileReference.cs b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerFileReference.cs index 3d465669f6b92..35813f8238917 100644 --- a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerFileReference.cs +++ b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerFileReference.cs @@ -61,7 +61,7 @@ public AnalyzerFileReference(string fullPath, IAnalyzerAssemblyLoader assemblyLo _assemblyLoader = assemblyLoader ?? throw new ArgumentNullException(nameof(assemblyLoader)); _diagnosticAnalyzers = new Extensions(this, IsDiagnosticAnalyzerAttribute, GetDiagnosticsAnalyzerSupportedLanguages, allowNetFramework: true); - _generators = new Extensions(this, IsGeneratorAttribute, GetGeneratorsSupportedLanguages, allowNetFramework: false); + _generators = new Extensions(this, IsGeneratorAttribute, GetGeneratorSupportedLanguages, allowNetFramework: false); // Note this analyzer full path as a dependency location, so that the analyzer loader // can correctly load analyzer dependencies. @@ -111,7 +111,9 @@ public override int GetHashCode() public override ImmutableArray GetAnalyzersForAllLanguages() { - return _diagnosticAnalyzers.GetExtensionsForAllLanguages(); + // This API returns duplicates of analyzers that support multiple languages. + // We explicitly retain this behaviour to ensure back compat + return _diagnosticAnalyzers.GetExtensionsForAllLanguages(includeDuplicates: true); } public override ImmutableArray GetAnalyzers(string language) @@ -119,9 +121,20 @@ public override ImmutableArray GetAnalyzers(string language) return _diagnosticAnalyzers.GetExtensions(language); } + public override ImmutableArray GetGeneratorsForAllLanguages() + { + return _generators.GetExtensionsForAllLanguages(includeDuplicates: false); + } + + [Obsolete("Use GetGenerators(string language) or GetGeneratorsForAllLanguages()")] public override ImmutableArray GetGenerators() { - return _generators.GetExtensionsForAllLanguages(); + return _generators.GetExtensions(LanguageNames.CSharp); + } + + public override ImmutableArray GetGenerators(string language) + { + return _generators.GetExtensions(language); } public override string Display @@ -254,7 +267,33 @@ private static IEnumerable GetDiagnosticsAnalyzerSupportedLanguages(PEMo // first supported language and an array parameter for addition supported languages. // Parse the argument blob to extract the languages. BlobReader argsReader = peModule.GetMemoryReaderOrThrow(peModule.GetCustomAttributeValueOrThrow(customAttrHandle)); + return ReadLanguagesFromAttribute(ref argsReader); + } + private static bool IsGeneratorAttribute(PEModule peModule, CustomAttributeHandle customAttrHandle) + { + return peModule.IsTargetAttribute(customAttrHandle, s_generatorAttributeNamespace, nameof(GeneratorAttribute), ctor: out _); + } + + private static IEnumerable GetGeneratorSupportedLanguages(PEModule peModule, CustomAttributeHandle customAttrHandle) + { + // The GeneratorAttribute has two constructors: one default, and one with a string parameter for the + // first supported language and an array parameter for addition supported languages. + BlobReader argsReader = peModule.GetMemoryReaderOrThrow(peModule.GetCustomAttributeValueOrThrow(customAttrHandle)); + if (argsReader.Length == 4) + { + // default ctor + return ImmutableArray.Create(LanguageNames.CSharp); + } + else + { + // Parse the argument blob to extract the languages. + return ReadLanguagesFromAttribute(ref argsReader); + } + } + + private static IEnumerable ReadLanguagesFromAttribute(ref BlobReader argsReader) + { if (argsReader.Length > 4) { // Arguments are present--check prologue. @@ -278,16 +317,9 @@ private static IEnumerable GetDiagnosticsAnalyzerSupportedLanguages(PEMo } } } - return SpecializedCollections.EmptyEnumerable(); } - private static bool IsGeneratorAttribute(PEModule peModule, CustomAttributeHandle customAttrHandle) - { - return peModule.IsTargetAttribute(customAttrHandle, s_generatorAttributeNamespace, nameof(GeneratorAttribute), ctor: out _); - } - - private static IEnumerable GetGeneratorsSupportedLanguages(PEModule peModule, CustomAttributeHandle customAttrHandle) => ImmutableArray.Create(LanguageNames.CSharp); private static string GetFullyQualifiedTypeName(TypeDefinition typeDef, PEModule peModule) { @@ -325,17 +357,17 @@ internal Extensions(AnalyzerFileReference reference, AttributePredicate attribut _lazyExtensionsPerLanguage = ImmutableDictionary>.Empty; } - internal ImmutableArray GetExtensionsForAllLanguages() + internal ImmutableArray GetExtensionsForAllLanguages(bool includeDuplicates) { if (_lazyAllExtensions.IsDefault) { - ImmutableInterlocked.InterlockedInitialize(ref _lazyAllExtensions, CreateExtensionsForAllLanguages(this)); + ImmutableInterlocked.InterlockedInitialize(ref _lazyAllExtensions, CreateExtensionsForAllLanguages(this, includeDuplicates)); } return _lazyAllExtensions; } - private static ImmutableArray CreateExtensionsForAllLanguages(Extensions extensions) + private static ImmutableArray CreateExtensionsForAllLanguages(Extensions extensions, bool includeDuplicates) { // Get all analyzers in the assembly. var map = ImmutableDictionary.CreateBuilder>(); @@ -344,7 +376,13 @@ private static ImmutableArray CreateExtensionsForAllLanguages(Extens var builder = ImmutableArray.CreateBuilder(); foreach (var analyzers in map.Values) { - builder.AddRange(analyzers); + foreach (var analyzer in analyzers) + { + if (includeDuplicates || !builder.Contains(t => t.GetType().Equals(analyzer.GetType()))) + { + builder.Add(analyzer); + } + } } return builder.ToImmutable(); diff --git a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerReference.cs b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerReference.cs index 4837da230facd..4f3a54a25cd85 100644 --- a/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerReference.cs +++ b/src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerReference.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; using System.Collections.Immutable; namespace Microsoft.CodeAnalysis.Diagnostics @@ -63,6 +64,15 @@ public virtual string Display /// /// Gets all the source generators defined in this assembly reference. /// + public virtual ImmutableArray GetGeneratorsForAllLanguages() { return ImmutableArray.Empty; } + + [Obsolete("Use GetGenerators(string language) or GetGeneratorsForAllLanguages()")] public virtual ImmutableArray GetGenerators() { return ImmutableArray.Empty; } + + /// + /// Gets all the diagnostic generators defined in this assembly reference for the given . + /// + /// Language name. + public virtual ImmutableArray GetGenerators(string language) { return ImmutableArray.Empty; } } } diff --git a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt index 5e2cd74d0c0ea..41853b3182167 100644 --- a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt @@ -1,5 +1,11 @@ +Microsoft.CodeAnalysis.GeneratorAttribute.GeneratorAttribute(string firstLanguage, params string[] additionalLanguages) -> void +Microsoft.CodeAnalysis.GeneratorAttribute.Languages.get -> string[] Microsoft.CodeAnalysis.ITypeSymbol.IsRecord.get -> bool Microsoft.CodeAnalysis.SymbolDisplayPartKind.RecordName = 31 -> Microsoft.CodeAnalysis.SymbolDisplayPartKind const Microsoft.CodeAnalysis.WellKnownDiagnosticTags.CompilationEnd = "CompilationEnd" -> string static Microsoft.CodeAnalysis.CaseInsensitiveComparison.Compare(System.ReadOnlySpan left, System.ReadOnlySpan right) -> int static Microsoft.CodeAnalysis.CaseInsensitiveComparison.Equals(System.ReadOnlySpan left, System.ReadOnlySpan right) -> bool +override Microsoft.CodeAnalysis.Diagnostics.AnalyzerFileReference.GetGenerators(string language) -> System.Collections.Immutable.ImmutableArray +override Microsoft.CodeAnalysis.Diagnostics.AnalyzerFileReference.GetGeneratorsForAllLanguages() -> System.Collections.Immutable.ImmutableArray +virtual Microsoft.CodeAnalysis.Diagnostics.AnalyzerReference.GetGenerators(string language) -> System.Collections.Immutable.ImmutableArray +virtual Microsoft.CodeAnalysis.Diagnostics.AnalyzerReference.GetGeneratorsForAllLanguages() -> System.Collections.Immutable.ImmutableArray diff --git a/src/Compilers/Core/Portable/SourceGeneration/AdditionalSourcesCollection.cs b/src/Compilers/Core/Portable/SourceGeneration/AdditionalSourcesCollection.cs index 37c6ef52c7f81..2d63c99895788 100644 --- a/src/Compilers/Core/Portable/SourceGeneration/AdditionalSourcesCollection.cs +++ b/src/Compilers/Core/Portable/SourceGeneration/AdditionalSourcesCollection.cs @@ -15,19 +15,16 @@ internal sealed class AdditionalSourcesCollection { private readonly ArrayBuilder _sourcesAdded; + private readonly string _fileExtension; + private const StringComparison _hintNameComparison = StringComparison.OrdinalIgnoreCase; private static readonly StringComparer s_hintNameComparer = StringComparer.OrdinalIgnoreCase; - internal AdditionalSourcesCollection() + internal AdditionalSourcesCollection(string fileExtension) { _sourcesAdded = ArrayBuilder.GetInstance(); - } - - internal AdditionalSourcesCollection(ImmutableArray existingSources) - : this() - { - _sourcesAdded.AddRange(existingSources); + _fileExtension = fileExtension; } public void Add(string hintName, SourceText source) @@ -72,6 +69,8 @@ public void Add(string hintName, SourceText source) _sourcesAdded.Add(new GeneratedSourceText(hintName, source)); } + public void AddRange(ImmutableArray texts) => _sourcesAdded.AddRange(texts); + public void RemoveSource(string hintName) { hintName = AppendExtensionIfRequired(hintName); @@ -100,11 +99,11 @@ public bool Contains(string hintName) internal ImmutableArray ToImmutableAndFree() => _sourcesAdded.ToImmutableAndFree(); - private static string AppendExtensionIfRequired(string hintName) + private string AppendExtensionIfRequired(string hintName) { - if (!hintName.EndsWith(".cs", _hintNameComparison)) + if (!hintName.EndsWith(_fileExtension, _hintNameComparison)) { - hintName = string.Concat(hintName, ".cs"); + hintName = string.Concat(hintName, _fileExtension); } return hintName; diff --git a/src/Compilers/Core/Portable/SourceGeneration/GeneratorAttribute.cs b/src/Compilers/Core/Portable/SourceGeneration/GeneratorAttribute.cs index 0cc09d5fa4168..d17590390ca34 100644 --- a/src/Compilers/Core/Portable/SourceGeneration/GeneratorAttribute.cs +++ b/src/Compilers/Core/Portable/SourceGeneration/GeneratorAttribute.cs @@ -11,6 +11,43 @@ namespace Microsoft.CodeAnalysis [AttributeUsage(AttributeTargets.Class)] public sealed class GeneratorAttribute : Attribute { - // https://github.com/dotnet/roslyn/issues/: we don't know if we'll keep this, but for now it lets us re-use the analyzer discovery mechanism + /// + /// The source languages to which this generator applies. See . + /// + public string[] Languages { get; } + + /// + /// Attribute constructor used to specify the attached class is a source generator that provides CSharp sources. + /// + public GeneratorAttribute() + : this(LanguageNames.CSharp) { } + + /// + /// Attribute constructor used to specify the attached class is a source generator and indicate which language(s) it supports. + /// + /// One language to which the generator applies. + /// Additional languages to which the generator applies. See . + public GeneratorAttribute(string firstLanguage, params string[] additionalLanguages) + { + if (firstLanguage == null) + { + throw new ArgumentNullException(nameof(firstLanguage)); + } + + if (additionalLanguages == null) + { + throw new ArgumentNullException(nameof(additionalLanguages)); + } + + var languages = new string[additionalLanguages.Length + 1]; + languages[0] = firstLanguage; + for (int index = 0; index < additionalLanguages.Length; index++) + { + languages[index + 1] = additionalLanguages[index]; + } + + this.Languages = languages; + } + } } diff --git a/src/Compilers/Core/Portable/SourceGeneration/GeneratorContexts.cs b/src/Compilers/Core/Portable/SourceGeneration/GeneratorContexts.cs index bd4228afb9920..0f3ae00f47c9e 100644 --- a/src/Compilers/Core/Portable/SourceGeneration/GeneratorContexts.cs +++ b/src/Compilers/Core/Portable/SourceGeneration/GeneratorContexts.cs @@ -19,7 +19,7 @@ public readonly struct GeneratorExecutionContext private readonly AdditionalSourcesCollection _additionalSources; - internal GeneratorExecutionContext(Compilation compilation, ParseOptions parseOptions, ImmutableArray additionalTexts, AnalyzerConfigOptionsProvider optionsProvider, ISyntaxReceiver? syntaxReceiver, CancellationToken cancellationToken = default) + internal GeneratorExecutionContext(Compilation compilation, ParseOptions parseOptions, ImmutableArray additionalTexts, AnalyzerConfigOptionsProvider optionsProvider, ISyntaxReceiver? syntaxReceiver, AdditionalSourcesCollection additionalSources, CancellationToken cancellationToken = default) { Compilation = compilation; ParseOptions = parseOptions; @@ -27,7 +27,7 @@ internal GeneratorExecutionContext(Compilation compilation, ParseOptions parseOp AnalyzerConfigOptions = optionsProvider; SyntaxReceiver = syntaxReceiver; CancellationToken = cancellationToken; - _additionalSources = new AdditionalSourcesCollection(); + _additionalSources = additionalSources; _diagnostics = new DiagnosticBag(); } @@ -150,9 +150,9 @@ private static void CheckIsEmpty(T x) internal readonly struct GeneratorEditContext { - internal GeneratorEditContext(ImmutableArray sources, CancellationToken cancellationToken = default) + internal GeneratorEditContext(AdditionalSourcesCollection sources, CancellationToken cancellationToken = default) { - AdditionalSources = new AdditionalSourcesCollection(sources); + AdditionalSources = sources; CancellationToken = cancellationToken; } diff --git a/src/Compilers/Core/Portable/SourceGeneration/GeneratorDriver.cs b/src/Compilers/Core/Portable/SourceGeneration/GeneratorDriver.cs index 16f254ea0a6de..4558041229fe6 100644 --- a/src/Compilers/Core/Portable/SourceGeneration/GeneratorDriver.cs +++ b/src/Compilers/Core/Portable/SourceGeneration/GeneratorDriver.cs @@ -240,7 +240,7 @@ internal GeneratorDriverState RunGeneratorsCore(Compilation compilation, Diagnos Debug.Assert(generatorState.Info.Initialized); // we create a new context for each run of the generator. We'll never re-use existing state, only replace anything we have - var context = new GeneratorExecutionContext(compilation, state.ParseOptions, state.AdditionalTexts.NullToEmpty(), state.OptionsProvider, generatorState.SyntaxReceiver); + var context = new GeneratorExecutionContext(compilation, state.ParseOptions, state.AdditionalTexts.NullToEmpty(), state.OptionsProvider, generatorState.SyntaxReceiver, CreateSourcesCollection()); try { generator.Execute(context); @@ -279,7 +279,9 @@ private GeneratorDriverState ApplyPartialEdit(GeneratorDriverState state, Pendin if (edit.AcceptedBy(generatorState.Info)) { // attempt to apply the edit - var context = new GeneratorEditContext(generatorState.SourceTexts.ToImmutableArray(), cancellationToken); + var previousSources = CreateSourcesCollection(); + previousSources.AddRange(generatorState.SourceTexts); + var context = new GeneratorEditContext(previousSources, cancellationToken); var succeeded = edit.TryApply(generatorState.Info, context); if (!succeeded) { @@ -289,7 +291,7 @@ private GeneratorDriverState ApplyPartialEdit(GeneratorDriverState state, Pendin } // update the state with the new edits - var additionalSources = context.AdditionalSources.ToImmutableAndFree(); + var additionalSources = previousSources.ToImmutableAndFree(); state = state.With(generatorStates: state.GeneratorStates.SetItem(i, new GeneratorState(generatorState.Info, sourceTexts: additionalSources, trees: ParseAdditionalSources(generator, additionalSources, cancellationToken), diagnostics: ImmutableArray.Empty))); } } @@ -394,5 +396,7 @@ internal static string GetFilePathPrefixForGenerator(ISourceGenerator generator) internal abstract GeneratorDriver FromState(GeneratorDriverState state); internal abstract SyntaxTree ParseGeneratedSourceText(GeneratedSourceText input, string fileName, CancellationToken cancellationToken); + + internal abstract AdditionalSourcesCollection CreateSourcesCollection(); } } diff --git a/src/Compilers/Test/Core/SourceGeneration/TestGenerators.cs b/src/Compilers/Test/Core/SourceGeneration/TestGenerators.cs index 60c5bbb518c6b..5beea3fae7517 100644 --- a/src/Compilers/Test/Core/SourceGeneration/TestGenerators.cs +++ b/src/Compilers/Test/Core/SourceGeneration/TestGenerators.cs @@ -57,7 +57,7 @@ public void Execute(GeneratorExecutionContext context) _onExecute(context); if (!string.IsNullOrWhiteSpace(_source)) { - context.AddSource("source.cs", SourceText.From(_source, Encoding.UTF8)); + context.AddSource("source", SourceText.From(_source, Encoding.UTF8)); } } public void Initialize(GeneratorInitializationContext context) => _onInit(context); diff --git a/src/Compilers/VisualBasic/Portable/CommandLine/VisualBasicCompiler.vb b/src/Compilers/VisualBasic/Portable/CommandLine/VisualBasicCompiler.vb index 8efe8137042dd..9f1d6b2fde55b 100644 --- a/src/Compilers/VisualBasic/Portable/CommandLine/VisualBasicCompiler.vb +++ b/src/Compilers/VisualBasic/Portable/CommandLine/VisualBasicCompiler.vb @@ -297,6 +297,14 @@ Namespace Microsoft.CodeAnalysis.VisualBasic embeddedFiles.Add(resolvedPath) Next End Sub + Private Protected Overrides Function RunGenerators(input As Compilation, parseOptions As ParseOptions, generators As ImmutableArray(Of ISourceGenerator), analyzerConfigOptionsProvider As AnalyzerConfigOptionsProvider, additionalTexts As ImmutableArray(Of AdditionalText), diagnostics As DiagnosticBag) As Compilation + Dim driver = VisualBasicGeneratorDriver.Create(generators, additionalTexts, DirectCast(parseOptions, VisualBasicParseOptions), analyzerConfigOptionsProvider) + Dim compilationOut As Compilation = Nothing, generatorDiagnostics As ImmutableArray(Of Diagnostic) = Nothing + driver.RunGeneratorsAndUpdateCompilation(input, compilationOut, generatorDiagnostics) + diagnostics.AddRange(generatorDiagnostics) + Return compilationOut + End Function + End Class End Namespace diff --git a/src/Compilers/VisualBasic/Portable/Errors/Errors.vb b/src/Compilers/VisualBasic/Portable/Errors/Errors.vb index 413174db5d049..896fd94f778f8 100644 --- a/src/Compilers/VisualBasic/Portable/Errors/Errors.vb +++ b/src/Compilers/VisualBasic/Portable/Errors/Errors.vb @@ -1976,6 +1976,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic WRN_AttributeNotSupportedInVB = 42381 ERR_MultipleAnalyzerConfigsInSameDir = 42500 + WRN_GeneratorFailedDuringInitialization = 42501 + WRN_GeneratorFailedDuringGeneration = 42502 ' // AVAILABLE 42600 - 49998 ERRWRN_NextAvailable = 42600 diff --git a/src/Compilers/VisualBasic/Portable/Errors/MessageProvider.vb b/src/Compilers/VisualBasic/Portable/Errors/MessageProvider.vb index 4f8daa201656d..b64c4a0625578 100644 --- a/src/Compilers/VisualBasic/Portable/Errors/MessageProvider.vb +++ b/src/Compilers/VisualBasic/Portable/Errors/MessageProvider.vb @@ -584,13 +584,13 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ' Generators Public Overrides ReadOnly Property WRN_GeneratorFailedDuringInitialization As Integer Get - Throw ExceptionUtilities.Unreachable + Return ERRID.WRN_GeneratorFailedDuringInitialization End Get End Property Public Overrides ReadOnly Property WRN_GeneratorFailedDuringGeneration As Integer Get - Throw ExceptionUtilities.Unreachable + Return ERRID.WRN_GeneratorFailedDuringGeneration End Get End Property diff --git a/src/Compilers/VisualBasic/Portable/PublicAPI.Unshipped.txt b/src/Compilers/VisualBasic/Portable/PublicAPI.Unshipped.txt index 8b137891791fe..2afc778f2f9de 100644 --- a/src/Compilers/VisualBasic/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/VisualBasic/Portable/PublicAPI.Unshipped.txt @@ -1 +1,2 @@ - +Microsoft.CodeAnalysis.VisualBasic.VisualBasicGeneratorDriver +Shared Microsoft.CodeAnalysis.VisualBasic.VisualBasicGeneratorDriver.Create(generators As System.Collections.Immutable.ImmutableArray(Of Microsoft.CodeAnalysis.ISourceGenerator), additionalTexts As System.Collections.Immutable.ImmutableArray(Of Microsoft.CodeAnalysis.AdditionalText) = Nothing, parseOptions As Microsoft.CodeAnalysis.VisualBasic.VisualBasicParseOptions = Nothing, analyzerConfigOptionsProvider As Microsoft.CodeAnalysis.Diagnostics.AnalyzerConfigOptionsProvider = Nothing) -> Microsoft.CodeAnalysis.VisualBasic.VisualBasicGeneratorDriver diff --git a/src/Compilers/VisualBasic/Portable/SourceGeneration/VisualBasicGeneratorDriver.vb b/src/Compilers/VisualBasic/Portable/SourceGeneration/VisualBasicGeneratorDriver.vb new file mode 100644 index 0000000000000..f98e598291dbb --- /dev/null +++ b/src/Compilers/VisualBasic/Portable/SourceGeneration/VisualBasicGeneratorDriver.vb @@ -0,0 +1,48 @@ +' Licensed to the .NET Foundation under one or more agreements. +' The .NET Foundation licenses this file to you under the MIT license. +' See the LICENSE file in the project root for more information. + +Imports System.Collections.Immutable +Imports System.Threading +Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Diagnostics +Imports Microsoft.CodeAnalysis.VisualBasic.Syntax + +Namespace Microsoft.CodeAnalysis.VisualBasic + + Public Class VisualBasicGeneratorDriver + Inherits GeneratorDriver + + Private Sub New(state As GeneratorDriverState) + MyBase.New(state) + End Sub + + Friend Sub New(parseOptions As VisualBasicParseOptions, generators As ImmutableArray(Of ISourceGenerator), optionsProvider As AnalyzerConfigOptionsProvider, additionalTexts As ImmutableArray(Of AdditionalText)) + MyBase.New(parseOptions, generators, optionsProvider, additionalTexts) + End Sub + + Friend Overrides ReadOnly Property MessageProvider As CommonMessageProvider + Get + Return VisualBasic.MessageProvider.Instance + End Get + End Property + + Friend Overrides Function FromState(state As GeneratorDriverState) As GeneratorDriver + Return New VisualBasicGeneratorDriver(state) + End Function + + Friend Overrides Function ParseGeneratedSourceText(input As GeneratedSourceText, fileName As String, cancellationToken As CancellationToken) As SyntaxTree + Return SyntaxFactory.ParseSyntaxTree(input.Text, _state.ParseOptions, fileName, cancellationToken) + End Function + + Public Shared Function Create(generators As ImmutableArray(Of ISourceGenerator), Optional additionalTexts As ImmutableArray(Of AdditionalText) = Nothing, Optional parseOptions As VisualBasicParseOptions = Nothing, Optional analyzerConfigOptionsProvider As AnalyzerConfigOptionsProvider = Nothing) As VisualBasicGeneratorDriver + Return New VisualBasicGeneratorDriver(parseOptions, generators, analyzerConfigOptionsProvider, additionalTexts) + End Function + + Friend Overrides Function CreateSourcesCollection() As AdditionalSourcesCollection + Return New AdditionalSourcesCollection(".vb") + End Function + + End Class + +End Namespace diff --git a/src/Compilers/VisualBasic/Portable/VBResources.resx b/src/Compilers/VisualBasic/Portable/VBResources.resx index 86c0a8cc0948d..5c7ed72f746a7 100644 --- a/src/Compilers/VisualBasic/Portable/VBResources.resx +++ b/src/Compilers/VisualBasic/Portable/VBResources.resx @@ -5580,4 +5580,28 @@ Attribute is not supported in VB + + Generator '{0}' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + {0} is the name of the generator that failed. {1} is the type of exception that was thrown {2} is the message in the exception + + + Generator threw the following exception: +'{0}'. + {0} is the string representation of the exception that was thrown. + + + Generator failed to generate source. + + + Generator '{0}' failed to initialize. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + {0} is the name of the generator that failed. {1} is the type of exception that was thrown {2} is the message in the exception + + + Generator threw the following exception: +'{0}'. + {0} is the string representation of the exception that was thrown. + + + Generator failed to initialize. + diff --git a/src/Compilers/VisualBasic/Portable/xlf/VBResources.cs.xlf b/src/Compilers/VisualBasic/Portable/xlf/VBResources.cs.xlf index 2a771895a42f2..4375b2ef9a7be 100644 --- a/src/Compilers/VisualBasic/Portable/xlf/VBResources.cs.xlf +++ b/src/Compilers/VisualBasic/Portable/xlf/VBResources.cs.xlf @@ -463,6 +463,40 @@ Argument typu nemůže být Nothing. + + Generator '{0}' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + Generator '{0}' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + {0} is the name of the generator that failed. {1} is the type of exception that was thrown {2} is the message in the exception + + + Generator threw the following exception: +'{0}'. + Generator threw the following exception: +'{0}'. + {0} is the string representation of the exception that was thrown. + + + Generator failed to generate source. + Generator failed to generate source. + + + + Generator '{0}' failed to initialize. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + Generator '{0}' failed to initialize. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + {0} is the name of the generator that failed. {1} is the type of exception that was thrown {2} is the message in the exception + + + Generator threw the following exception: +'{0}'. + Generator threw the following exception: +'{0}'. + {0} is the string representation of the exception that was thrown. + + + Generator failed to initialize. + Generator failed to initialize. + + Wrong number of type arguments Chybný počet argumentů typu diff --git a/src/Compilers/VisualBasic/Portable/xlf/VBResources.de.xlf b/src/Compilers/VisualBasic/Portable/xlf/VBResources.de.xlf index b6c94960b2008..1cc0f4e83e406 100644 --- a/src/Compilers/VisualBasic/Portable/xlf/VBResources.de.xlf +++ b/src/Compilers/VisualBasic/Portable/xlf/VBResources.de.xlf @@ -463,6 +463,40 @@ Typargument kann nicht "Nothing" sein + + Generator '{0}' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + Generator '{0}' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + {0} is the name of the generator that failed. {1} is the type of exception that was thrown {2} is the message in the exception + + + Generator threw the following exception: +'{0}'. + Generator threw the following exception: +'{0}'. + {0} is the string representation of the exception that was thrown. + + + Generator failed to generate source. + Generator failed to generate source. + + + + Generator '{0}' failed to initialize. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + Generator '{0}' failed to initialize. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + {0} is the name of the generator that failed. {1} is the type of exception that was thrown {2} is the message in the exception + + + Generator threw the following exception: +'{0}'. + Generator threw the following exception: +'{0}'. + {0} is the string representation of the exception that was thrown. + + + Generator failed to initialize. + Generator failed to initialize. + + Wrong number of type arguments Falsche Anzahl von Typargumenten. diff --git a/src/Compilers/VisualBasic/Portable/xlf/VBResources.es.xlf b/src/Compilers/VisualBasic/Portable/xlf/VBResources.es.xlf index a54305325761d..4dd3aed6199b6 100644 --- a/src/Compilers/VisualBasic/Portable/xlf/VBResources.es.xlf +++ b/src/Compilers/VisualBasic/Portable/xlf/VBResources.es.xlf @@ -463,6 +463,40 @@ El argumento de tipo no puede ser Nothing + + Generator '{0}' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + Generator '{0}' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + {0} is the name of the generator that failed. {1} is the type of exception that was thrown {2} is the message in the exception + + + Generator threw the following exception: +'{0}'. + Generator threw the following exception: +'{0}'. + {0} is the string representation of the exception that was thrown. + + + Generator failed to generate source. + Generator failed to generate source. + + + + Generator '{0}' failed to initialize. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + Generator '{0}' failed to initialize. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + {0} is the name of the generator that failed. {1} is the type of exception that was thrown {2} is the message in the exception + + + Generator threw the following exception: +'{0}'. + Generator threw the following exception: +'{0}'. + {0} is the string representation of the exception that was thrown. + + + Generator failed to initialize. + Generator failed to initialize. + + Wrong number of type arguments Número de argumentos de tipo incorrecto diff --git a/src/Compilers/VisualBasic/Portable/xlf/VBResources.fr.xlf b/src/Compilers/VisualBasic/Portable/xlf/VBResources.fr.xlf index bbb265ea4e746..53b4992dea4b2 100644 --- a/src/Compilers/VisualBasic/Portable/xlf/VBResources.fr.xlf +++ b/src/Compilers/VisualBasic/Portable/xlf/VBResources.fr.xlf @@ -463,6 +463,40 @@ L'argument de type ne peut pas être Nothing + + Generator '{0}' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + Generator '{0}' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + {0} is the name of the generator that failed. {1} is the type of exception that was thrown {2} is the message in the exception + + + Generator threw the following exception: +'{0}'. + Generator threw the following exception: +'{0}'. + {0} is the string representation of the exception that was thrown. + + + Generator failed to generate source. + Generator failed to generate source. + + + + Generator '{0}' failed to initialize. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + Generator '{0}' failed to initialize. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + {0} is the name of the generator that failed. {1} is the type of exception that was thrown {2} is the message in the exception + + + Generator threw the following exception: +'{0}'. + Generator threw the following exception: +'{0}'. + {0} is the string representation of the exception that was thrown. + + + Generator failed to initialize. + Generator failed to initialize. + + Wrong number of type arguments Nombre incorrect d'arguments de type diff --git a/src/Compilers/VisualBasic/Portable/xlf/VBResources.it.xlf b/src/Compilers/VisualBasic/Portable/xlf/VBResources.it.xlf index fd609c72ecf15..8384bb2773331 100644 --- a/src/Compilers/VisualBasic/Portable/xlf/VBResources.it.xlf +++ b/src/Compilers/VisualBasic/Portable/xlf/VBResources.it.xlf @@ -463,6 +463,40 @@ L'argomento di tipo non può essere Nothing + + Generator '{0}' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + Generator '{0}' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + {0} is the name of the generator that failed. {1} is the type of exception that was thrown {2} is the message in the exception + + + Generator threw the following exception: +'{0}'. + Generator threw the following exception: +'{0}'. + {0} is the string representation of the exception that was thrown. + + + Generator failed to generate source. + Generator failed to generate source. + + + + Generator '{0}' failed to initialize. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + Generator '{0}' failed to initialize. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + {0} is the name of the generator that failed. {1} is the type of exception that was thrown {2} is the message in the exception + + + Generator threw the following exception: +'{0}'. + Generator threw the following exception: +'{0}'. + {0} is the string representation of the exception that was thrown. + + + Generator failed to initialize. + Generator failed to initialize. + + Wrong number of type arguments Il numero di argomenti di tipo è errato diff --git a/src/Compilers/VisualBasic/Portable/xlf/VBResources.ja.xlf b/src/Compilers/VisualBasic/Portable/xlf/VBResources.ja.xlf index afde707d91047..c38cbed55f142 100644 --- a/src/Compilers/VisualBasic/Portable/xlf/VBResources.ja.xlf +++ b/src/Compilers/VisualBasic/Portable/xlf/VBResources.ja.xlf @@ -463,6 +463,40 @@ 型引数に Nothing は使用できません。 + + Generator '{0}' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + Generator '{0}' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + {0} is the name of the generator that failed. {1} is the type of exception that was thrown {2} is the message in the exception + + + Generator threw the following exception: +'{0}'. + Generator threw the following exception: +'{0}'. + {0} is the string representation of the exception that was thrown. + + + Generator failed to generate source. + Generator failed to generate source. + + + + Generator '{0}' failed to initialize. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + Generator '{0}' failed to initialize. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + {0} is the name of the generator that failed. {1} is the type of exception that was thrown {2} is the message in the exception + + + Generator threw the following exception: +'{0}'. + Generator threw the following exception: +'{0}'. + {0} is the string representation of the exception that was thrown. + + + Generator failed to initialize. + Generator failed to initialize. + + Wrong number of type arguments 型引数の数が正しくありません。 diff --git a/src/Compilers/VisualBasic/Portable/xlf/VBResources.ko.xlf b/src/Compilers/VisualBasic/Portable/xlf/VBResources.ko.xlf index 3a471c48bc5bf..bfcd72045b56a 100644 --- a/src/Compilers/VisualBasic/Portable/xlf/VBResources.ko.xlf +++ b/src/Compilers/VisualBasic/Portable/xlf/VBResources.ko.xlf @@ -463,6 +463,40 @@ 형식 인수는 Nothing일 수 없습니다. + + Generator '{0}' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + Generator '{0}' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + {0} is the name of the generator that failed. {1} is the type of exception that was thrown {2} is the message in the exception + + + Generator threw the following exception: +'{0}'. + Generator threw the following exception: +'{0}'. + {0} is the string representation of the exception that was thrown. + + + Generator failed to generate source. + Generator failed to generate source. + + + + Generator '{0}' failed to initialize. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + Generator '{0}' failed to initialize. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + {0} is the name of the generator that failed. {1} is the type of exception that was thrown {2} is the message in the exception + + + Generator threw the following exception: +'{0}'. + Generator threw the following exception: +'{0}'. + {0} is the string representation of the exception that was thrown. + + + Generator failed to initialize. + Generator failed to initialize. + + Wrong number of type arguments 형식 인수 수가 잘못되었습니다. diff --git a/src/Compilers/VisualBasic/Portable/xlf/VBResources.pl.xlf b/src/Compilers/VisualBasic/Portable/xlf/VBResources.pl.xlf index b4f5f586f7ae9..7dc2d6038d4e6 100644 --- a/src/Compilers/VisualBasic/Portable/xlf/VBResources.pl.xlf +++ b/src/Compilers/VisualBasic/Portable/xlf/VBResources.pl.xlf @@ -463,6 +463,40 @@ Argument typu nie może mieć wartości Nothing + + Generator '{0}' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + Generator '{0}' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + {0} is the name of the generator that failed. {1} is the type of exception that was thrown {2} is the message in the exception + + + Generator threw the following exception: +'{0}'. + Generator threw the following exception: +'{0}'. + {0} is the string representation of the exception that was thrown. + + + Generator failed to generate source. + Generator failed to generate source. + + + + Generator '{0}' failed to initialize. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + Generator '{0}' failed to initialize. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + {0} is the name of the generator that failed. {1} is the type of exception that was thrown {2} is the message in the exception + + + Generator threw the following exception: +'{0}'. + Generator threw the following exception: +'{0}'. + {0} is the string representation of the exception that was thrown. + + + Generator failed to initialize. + Generator failed to initialize. + + Wrong number of type arguments Nieprawidłowa liczba argumentów typu diff --git a/src/Compilers/VisualBasic/Portable/xlf/VBResources.pt-BR.xlf b/src/Compilers/VisualBasic/Portable/xlf/VBResources.pt-BR.xlf index 1bae75be97849..d9113d38850ab 100644 --- a/src/Compilers/VisualBasic/Portable/xlf/VBResources.pt-BR.xlf +++ b/src/Compilers/VisualBasic/Portable/xlf/VBResources.pt-BR.xlf @@ -463,6 +463,40 @@ Argumento de tipo não pode ser Nothing + + Generator '{0}' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + Generator '{0}' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + {0} is the name of the generator that failed. {1} is the type of exception that was thrown {2} is the message in the exception + + + Generator threw the following exception: +'{0}'. + Generator threw the following exception: +'{0}'. + {0} is the string representation of the exception that was thrown. + + + Generator failed to generate source. + Generator failed to generate source. + + + + Generator '{0}' failed to initialize. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + Generator '{0}' failed to initialize. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + {0} is the name of the generator that failed. {1} is the type of exception that was thrown {2} is the message in the exception + + + Generator threw the following exception: +'{0}'. + Generator threw the following exception: +'{0}'. + {0} is the string representation of the exception that was thrown. + + + Generator failed to initialize. + Generator failed to initialize. + + Wrong number of type arguments Número errado de argumentos de tipo diff --git a/src/Compilers/VisualBasic/Portable/xlf/VBResources.ru.xlf b/src/Compilers/VisualBasic/Portable/xlf/VBResources.ru.xlf index b2cb46ddaa46b..505c3ea3333f3 100644 --- a/src/Compilers/VisualBasic/Portable/xlf/VBResources.ru.xlf +++ b/src/Compilers/VisualBasic/Portable/xlf/VBResources.ru.xlf @@ -463,6 +463,40 @@ Аргумент типа не может иметь значение Nothing + + Generator '{0}' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + Generator '{0}' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + {0} is the name of the generator that failed. {1} is the type of exception that was thrown {2} is the message in the exception + + + Generator threw the following exception: +'{0}'. + Generator threw the following exception: +'{0}'. + {0} is the string representation of the exception that was thrown. + + + Generator failed to generate source. + Generator failed to generate source. + + + + Generator '{0}' failed to initialize. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + Generator '{0}' failed to initialize. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + {0} is the name of the generator that failed. {1} is the type of exception that was thrown {2} is the message in the exception + + + Generator threw the following exception: +'{0}'. + Generator threw the following exception: +'{0}'. + {0} is the string representation of the exception that was thrown. + + + Generator failed to initialize. + Generator failed to initialize. + + Wrong number of type arguments Неверное число аргументов типа diff --git a/src/Compilers/VisualBasic/Portable/xlf/VBResources.tr.xlf b/src/Compilers/VisualBasic/Portable/xlf/VBResources.tr.xlf index 2df1e7145559e..cea864762fbf8 100644 --- a/src/Compilers/VisualBasic/Portable/xlf/VBResources.tr.xlf +++ b/src/Compilers/VisualBasic/Portable/xlf/VBResources.tr.xlf @@ -463,6 +463,40 @@ Tür bağımsız değişkeni Nothing olamaz + + Generator '{0}' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + Generator '{0}' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + {0} is the name of the generator that failed. {1} is the type of exception that was thrown {2} is the message in the exception + + + Generator threw the following exception: +'{0}'. + Generator threw the following exception: +'{0}'. + {0} is the string representation of the exception that was thrown. + + + Generator failed to generate source. + Generator failed to generate source. + + + + Generator '{0}' failed to initialize. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + Generator '{0}' failed to initialize. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + {0} is the name of the generator that failed. {1} is the type of exception that was thrown {2} is the message in the exception + + + Generator threw the following exception: +'{0}'. + Generator threw the following exception: +'{0}'. + {0} is the string representation of the exception that was thrown. + + + Generator failed to initialize. + Generator failed to initialize. + + Wrong number of type arguments Tür bağımsız değişkenlerinin yanlış sayısı diff --git a/src/Compilers/VisualBasic/Portable/xlf/VBResources.zh-Hans.xlf b/src/Compilers/VisualBasic/Portable/xlf/VBResources.zh-Hans.xlf index eada1fbfd36fd..2122b26767d23 100644 --- a/src/Compilers/VisualBasic/Portable/xlf/VBResources.zh-Hans.xlf +++ b/src/Compilers/VisualBasic/Portable/xlf/VBResources.zh-Hans.xlf @@ -463,6 +463,40 @@ 类型参数不能是任何内容 + + Generator '{0}' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + Generator '{0}' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + {0} is the name of the generator that failed. {1} is the type of exception that was thrown {2} is the message in the exception + + + Generator threw the following exception: +'{0}'. + Generator threw the following exception: +'{0}'. + {0} is the string representation of the exception that was thrown. + + + Generator failed to generate source. + Generator failed to generate source. + + + + Generator '{0}' failed to initialize. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + Generator '{0}' failed to initialize. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + {0} is the name of the generator that failed. {1} is the type of exception that was thrown {2} is the message in the exception + + + Generator threw the following exception: +'{0}'. + Generator threw the following exception: +'{0}'. + {0} is the string representation of the exception that was thrown. + + + Generator failed to initialize. + Generator failed to initialize. + + Wrong number of type arguments 类型参数的数目不正确 diff --git a/src/Compilers/VisualBasic/Portable/xlf/VBResources.zh-Hant.xlf b/src/Compilers/VisualBasic/Portable/xlf/VBResources.zh-Hant.xlf index c1a98587d7daa..0b6368947e414 100644 --- a/src/Compilers/VisualBasic/Portable/xlf/VBResources.zh-Hant.xlf +++ b/src/Compilers/VisualBasic/Portable/xlf/VBResources.zh-Hant.xlf @@ -463,6 +463,40 @@ 類型引數不可為 Nothing + + Generator '{0}' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + Generator '{0}' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + {0} is the name of the generator that failed. {1} is the type of exception that was thrown {2} is the message in the exception + + + Generator threw the following exception: +'{0}'. + Generator threw the following exception: +'{0}'. + {0} is the string representation of the exception that was thrown. + + + Generator failed to generate source. + Generator failed to generate source. + + + + Generator '{0}' failed to initialize. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + Generator '{0}' failed to initialize. It will not contribute to the output and compilation errors may occur as a result. Exception was of type '{1}' with message '{2}' + {0} is the name of the generator that failed. {1} is the type of exception that was thrown {2} is the message in the exception + + + Generator threw the following exception: +'{0}'. + Generator threw the following exception: +'{0}'. + {0} is the string representation of the exception that was thrown. + + + Generator failed to initialize. + Generator failed to initialize. + + Wrong number of type arguments 類型引數的數目錯誤 diff --git a/src/Compilers/VisualBasic/Test/Semantic/SourceGeneration/GeneratorDriverTests.vb b/src/Compilers/VisualBasic/Test/Semantic/SourceGeneration/GeneratorDriverTests.vb new file mode 100644 index 0000000000000..b35d948b9a092 --- /dev/null +++ b/src/Compilers/VisualBasic/Test/Semantic/SourceGeneration/GeneratorDriverTests.vb @@ -0,0 +1,213 @@ +' Licensed to the .NET Foundation under one or more agreements. +' The .NET Foundation licenses this file to you under the MIT license. +' See the LICENSE file in the project root for more information. + +Imports System.Collections.Immutable +Imports Microsoft.CodeAnalysis.VisualBasic.Syntax +Imports Roslyn.Test.Utilities.TestGenerators + +Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests + + Public Class GeneratorDriverTests + Inherits BasicTestBase + + + Public Sub Single_File_Is_Added() + + Dim generatorSource = " +Public Class GeneratedClass + +End Class +" + Dim parseOptions = TestOptions.Regular + Dim compilation = GetCompilation(parseOptions) + Dim testGenerator As SingleFileTestGenerator = New SingleFileTestGenerator(generatorSource) + Dim driver As GeneratorDriver = VisualBasicGeneratorDriver.Create(ImmutableArray.Create(Of ISourceGenerator)(testGenerator), parseOptions:=parseOptions) + + Dim outputCompilation As Compilation = Nothing + Dim outputDiagnostics As ImmutableArray(Of Diagnostic) = Nothing + driver.RunGeneratorsAndUpdateCompilation(compilation, outputCompilation, outputDiagnostics) + outputDiagnostics.Verify() + + Assert.Equal(2, outputCompilation.SyntaxTrees.Count()) + Assert.NotEqual(compilation, outputCompilation) + End Sub + + + Public Sub Can_Access_Additional_Files() + + Dim additionalText = New InMemoryAdditionalText("a\\file1.cs", "Hello World") + + Dim parseOptions = TestOptions.Regular + Dim compilation As Compilation = GetCompilation(parseOptions) + Dim testGenerator As CallbackGenerator = New CallbackGenerator(Sub(i) + End Sub, + Sub(e) Assert.Equal("Hello World", e.AdditionalFiles.First().GetText().ToString())) + + Dim driver As GeneratorDriver = VisualBasicGeneratorDriver.Create(ImmutableArray.Create(Of ISourceGenerator)(testGenerator), + additionalTexts:=ImmutableArray.Create(Of AdditionalText)(additionalText), + parseOptions:=parseOptions) + + Dim outputCompilation As Compilation = Nothing + Dim outputDiagnostics As ImmutableArray(Of Diagnostic) = Nothing + driver.RunGeneratorsAndUpdateCompilation(compilation, outputCompilation, outputDiagnostics) + outputDiagnostics.Verify() + End Sub + + + Public Sub Generator_Can_Be_Written_In_Visual_Basic() + + Dim parseOptions = TestOptions.Regular + Dim compilation As Compilation = GetCompilation(parseOptions) + Dim testGenerator As VBGenerator = New VBGenerator() + Dim driver As GeneratorDriver = VisualBasicGeneratorDriver.Create(ImmutableArray.Create(Of ISourceGenerator)(testGenerator), parseOptions:=parseOptions) + + Dim outputCompilation As Compilation = Nothing + Dim outputDiagnostics As ImmutableArray(Of Diagnostic) = Nothing + driver.RunGeneratorsAndUpdateCompilation(compilation, outputCompilation, outputDiagnostics) + outputDiagnostics.Verify() + + Assert.Equal(2, outputCompilation.SyntaxTrees.Count()) + Assert.NotEqual(compilation, outputCompilation) + End Sub + + + Public Sub Generator_Can_See_Syntax() + + Dim source = " +Imports System +Namespace ANamespace + Public Class AClass + Public Sub AMethod(p as String) + Throw New InvalidOperationException() + End Sub + End Class +End Namespace +" + + Dim parseOptions = TestOptions.Regular + Dim compilation As Compilation = GetCompilation(parseOptions, source) + Dim testGenerator As VBGenerator = New VBGenerator() + Dim driver As GeneratorDriver = VisualBasicGeneratorDriver.Create(ImmutableArray.Create(Of ISourceGenerator)(testGenerator), parseOptions:=parseOptions) + + Dim outputCompilation As Compilation = Nothing + Dim outputDiagnostics As ImmutableArray(Of Diagnostic) = Nothing + driver.RunGeneratorsAndUpdateCompilation(compilation, outputCompilation, outputDiagnostics) + outputDiagnostics.Verify() + + Assert.Equal(23, testGenerator._receiver._nodes.Count) + Assert.IsType(GetType(CompilationUnitSyntax), testGenerator._receiver._nodes(0)) + Assert.IsType(GetType(ClassStatementSyntax), testGenerator._receiver._nodes(8)) + Assert.IsType(GetType(ThrowStatementSyntax), testGenerator._receiver._nodes(16)) + Assert.IsType(GetType(EndBlockStatementSyntax), testGenerator._receiver._nodes(22)) + + End Sub + + + Public Sub Exception_During_Init() + Dim parseOptions = TestOptions.Regular + Dim compilation As Compilation = GetCompilation(parseOptions) + Dim testGenerator As CallbackGenerator = New CallbackGenerator(Sub(i) Throw New Exception("Init Exception"), + Sub(e) + End Sub) + + Dim driver As GeneratorDriver = VisualBasicGeneratorDriver.Create(ImmutableArray.Create(Of ISourceGenerator)(testGenerator), parseOptions:=parseOptions) + + Dim outputCompilation As Compilation = Nothing + Dim outputDiagnostics As ImmutableArray(Of Diagnostic) = Nothing + driver.RunGeneratorsAndUpdateCompilation(compilation, outputCompilation, outputDiagnostics) + outputDiagnostics.Verify( + Diagnostic("BC42501").WithArguments("CallbackGenerator", "Exception", "Init Exception").WithLocation(1, 1) + ) + End Sub + + + Public Sub Exception_During_Execute() + Dim parseOptions = TestOptions.Regular + Dim compilation As Compilation = GetCompilation(parseOptions) + Dim testGenerator As CallbackGenerator = New CallbackGenerator(Sub(i) + End Sub, + Sub(e) Throw New Exception("Generate Exception")) + + Dim driver As GeneratorDriver = VisualBasicGeneratorDriver.Create(ImmutableArray.Create(Of ISourceGenerator)(testGenerator), parseOptions:=parseOptions) + + Dim outputCompilation As Compilation = Nothing + Dim outputDiagnostics As ImmutableArray(Of Diagnostic) = Nothing + driver.RunGeneratorsAndUpdateCompilation(compilation, outputCompilation, outputDiagnostics) + outputDiagnostics.Verify( + Diagnostic("BC42502").WithArguments("CallbackGenerator", "Exception", "Generate Exception").WithLocation(1, 1) + ) + + End Sub + + + Public Sub Exception_During_SyntaxWalk() + Dim parseOptions = TestOptions.Regular + Dim compilation As Compilation = GetCompilation(parseOptions) + Dim testGenerator As VBGenerator = New VBGenerator() + testGenerator._receiver._throw = True + + Dim driver As GeneratorDriver = VisualBasicGeneratorDriver.Create(ImmutableArray.Create(Of ISourceGenerator)(testGenerator), parseOptions:=parseOptions) + + Dim outputCompilation As Compilation = Nothing + Dim outputDiagnostics As ImmutableArray(Of Diagnostic) = Nothing + driver.RunGeneratorsAndUpdateCompilation(compilation, outputCompilation, outputDiagnostics) + outputDiagnostics.Verify( + Diagnostic("BC42502").WithArguments("VBGenerator", "Exception", "Syntax Walk").WithLocation(1, 1) + ) + End Sub + + Shared Function GetCompilation(parseOptions As VisualBasicParseOptions, Optional source As String = "") As Compilation + If (String.IsNullOrWhiteSpace(source)) Then + source = " +Public Class C +End Class +" + End If + + Dim compilation As Compilation = CreateCompilation(source, options:=TestOptions.DebugDll, parseOptions:=parseOptions) + compilation.VerifyDiagnostics() + Assert.Single(compilation.SyntaxTrees) + + Return compilation + End Function + + End Class + + + + Friend Class VBGenerator + Implements ISourceGenerator + + Public _receiver As Receiver = New Receiver() + + Public Sub Initialize(context As GeneratorInitializationContext) Implements ISourceGenerator.Initialize + context.RegisterForSyntaxNotifications(Function() _receiver) + End Sub + + Public Sub Execute(context As GeneratorExecutionContext) Implements ISourceGenerator.Execute + context.AddSource("source.vb", " +Public Class D +End Class +") + End Sub + + Class Receiver + Implements ISyntaxReceiver + + Public _throw As Boolean + + Public _nodes As List(Of SyntaxNode) = New List(Of SyntaxNode)() + + Public Sub OnVisitSyntaxNode(syntaxNode As SyntaxNode) Implements ISyntaxReceiver.OnVisitSyntaxNode + If (_throw) Then + Throw New Exception("Syntax Walk") + End If + _nodes.Add(syntaxNode) + End Sub + End Class + + End Class + + +End Namespace diff --git a/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzerItem/AnalyzerItemSource.cs b/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzerItem/AnalyzerItemSource.cs index da92ecc4214a5..1fea8d81f8b2c 100644 --- a/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzerItem/AnalyzerItemSource.cs +++ b/src/VisualStudio/Core/Impl/SolutionExplorer/AnalyzerItem/AnalyzerItemSource.cs @@ -222,7 +222,7 @@ private ImmutableArray GetFilteredAnalyzers(IEnumerable TransformCompilationAsync(Compilation oldCompi internal sealed class AddAnalyzerReferencesAction : CompilationAndGeneratorDriverTranslationAction { private readonly ImmutableArray _analyzerReferences; + private readonly string _language; - public AddAnalyzerReferencesAction(ImmutableArray analyzerReferences) + public AddAnalyzerReferencesAction(ImmutableArray analyzerReferences, string language) { _analyzerReferences = analyzerReferences; + _language = language; } public override TrackedGeneratorDriver TransformGeneratorDriver(TrackedGeneratorDriver generatorDriver) { - var generators = _analyzerReferences.SelectMany(a => a.GetGenerators()).ToImmutableArray(); + var generators = _analyzerReferences.SelectMany(a => a.GetGenerators(_language)).ToImmutableArray(); return new TrackedGeneratorDriver(generatorDriver.GeneratorDriver?.AddGenerators(generators)); } } @@ -172,15 +174,17 @@ public override TrackedGeneratorDriver TransformGeneratorDriver(TrackedGenerator internal sealed class RemoveAnalyzerReferencesAction : CompilationAndGeneratorDriverTranslationAction { private readonly ImmutableArray _analyzerReferences; + private readonly string _language; - public RemoveAnalyzerReferencesAction(ImmutableArray analyzerReferences) + public RemoveAnalyzerReferencesAction(ImmutableArray analyzerReferences, string language) { _analyzerReferences = analyzerReferences; + _language = language; } public override TrackedGeneratorDriver TransformGeneratorDriver(TrackedGeneratorDriver generatorDriver) { - var generators = _analyzerReferences.SelectMany(a => a.GetGenerators()).ToImmutableArray(); + var generators = _analyzerReferences.SelectMany(a => a.GetGenerators(_language)).ToImmutableArray(); return new TrackedGeneratorDriver(generatorDriver.GeneratorDriver?.RemoveGenerators(generators)); } } diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.CompilationTracker.cs b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.CompilationTracker.cs index bf4cf28bb6ae8..b0378c6dcb87f 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.CompilationTracker.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.CompilationTracker.cs @@ -729,7 +729,7 @@ private async Task FinalizeCompilationAsync( // Now we run generators; if we don't have a generator driver at all, we must try create one if (generatorDriver.GeneratorDriver == null) { - var generators = this.ProjectState.AnalyzerReferences.SelectMany(a => a.GetGenerators()).ToImmutableArray(); + var generators = this.ProjectState.AnalyzerReferences.SelectMany(a => a.GetGenerators(this.ProjectState.Language)).ToImmutableArray(); var additionalTexts = this.ProjectState.AdditionalDocumentStates.Values.SelectAsArray(a => (AdditionalText)new AdditionalTextWithState(a)); var compilationFactory = this.ProjectState.LanguageServices.GetRequiredService(); diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.cs b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.cs index 134be5e611f0b..539bec64049a3 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.cs @@ -981,7 +981,7 @@ public SolutionState AddAnalyzerReferences(ProjectId projectId, ImmutableArray @@ -1000,7 +1000,7 @@ public SolutionState RemoveAnalyzerReference(ProjectId projectId, AnalyzerRefere return ForkProject( oldProject.WithAnalyzerReferences(newReferences), - new CompilationAndGeneratorDriverTranslationAction.RemoveAnalyzerReferencesAction(ImmutableArray.Create(analyzerReference))); + new CompilationAndGeneratorDriverTranslationAction.RemoveAnalyzerReferencesAction(ImmutableArray.Create(analyzerReference), oldProject.Language)); } /// diff --git a/src/Workspaces/CoreTest/SolutionTests/SolutionWithSourceGeneratorTests.cs b/src/Workspaces/CoreTest/SolutionTests/SolutionWithSourceGeneratorTests.cs index 48210ac15ad95..b3adc65d103bc 100644 --- a/src/Workspaces/CoreTest/SolutionTests/SolutionWithSourceGeneratorTests.cs +++ b/src/Workspaces/CoreTest/SolutionTests/SolutionWithSourceGeneratorTests.cs @@ -180,7 +180,7 @@ public TestGeneratorReference(ISourceGenerator generator) public override ImmutableArray GetAnalyzers(string language) => ImmutableArray.Empty; public override ImmutableArray GetAnalyzersForAllLanguages() => ImmutableArray.Empty; - public override ImmutableArray GetGenerators() => ImmutableArray.Create(_generator); + public override ImmutableArray GetGenerators(string language) => ImmutableArray.Create(_generator); } private sealed class GenerateFileForEachAdditionalFileWithContentsCommented : ISourceGenerator diff --git a/src/Workspaces/VisualBasic/Portable/Workspace/LanguageServices/VisualBasicCompilationFactoryService.vb b/src/Workspaces/VisualBasic/Portable/Workspace/LanguageServices/VisualBasicCompilationFactoryService.vb index f9cb3c279408c..36838a5068ed8 100644 --- a/src/Workspaces/VisualBasic/Portable/Workspace/LanguageServices/VisualBasicCompilationFactoryService.vb +++ b/src/Workspaces/VisualBasic/Portable/Workspace/LanguageServices/VisualBasicCompilationFactoryService.vb @@ -49,7 +49,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic End Function Public Function CreateGeneratorDriver(parseOptions As ParseOptions, generators As ImmutableArray(Of ISourceGenerator), optionsProvider As AnalyzerConfigOptionsProvider, additionalTexts As ImmutableArray(Of AdditionalText)) As GeneratorDriver Implements ICompilationFactoryService.CreateGeneratorDriver - Return Nothing + Return VisualBasicGeneratorDriver.Create(generators, additionalTexts, DirectCast(parseOptions, VisualBasicParseOptions), optionsProvider) End Function End Class End Namespace