Skip to content

Commit

Permalink
Don't propagate symbols in ObservableValidatorValidateAllPropertiesGe…
Browse files Browse the repository at this point in the history
…nerator
  • Loading branch information
Sergio0694 committed Sep 10, 2022
1 parent f1f3f9c commit 5f90862
Showing 1 changed file with 27 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,31 +21,43 @@ public sealed partial class ObservableValidatorValidateAllPropertiesGenerator :
/// <inheritdoc/>
public void Initialize(IncrementalGeneratorInitializationContext context)
{
// Get all class declarations. We intentionally skip generating code for abstract types, as that would never be used.
// The methods that are generated by this generator are retrieved through reflection using the type of the invoking
// instance as discriminator, which means a type that is abstract could never be used (since it couldn't be instantiated).
IncrementalValuesProvider<INamedTypeSymbol> typeSymbols =
// Get the types that inherit from ObservableValidator and gather their info
IncrementalValuesProvider<ValidationInfo> validationInfo =
context.SyntaxProvider
.CreateSyntaxProvider(
static (node, _) => node is ClassDeclarationSyntax,
static (context, _) =>
static (context, token) =>
{
if (!context.SemanticModel.Compilation.HasLanguageVersionAtLeastEqualTo(LanguageVersion.CSharp8))
{
return default;
}

return (context.Node, Symbol: (INamedTypeSymbol)context.SemanticModel.GetDeclaredSymbol(context.Node)!);
})
.Where(static item => item.Symbol is { IsAbstract: false, IsGenericType: false } && item.Node.IsFirstSyntaxDeclarationForSymbol(item.Symbol))
.Select(static (item, _) => item.Symbol);
INamedTypeSymbol typeSymbol = (INamedTypeSymbol)context.SemanticModel.GetDeclaredSymbol(context.Node, token)!;

// Get the types that inherit from ObservableValidator and gather their info
IncrementalValuesProvider<ValidationInfo> validationInfo =
typeSymbols
.Where(Execute.IsObservableValidator)
.Select(static (item, _) => Execute.GetInfo(item))
.WithComparer(ValidationInfo.Comparer.Default);
// Skip generating code for abstract types, as that would never be used. The methods that are generated by
// this generator are retrieved through reflection using the type of the invoking instance as discriminator,
// which means a type that is abstract could never be used (since it couldn't be instantiated).
if (typeSymbol is not { IsAbstract: false, IsGenericType: false })
{
return default;
}

// Just like in IMessengerRegisterAllGenerator, only select the first declaration for this type symbol
if (!context.Node.IsFirstSyntaxDeclarationForSymbol(typeSymbol))
{
return default;
}

// Only select types inheriting from ObservableValidator
if (!Execute.IsObservableValidator(typeSymbol))
{
return default;
}

return Execute.GetInfo(typeSymbol);
})
.Where(static item => item is not null)!;

// Check whether the header file is needed
IncrementalValueProvider<bool> isHeaderFileNeeded =
Expand Down

0 comments on commit 5f90862

Please sign in to comment.