Add [GeneratedCustomPropertyProvider] generator and analyzers#2160
Merged
Sergio0694 merged 100 commits intostaging/3.0from Mar 16, 2026
Merged
Add [GeneratedCustomPropertyProvider] generator and analyzers#2160Sergio0694 merged 100 commits intostaging/3.0from
[GeneratedCustomPropertyProvider] generator and analyzers#2160Sergio0694 merged 100 commits intostaging/3.0from
Conversation
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 38 out of 38 changed files in this pull request and generated 8 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
manodasanW
reviewed
Jan 10, 2026
manodasanW
reviewed
Jan 11, 2026
manodasanW
reviewed
Jan 11, 2026
03b0d31 to
4aea9d1
Compare
232eb11 to
a48ddc5
Compare
0027c3a to
1ee568d
Compare
090c57a to
76285ec
Compare
manodasanW
reviewed
Mar 14, 2026
manodasanW
reviewed
Mar 14, 2026
manodasanW
reviewed
Mar 14, 2026
manodasanW
reviewed
Mar 14, 2026
manodasanW
approved these changes
Mar 14, 2026
Introduces the GeneratedCustomPropertyProviderAttribute for marking bindable properties in XAML scenarios. Supports specifying property names and indexer types for binding code generation via ICustomPropertyProvider interfaces.
Introduces a new SyntaxExtensions class providing extension methods for SyntaxNode and SyntaxTokenList. These methods allow checking if a node or token list matches any of the specified SyntaxKind values, improving code readability and reuse in Roslyn-based source generators.
Introduces IncrementalGeneratorInitializationContextExtensions with a method to combine attribute-based syntax analysis and analyzer config options. Also adds a struct to encapsulate both GeneratorAttributeSyntaxContext and AnalyzerConfigOptions for use in source generators.
Introduce GeneratedCustomPropertyProviderExistingMemberImplementationAnalyzer to detect when [GeneratedCustomPropertyProvider] is applied to a type that already has or inherits implementations for ICustomPropertyProvider members (checks both Windows.UI.Xaml and Microsoft.UI.Xaml). Add a new diagnostic descriptor (CSWINRT2003) describing the error and update AnalyzerReleases.Shipped.md to include the new rule. This prevents the generator from producing duplicate member implementations on annotated types. Co-Authored-By: Copilot <223556219+Copilot@users.noreply.github.com>
Add Test_GeneratedCustomPropertyProviderExistingMemberImplementationAnalyzer.cs containing unit tests for GeneratedCustomPropertyProviderExistingMemberImplementationAnalyzer. Tests cover class/struct declarations, cases with no interface or no members (no warnings), explicit and implicit ICustomPropertyProvider implementations (complete and incomplete), and inherited implementations; they verify CSWINRT2003 warnings are produced where appropriate. Co-Authored-By: Copilot <223556219+Copilot@users.noreply.github.com>
Add an optional ReadOnlySpan<DiagnosticResult> expectedDiagnostics parameter to CSharpAnalyzerTest.VerifyAnalyzerAsync and forward its contents into TestState.ExpectedDiagnostics so tests can supply expected diagnostics programmatically. Update tests to import Microsoft.CodeAnalysis.Testing, add a VerifyCS alias, and pass explicit expected diagnostic arrays for the analyzer cases. Also simplify one parameterized test to a single-class case and adjust using/imports accordingly.
Add comprehensive .editorconfig files for Authoring/WinRT.SourceGenerator2 and Tests/SourceGenerator2Test to enforce consistent C# formatting and .NET coding conventions (indentation, naming, spacing, wrapping, and other rules). Also normalize file endings/EOF presence in several source files (GeneratedCustomPropertyProviderExistingMemberImplementationAnalyzer.cs, IncrementalGeneratorInitializationContextExtensions.cs, IncrementalValuesProviderExtensions.cs, CustomPropertyInfo.cs) — these are non-functional formatting changes to ensure consistent repository style.
Fix three missing semicolons in generated 'using' directives (CodeDom.Compiler, Diagnostics, Diagnostics.CodeAnalysis) and fix the switch expression closing brace to emit '};' instead of '}' by replacing WriteBlock with manual indent management. Also update all corresponding expected outputs in the unit tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The generator was unconditionally emitting property access code in GetValue/SetValue/GetIndexedValue/SetIndexedValue regardless of whether the property supported that operation. This caused CS0200 errors when a read-only property's generated SetValue tried to assign to it. Now, when CanRead is false, GetValue/GetIndexedValue emit 'throw new NotSupportedException()' instead of the property/indexer access. Likewise for CanWrite being false with SetValue/SetIndexedValue. Updated expected outputs in ReadOnlyProperty, WriteOnlyProperty and ReadOnlyIndexer unit tests. Co-Authored-By: Copilot <223556219+Copilot@users.noreply.github.com>
…mbers Call WriteGeneratedAttributes with includeNonUserCodeAttributes: false on each of the four generated explicit interface implementations (Type, GetCustomProperty, GetIndexedProperty, GetStringRepresentation). This annotates them with [GeneratedCode] so the analyzer can distinguish generated implementations from user-authored ones. Updated all expected outputs in unit tests accordingly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The analyzer was incorrectly firing for types using
[GeneratedCustomPropertyProvider] because it detected the interface
member implementations produced by the generator itself. Now
HasAnyImplementedMembersForInterface accepts an optional
GeneratedCodeAttribute type and generator name: implementations
annotated with [GeneratedCode("CustomPropertyProviderGenerator", ...)]
are excluded from the check.
Also removed the unnecessary explicit ': ICustomPropertyProvider' from
TestCustomPropertyProvider in the functional tests (the generator adds
it via the partial class).
Added two new analyzer tests:
- TypeWithGeneratedExplicitInterfaceImplementation_DoesNotWarn
- TypeWithMixedGeneratedAndUserImplementation_Warns
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Split the monolithic HasAnyImplementedMembersForInterface into: - EnumerateImplementedMembersForInterface: enumerates all implemented members - HasAnyImplementedMembersForInterface: simplified to delegate to the enumerator - AreAllImplementedByGenerator: checks if all symbols in a sequence are generated Update the analyzer to use AreAllImplementedByGenerator, so it no longer warns when all interface member implementations are produced by our generator. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Improve detection of generated ICustomPropertyProvider implementations and simplify attribute handling. Make GeneratedCodeAttribute resolution non-nullable and add HasNonGeneratedImplementedMembers helper to centralize logic for checking implemented interface members that were not emitted by this generator. Simplify attribute checks in ISymbolExtensions by using TryGetAttributeWithType and validating the constructor argument, and replace manual loop with LINQ.Any in ITypeSymbolExtensions (added System.Linq). Removes duplicate/nullable checks and streamlines the analyzer to avoid false diagnostics for generator-emitted members.
Add 5 new diagnostic descriptors (CSWINRT2004-CSWINRT2008) for validating [GeneratedCustomPropertyProvider] attribute arguments: - CSWINRT2004: Null property name - CSWINRT2005: Null indexer type - CSWINRT2006: Property name not found - CSWINRT2007: Indexer type not found - CSWINRT2008: Static indexer not supported Also update AnalyzerReleases.Unshipped.md with the new rules. Co-Authored-By: Copilot <223556219+Copilot@users.noreply.github.com>
Add GeneratedCustomPropertyProviderAttributeArgumentAnalyzer that validates the explicit property names and indexer types passed to the attribute constructor, replicating the filtering logic from the generator: - Reports CSWINRT2004 for null property names in the array - Reports CSWINRT2005 for null indexer types in the array - Reports CSWINRT2006 when a property name doesn't match any accessible public, non-override, non-indexer property on the type - Reports CSWINRT2007 when an indexer type doesn't match any accessible public, non-override, non-static, single-parameter indexer - Reports CSWINRT2008 when the matching indexer is static Co-Authored-By: Copilot <223556219+Copilot@users.noreply.github.com>
Add comprehensive test coverage for GeneratedCustomPropertyProviderAttributeArgumentAnalyzer with 20 test cases covering all 5 diagnostics: No-warning cases (10): - Default constructor, empty arrays, valid names/types - Inherited members, multiple valid names, overridden properties CSWINRT2004 - Null property name (2): - Single null, null among valid names CSWINRT2005 - Null indexer type (2): - Single null, null among valid types CSWINRT2006 - Property name not found (3): - Missing name, private property, multiple missing names CSWINRT2007 - Indexer type not found (4): - Wrong type, no indexer, multi-parameter indexer, multiple missing Combined (1): - Mixed invalid arguments reports all applicable diagnostics Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Make detection of generator-produced members more robust. Return false early when the interface type is null and collect implemented members to ensure at least one exists before treating them as "all generated". Enhance AreAllImplementedByGenerator to handle accessor methods by moving to the associated property and to walk parent symbols to find a [GeneratedCode] attribute on the closest containing symbol; also tighten the attribute pattern check and return false for empty symbol sets. These changes prevent false positives when members are inherited/implemented but not actually produced by the generator.
Add a conditional PropertyGroup in src/Tests/FunctionalTests/Directory.Build.props that sets CsWinRTUseWindowsUIXamlProjections to false when it is not already defined, preventing the feature switch below from being considered invalid. Also normalize whitespace in a commented CsWinRTKeepGeneratedSources line in src/Tests/AuthoringWuxTest/AuthoringWuxTest.csproj (formatting-only change).
Add a :sourcegenerator2test block to build.cmd that runs the SourceGenerator2Test project via dotnet test, following the same pattern as the existing :sourcegeneratortest block. Includes platform parameter since the project requires x64/x86. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Update WinRT.SourceGenerator2/.editorconfig to use LF line endings (copy of root file with CRLF replaced by LF) so generated sources use consistent LF endings (helps with multiline string literals and formatting). Remove redundant .editorconfig from Tests/SourceGenerator2Test.
Add GetCsWinRTUseWindowsUIXamlProjections extension to AnalyzerConfigOptionsExtensions and update CustomPropertyProviderGenerator to use it instead of calling GetBooleanProperty directly. This centralizes retrieval of the "CsWinRTUseWindowsUIXamlProjections" analyzer/MSBuild option and keeps option access consistent across the codebase.
Update DiagnosticDescriptors.cs message to suggest referencing 'Microsoft.WindowsAppSDK.WinUI' instead of 'WindowsAppSDK.WinUI', so the diagnostic points users to the correct package/namespace to resolve the missing ICustomPropertyProvider interface.
Update CSharpGeneratorTest to normalize expected text line endings by replacing CRLF with LF when constructing expectedText. Added a comment explaining the change so test files won't fail due to platform line ending differences; assembly version replacement remains unchanged.
Remove the local .editorconfig and normalize generated source line endings to LF. Trim trailing '\r' when splitting lines in IndentedTextWriter so emitted text uses LF regardless of repo CRLF. Mark multi-line string writes in source generators (AuthoringExportTypesGenerator, TypeMapAssemblyTargetGenerator) with isMultiline: true to preserve raw multiline literal formatting and avoid extra indentation/whitespace in generated outputs.
Replace direct assignments to global::MyNamespace.MyClass.Name with throwing NotSupportedException in the generated SetValue implementations (two occurrences). This prevents the generated property provider from attempting to set the property value.
c8cd9e0 to
56fc294
Compare
Delete the temporary -include for Windows.UI.Xaml.Markup.ContentPropertyAttribute from src/Projections/WinAppSDK/WinAppSDK.csproj. This removes an unnecessary/manual projection include now that the corresponding types are provided elsewhere, cleaning up the project file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Title. This doesn't need any special casing at all in CsWinRT 3.0, thanks to 'cswinrtgen'.