Skip to content

VB generators - #49139

Merged
chsienki merged 27 commits into
dotnet:masterfrom
chsienki:vb_generators
Nov 11, 2020
Merged

chsienki merged 27 commits into
dotnet:masterfrom
chsienki:vb_generators

Conversation

@chsienki

@chsienki chsienki commented Nov 2, 2020

Copy link
Copy Markdown
Member

Enable generators in the Visual Basic compiler

}

[Obsolete("Use GetGenerators(string language) or GetGeneratorsForAllLanguages()")]
public override ImmutableArray<ISourceGenerator> GetGenerators()

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝@333fred I'd like to run this by the API compat review board.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is your hope to just break it? Does this fall under our "source generator hosting isn't frozen" bar?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In a perfect world, I'd just remove it. Right now I've obsoleted it, and it returns only CSharp generators, which is essentially what it did before.

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

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝I'm not sure if it was ever intentional to return duplicate analyzer references, but I've ensured we keep the previous behavior.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we just break this? I admit I can't think of anything that would care, and honestly more that might be broken. :-)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I have no idea. It is a public API though, and it's been around for at least 6 years according to blame.

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
/// <summary>

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❓ This is the same layout as the DiagnosticAnalyzer attribute, so that we can re-use the lookup logic. Should we enforce this via some stronger mechanism like inheritance (does that break binary compat?) or are we confident with tests covering it working as expected?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with it being separate. I think inheritance may be over doing it a bit here.

@chsienki

chsienki commented Nov 2, 2020

Copy link
Copy Markdown
Member Author

@dotnet/roslyn-compiler for review (/cc @jasonmalinowski for IDE).

Hopefully it's fairly clear what's going on, but you may find it easier to review commit-by-commit, as I tried to do the work in small distinct stages to make review easier.

Comment thread src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerReference.cs Outdated
Comment thread src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerReference.cs Outdated
Comment thread src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerReference.cs Outdated

internal AdditionalSourcesCollection()
internal AdditionalSourcesCollection(string fileExtension)
{

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When dealing with extensions can never remember if we should or should not include the .. So ".cs" vs. "cs". Consider either enforcing one or the other is passed here or normalizing the input to a specific one.

Comment thread src/Compilers/Core/Portable/SourceGeneration/GeneratorAttribute.cs Outdated
public string[] Languages { get; }

/// <summary>
/// Attribute constructor used to specify the attached class is a source generator that provides CSharp sources.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Attribute constructor used to specify the attached class is a source generator that provides CSharp sources.
/// Attribute constructor used to specify the attached class is a source generator that provides CSharp sources.

Crazy aside: is it required to be a class or can it say be a struct?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<insert appropriate meme here for @jaredpar asking crazy questions>

More seriously, when generators are ran the IDE needs to compare results from one run to the next. I naively used == to compare the instances, so...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It has to be a class. We explicitly set the allowed location of the attribute to be class (see line 11) so loading via AnalyzerReference it can't ever be a struct.

As a second defense we check that the generator is also an ISourceGenerator, so there's no way you can pass a struct via the generator driver in code either.

return peModule.IsTargetAttribute(customAttrHandle, s_generatorAttributeNamespace, nameof(GeneratorAttribute), ctor: out _);
}

private static IEnumerable<string> GetGeneratorSupportedLanguages(PEModule peModule, CustomAttributeHandle customAttrHandle)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be a local function?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've left these for now as they've got the comments explaining them and it seemed weird embedding them in the ctor.

return ReadLanguagesFromAttribute(ref argsReader);
}

private static bool IsGeneratorAttribute(PEModule peModule, CustomAttributeHandle customAttrHandle)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be a local function?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I refactored out the extensions logic to make it simpler and not need it.

@chsienki

chsienki commented Nov 2, 2020

Copy link
Copy Markdown
Member Author

Closing/reopening to fix CI

@chsienki chsienki closed this Nov 2, 2020
@chsienki chsienki reopened this Nov 2, 2020

@jasonmalinowski jasonmalinowski left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IDE stuff looks good except it also needs a change in src/Features/Core/Portable/Diagnostics/AnalyzerHelper.cs, where we updated in #48400. There's comments with "we don't support VB" that need to be updated with the right diagnostic IDs.

}

[Obsolete("Use GetGenerators(string language) or GetGeneratorsForAllLanguages()")]
public override ImmutableArray<ISourceGenerator> GetGenerators()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is your hope to just break it? Does this fall under our "source generator hosting isn't frozen" bar?

public string[] Languages { get; }

/// <summary>
/// Attribute constructor used to specify the attached class is a source generator that provides CSharp sources.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<insert appropriate meme here for @jaredpar asking crazy questions>

More seriously, when generators are ran the IDE needs to compare results from one run to the next. I naively used == to compare the instances, so...

@paul1956

paul1956 commented Nov 3, 2020

Copy link
Copy Markdown
Contributor

Is this internal or the same as the C# Source Generator feature or something else? If its public is there any VB specific documentation/examples?

@chsienki

chsienki commented Nov 6, 2020

Copy link
Copy Markdown
Member Author

@jasonmalinowski I've updated the AnalyzerHelper to include the VB warning, and added the required warning to the VB code itself.

I have a test in the VB layer, but currently can't run it because we're not running VB command line tests on core. That is proving to be an interesting challenge, so I may just open an issue for it and add the test as part of the move later on.

@chsienki

chsienki commented Nov 6, 2020

Copy link
Copy Markdown
Member Author

Ok I've added the test, even though it will always be skipped for now, and opened an issue to track enabling the command-line tests for VB.

@paul1956

paul1956 commented Nov 6, 2020

Copy link
Copy Markdown
Contributor

When does this appear in some Preview I can try?

@chsienki

Copy link
Copy Markdown
Member Author

@paul1956

When does this appear in some Preview I can try?

When the PR merges it'll be available in the Roslyn nightly NuGet packages. We don't have a definitive date or target release of visual studio that it'll be available by, but we'll be sure to call it out when there is one.

@paul1956

Copy link
Copy Markdown
Contributor

@chsienki when it is available in NuGet can you post minimal instructions on where to download and simple usage?

@chsienki

Copy link
Copy Markdown
Member Author

@dotnet/roslyn-compiler for a second review please :)

Comment thread src/Compilers/Core/CodeAnalysisTest/Analyzers/AnalyzerFileReferenceTests.cs Outdated
Comment thread src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerFileReference.cs Outdated
Comment thread src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerFileReference.cs Outdated
Comment thread src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerFileReference.cs Outdated
Comment thread src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerFileReference.cs Outdated
Comment thread src/Compilers/Core/CodeAnalysisTest/Analyzers/AnalyzerFileReferenceTests.cs Outdated
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);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we just break this? I admit I can't think of anything that would care, and honestly more that might be broken. :-)

Comment thread src/Compilers/VisualBasic/Test/CommandLine/CommandLineTests.vb
Comment thread src/Compilers/Core/CodeAnalysisTest/Analyzers/AnalyzerFileReferenceTests.cs Outdated
Comment thread src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerFileReference.cs Outdated
Comment thread src/Compilers/Core/Portable/DiagnosticAnalyzer/AnalyzerFileReference.cs Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants