@@ -108,6 +108,54 @@ private static void GenerateUnifiedPropertyClass(
108108 var voidTypeSymbol = compilation . GetSpecialType ( SpecialType . System_Void ) ;
109109 var propertyChangedEventType = compilation . GetTypeByMetadataName ( "System.ComponentModel.PropertyChangedEventHandler" ) ;
110110
111+ // --- RULE CHECKS FOR BINDABLE FIELDS ---
112+ foreach ( var info in bindableFields )
113+ {
114+ // Rule 1: Class must be partial
115+ if ( ! PropertyGeneratorHelpers . IsPartial ( classSymbol ) )
116+ {
117+ PropertyGeneratorHelpers . ReportDiagnostic ( context , info . FieldDeclaration . GetLocation ( ) , $ "Class '{ classSymbol . Name } ' must be partial to use [BindableProperty].") ;
118+ continue ;
119+ }
120+ // Rule 2: Field must start with "_" or lowercase
121+ if ( ! PropertyGeneratorHelpers . IsValidFieldName ( info . FieldSymbol . Name ) )
122+ {
123+ PropertyGeneratorHelpers . ReportDiagnostic ( context , info . FieldDeclaration . GetLocation ( ) , $ "Field '{ info . FieldSymbol . Name } ' must start with '_' or a lowercase letter to use [BindableProperty].") ;
124+ continue ;
125+ }
126+ // Rule 3: Property must not already exist
127+ var propertyName = PropertyGeneratorHelpers . ToPropertyName ( info . FieldSymbol . Name ) ;
128+ if ( PropertyGeneratorHelpers . PropertyExists ( classSymbol , propertyName ) )
129+ {
130+ PropertyGeneratorHelpers . ReportDiagnostic ( context , info . FieldDeclaration . GetLocation ( ) , $ "Property '{ propertyName } ' already exists in '{ classSymbol . Name } '.") ;
131+ continue ;
132+ }
133+ }
134+
135+ // --- RULE CHECKS FOR PROPERTY FIELDS ---
136+ foreach ( var info in propertyFields )
137+ {
138+ // Rule 1: Class must be partial
139+ if ( ! PropertyGeneratorHelpers . IsPartial ( classSymbol ) )
140+ {
141+ PropertyGeneratorHelpers . ReportDiagnostic ( context , info . FieldDeclaration . GetLocation ( ) , $ "Class '{ classSymbol . Name } ' must be partial to use [Property].") ;
142+ continue ;
143+ }
144+ // Rule 2: Field must start with "_" or lowercase
145+ if ( ! PropertyGeneratorHelpers . IsValidFieldName ( info . FieldSymbol . Name ) )
146+ {
147+ PropertyGeneratorHelpers . ReportDiagnostic ( context , info . FieldDeclaration . GetLocation ( ) , $ "Field '{ info . FieldSymbol . Name } ' must start with '_' or a lowercase letter to use [Property].") ;
148+ continue ;
149+ }
150+ // Rule 3: Property must not already exist
151+ var propertyName = PropertyGeneratorHelpers . ToPropertyName ( info . FieldSymbol . Name ) ;
152+ if ( PropertyGeneratorHelpers . PropertyExists ( classSymbol , propertyName ) )
153+ {
154+ PropertyGeneratorHelpers . ReportDiagnostic ( context , info . FieldDeclaration . GetLocation ( ) , $ "Property '{ propertyName } ' already exists in '{ classSymbol . Name } '.") ;
155+ continue ;
156+ }
157+ }
158+
111159 var source = new StringBuilder ( ) ;
112160 var ns = classSymbol . ContainingNamespace . IsGlobalNamespace ? null : classSymbol . ContainingNamespace . ToDisplayString ( ) ;
113161
@@ -155,9 +203,17 @@ public virtual void OnPropertyChanged([System.Runtime.CompilerServices.CallerMem
155203 // Generate all bindable properties
156204 foreach ( var info in bindableFields )
157205 {
206+ // Skip if any rule failed (diagnostic already reported)
207+ var propertyName = PropertyGeneratorHelpers . ToPropertyName ( info . FieldSymbol . Name ) ;
208+ if ( ! PropertyGeneratorHelpers . IsPartial ( classSymbol ) ||
209+ ! PropertyGeneratorHelpers . IsValidFieldName ( info . FieldSymbol . Name ) ||
210+ PropertyGeneratorHelpers . PropertyExists ( classSymbol , propertyName ) )
211+ {
212+ continue ;
213+ }
214+
158215 var fieldSymbol = info . FieldSymbol ;
159216 var fieldName = fieldSymbol . Name ;
160- var propertyName = PropertyGeneratorHelpers . ToPropertyName ( fieldName ) ;
161217 var typeName = fieldSymbol . Type . ToDisplayString ( ) ;
162218
163219 var readOnly = info . AttributeData . ConstructorArguments . Length > 0 && ( bool ) info . AttributeData . ConstructorArguments [ 0 ] . Value ! ;
@@ -225,9 +281,17 @@ public virtual void OnPropertyChanged([System.Runtime.CompilerServices.CallerMem
225281 // Generate all regular properties
226282 foreach ( var info in propertyFields )
227283 {
284+ // Skip if any rule failed (diagnostic already reported)
285+ var propertyName = PropertyGeneratorHelpers . ToPropertyName ( info . FieldSymbol . Name ) ;
286+ if ( ! PropertyGeneratorHelpers . IsPartial ( classSymbol ) ||
287+ ! PropertyGeneratorHelpers . IsValidFieldName ( info . FieldSymbol . Name ) ||
288+ PropertyGeneratorHelpers . PropertyExists ( classSymbol , propertyName ) )
289+ {
290+ continue ;
291+ }
292+
228293 var fieldSymbol = info . FieldSymbol ;
229294 var fieldName = fieldSymbol . Name ;
230- var propertyName = PropertyGeneratorHelpers . ToPropertyName ( fieldName ) ;
231295 var typeName = fieldSymbol . Type . ToDisplayString ( ) ;
232296
233297 var readOnly = info . AttributeData . ConstructorArguments . Length > 0 && ( bool ) info . AttributeData . ConstructorArguments [ 0 ] . Value ! ;
0 commit comments