Skip to content

Commit 1e1ba01

Browse files
committed
Use ForAttributeWithMetadataName whenever possible
1 parent 3bb80e7 commit 1e1ba01

File tree

8 files changed

+51
-36
lines changed

8 files changed

+51
-36
lines changed

CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/INotifyPropertyChangedGenerator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public sealed class INotifyPropertyChangedGenerator : TransitiveMembersGenerator
2323
/// Initializes a new instance of the <see cref="INotifyPropertyChangedGenerator"/> class.
2424
/// </summary>
2525
public INotifyPropertyChangedGenerator()
26-
: base("global::CommunityToolkit.Mvvm.ComponentModel.INotifyPropertyChangedAttribute")
26+
: base("CommunityToolkit.Mvvm.ComponentModel.INotifyPropertyChangedAttribute")
2727
{
2828
}
2929

CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservableObjectGenerator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public sealed class ObservableObjectGenerator : TransitiveMembersGenerator<objec
2222
/// Initializes a new instance of the <see cref="ObservableObjectGenerator"/> class.
2323
/// </summary>
2424
public ObservableObjectGenerator()
25-
: base("global::CommunityToolkit.Mvvm.ComponentModel.ObservableObjectAttribute")
25+
: base("CommunityToolkit.Mvvm.ComponentModel.ObservableObjectAttribute")
2626
{
2727
}
2828

CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservablePropertyGenerator.cs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
2727
// Gather info for all annotated fields
2828
IncrementalValuesProvider<(HierarchyInfo Hierarchy, Result<PropertyInfo?> Info)> propertyInfoWithErrors =
2929
context.SyntaxProvider
30-
.CreateSyntaxProvider(
30+
.ForAttributeWithMetadataName(
31+
"CommunityToolkit.Mvvm.ComponentModel.ObservablePropertyAttribute",
3132
static (node, _) => node is VariableDeclaratorSyntax { Parent: VariableDeclarationSyntax { Parent: FieldDeclarationSyntax { Parent: ClassDeclarationSyntax or RecordDeclarationSyntax, AttributeLists.Count: > 0 } } },
3233
static (context, token) =>
3334
{
@@ -36,13 +37,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
3637
return default;
3738
}
3839

39-
IFieldSymbol fieldSymbol = (IFieldSymbol)context.SemanticModel.GetDeclaredSymbol(context.Node, token)!;
40-
41-
// Filter the fields using [ObservableProperty]
42-
if (!fieldSymbol.HasAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.ComponentModel.ObservablePropertyAttribute"))
43-
{
44-
return default;
45-
}
40+
IFieldSymbol fieldSymbol = (IFieldSymbol)context.TargetSymbol;
4641

4742
// Produce the incremental models
4843
HierarchyInfo hierarchy = HierarchyInfo.From(fieldSymbol.ContainingType);

CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservableRecipientGenerator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public sealed class ObservableRecipientGenerator : TransitiveMembersGenerator<Ob
2525
/// Initializes a new instance of the <see cref="ObservableRecipientGenerator"/> class.
2626
/// </summary>
2727
public ObservableRecipientGenerator()
28-
: base("global::CommunityToolkit.Mvvm.ComponentModel.ObservableRecipientAttribute")
28+
: base("CommunityToolkit.Mvvm.ComponentModel.ObservableRecipientAttribute")
2929
{
3030
}
3131

CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/TransitiveMembersGenerator.cs

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ namespace CommunityToolkit.Mvvm.SourceGenerators;
2121
public abstract partial class TransitiveMembersGenerator<TInfo> : IIncrementalGenerator
2222
{
2323
/// <summary>
24-
/// The fully qualified name of the attribute type to look for.
24+
/// The fully qualified metadata name of the attribute type to look for.
2525
/// </summary>
26-
private readonly string attributeType;
26+
private readonly string fullyQualifiedAttributeMetadataName;
2727

2828
/// <summary>
2929
/// An <see cref="IEqualityComparer{T}"/> instance to compare intermediate models.
@@ -51,13 +51,13 @@ public abstract partial class TransitiveMembersGenerator<TInfo> : IIncrementalGe
5151
/// <summary>
5252
/// Initializes a new instance of the <see cref="TransitiveMembersGenerator{TInfo}"/> class.
5353
/// </summary>
54-
/// <param name="attributeType">The fully qualified name of the attribute type to look for.</param>
54+
/// <param name="fullyQualifiedAttributeMetadataName">The fully qualified metadata name of the attribute type to look for.</param>
5555
/// <param name="comparer">An <see cref="IEqualityComparer{T}"/> instance to compare intermediate models.</param>
56-
private protected TransitiveMembersGenerator(string attributeType, IEqualityComparer<TInfo>? comparer = null)
56+
private protected TransitiveMembersGenerator(string fullyQualifiedAttributeMetadataName, IEqualityComparer<TInfo>? comparer = null)
5757
{
58-
this.attributeType = attributeType;
58+
this.fullyQualifiedAttributeMetadataName = fullyQualifiedAttributeMetadataName;
5959
this.comparer = comparer ?? EqualityComparer<TInfo>.Default;
60-
this.classDeclaration = Execute.LoadClassDeclaration(attributeType);
60+
this.classDeclaration = Execute.LoadClassDeclaration(fullyQualifiedAttributeMetadataName);
6161

6262
Execute.ProcessMemberDeclarations(
6363
GetType(),
@@ -72,25 +72,20 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
7272
// Gather all generation info, and any diagnostics
7373
IncrementalValuesProvider<Result<(HierarchyInfo Hierarchy, bool IsSealed, TInfo? Info)>> generationInfoWithErrors =
7474
context.SyntaxProvider
75-
.CreateSyntaxProvider(
76-
static (node, _) => node is ClassDeclarationSyntax { AttributeLists.Count: > 0 },
75+
.ForAttributeWithMetadataName(
76+
this.fullyQualifiedAttributeMetadataName,
77+
static (node, _) => node is ClassDeclarationSyntax classDeclaration && classDeclaration.HasOrPotentiallyHasAttributes(),
7778
(context, token) =>
7879
{
7980
if (!context.SemanticModel.Compilation.HasLanguageVersionAtLeastEqualTo(LanguageVersion.CSharp8))
8081
{
8182
return default;
8283
}
8384

84-
INamedTypeSymbol typeSymbol = (INamedTypeSymbol)context.SemanticModel.GetDeclaredSymbol(context.Node, token)!;
85-
86-
// Filter the types with the target attribute
87-
if (!typeSymbol.TryGetAttributeWithFullyQualifiedName(this.attributeType, out AttributeData? attributeData))
88-
{
89-
return default;
90-
}
85+
INamedTypeSymbol typeSymbol = (INamedTypeSymbol)context.TargetSymbol;
9186

9287
// Gather all generation info, and any diagnostics
93-
TInfo? info = ValidateTargetTypeAndGetInfo(typeSymbol, attributeData, context.SemanticModel.Compilation, out ImmutableArray<Diagnostic> diagnostics);
88+
TInfo? info = ValidateTargetTypeAndGetInfo(typeSymbol, context.Attributes[0], context.SemanticModel.Compilation, out ImmutableArray<Diagnostic> diagnostics);
9489

9590
// If there are any diagnostics, there's no need to compute the hierarchy info at all, just return them
9691
if (diagnostics.Length > 0)

CommunityToolkit.Mvvm.SourceGenerators/Extensions/ISymbolExtensions.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
// See the LICENSE file in the project root for more information.
44

55
using System.Collections.Immutable;
6+
#if !ROSLYN_4_3
67
using System.Diagnostics.CodeAnalysis;
8+
#endif
79
using Microsoft.CodeAnalysis;
810

911
namespace CommunityToolkit.Mvvm.SourceGenerators.Extensions;
@@ -65,6 +67,7 @@ public static bool HasAttributeWithFullyQualifiedName(this ISymbol symbol, strin
6567
return false;
6668
}
6769

70+
#if !ROSLYN_4_3
6871
/// <summary>
6972
/// Tries to get an attribute with the specified full name.
7073
/// </summary>
@@ -90,6 +93,7 @@ public static bool TryGetAttributeWithFullyQualifiedName(this ISymbol symbol, st
9093

9194
return false;
9295
}
96+
#endif
9397

9498
/// <summary>
9599
/// Calculates the effective accessibility for a given symbol.

CommunityToolkit.Mvvm.SourceGenerators/Extensions/TypeDeclarationSyntaxExtensions.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,30 @@ public static bool HasOrPotentiallyHasBaseTypes(this TypeDeclarationSyntax typeD
3838

3939
return false;
4040
}
41+
42+
/// <summary>
43+
/// Checks whether a given <see cref="TypeDeclarationSyntax"/> has or could possibly have any attributes, using only syntax.
44+
/// </summary>
45+
/// <param name="typeDeclaration">The input <see cref="TypeDeclarationSyntax"/> instance to check.</param>
46+
/// <returns>Whether <paramref name="typeDeclaration"/> has or could possibly have any attributes.</returns>
47+
public static bool HasOrPotentiallyHasAttributes(this TypeDeclarationSyntax typeDeclaration)
48+
{
49+
// If the type has any attributes lists, then clearly it can have attributes
50+
if (typeDeclaration.AttributeLists.Count > 0)
51+
{
52+
return true;
53+
}
54+
55+
// If the declaration has no attribute lists, check if the type is partial. If it is, it means
56+
// that there could be another partial declaration with some attribute lists over them.
57+
foreach (SyntaxToken modifier in typeDeclaration.Modifiers)
58+
{
59+
if (modifier.IsKind(SyntaxKind.PartialKeyword))
60+
{
61+
return true;
62+
}
63+
}
64+
65+
return false;
66+
}
4167
}

CommunityToolkit.Mvvm.SourceGenerators/Input/RelayCommandGenerator.cs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
2626
// Gather info for all annotated command methods (starting from method declarations with at least one attribute)
2727
IncrementalValuesProvider<(HierarchyInfo Hierarchy, Result<CommandInfo?> Info)> commandInfoWithErrors =
2828
context.SyntaxProvider
29-
.CreateSyntaxProvider(
29+
.ForAttributeWithMetadataName(
30+
"CommunityToolkit.Mvvm.Input.RelayCommandAttribute",
3031
static (node, _) => node is MethodDeclarationSyntax { Parent: ClassDeclarationSyntax, AttributeLists.Count: > 0 },
3132
static (context, token) =>
3233
{
@@ -35,17 +36,11 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
3536
return default;
3637
}
3738

38-
IMethodSymbol methodSymbol = (IMethodSymbol)context.SemanticModel.GetDeclaredSymbol(context.Node, token)!;
39-
40-
// Filter the methods using [RelayCommand]
41-
if (!methodSymbol.TryGetAttributeWithFullyQualifiedName("global::CommunityToolkit.Mvvm.Input.RelayCommandAttribute", out AttributeData? attribute))
42-
{
43-
return default;
44-
}
39+
IMethodSymbol methodSymbol = (IMethodSymbol)context.TargetSymbol;
4540

4641
// Produce the incremental models
4742
HierarchyInfo hierarchy = HierarchyInfo.From(methodSymbol.ContainingType);
48-
CommandInfo? commandInfo = Execute.GetInfo(methodSymbol, attribute, out ImmutableArray<Diagnostic> diagnostics);
43+
CommandInfo? commandInfo = Execute.GetInfo(methodSymbol, context.Attributes[0], out ImmutableArray<Diagnostic> diagnostics);
4944

5045
return (Hierarchy: hierarchy, new Result<CommandInfo?>(commandInfo, diagnostics));
5146
})

0 commit comments

Comments
 (0)