mirror of
https://github.com/CommunityToolkit/dotnet.git
synced 2026-10-21 14:52:21 +08:00
Merge pull request #564 from CommunityToolkit/dev/property-attribute-diagnostic
Emit diagnostic for unresolved property: attribute over [ObservableProperty] field
This commit is contained in:
@@ -48,3 +48,4 @@ Rule ID | Category | Severity | Notes
|
||||
MVVMTK0032 | CommunityToolkit.Mvvm.SourceGenerators.INotifyPropertyChangedGenerator | Warning | See https://aka.ms/mvvmtoolkit/errors/mvvmtk0032
|
||||
MVVMTK0033 | CommunityToolkit.Mvvm.SourceGenerators.ObservableObjectGenerator | Warning | See https://aka.ms/mvvmtoolkit/errors/mvvmtk0033
|
||||
MVVMTK0034 | CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator | Warning | See https://aka.ms/mvvmtoolkit/errors/mvvmtk0034
|
||||
MVVMTK0035 | CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator | Error | See https://aka.ms/mvvmtoolkit/errors/mvvmtk0035
|
||||
|
||||
+8
@@ -214,9 +214,17 @@ partial class ObservablePropertyGenerator
|
||||
// lack of IntelliSense when constructing attributes over the field, but this is the best we can do from this end anyway.
|
||||
SymbolInfo attributeSymbolInfo = semanticModel.GetSymbolInfo(attribute, token);
|
||||
|
||||
// Check if the attribute type can be resolved, and emit a diagnostic if that is not the case. This happens if eg. the
|
||||
// attribute type is spelled incorrectly, or if a user is missing the using directive for the attribute type being used.
|
||||
if ((attributeSymbolInfo.Symbol ?? attributeSymbolInfo.CandidateSymbols.SingleOrDefault()) is not ISymbol attributeSymbol ||
|
||||
(attributeSymbol as INamedTypeSymbol ?? attributeSymbol.ContainingType) is not INamedTypeSymbol attributeTypeSymbol)
|
||||
{
|
||||
builder.Add(
|
||||
InvalidPropertyTargetedAttributeOnObservablePropertyField,
|
||||
attribute,
|
||||
fieldSymbol,
|
||||
attribute.Name);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -541,7 +541,7 @@ internal static class DiagnosticDescriptors
|
||||
description:
|
||||
"Classes with no base types should prefer inheriting from ObservableObject instead of using attributes to generate INotifyPropertyChanged code, as that will " +
|
||||
"reduce the binary size of the application (the attributes are only meant to support cases where the annotated types are already inheriting from a different type).",
|
||||
helpLinkUri: "https://aka.ms/mvvmtoolkit/errors/mvvmtk0032");
|
||||
helpLinkUri: "https://aka.ms/mvvmtoolkit/errors/mvvmtk0033");
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="DiagnosticDescriptor"/> indicating when a field with <c>[ObservableProperty]</c> is being directly referenced.
|
||||
@@ -557,5 +557,21 @@ internal static class DiagnosticDescriptors
|
||||
defaultSeverity: DiagnosticSeverity.Warning,
|
||||
isEnabledByDefault: true,
|
||||
description: "Fields with [ObservableProperty] should not be directly referenced, and the generated properties should be used instead.",
|
||||
helpLinkUri: "https://aka.ms/mvvmtoolkit/errors/mvvmtk0033");
|
||||
helpLinkUri: "https://aka.ms/mvvmtoolkit/errors/mvvmtk0034");
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="DiagnosticDescriptor"/> indicating when a field with <c>[ObservableProperty]</c> is using an invalid attribute targeting the property.
|
||||
/// <para>
|
||||
/// Format: <c>"The field {0} annotated with [ObservableProperty] is using attribute "{1}" which was not recognized as a valid type (are you missing a using directive?)"</c>.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public static readonly DiagnosticDescriptor InvalidPropertyTargetedAttributeOnObservablePropertyField = new DiagnosticDescriptor(
|
||||
id: "MVVMTK0035",
|
||||
title: "Invalid property targeted attribute type",
|
||||
messageFormat: "The field {0} annotated with [ObservableProperty] is using attribute \"{1}\" which was not recognized as a valid type (are you missing a using directive?)",
|
||||
category: typeof(ObservablePropertyGenerator).FullName,
|
||||
defaultSeverity: DiagnosticSeverity.Error,
|
||||
isEnabledByDefault: true,
|
||||
description: "All attributes targeting the generated property for a field annotated with [ObservableProperty] must correctly be resolved to valid types.",
|
||||
helpLinkUri: "https://aka.ms/mvvmtoolkit/errors/mvvmtk0035");
|
||||
}
|
||||
|
||||
+50
@@ -1625,6 +1625,56 @@ public class Test_SourceGeneratorsDiagnostics
|
||||
await VerifyAnalyzerDiagnosticsAndSuccessfulGeneration<FieldReferenceForObservablePropertyFieldAnalyzer>(source, LanguageVersion.CSharp8);
|
||||
}
|
||||
|
||||
// See https://github.com/CommunityToolkit/dotnet/issues/563
|
||||
[TestMethod]
|
||||
public void InvalidPropertyTargetedAttributeOnObservablePropertyField_MissingUsingDirective()
|
||||
{
|
||||
string source = """
|
||||
using System;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace MyApp
|
||||
{
|
||||
public partial class MyViewModel : ObservableObject
|
||||
{
|
||||
[ObservableProperty]
|
||||
[property: MyTest]
|
||||
public int number;
|
||||
}
|
||||
}
|
||||
|
||||
namespace MyAttributes
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class MyTestAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
||||
""";
|
||||
|
||||
VerifyGeneratedDiagnostics<ObservablePropertyGenerator>(source, "MVVMTK0035");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void InvalidPropertyTargetedAttributeOnObservablePropertyField_TypoInAttributeName()
|
||||
{
|
||||
string source = """
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace MyApp
|
||||
{
|
||||
public partial class MyViewModel : ObservableObject
|
||||
{
|
||||
[ObservableProperty]
|
||||
[property: Fbuifbweif]
|
||||
public int number;
|
||||
}
|
||||
}
|
||||
""";
|
||||
|
||||
VerifyGeneratedDiagnostics<ObservablePropertyGenerator>(source, "MVVMTK0035");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies the diagnostic errors for a given analyzer, and that all available source generators can run successfully with the input source (including subsequent compilation).
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user