Skip to content

Commit 5f90862

Browse files
committed
Don't propagate symbols in ObservableValidatorValidateAllPropertiesGenerator
1 parent f1f3f9c commit 5f90862

File tree

1 file changed

+27
-15
lines changed

1 file changed

+27
-15
lines changed

CommunityToolkit.Mvvm.SourceGenerators/ComponentModel/ObservableValidatorValidateAllPropertiesGenerator.cs

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,31 +21,43 @@ public sealed partial class ObservableValidatorValidateAllPropertiesGenerator :
2121
/// <inheritdoc/>
2222
public void Initialize(IncrementalGeneratorInitializationContext context)
2323
{
24-
// Get all class declarations. We intentionally skip generating code for abstract types, as that would never be used.
25-
// The methods that are generated by this generator are retrieved through reflection using the type of the invoking
26-
// instance as discriminator, which means a type that is abstract could never be used (since it couldn't be instantiated).
27-
IncrementalValuesProvider<INamedTypeSymbol> typeSymbols =
24+
// Get the types that inherit from ObservableValidator and gather their info
25+
IncrementalValuesProvider<ValidationInfo> validationInfo =
2826
context.SyntaxProvider
2927
.CreateSyntaxProvider(
3028
static (node, _) => node is ClassDeclarationSyntax,
31-
static (context, _) =>
29+
static (context, token) =>
3230
{
3331
if (!context.SemanticModel.Compilation.HasLanguageVersionAtLeastEqualTo(LanguageVersion.CSharp8))
3432
{
3533
return default;
3634
}
3735

38-
return (context.Node, Symbol: (INamedTypeSymbol)context.SemanticModel.GetDeclaredSymbol(context.Node)!);
39-
})
40-
.Where(static item => item.Symbol is { IsAbstract: false, IsGenericType: false } && item.Node.IsFirstSyntaxDeclarationForSymbol(item.Symbol))
41-
.Select(static (item, _) => item.Symbol);
36+
INamedTypeSymbol typeSymbol = (INamedTypeSymbol)context.SemanticModel.GetDeclaredSymbol(context.Node, token)!;
4237

43-
// Get the types that inherit from ObservableValidator and gather their info
44-
IncrementalValuesProvider<ValidationInfo> validationInfo =
45-
typeSymbols
46-
.Where(Execute.IsObservableValidator)
47-
.Select(static (item, _) => Execute.GetInfo(item))
48-
.WithComparer(ValidationInfo.Comparer.Default);
38+
// Skip generating code for abstract types, as that would never be used. The methods that are generated by
39+
// this generator are retrieved through reflection using the type of the invoking instance as discriminator,
40+
// which means a type that is abstract could never be used (since it couldn't be instantiated).
41+
if (typeSymbol is not { IsAbstract: false, IsGenericType: false })
42+
{
43+
return default;
44+
}
45+
46+
// Just like in IMessengerRegisterAllGenerator, only select the first declaration for this type symbol
47+
if (!context.Node.IsFirstSyntaxDeclarationForSymbol(typeSymbol))
48+
{
49+
return default;
50+
}
51+
52+
// Only select types inheriting from ObservableValidator
53+
if (!Execute.IsObservableValidator(typeSymbol))
54+
{
55+
return default;
56+
}
57+
58+
return Execute.GetInfo(typeSymbol);
59+
})
60+
.Where(static item => item is not null)!;
4961

5062
// Check whether the header file is needed
5163
IncrementalValueProvider<bool> isHeaderFileNeeded =

0 commit comments

Comments
 (0)