Skip to content

Commit 19ffbab

Browse files
Added rule checks before generating code
1 parent 8edd477 commit 19ffbab

File tree

1 file changed

+66
-2
lines changed

1 file changed

+66
-2
lines changed

src/ThunderDesign.Net-PCL.SourceGenerators/UnifiedPropertyGenerator.cs

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)