KEMBAR78
Source Generator for XAML by StephaneDelcroix · Pull Request #30442 · dotnet/maui · GitHub
Skip to content

Conversation

StephaneDelcroix
Copy link
Contributor

@StephaneDelcroix StephaneDelcroix commented Jul 4, 2025

Note

Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!

Description of Change

This is Xaml Source generation. After Runtime, and XamlC, SourceGen is a third Xaml Inflator for MAUI.

Runtime inflation is used in Debug scenario cause it doesn't slow down the devloop, and is easily instrumented. Most of the tooling for VS depend on diagnostic generated only by the runtime inflation. But it is also quite slow at runtime, use reflection to find and create types and set properties and prevents AOT scenarios

XAMLC inflation is used for Release, and replace all the XAML by the equivalent IL. it takes a handfull of seconds as is rewrites assemblies but it's as fast as possible while running. The downside is that it's hard to maintain, hard to evolve, hard to debug, and it's hard to reflect about the code generated.

SourceGen inflation, the new one, will eventually replace both.
As it generates C# before the compilation, the devloop impact is barely noticeable. It's easy to instrument, it produces code as fast as XamlC does (and is already faster in some cases), it's easy to debug (it's C#), the output is easy to read, easy to reason about.

And as a bonus it'll allow MAUI to innovate with XAML again.

The plan is to merge this soonish in net10.0 and keep the feature behind a feature flag. It is important to review the areas that were modified but that do not pertain to sourcegen, to ensure we do not regress anything in net10.0

This is unfinished work, in terms of feature (still a few unsupported scenarios), and code quality (FIXME here and there, error reporting, extensibility points, etc) but the branch is too large to be maintained on it's own, it's too expensive to merge or rebase.

how to use

grab the nugets from the artefacts, use them in a projects, enable preview features, and decorate your code behind type with [XamlProcessing(XamlInflator.SourceGen)]

Fixes

@Copilot Copilot AI review requested due to automatic review settings July 4, 2025 19:19
@StephaneDelcroix StephaneDelcroix requested a review from a team as a code owner July 4, 2025 19:19
@StephaneDelcroix StephaneDelcroix requested review from mattleibow and rmarinho and removed request for Copilot July 4, 2025 19:19
Copilot

This comment was marked as outdated.

jfversluis
jfversluis previously approved these changes Jul 4, 2025
@StephaneDelcroix StephaneDelcroix requested a review from Copilot July 4, 2025 19:30
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR integrates a new XAML source generator, standardizing XAML inflation across Debug and Release builds, replacing legacy overloads, and updating tests to target multiple inflators (Runtime, XamlC, SourceGen).

  • Added [XamlProcessing] attributes to pages to control which inflate modes apply, and removed old bool useCompiledXaml overloads in favor of a single-parameter constructor.
  • Refactored tests to use [Values] XamlInflator instead of boolean [TestCase], with branches covering Runtime, XamlC, and SourceGen.
  • Updated test helpers (XamlInflatorRuntimeTestsHelpers) and test assertions to verify generated code and diagnostics for each inflate mode.

Reviewed Changes

Copilot reviewed 272 out of 514 changed files in this pull request and generated 1 comment.

File Description
src/Controls/tests/Xaml.UnitTests/Issues/Gh3512.xaml.cs Test updated to cover SourceGen diagnostics branch
src/Controls/tests/Xaml.UnitTests/InflatorSwitch/XamlInflatorSourceGen.xaml.cs Added source-gen-specific inflator test
src/Controls/tests/Xaml.UnitTests/InflatorSwitch/XamlInflatorRuntimeTestsHelpers.cs Introduced test helper for verifying inflate-specific IL sizes
Files not reviewed (2)
  • src/Controls/src/SourceGen/MauiGResources.Designer.cs: Language not supported
  • src/Controls/src/SourceGen/xlf/MauiGResources.Designer.cs: Language not supported
Comments suppressed due to low confidence (2)

src/Controls/tests/Xaml.UnitTests/Issues/Bz60575.xaml.cs:25

  • After generating with MockSourceGenerator, add an assertion on result.Diagnostics (e.g., Assert.That(result.Diagnostics, Is.Empty)) to ensure SourceGen produces no unexpected diagnostics.
{

src/Controls/tests/Xaml.UnitTests/InflatorSwitch/XamlInflatorRuntimeTestsHelpers.cs:17

  • The GetConstructor([typeof(XamlInflator)]) syntax is invalid. Use an array initializer: GetConstructor(new[] { typeof(XamlInflator) }).
			Assert.IsNotNull(type.GetConstructor([typeof(XamlInflator)]), $"{type.Name} should have InitializeComponent method with XamlInflator argument");

@StephaneDelcroix
Copy link
Contributor Author

see #30489

@StephaneDelcroix StephaneDelcroix force-pushed the XamlSourceGen branch 11 times, most recently from c5991e6 to ad330c5 Compare July 16, 2025 20:09
@StephaneDelcroix StephaneDelcroix force-pushed the XamlSourceGen branch 5 times, most recently from ff3fe7f to 074aa42 Compare July 18, 2025 05:01
@StephaneDelcroix StephaneDelcroix force-pushed the XamlSourceGen branch 2 times, most recently from 3b477b4 to c42b1f1 Compare July 23, 2025 08:48
|| x.ExternalReferences.Length != y.ExternalReferences.Length)
return false;

return x.ExternalReferences.OfType<PortableExecutableReference>().SequenceEqual(y.ExternalReferences.OfType<PortableExecutableReference>());
Copy link
Member

Choose a reason for hiding this comment

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

Are the external references always in the same order?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

adding a comment to look at that

@rmarinho rmarinho added this to the .NET 10.0-preview7 milestone Jul 23, 2025
@rmarinho rmarinho added area-xaml XAML, CSS, Triggers, Behaviors p/0 Work that we can't release without labels Jul 23, 2025
@rmarinho rmarinho moved this from Todo to Ready To Review in MAUI SDK Ongoing Jul 23, 2025
simonrozsival
simonrozsival previously approved these changes Jul 24, 2025
simonrozsival
simonrozsival previously approved these changes Jul 25, 2025
This is Xaml Source generation. After Runtime, and XamlC, SourceGen is a
third Xaml Inflator for MAUI.

Runtime inflation is used in Debug scenario cause it doesn't slow down
the devloop, and is easily instrumented. Most of the toolin for VS
depend on diagnostic generated only by the runtime inflation. But it is
also quite slow at runtime, use reflection to find and create types and
set properties and prevents AOT scenarios

XAMLC inflation is used for Release, and replace all the XAML by the
equivalent IL. it takes a handfull of seconds as is rewrites assemblies
but it's as fast as possible while running. The downside is that it's
hard to maintain, hard to evolve, hard to debug, and it's hard to
reflect about the code generated.

SourceGen inflation, the new one, will eventually replace both.
As it generates C# before the compilation, the devloop impact is barely
noticeable. It's easy to instrument, it produces code as fast as XamlC
does, it's easy to debug (it's C#), the output is easy ot read, easy to
reason about.

And as a bonus it'll allow MAUI to innovate with XAML again.
Copy link
Member

@PureWeen PureWeen left a comment

Choose a reason for hiding this comment

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

This is awesome! I tested our developer balance template and the performance is night and day in debug mode!

Without Source Gen

Untitled.mov

With Source Gen

Screen.Recording.2025-07-25.at.5.06.01.PM.mov

The testing here looks to maintain pre-source gen validation so we're good to merge for preview7 and then get as much feedback as we can.

The one issue I ran into with the developer balance template was the following error in the source gen

public class ChipDataTemplateSelector : DataTemplateSelector

This gave me the following error
image

If I change these to nullable it works

public class ChipDataTemplateSelector : DataTemplateSelector
{
	public DataTemplate? SelectedTagTemplate { get; set; }
	public DataTemplate? NormalTagTemplate { get; set; }

	protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
	{
		var isSelected = (item as Tag)?.IsSelected ?? false;
		return isSelected ? (SelectedTagTemplate ?? new DataTemplate()) : (NormalTagTemplate ?? new DataTemplate());
	}
}

These are specified on the XAML so I'm assuming they should be generating ?

image

@github-project-automation github-project-automation bot moved this from Ready To Review to Approved in MAUI SDK Ongoing Jul 25, 2025
@StephaneDelcroix StephaneDelcroix merged commit af05922 into net10.0 Jul 26, 2025
130 checks passed
@StephaneDelcroix StephaneDelcroix deleted the XamlSourceGen branch July 26, 2025 06:53
@github-project-automation github-project-automation bot moved this from Approved to Done in MAUI SDK Ongoing Jul 26, 2025
@MartyIX
Copy link
Contributor

MartyIX commented Jul 26, 2025

This is awesome! I tested our developer balance template and the performance is night and day in debug mode!

@StephaneDelcroix Could you please just explain what's the cause of the speedup? Will we see similar speedup on Windows as well?

@StephaneDelcroix
Copy link
Contributor Author

@MartyIX you'll see shortened devloop, speedup on Debug, and Release should be faster as well but not by the same factor.

with this (disabled by default for the time being), Xaml. inflation on Debug builds no longer uses reflection, causing the speedup

@github-actions github-actions bot locked and limited conversation to collaborators Aug 26, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-xaml XAML, CSS, Triggers, Behaviors p/0 Work that we can't release without

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

7 participants