Support incremental code generation in Visual Studio 2022#355
Support incremental code generation in Visual Studio 2022#355sharwell wants to merge 10 commits into
Conversation
56628fa to
16f0ba3
Compare
| <ProjectReference Include="..\Microsoft.Windows.CsWin32\Roslyn38\Microsoft.Windows.CsWin32.Roslyn38.csproj" Private="true" ReferenceOutputAssembly="false" /> | ||
| <ProjectReference Include="..\Microsoft.Windows.CsWin32\Roslyn40\Microsoft.Windows.CsWin32.Roslyn40.csproj" Private="true" ReferenceOutputAssembly="false" /> |
There was a problem hiding this comment.
📝 The Roslyn38 and Roslyn40 subfolders seemed the easiest way to achieve all of:
- Share version.json
- Not move settings.schema.json
- Not have 3 top-level folders for one multi-targeted assembly
| /// <param name="parseOptions">The parse options that will be used for the generated code.</param> | ||
| public Generator(string metadataLibraryPath, string? apiDocsPath, GeneratorOptions? options = null, CSharpCompilation? compilation = null, CSharpParseOptions? parseOptions = null) | ||
| /// <param name="languageVersion">The language version that will be used for the generated code.</param> | ||
| public Generator(string metadataLibraryPath, string? apiDocsPath, GeneratorOptions? options = null, CSharpCompilation? compilation = null, LanguageVersion? languageVersion = null) |
There was a problem hiding this comment.
📝 This pull request contains a few distinct examples of taking a value that frequently changes and extracting an intermediate incremental value which doesn't change as frequently. Breaking up compilation in the same manner could be a high-value win, but it's also significantly more work.
There was a problem hiding this comment.
The general approach for breaking up compilation would be:
- Keep a map of source document → types of interest declared in that source document
- Keep a map of metadata reference → types of interest declared in that metadata reference
- Reference the maps in the code generation step instead of directly using
Compilation
This approach means a change to one source file only requires a change to one value in the maps, and then a quick lookup during the incremental output step.
There was a problem hiding this comment.
I like the idea. I'm puzzled by your removal of ParseOptions though as that should change infrequently. And isn't that where I'd find things like whether NRT is enabled? I don't use that yet but I may someday.
There was a problem hiding this comment.
I don't use that yet but I may someday.
None of this is public API. If/when you need something new, feel free to add it. Until then, omitting it means the source generator won't trigger on changes to that item.
|
Commenter does not have sufficient privileges for PR 355 in repo microsoft/CsWin32 |
|
I see you split out the Microsoft.Windows.CsWin32.props file into |
|
The |
|
The tools/install.ps1 script should be updated to look for the analyzer dll's in the new location, right? |
var inputs = context.CompilationProvider
.Combine(languageVersion)
.Combine(configFiles)
.Combine(globalConfig)
.Select((data, cancellationToken) => (compilation: data.Left.Left.Left, languageVersion: data.Left.Left.Right, additionalFiles: data.Left.Right, analyzerConfigOptions: data.Right));Does this mean that the result will be reused so long as those inputs have not changed? |
| /// <param name="parseOptions">The parse options that will be used for the generated code.</param> | ||
| public Generator(string metadataLibraryPath, string? apiDocsPath, GeneratorOptions? options = null, CSharpCompilation? compilation = null, CSharpParseOptions? parseOptions = null) | ||
| /// <param name="languageVersion">The language version that will be used for the generated code.</param> | ||
| public Generator(string metadataLibraryPath, string? apiDocsPath, GeneratorOptions? options = null, CSharpCompilation? compilation = null, LanguageVersion? languageVersion = null) |
There was a problem hiding this comment.
I like the idea. I'm puzzled by your removal of ParseOptions though as that should change infrequently. And isn't that where I'd find things like whether NRT is enabled? I don't use that yet but I may someday.
| <AdditionalFiles Include="$(MSBuildThisFileDirectory)BannedSymbols.txt" /> | ||
| </ItemGroup> | ||
| <ItemGroup> | ||
| <Compile Include="$(MSBuildThisFileDirectory)ArrayTypeHandleInfo.cs" /> |
There was a problem hiding this comment.
Do we really have to give up globbing for source files here?
What if instead of using Shared Projects, we simply used globbing in the two head projects to reach into a common directory?
There was a problem hiding this comment.
IMO this limitation is an unfortunate side effect of the only current recommendations for building projects with completely different dependency sets. It's been a while since I tried using globs in .projitems and it's possible it works now.
|
FYI I have checked out your branch and resolved merge conflicts. I can't push to your branch to share the work though. |
9c9eb1a to
7e924fe
Compare
This comment has been minimized.
This comment has been minimized.
Yes, but one of the inputs is currently
This refactoring is quite complex due to the current state of the generator, but offers a significant benefit where (1) only needs to be executed if |
|
There are surely some caching opportunities here, but I'll close this PR since in its present form it cannot be merged, and we aren't looking at caching across invocations right now. |
…son-updates Update Dockerfile and global.json updates to v9.0.201
Uh oh!
There was an error while loading. Please reload this page.