-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SG: Implementation outputs #54798
SG: Implementation outputs #54798
Conversation
- Make output kinds public - Take a parameter during construction - Don't run outputs passed in as disabled to the generator
@dotnet/roslyn-compiler for review please :) |
src/Compilers/Core/Portable/SourceGeneration/Nodes/IIncrementalGeneratorOutputNode.cs
Show resolved
Hide resolved
src/Compilers/CSharp/Portable/SourceGeneration/CSharpGeneratorDriver.cs
Outdated
Show resolved
Hide resolved
Ping @dotnet/roslyn-compiler for a second review please :) |
public void RegisterSourceOutput<TSource>(IncrementalValuesProvider<TSource> source, Action<SourceProductionContext, TSource> action) => source.Node.RegisterOutput(new SourceOutputNode<TSource>(source.Node, action.WrapUserAction())); | ||
public void RegisterSourceOutput<TSource>(IncrementalValuesProvider<TSource> source, Action<SourceProductionContext, TSource> action) => source.Node.RegisterOutput(new SourceOutputNode<TSource>(source.Node, action.WrapUserAction(), IncrementalGeneratorOutputKind.Source)); | ||
|
||
public void RegisterImplementationSourceOutput<TSource>(IncrementalValueProvider<TSource> source, Action<SourceProductionContext, TSource> action) => source.Node.RegisterOutput(new SourceOutputNode<TSource>(source.Node, action.WrapUserAction(), IncrementalGeneratorOutputKind.Implementation)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// <returns>A new <see cref="CSharpGeneratorDriver"/> instance.</returns> | ||
public static CSharpGeneratorDriver Create(IEnumerable<ISourceGenerator> generators, IEnumerable<AdditionalText>? additionalTexts = null, CSharpParseOptions? parseOptions = null, AnalyzerConfigOptionsProvider? optionsProvider = null) | ||
=> new CSharpGeneratorDriver(parseOptions ?? CSharpParseOptions.Default, generators.ToImmutableArray(), optionsProvider ?? CompilerAnalyzerConfigOptionsProvider.Empty, additionalTexts.AsImmutableOrEmpty()); | ||
public static CSharpGeneratorDriver Create(IEnumerable<ISourceGenerator> generators, IEnumerable<AdditionalText>? additionalTexts = null, CSharpParseOptions? parseOptions = null, AnalyzerConfigOptionsProvider? optionsProvider = null, IncrementalGeneratorOutputKind disabledOutputs = IncrementalGeneratorOutputKind.None) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we plan to have more, but IncrementalGeneratorOutputKind
is a [Flags]
so we can combine them together like IncrementalGeneratorOutputKind.Implementation | IncrementalGeneratorKind.SomeOtherOutput
to build up which nodes we don't want.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding more IncrementalGeneratorOutputKind
values can be accomodated with the current overload but do we expect to add options other than IncrementatlGeneratorOutputKind
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I see what you're saying. Yeah actually that probably makes sense.
|
||
if (disabledOutput.HasFlag((IncrementalGeneratorOutputKind)kind)) | ||
{ | ||
Assert.DoesNotContain(result.Results[0].GeneratedSources, (s) => s.HintName == Enum.GetName(typeof(IncrementalGeneratorOutputKind), kind) + ".cs"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// </summary> | ||
public readonly struct GeneratorDriverOptions | ||
{ | ||
public static GeneratorDriverOptions Default = new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// </summary> | ||
public readonly struct GeneratorDriverOptions | ||
{ | ||
public static GeneratorDriverOptions Default = new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// 3.11 BACKCOMPAT OVERLOAD -- DO NOT TOUCH | ||
[EditorBrowsable(EditorBrowsableState.Never)] | ||
public static CSharpGeneratorDriver Create(IEnumerable<ISourceGenerator> generators, IEnumerable<AdditionalText>? additionalTexts, CSharpParseOptions? parseOptions, AnalyzerConfigOptionsProvider? optionsProvider) | ||
=> new CSharpGeneratorDriver(parseOptions ?? CSharpParseOptions.Default, generators.ToImmutableArray(), optionsProvider ?? CompilerAnalyzerConfigOptionsProvider.Empty, additionalTexts.AsImmutableOrEmpty(), driverOptions: GeneratorDriverOptions.Default); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
new CSharpGeneratorDriver(parseOptions ?? CSharpParseOptions.Default, generators.ToImmutableArray(), optionsProvider ?? CompilerAnalyzerConfigOptionsProvider.Empty, additionalTexts.AsImmutableOrEmpty(), driverOptions: GeneratorDriverOptions.Default);
Consider calling the new Create()
instead to avoid duplicating the handling of optional values: Create(parseOptions, optionsProvider, additionalTexts, driverOptions: null)
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, If(analyzerConfigOptionsProvider, CompilerAnalyzerConfigOptionsProvider.Empty), additionalTexts.NullToEmpty()) | ||
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, Optional driverOptions As GeneratorDriverOptions? = Nothing) As VisualBasicGeneratorDriver | ||
Return New VisualBasicGeneratorDriver(parseOptions, generators, If(analyzerConfigOptionsProvider, CompilerAnalyzerConfigOptionsProvider.Empty), additionalTexts.NullToEmpty(), If(driverOptions, DirectCast(Nothing, GeneratorDriverOptions))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This implements the idea of 'non semantic' source generation. That is source that can be safely ignored from the IDE perspective (no intellisense impact etc) but required for the on disk build.
I have used the name 'Implementation' for two reasons:
Note: this doesn't hook up the IDE side of things yet, but just makes the API available for consumption.
Closes: #53609
Api Review: #54723