Fix XamlC to respect ObsoleteAttribute message and isError parameter#32946
Fix XamlC to respect ObsoleteAttribute message and isError parameter#32946StephaneDelcroix merged 14 commits intonet11.0from
Conversation
There was a problem hiding this comment.
Pull request overview
This PR enhances XamlC to properly handle the ObsoleteAttribute by extracting and displaying custom messages and respecting the isError parameter to differentiate between warnings (XC0618) and errors (XC0619).
- Adds helper methods
TryGetObsoleteAttribute()andLogObsoleteWarningOrError()to extract obsolete attribute information and log appropriate diagnostics - Updates error message resources to include custom messages from
ObsoleteAttribute - Extends obsolete checking to types in addition to properties, fields, and bindable properties
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Controls/tests/Xaml.UnitTests/Issues/Maui23961Error.xaml.cs | Test code for obsolete attributes with error: true parameter |
| src/Controls/tests/Xaml.UnitTests/Issues/Maui23961Error.rt.xaml | XAML test file for obsolete error cases |
| src/Controls/tests/Xaml.UnitTests/Issues/Maui23961.xaml.cs | Test code for obsolete attributes with error: false parameter (warnings) |
| src/Controls/tests/Xaml.UnitTests/Issues/Maui23961.xaml | XAML test file for obsolete warning cases |
| src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj | Adds XC0619 to WarningsNotAsErrors to allow compilation of test files with obsolete errors |
| src/Controls/src/Build.Tasks/SetPropertiesVisitor.cs | Implements obsolete attribute extraction logic and refactors obsolete checking to use new helper methods |
| src/Controls/src/Build.Tasks/ErrorMessages.resx | Updates error messages for obsolete warnings and errors to include custom messages |
| src/Controls/src/Build.Tasks/CreateObjectVisitor.cs | Adds obsolete type checking when XAML elements are created |
| src/Controls/src/Build.Tasks/BuildException.cs | Adds XC0619 error code for obsolete errors |
| else | ||
| { | ||
| // Runtime doesn't check for obsolete at compile time | ||
| var page = new Maui23961Error(inflator); |
There was a problem hiding this comment.
The constructor call new Maui23961Error(inflator) will fail because the class only has a parameterless constructor public Maui23961Error() => InitializeComponent(); (line 14). This parameterized constructor pattern with XamlInflator is not defined for this class.
Looking at other test files, the XamlInflator parameter constructor is typically auto-generated for regular XAML files (not .rt.xaml). However, this is a .rt.xaml file (runtime-only), which means the auto-generated XamlInflator constructor won't exist.
The test logic on lines 46-56 appears to have incorrect branching. For the XamlInflator.SourceGen case, it correctly recognizes that .rt.xaml files aren't processed, but the else block (line 51-56) attempts to use a non-existent constructor.
Consider revising the test to either:
- Use the parameterless constructor:
var page = new Maui23961Error(); - Skip the runtime test path entirely for
.rt.xamlfiles since they're meant for runtime-only processing
| var page = new Maui23961Error(inflator); | |
| var page = new Maui23961Error(); |
| </data> | ||
| <data name="ObsoleteProperty" xml:space="preserve"> | ||
| <value>Property, Property setter or BindableProperty "{0}" is deprecated.</value> | ||
| <value>"{0}" is deprecated: {1}</value> |
There was a problem hiding this comment.
The error message uses "is obsolete" while the warning message uses "is deprecated". For consistency with C# compiler behavior, both should use the same terminology. The C# compiler uses "is obsolete" for both warnings (CS0618) and errors (CS0619).
Consider changing the warning message from "{0}" is deprecated: {1} to "{0}" is obsolete: {1} to match standard C# compiler terminology and maintain consistency with the error message.
| <value>"{0}" is deprecated: {1}</value> | |
| <value>"{0}" is obsolete: {1}</value> |
| } | ||
|
|
||
| if ( dataTypeNode is ElementNode enode | ||
| if (dataTypeNode is ElementNode enode |
There was a problem hiding this comment.
[nitpick] This whitespace change (removing spaces after if) is unrelated to the PR's purpose of fixing ObsoleteAttribute handling. The PR should focus only on changes directly related to the obsolete attribute functionality to keep the changes minimal and reviewable.
Consider reverting this whitespace change.
| if (dataTypeNode is ElementNode enode | |
| if ( dataTypeNode is ElementNode enode |
be916b2 to
600c3dc
Compare
d232169 to
087a2cc
Compare
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 32946Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 32946" |
e44fb8a to
65f091e
Compare
|
/azp run maui-pr-devicetests, maui-pr-uitests |
|
Azure Pipelines successfully started running 2 pipeline(s). |
fe4328a to
2578ec0
Compare
There was a problem hiding this comment.
It appears copilot messed up indentation in this file.
There was a problem hiding this comment.
It appears copilot messed up indentation in this file.
|
|
Fixes #23961 - Extract and display the custom message from ObsoleteAttribute - Respect the isError parameter: when true, emit XC0619 error instead of XC0618 warning - Add obsolete type detection for classes used in XAML - Add XC0619 (ObsoletePropertyError) for error cases - Update message format to include the attribute's message text - Add unit tests for both warning and error scenarios
Samples use obsolete types like ListView, ViewCell, etc. which now trigger XC0618 warnings. Add these codes to WarningsNotAsErrors to prevent build failures when TreatWarningsAsErrors is enabled.
The TestResultPage.xaml uses Frame which is obsolete.
The ManualTests use obsolete types like TextCell in CollectionView tests.
The test now receives AggregateException when treatWarningsAsErrors is true because both the obsolete Compatibility.StackLayout type and the binding without DataType produce errors. Updated test to use Assert.Catch and verify the expected XC0022 error is present.
- LogObsoleteWarningOrError: call LogError directly when isError=true, bypassing LogWarningOrError which ignores error semantics - Maui23961Error test: assert MockCompiler.Compile throws for [Obsolete(error: true)] - Maui23989 test: document AggregateException from multiple warnings-as-errors - HostApp csproj: preserve $(WarningsNotAsErrors) to not clobber XC0618 suppression Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Xaml.UnitTests migrated from NUnit to xUnit on net11.0. Convert Maui23961.xaml.cs and Maui23961Error.xaml.cs to use xUnit patterns: [TestFixture] → [Collection], [Test]+[Values] → [Theory]+[XamlInflatorData], [SetUp]/[TearDown] → constructor/IDisposable, Assert.That → Assert.NotNull. Also revert Maui23989.xaml.cs to net11.0 version (had NUnit remnants). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add missing Maui23961ObsoleteClass2 type referenced in Maui23961.xaml - Fix Maui23961Error test to use parameterless ctor (rt.xaml has no XamlInflator ctor) - Add comments to WarningsNotAsErrors entries clarifying XC0619 behavior Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Maui23961Error.xaml.cs: Use Assert.ThrowsAny<Exception> instead of Assert.Throws<Exception> — multiple [Obsolete(error:true)] members produce an AggregateException, not a bare Exception. ThrowsAny handles both BuildException (single error) and AggregateException (multiple). - CreateObjectVisitor.cs: Guard LogObsoleteWarningOrError behind 'typedef != null' check to prevent NullReferenceException when a type reference cannot be resolved (ResolveCached returns null in that case). - Add XC0619 explanatory comment to 5 remaining project files (TestCases.HostApp, Essentials/samples, ProfiledAot, DeviceTests.Runners, ManualTests) for consistency with the other 2 files already commented. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Guard propertySetter.CustomAttributes against NRE when SetMethod is null in Set(): CanSet() already gates this path, but the guard makes Set() safe to call defensively if that invariant ever changes. - Document that XC0619 intentionally bypasses <NoWarn>, matching C# CS0619 behavior: obsolete-as-error cannot be suppressed, users must remove usage. - Document dual obsolete check: property declaration and setter are each checked separately, so both carrying [Obsolete] emits two diagnostics (matching C# compiler behavior). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The PR's new ObsoleteAttribute handling in XamlC now correctly emits XC0618 when XAML uses deprecated types. Maui23989.xaml was using Compatibility.StackLayout which carries [Obsolete], causing XC0618 to be emitted alongside XC0022. With treatWarningsAsErrors:true, both errors wrapped in AggregateException instead of the expected single BuildException, failing the test. Replace <cmp:StackLayout> with the standard <StackLayout> so XamlC only sees the expected XC0022 warning in the test scenario. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Change XC0618 message from 'deprecated' to 'obsolete' to match C# CS0618 - Add MockCompiler.Compile overload that exposes logged warnings - Assert ObsoleteWarningIncludesMessage verifies custom message text is present - Assert ObsoleteErrorProducesCompilationError verifies XC0619 code in exception Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… number - Add StringComparison.Ordinal to string.Contains and Assert.Contains calls to satisfy CA1307 analyzer rule - Update Maui23989 expected error line from 12 to 11 after removing the cmp:StackLayout namespace prefix line from the XAML Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
a57ab80 to
a17d19a
Compare
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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
Fixes #23961
This PR fixes XamlC to properly handle the
ObsoleteAttributeby:[Obsolete("message")]instead of a generic deprecation messageisErrorparameter - when[Obsolete("message", error: true)]is used, XamlC now emits an error (XC0619) instead of a warning (XC0618)[Obsolete]when used in XAMLChanges
ErrorMessages.resx: UpdatedObsoletePropertymessage format to include the custom message:"{0}" is deprecated: {1}BuildException.cs: AddedXC0619(ObsoletePropertyError) for error cases whenisError=trueSetPropertiesVisitor.cs:TryGetObsoleteAttribute()helper to extract message and isError from the attributeLogObsoleteWarningOrError()helper that logs the appropriate warning or error based on the attributeCreateObjectVisitor.cs: Added obsolete type detection when XAML elements are createdBefore
After
Testing
Maui23961.xaml/.cs- tests for warnings witherror: falseMaui23961Error.rt.xaml/.cs- tests for errors witherror: true