Conversation
| } | ||
|
|
||
| internal delegate CodeActionOptions CodeActionOptionsProvider(HostLanguageServices languageService); | ||
| internal abstract class AbstractCodeActionOptionsProvider : CodeActionOptionsProvider |
There was a problem hiding this comment.
Makes it easier to implement CodeActionOption providers that fetch all CodeActionOptions and then provide all the subsets of options needed by code actions.
| #endif | ||
| } | ||
|
|
||
| internal sealed class DelegatingCodeActionOptionsProvider : AbstractCodeActionOptionsProvider |
There was a problem hiding this comment.
Helper to allow inline definition of a CodeActionOptionProvider using a lambda.
|
|
||
| namespace Microsoft.CodeAnalysis.CSharp.CodeGeneration; | ||
|
|
||
| internal static class CSharpCodeGenerationOptionsStorage |
|
|
||
| namespace Microsoft.CodeAnalysis.CodeGeneration | ||
| { | ||
| internal readonly record struct CodeGenerationSolutionContext( |
There was a problem hiding this comment.
Groups information needed for generating code to arbitrary file in the solution. This may require generating code in more than one language and thus language specific fallback options.
| AnalyzerResult analyzerResult, | ||
| OptionSet options, | ||
| CSharpCodeGenerationOptions options, | ||
| NamingStylePreferencesProvider namingPreferences, |
There was a problem hiding this comment.
Naming preferences are separate from code gen options since they are fairly expensive and not always needed. Currently they are also not messagepack-serializable. Will follow up on that.
| public static readonly ExtractMethodOptions Default = new(); | ||
| } | ||
|
|
||
| internal readonly record struct ExtractMethodGenerationOptions( |
There was a problem hiding this comment.
ExtractMethodOptions only contains options specific to method extraction. Additional options needed for code generation, naming and formatting are added in ExtractMethodGenerationOptions. Separating these options makes them composable to other option sets w/o duplication, e.g. CodeActionOptions.
cac7c43 to
d7be96d
Compare
21df354 to
4394aa5
Compare
| } | ||
|
|
||
| public CodeGenerationOptions GetOptions(IGlobalOptionService globalOptions) | ||
| => GetCSharpCodeGenerationOptions(globalOptions); |
There was a problem hiding this comment.
aside, why not pull in IGlobalOptionService in teh importing constructor here. tehn, the client of ICodeGenerationOptionsStorage doesn't need to get IGlobalOptionService themselves. they just call .GetOptions() without having to care bout the impl detail of how that works.
There was a problem hiding this comment.
That would be possible, but the call site is an extension method on IGlobalOptionService:
public static CodeGenerationOptions GetCodeGenerationOptions(this IGlobalOptionService globalOptions, HostLanguageServices languageServices)
=> languageServices.GetRequiredService<ICodeGenerationOptionsStorage>().GetOptions(globalOptions);The caller already has the global options and asks for various options from it. So the ICodeGenerationOptionsStorage is the implementation detail here needed only to instantiate language specific options object.
| var sourceText = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); | ||
| var triggerText = sourceText.ToString(triggerToken.Span); | ||
| var fallbackOptions = _globalOptions.GetCodeCleanupOptionsProvider(); | ||
| var fallbackOptions = _globalOptions.CreateProvider(); |
There was a problem hiding this comment.
hrmm.. this reads a bit odd. what sort of provider is this making?
There was a problem hiding this comment.
Yeah, it's not very descriptive. I'll rename to CreateCodeActionOptionsProvider. It's just temporary. the IGlobalOptionsService should itself implement the provider interfaces. Currently that's not possible due to layering, but eventually it should be.
There was a problem hiding this comment.
Actually, not sure about the rename to CreateCodeActionOptionsProvider. It creates a provider that implements various options. It's not just CodeActionOptions, but all kinds of other options. While CodeActionOptions generally have all of these options, it's misleading to call the factory CreateCodeActionOptionsProvider since the call site might not actually care about code action options but other options. So I think I'd rather keep the name as is for now.
| End Sub | ||
|
|
||
| Public Function GetOptions(globalOptions As IGlobalOptionService) As CodeGenerationOptions Implements ICodeGenerationOptionsStorage.GetOptions | ||
| Return VisualBasicCodeGenerationOptions.Default |
There was a problem hiding this comment.
interesting. is thsi expected? VB doesn't have any special options here?
There was a problem hiding this comment.
Expected in this phase. Next PR will add one :)
Features that use code generation require different sets of options depending on what kind of operations they are performing on the generated code. We can identify 4 sets of options that features commonly require:
CodeGenerationOptionsOptions that directly affect code generation such as preferences for expression bodies, etc.
CodeAndImportGenerationOptions=CodeGerationOptions+ImportPlacementOptionsCode generation that also updates namespace imports.
CodeCleanupOptions=SyntaxFormattingOptions+SimplifierOptions+AddImportPlacementOptionsOptions that affect code cleanup/prettification
CleanCodeGenerationOptions=CodeGenerationOptions+CodeCleanupOptionsCode generation followed by code cleanup.
This change introduces these sets of options and corresponding providers (
XyzOptionsProvider) that retrieve them from an option storage.Previous PRs introduced
XyzOptionsProvideras delegates. Given that one option storage can provide multiple sets of options it turned out to be beneficial to switch these types to interfaces. It simplifies access patterns that occur very frequently and also avoid delegate allocations. Small amount of code got a bit more complex but the tradeoff is in favor of using interfaces.The first couple of commits rename current
CodeGeneratorPreferencestoCodeGeneratorOptionsandCodeGeneratorOptionstoCodeGeneratorContextInfoto fit the naming pattern of-Optionstypes.CodeGeneratorContextInfocombinesCodeGeneratorOptions,CodeGeneratorContextandLanguageVersion. Further refactoring may be possible that merges Context and ContextInfo, but is out of scope of this PR.ExtractMethodGenerationOptionsandImplementTypeGenerationOptionsadded in this PR are also worth mentioning.They combine primitive options (i.e.
ExtractMethodOptions,ImplementTypeOptions) with additional code generation/cleanup options. Separating these is important for option set composition. E.g.CodeActionOptionsinclude all options needed for extract method and implement type features. The primitive sets are included there along with all the primitive code generation options.Fixes #60794
Passed VS validation build tests: https://dev.azure.com/devdiv/DevDiv/_git/VS/pullrequest/396534