5
5
using System . Collections . Immutable ;
6
6
using System . Linq ;
7
7
using Microsoft . AspNetCore . Analyzers . Infrastructure ;
8
+ using Microsoft . AspNetCore . App . Analyzers . Infrastructure ;
8
9
using Microsoft . AspNetCore . Http . RequestDelegateGenerator . StaticRouteHandlerModel ;
9
10
using Microsoft . CodeAnalysis ;
10
11
using Microsoft . CodeAnalysis . CSharp ;
@@ -18,7 +19,7 @@ public sealed partial class ValidationsGenerator : IIncrementalGenerator
18
19
globalNamespaceStyle : SymbolDisplayGlobalNamespaceStyle . Included ,
19
20
typeQualificationStyle : SymbolDisplayTypeQualificationStyle . NameAndContainingTypesAndNamespaces ) ;
20
21
21
- internal ImmutableArray < ValidatableType > ExtractValidatableTypes ( IInvocationOperation operation , RequiredSymbols requiredSymbols )
22
+ internal ImmutableArray < ValidatableType > ExtractValidatableTypes ( IInvocationOperation operation , WellKnownTypes wellKnownTypes )
22
23
{
23
24
AnalyzerDebug . Assert ( operation . SemanticModel != null , "SemanticModel should not be null." ) ;
24
25
var parameters = operation . TryGetRouteHandlerMethod ( operation . SemanticModel , out var method )
@@ -28,12 +29,12 @@ internal ImmutableArray<ValidatableType> ExtractValidatableTypes(IInvocationOper
28
29
List < ITypeSymbol > visitedTypes = [ ] ;
29
30
foreach ( var parameter in parameters )
30
31
{
31
- _ = TryExtractValidatableType ( parameter . Type . UnwrapType ( requiredSymbols . IEnumerable ) , requiredSymbols , ref validatableTypes , ref visitedTypes ) ;
32
+ _ = TryExtractValidatableType ( parameter . Type . UnwrapType ( wellKnownTypes . Get ( WellKnownTypeData . WellKnownType . System_Collections_IEnumerable ) ) , wellKnownTypes , ref validatableTypes , ref visitedTypes ) ;
32
33
}
33
34
return [ .. validatableTypes ] ;
34
35
}
35
36
36
- internal bool TryExtractValidatableType ( ITypeSymbol typeSymbol , RequiredSymbols requiredSymbols , ref HashSet < ValidatableType > validatableTypes , ref List < ITypeSymbol > visitedTypes )
37
+ internal bool TryExtractValidatableType ( ITypeSymbol typeSymbol , WellKnownTypes wellKnownTypes , ref HashSet < ValidatableType > validatableTypes , ref List < ITypeSymbol > visitedTypes )
37
38
{
38
39
if ( typeSymbol . SpecialType != SpecialType . None )
39
40
{
@@ -45,7 +46,7 @@ internal bool TryExtractValidatableType(ITypeSymbol typeSymbol, RequiredSymbols
45
46
return true ;
46
47
}
47
48
48
- if ( typeSymbol . IsExemptType ( requiredSymbols ) )
49
+ if ( typeSymbol . IsExemptType ( wellKnownTypes ) )
49
50
{
50
51
return false ;
51
52
}
@@ -57,19 +58,23 @@ internal bool TryExtractValidatableType(ITypeSymbol typeSymbol, RequiredSymbols
57
58
var hasValidatableBaseType = false ;
58
59
while ( current != null && current . SpecialType != SpecialType . System_Object )
59
60
{
60
- hasValidatableBaseType |= TryExtractValidatableType ( current , requiredSymbols , ref validatableTypes , ref visitedTypes ) ;
61
+ hasValidatableBaseType |= TryExtractValidatableType ( current , wellKnownTypes , ref validatableTypes , ref visitedTypes ) ;
61
62
current = current . BaseType ;
62
63
}
63
64
64
65
// Extract validatable types discovered in members of this type and add them to the top-level list.
65
- var members = ExtractValidatableMembers ( typeSymbol , requiredSymbols , ref validatableTypes , ref visitedTypes ) ;
66
+ ImmutableArray < ValidatableProperty > members = [ ] ;
67
+ if ( ParsabilityHelper . GetParsability ( typeSymbol , wellKnownTypes ) is Parsability . NotParsable )
68
+ {
69
+ members = ExtractValidatableMembers ( typeSymbol , wellKnownTypes , ref validatableTypes , ref visitedTypes ) ;
70
+ }
66
71
67
72
// Extract the validatable types discovered in the JsonDerivedTypeAttributes of this type and add them to the top-level list.
68
- var derivedTypes = typeSymbol . GetJsonDerivedTypes ( requiredSymbols . JsonDerivedTypeAttribute ) ;
73
+ var derivedTypes = typeSymbol . GetJsonDerivedTypes ( wellKnownTypes . Get ( WellKnownTypeData . WellKnownType . System_Text_Json_Serialization_JsonDerivedTypeAttribute ) ) ;
69
74
var hasValidatableDerivedTypes = false ;
70
75
foreach ( var derivedType in derivedTypes ?? [ ] )
71
76
{
72
- hasValidatableDerivedTypes |= TryExtractValidatableType ( derivedType , requiredSymbols , ref validatableTypes , ref visitedTypes ) ;
77
+ hasValidatableDerivedTypes |= TryExtractValidatableType ( derivedType , wellKnownTypes , ref validatableTypes , ref visitedTypes ) ;
73
78
}
74
79
75
80
// No validatable members or derived types found, so we don't need to add this type.
@@ -86,7 +91,7 @@ internal bool TryExtractValidatableType(ITypeSymbol typeSymbol, RequiredSymbols
86
91
return true ;
87
92
}
88
93
89
- internal ImmutableArray < ValidatableProperty > ExtractValidatableMembers ( ITypeSymbol typeSymbol , RequiredSymbols requiredSymbols , ref HashSet < ValidatableType > validatableTypes , ref List < ITypeSymbol > visitedTypes )
94
+ internal ImmutableArray < ValidatableProperty > ExtractValidatableMembers ( ITypeSymbol typeSymbol , WellKnownTypes wellKnownTypes , ref HashSet < ValidatableType > validatableTypes , ref List < ITypeSymbol > visitedTypes )
90
95
{
91
96
var members = new List < ValidatableProperty > ( ) ;
92
97
var resolvedRecordProperty = new List < IPropertySymbol > ( ) ;
@@ -121,17 +126,17 @@ internal ImmutableArray<ValidatableProperty> ExtractValidatableMembers(ITypeSymb
121
126
// Check if the property's type is validatable, this resolves
122
127
// validatable types in the inheritance hierarchy
123
128
var hasValidatableType = TryExtractValidatableType (
124
- correspondingProperty . Type . UnwrapType ( requiredSymbols . IEnumerable ) ,
125
- requiredSymbols ,
129
+ correspondingProperty . Type . UnwrapType ( wellKnownTypes . Get ( WellKnownTypeData . WellKnownType . System_Collections_IEnumerable ) ) ,
130
+ wellKnownTypes ,
126
131
ref validatableTypes ,
127
132
ref visitedTypes ) ;
128
133
129
134
members . Add ( new ValidatableProperty (
130
135
ContainingType : correspondingProperty . ContainingType ,
131
136
Type : correspondingProperty . Type ,
132
137
Name : correspondingProperty . Name ,
133
- DisplayName : parameter . GetDisplayName ( requiredSymbols . DisplayAttribute ) ??
134
- correspondingProperty . GetDisplayName ( requiredSymbols . DisplayAttribute ) ,
138
+ DisplayName : parameter . GetDisplayName ( wellKnownTypes . Get ( WellKnownTypeData . WellKnownType . System_ComponentModel_DataAnnotations_DisplayAttribute ) ) ??
139
+ correspondingProperty . GetDisplayName ( wellKnownTypes . Get ( WellKnownTypeData . WellKnownType . System_ComponentModel_DataAnnotations_DisplayAttribute ) ) ,
135
140
Attributes : [ ] ) ) ;
136
141
}
137
142
}
@@ -148,8 +153,8 @@ internal ImmutableArray<ValidatableProperty> ExtractValidatableMembers(ITypeSymb
148
153
continue ;
149
154
}
150
155
151
- var hasValidatableType = TryExtractValidatableType ( member . Type . UnwrapType ( requiredSymbols . IEnumerable ) , requiredSymbols , ref validatableTypes , ref visitedTypes ) ;
152
- var attributes = ExtractValidationAttributes ( member , requiredSymbols , out var isRequired ) ;
156
+ var hasValidatableType = TryExtractValidatableType ( member . Type . UnwrapType ( wellKnownTypes . Get ( WellKnownTypeData . WellKnownType . System_Collections_IEnumerable ) ) , wellKnownTypes , ref validatableTypes , ref visitedTypes ) ;
157
+ var attributes = ExtractValidationAttributes ( member , wellKnownTypes , out var isRequired ) ;
153
158
154
159
// If the member has no validation attributes or validatable types and is not required, skip it.
155
160
if ( attributes . IsDefaultOrEmpty && ! hasValidatableType && ! isRequired )
@@ -161,14 +166,14 @@ internal ImmutableArray<ValidatableProperty> ExtractValidatableMembers(ITypeSymb
161
166
ContainingType : member . ContainingType ,
162
167
Type : member . Type ,
163
168
Name : member . Name ,
164
- DisplayName : member . GetDisplayName ( requiredSymbols . DisplayAttribute ) ,
169
+ DisplayName : member . GetDisplayName ( wellKnownTypes . Get ( WellKnownTypeData . WellKnownType . System_ComponentModel_DataAnnotations_DisplayAttribute ) ) ,
165
170
Attributes : attributes ) ) ;
166
171
}
167
172
168
173
return [ .. members ] ;
169
174
}
170
175
171
- internal static ImmutableArray < ValidationAttribute > ExtractValidationAttributes ( ISymbol symbol , RequiredSymbols requiredSymbols , out bool isRequired )
176
+ internal static ImmutableArray < ValidationAttribute > ExtractValidationAttributes ( ISymbol symbol , WellKnownTypes wellKnownTypes , out bool isRequired )
172
177
{
173
178
var attributes = symbol . GetAttributes ( ) ;
174
179
if ( attributes . Length == 0 )
@@ -179,15 +184,15 @@ internal static ImmutableArray<ValidationAttribute> ExtractValidationAttributes(
179
184
180
185
var validationAttributes = attributes
181
186
. Where ( attribute => attribute . AttributeClass != null )
182
- . Where ( attribute => attribute . AttributeClass ! . ImplementsValidationAttribute ( requiredSymbols . ValidationAttribute ) ) ;
183
- isRequired = validationAttributes . Any ( attr => SymbolEqualityComparer . Default . Equals ( attr . AttributeClass , requiredSymbols . RequiredAttribute ) ) ;
187
+ . Where ( attribute => attribute . AttributeClass ! . ImplementsValidationAttribute ( wellKnownTypes . Get ( WellKnownTypeData . WellKnownType . System_ComponentModel_DataAnnotations_ValidationAttribute ) ) ) ;
188
+ isRequired = validationAttributes . Any ( attr => SymbolEqualityComparer . Default . Equals ( attr . AttributeClass , wellKnownTypes . Get ( WellKnownTypeData . WellKnownType . System_ComponentModel_DataAnnotations_RequiredAttribute ) ) ) ;
184
189
return [ .. validationAttributes
185
- . Where ( attr => ! SymbolEqualityComparer . Default . Equals ( attr . AttributeClass , requiredSymbols . ValidationAttribute ) )
190
+ . Where ( attr => ! SymbolEqualityComparer . Default . Equals ( attr . AttributeClass , wellKnownTypes . Get ( WellKnownTypeData . WellKnownType . System_ComponentModel_DataAnnotations_ValidationAttribute ) ) )
186
191
. Select ( attribute => new ValidationAttribute (
187
192
Name : symbol . Name + attribute . AttributeClass ! . Name ,
188
193
ClassName : attribute . AttributeClass ! . ToDisplayString ( _symbolDisplayFormat ) ,
189
194
Arguments : [ .. attribute . ConstructorArguments . Select ( a => a . ToCSharpString ( ) ) ] ,
190
195
NamedArguments : attribute . NamedArguments . ToDictionary ( namedArgument => namedArgument . Key , namedArgument => namedArgument . Value . ToCSharpString ( ) ) ,
191
- IsCustomValidationAttribute : SymbolEqualityComparer . Default . Equals ( attribute . AttributeClass , requiredSymbols . CustomValidationAttribute ) ) ) ] ;
196
+ IsCustomValidationAttribute : SymbolEqualityComparer . Default . Equals ( attribute . AttributeClass , wellKnownTypes . Get ( WellKnownTypeData . WellKnownType . System_ComponentModel_DataAnnotations_CustomValidationAttribute ) ) ) ) ] ;
192
197
}
193
198
}
0 commit comments