@@ -35,8 +35,8 @@ public static PropertyInfo GetInfo(IFieldSymbol fieldSymbol, out ImmutableArray<
35
35
ImmutableArray < Diagnostic > . Builder builder = ImmutableArray . CreateBuilder < Diagnostic > ( ) ;
36
36
37
37
// Check whether the containing type implements INotifyPropertyChanging and whether it inherits from ObservableValidator
38
- bool isObservableObject = fieldSymbol . ContainingType . InheritsFrom ( "global::CommunityToolkit.Mvvm.ComponentModel.ObservableObject" ) ;
39
- bool isObservableValidator = fieldSymbol . ContainingType . InheritsFrom ( "global::CommunityToolkit.Mvvm.ComponentModel.ObservableValidator" ) ;
38
+ bool isObservableObject = fieldSymbol . ContainingType . InheritsFromFullyQualifiedName ( "global::CommunityToolkit.Mvvm.ComponentModel.ObservableObject" ) ;
39
+ bool isObservableValidator = fieldSymbol . ContainingType . InheritsFromFullyQualifiedName ( "global::CommunityToolkit.Mvvm.ComponentModel.ObservableValidator" ) ;
40
40
bool isNotifyPropertyChanging = fieldSymbol . ContainingType . AllInterfaces . Any ( static i => i . HasFullyQualifiedName ( "global::System.ComponentModel.INotifyPropertyChanging" ) ) ;
41
41
bool hasObservableObjectAttribute = fieldSymbol . ContainingType . GetAttributes ( ) . Any ( static a => a . AttributeClass ? . HasFullyQualifiedName ( "global::CommunityToolkit.Mvvm.ComponentModel.ObservableObjectAttribute" ) == true ) ;
42
42
@@ -81,7 +81,7 @@ public static PropertyInfo GetInfo(IFieldSymbol fieldSymbol, out ImmutableArray<
81
81
}
82
82
83
83
// Track the current validation attribute, if applicable
84
- if ( attributeData . AttributeClass ? . InheritsFrom ( "global::System.ComponentModel.DataAnnotations.ValidationAttribute" ) == true )
84
+ if ( attributeData . AttributeClass ? . InheritsFromFullyQualifiedName ( "global::System.ComponentModel.DataAnnotations.ValidationAttribute" ) == true )
85
85
{
86
86
validationAttributes . Add ( AttributeInfo . From ( attributeData ) ) ;
87
87
}
@@ -130,42 +130,44 @@ private static bool TryGatherDependentPropertyChangedNames(
130
130
{
131
131
foreach ( string ? dependentPropertyName in attributeData . GetConstructorArguments < string > ( ) )
132
132
{
133
+ if ( dependentPropertyName is null or "" )
134
+ {
135
+ goto InvalidProperty ;
136
+ }
137
+
133
138
// Each target must be a string matching the name of a property from the containing type of the annotated field
134
- if ( dependentPropertyName is { Length : > 0 } &&
135
- fieldSymbol . ContainingType . GetMembers ( dependentPropertyName ) . OfType < IPropertySymbol > ( ) . Any ( ) )
139
+ if ( fieldSymbol . ContainingType . GetMembers ( dependentPropertyName ) . OfType < IPropertySymbol > ( ) . Any ( ) )
136
140
{
137
141
propertyChangedNames . Add ( dependentPropertyName ) ;
142
+
143
+ goto ValidProperty ;
138
144
}
139
- else
140
- {
141
- bool isTargetValid = false ;
142
145
143
- // Check for generated properties too
144
- foreach ( ISymbol member in fieldSymbol . ContainingType . GetMembers ( ) )
146
+ // Check for generated properties too
147
+ foreach ( ISymbol member in fieldSymbol . ContainingType . GetMembers ( ) )
148
+ {
149
+ if ( member is IFieldSymbol otherFieldSymbol &&
150
+ ! SymbolEqualityComparer . Default . Equals ( fieldSymbol , otherFieldSymbol ) &&
151
+ otherFieldSymbol . HasAttributeWithFullyQualifiedName ( "global::CommunityToolkit.Mvvm.ComponentModel.ObservablePropertyAttribute" ) &&
152
+ dependentPropertyName == GetGeneratedPropertyName ( otherFieldSymbol ) )
145
153
{
146
- if ( member is IFieldSymbol otherFieldSymbol &&
147
- ! SymbolEqualityComparer . Default . Equals ( fieldSymbol , otherFieldSymbol ) &&
148
- otherFieldSymbol . HasAttributeWithFullyQualifiedName ( "global::CommunityToolkit.Mvvm.ComponentModel.ObservablePropertyAttribute" ) &&
149
- dependentPropertyName == GetGeneratedPropertyName ( otherFieldSymbol ) )
150
- {
151
- propertyChangedNames . Add ( dependentPropertyName ) ;
154
+ propertyChangedNames . Add ( dependentPropertyName ) ;
152
155
153
- isTargetValid = true ;
154
-
155
- break ;
156
- }
157
- }
158
-
159
- // Add the diagnostic if the target is definitely invalid
160
- if ( ! isTargetValid )
161
- {
162
- diagnostics . Add (
163
- AlsoNotifyChangeForInvalidTargetError ,
164
- fieldSymbol ,
165
- dependentPropertyName ?? "" ,
166
- fieldSymbol . ContainingType ) ;
156
+ goto ValidProperty ;
167
157
}
168
158
}
159
+
160
+ ValidProperty :
161
+
162
+ continue ;
163
+
164
+ InvalidProperty :
165
+
166
+ diagnostics . Add (
167
+ AlsoNotifyChangeForInvalidTargetError ,
168
+ fieldSymbol ,
169
+ dependentPropertyName ?? "" ,
170
+ fieldSymbol . ContainingType ) ;
169
171
}
170
172
171
173
return true ;
@@ -192,44 +194,46 @@ private static bool TryGatherDependentCommandNames(
192
194
{
193
195
foreach ( string ? commandName in attributeData . GetConstructorArguments < string > ( ) )
194
196
{
197
+ if ( commandName is null or "" )
198
+ {
199
+ goto InvalidProperty ;
200
+ }
201
+
195
202
// Each target must be a string matching the name of a property from the containing type of the annotated field, and the
196
203
// property must be of type IRelayCommand, or any type that implements that interface (to avoid generating invalid code).
197
- if ( commandName is { Length : > 0 } &&
198
- fieldSymbol . ContainingType . GetMembers ( commandName ) . OfType < IPropertySymbol > ( ) . FirstOrDefault ( ) is IPropertySymbol propertySymbol &&
204
+ if ( fieldSymbol . ContainingType . GetMembers ( commandName ) . OfType < IPropertySymbol > ( ) . FirstOrDefault ( ) is IPropertySymbol propertySymbol &&
199
205
propertySymbol is INamedTypeSymbol typeSymbol &&
200
- typeSymbol . InheritsFrom ( "global::CommunityToolkit.Mvvm.Input.IRelayCommand" ) )
206
+ typeSymbol . HasInterfaceWithFullyQualifiedName ( "global::CommunityToolkit.Mvvm.Input.IRelayCommand" ) )
201
207
{
202
208
notifiedCommandNames . Add ( commandName ) ;
209
+
210
+ goto ValidProperty ;
203
211
}
204
- else
205
- {
206
- bool isTargetValid = false ;
207
212
208
- // Check for generated commands too
209
- foreach ( ISymbol member in fieldSymbol . ContainingType . GetMembers ( ) )
213
+ // Check for generated commands too
214
+ foreach ( ISymbol member in fieldSymbol . ContainingType . GetMembers ( ) )
215
+ {
216
+ if ( member is IMethodSymbol methodSymbol &&
217
+ methodSymbol . HasAttributeWithFullyQualifiedName ( "global::CommunityToolkit.Mvvm.Input.ICommandAttribute" ) &&
218
+ commandName == ICommandGenerator . Execute . GetGeneratedFieldAndPropertyNames ( methodSymbol ) . PropertyName )
210
219
{
211
- if ( member is IMethodSymbol methodSymbol &&
212
- methodSymbol . HasAttributeWithFullyQualifiedName ( "global::CommunityToolkit.Mvvm.Input.ICommandAttribute" ) &&
213
- commandName == ICommandGenerator . Execute . GetGeneratedFieldAndPropertyNames ( methodSymbol ) . PropertyName )
214
- {
215
- notifiedCommandNames . Add ( commandName ) ;
220
+ notifiedCommandNames . Add ( commandName ) ;
216
221
217
- isTargetValid = true ;
218
-
219
- break ;
220
- }
221
- }
222
-
223
- // Add the diagnostic if the target is definitely invalid
224
- if ( ! isTargetValid )
225
- {
226
- diagnostics . Add (
227
- AlsoNotifyCanExecuteForInvalidTargetError ,
228
- fieldSymbol ,
229
- commandName ?? "" ,
230
- fieldSymbol . ContainingType ) ;
222
+ goto ValidProperty ;
231
223
}
232
224
}
225
+
226
+ ValidProperty :
227
+
228
+ continue ;
229
+
230
+ InvalidProperty :
231
+
232
+ diagnostics . Add (
233
+ AlsoNotifyCanExecuteForInvalidTargetError ,
234
+ fieldSymbol ,
235
+ commandName ?? "" ,
236
+ fieldSymbol . ContainingType ) ;
233
237
}
234
238
235
239
return true ;
0 commit comments