Skip to content

Migrate AvaloniaNameSourceGenerator to IIncrementalGenerator - #19216

Merged
MrJul merged 18 commits into
masterfrom
update-generators
Aug 13, 2025
Merged

Migrate AvaloniaNameSourceGenerator to IIncrementalGenerator#19216
MrJul merged 18 commits into
masterfrom
update-generators

Conversation

@maxkatz6

@maxkatz6 maxkatz6 commented Jul 8, 2025

Copy link
Copy Markdown
Member

What does the pull request do?

It was a bit long overdue.

Breaking changes

It raises minimal supported Visual Studio / .NET SDK version (only for source generators, not affecting anything else).

  • Visual Studio 2022+
  • .NET SDK 6.0+

@avaloniaui-bot

Copy link
Copy Markdown

You can test this PR using the following package version. 12.0.999-cibuild0057596-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

@avaloniaui-bot

Copy link
Copy Markdown

You can test this PR using the following package version. 12.0.999-cibuild0057610-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

Comment thread src/tools/Avalonia.Generators/Common/EquatableList.cs Outdated
var optionsProvider = pair.Right.Right;
var filePath = text.Path;

if (!(filePath.EndsWith(".xaml", StringComparison.OrdinalIgnoreCase) ||

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.

We should probably add some compiler-visible MSBuild metadata for XAML items that are going to be compiled (right now the actual check is the item being AvaloniaResource with the plan to have it restricted to AvaloniaXaml). It should be available before CoreCompile target, so we can pass that info into the analyzer.

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.

There is an extra metadata check already.
We read build_metadata.AdditionalFiles.SourceItemGroup metadata in the same file below, and for XAML files we set it as AvaloniaXaml.
See

<AdditionalFiles Include="@(AvaloniaXaml)" SourceItemGroup="AvaloniaXaml" />

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.

We had to add this metadata to avoid conflicts with MAUI XAML that also uses generators

Comment thread src/tools/Avalonia.Generators/NameGenerator/AvaloniaNameIncrementalGenerator.cs Outdated
})
.Where(tuple => tuple.textContent is not null);

var generatorInput = xamlFiles.Combine(context.CompilationProvider);

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.

IIRC passing CSharpCompilation to RegisterSourceOutput will trigger generator to run on any change in the entire project, which kinda defeats the purpose of generator being incremental.

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.

Possibly, but we need compilation provider, to have access to type system. Caching it might potentially lead to invalid state.
There can be a point in parsing XAML and reading x:Name metadata without type information, but it would be much more involving refactoring of the compiler.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

AFAIK, the CompilationProvider updates on every keystroke in source, so a Combine will rerun the latter portion of the pipeline on every keystroke (the entire RegisterSourceOutput in this case). This can be somewhat mitigated with frequent checking of the CancellationToken to bail out.

Normally, I gather type information from symbols during the transform part of ForAttributeWithMetadataName into an equatable model, but this is an AdditionalTextsProvider-based generator.

You could create another intermediate stage where you parse the XAML and return an equatable model containing unresolved types (fully-qualified names and ones that need additional resolution, such as a using with a group of namespaces). Then the next stage of the pipeline with CompilationProvider only needs to resolve types. Though in a large project, especially with automation, there could be thousands of named controls to resolve on keystroke. Tough problem.

@maxkatz6 maxkatz6 Jul 9, 2025

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.

Pushed changes to only update compilation instance when any dependency assembly was added or changed.

@maxkatz6 maxkatz6 Jul 9, 2025

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.

@stevemonaco just noticed your comment.
Yes, I tried to make XamlX work with unresolved types. Where I created a read-only type system containing pre-computed referenced assemblies. And treat any type as fake type, resolved after parsing on separated step.
I eventually gave up, when realized issues with conflicting XmlnsDefinition. Single XAML namespace can be mapped on multiple CLR namespaces, and XamlX can't delay this resolution until later.
I wasn't planning to refactor XamlX while making this PR.

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.

Actually, tried a bit different approach with parsing and resolving XML types first, without compilation info.
And then another step with up-to-date compilation combined used to resolve actual types.
Need to understand performance difference though.

â€Ķon should be reused between dependency changes
@avaloniaui-bot

Copy link
Copy Markdown

You can test this PR using the following package version. 12.0.999-cibuild0057630-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

@maxkatz6
maxkatz6 requested a review from kekekeks July 9, 2025 06:51
@avaloniaui-bot

Copy link
Copy Markdown

You can test this PR using the following package version. 12.0.999-cibuild0057638-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

@avaloniaui-bot

Copy link
Copy Markdown

You can test this PR using the following package version. 12.0.999-cibuild0057646-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

Comment thread src/tools/Avalonia.Generators/Common/GlobPatternGroup.cs Outdated
Comment thread src/tools/Avalonia.Generators/Common/GlobPatternGroup.cs Outdated
Comment thread src/tools/Avalonia.Generators/Common/GlobPatternGroup.cs Outdated
Comment thread src/tools/Avalonia.Generators/NameGenerator/AvaloniaNameIncrementalGenerator.cs Outdated
Comment thread src/tools/Avalonia.Generators/NameGenerator/AvaloniaNameIncrementalGenerator.cs Outdated
Comment thread src/tools/Avalonia.Generators/Common/Domain/IViewResolver.cs Outdated
@avaloniaui-bot

Copy link
Copy Markdown

You can test this PR using the following package version. 12.0.999-cibuild0057910-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

Comment thread src/tools/Avalonia.Generators/Common/XamlXNameResolver.cs
Comment thread src/tools/Avalonia.Generators/Common/XamlXViewResolver.cs
@maxkatz6
maxkatz6 requested a review from MrJul August 12, 2025 23:24
@avaloniaui-bot

Copy link
Copy Markdown

You can test this PR using the following package version. 12.0.999-cibuild0058209-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

@avaloniaui-bot

Copy link
Copy Markdown

You can test this PR using the following package version. 12.0.999-cibuild0058217-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

@MrJul MrJul 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.

LGTM!

@maxkatz6
maxkatz6 added this pull request to the merge queue Aug 13, 2025
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Aug 13, 2025
@MrJul
MrJul added this pull request to the merge queue Aug 13, 2025
Merged via the queue into master with commit fca45c1 Aug 13, 2025
12 checks passed
@MrJul
MrJul deleted the update-generators branch August 13, 2025 20:56
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.

5 participants