Skip to content

Commit 9bfdbcb

Browse files
committed
feat: enhance VectorizerFactoryAnalyzer with additional property checks
1 parent ad2860e commit 9bfdbcb

File tree

5 files changed

+116
-49
lines changed

5 files changed

+116
-49
lines changed

src/Weaviate.Client.Analyzers.Tests/VectorizerFactoryAnalyzerTests.cs

Lines changed: 85 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,30 @@ public class VectorizerFactory
6464
{
6565
Model = model
6666
// Missing: BaseURL = baseURL
67+
// Also missing: ImageFields, TextFields, VideoFields (no params)
6768
};
6869
}
6970
}";
7071

71-
var expected = VerifyCS
72-
.Diagnostic(VectorizerFactoryAnalyzer.MissingPropertyDiagnosticId)
73-
.WithLocation(0)
74-
.WithArguments("TestVectorizer", "BaseURL");
72+
var expected = new[]
73+
{
74+
VerifyCS
75+
.Diagnostic(VectorizerFactoryAnalyzer.MissingPropertyDiagnosticId)
76+
.WithLocation(0)
77+
.WithArguments("TestVectorizer", "BaseURL"),
78+
VerifyCS
79+
.Diagnostic(VectorizerFactoryAnalyzer.MissingPropertyDiagnosticId)
80+
.WithLocation(0)
81+
.WithArguments("TestVectorizer", "ImageFields"),
82+
VerifyCS
83+
.Diagnostic(VectorizerFactoryAnalyzer.MissingPropertyDiagnosticId)
84+
.WithLocation(0)
85+
.WithArguments("TestVectorizer", "TextFields"),
86+
VerifyCS
87+
.Diagnostic(VectorizerFactoryAnalyzer.MissingPropertyDiagnosticId)
88+
.WithLocation(0)
89+
.WithArguments("TestVectorizer", "VideoFields"),
90+
};
7591

7692
await VerifyCS.VerifyAnalyzerAsync(testCode, expected);
7793
}
@@ -90,12 +106,18 @@ public class VectorizerFactory
90106
{
91107
public VectorizerConfig TestVectorizer(
92108
string? model = null,
93-
string? baseURL = null
109+
string? baseURL = null,
110+
WeightedFields? imageFields = null,
111+
WeightedFields? textFields = null,
112+
WeightedFields? videoFields = null
94113
) =>
95114
new Models.Vectorizer.TestVectorizer
96115
{
97116
Model = model,
98-
BaseURL = baseURL
117+
BaseURL = baseURL,
118+
ImageFields = imageFields,
119+
TextFields = textFields,
120+
VideoFields = videoFields
99121
};
100122
}
101123
}";
@@ -116,7 +138,7 @@ namespace Weaviate.Client
116138
117139
public class VectorizerFactory
118140
{
119-
public VectorizerConfig TestVectorizer(
141+
public VectorizerConfig {|#0:TestVectorizer|}(
120142
WeightedFields imageFields,
121143
WeightedFields textFields,
122144
WeightedFields videoFields
@@ -126,15 +148,26 @@ WeightedFields videoFields
126148
ImageFields = imageFields,
127149
TextFields = textFields,
128150
VideoFields = videoFields,
129-
{|#0:Weights = VectorizerWeights.FromWeightedFields(imageFields, textFields)|}
151+
{|#1:Weights = VectorizerWeights.FromWeightedFields(imageFields, textFields)|}
130152
};
131153
}
132154
}";
133155

134-
var expected = VerifyCS
135-
.Diagnostic(VectorizerFactoryAnalyzer.MissingWeightFieldDiagnosticId)
136-
.WithLocation(0)
137-
.WithArguments("TestVectorizer", "videoFields");
156+
var expected = new[]
157+
{
158+
VerifyCS
159+
.Diagnostic(VectorizerFactoryAnalyzer.MissingWeightFieldDiagnosticId)
160+
.WithLocation(1)
161+
.WithArguments("TestVectorizer", "videoFields"),
162+
VerifyCS
163+
.Diagnostic(VectorizerFactoryAnalyzer.MissingPropertyDiagnosticId)
164+
.WithLocation(0)
165+
.WithArguments("TestVectorizer", "Model"),
166+
VerifyCS
167+
.Diagnostic(VectorizerFactoryAnalyzer.MissingPropertyDiagnosticId)
168+
.WithLocation(0)
169+
.WithArguments("TestVectorizer", "BaseURL"),
170+
};
138171

139172
await VerifyCS.VerifyAnalyzerAsync(testCode, expected);
140173
}
@@ -155,10 +188,14 @@ public class VectorizerFactory
155188
public VectorizerConfig TestVectorizer(
156189
WeightedFields imageFields,
157190
WeightedFields textFields,
158-
WeightedFields videoFields
191+
WeightedFields videoFields,
192+
string? model = null,
193+
string? baseURL = null
159194
) =>
160195
new Models.Vectorizer.TestVectorizer
161196
{
197+
Model = model,
198+
BaseURL = baseURL,
162199
ImageFields = imageFields,
163200
TextFields = textFields,
164201
VideoFields = videoFields,
@@ -186,10 +223,14 @@ public class VectorizerFactory
186223
public VectorizerConfig TestVectorizer(
187224
WeightedFields imageFields,
188225
WeightedFields textFields,
189-
WeightedFields videoFields
226+
WeightedFields videoFields,
227+
string? model = null,
228+
string? baseURL = null
190229
) =>
191230
new Models.Vectorizer.TestVectorizer
192231
{
232+
Model = model,
233+
BaseURL = baseURL,
193234
ImageFields = imageFields,
194235
TextFields = textFields,
195236
VideoFields = videoFields,
@@ -214,11 +255,19 @@ namespace Weaviate.Client
214255
public class VectorizerFactory
215256
{
216257
public VectorizerConfig TestVectorizer(
217-
string? model = null
258+
string? model = null,
259+
string? baseURL = null,
260+
WeightedFields? imageFields = null,
261+
WeightedFields? textFields = null,
262+
WeightedFields? videoFields = null
218263
) =>
219264
new Models.Vectorizer.TestVectorizer
220265
{
221-
Model = model
266+
Model = model,
267+
BaseURL = baseURL,
268+
ImageFields = imageFields,
269+
TextFields = textFields,
270+
VideoFields = videoFields
222271
};
223272
}
224273
}";
@@ -246,14 +295,30 @@ public class VectorizerFactoryMulti
246295
{
247296
Model = model
248297
// Missing: BaseURL = baseURL
298+
// Also missing: ImageFields, TextFields, VideoFields (no params)
249299
};
250300
}
251301
}";
252302

253-
var expected = VerifyCS
254-
.Diagnostic(VectorizerFactoryAnalyzer.MissingPropertyDiagnosticId)
255-
.WithLocation(0)
256-
.WithArguments("TestVectorizer", "BaseURL");
303+
var expected = new[]
304+
{
305+
VerifyCS
306+
.Diagnostic(VectorizerFactoryAnalyzer.MissingPropertyDiagnosticId)
307+
.WithLocation(0)
308+
.WithArguments("TestVectorizer", "BaseURL"),
309+
VerifyCS
310+
.Diagnostic(VectorizerFactoryAnalyzer.MissingPropertyDiagnosticId)
311+
.WithLocation(0)
312+
.WithArguments("TestVectorizer", "ImageFields"),
313+
VerifyCS
314+
.Diagnostic(VectorizerFactoryAnalyzer.MissingPropertyDiagnosticId)
315+
.WithLocation(0)
316+
.WithArguments("TestVectorizer", "TextFields"),
317+
VerifyCS
318+
.Diagnostic(VectorizerFactoryAnalyzer.MissingPropertyDiagnosticId)
319+
.WithLocation(0)
320+
.WithArguments("TestVectorizer", "VideoFields"),
321+
};
257322

258323
await VerifyCS.VerifyAnalyzerAsync(testCode, expected);
259324
}

src/Weaviate.Client.Analyzers/AnalyzerReleases.Shipped.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,7 @@
33
### New Rules
44

55
Rule ID | Category | Severity | Notes
6-
------------|----------|----------|-----------------------------------------------------
7-
WEAVIATE001 | Usage | Error | AutoArray<T> should only be used as method parameter
6+
------------|----------|----------|-----------------------------------------------------------------
7+
WEAVIATE001 | Usage | Warning | AutoArrayUsageAnalyzer - AutoArray should only be used as method parameter
8+
WEAVIATE002 | Usage | Error | VectorizerFactoryAnalyzer - Missing property initialization
9+
WEAVIATE003 | Usage | Error | VectorizerFactoryAnalyzer - Missing field in Weights calculation
Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11

22
### New Rules
33

4-
Rule ID | Category | Severity | Notes
5-
--------|----------|----------|-------
6-
WEAVIATE001 | Usage | Error | AutoArrayUsageAnalyzer
7-
WEAVIATE002 | Usage | Warning | VectorizerFactoryAnalyzer - Missing property initialization
8-
WEAVIATE003 | Usage | Warning | VectorizerFactoryAnalyzer - Missing field in Weights calculation
4+
Rule ID | Category | Severity | Notes
5+
------------|----------|----------|-----------------------------------------------------------------

src/Weaviate.Client.Analyzers/AutoArrayUsageAnalyzer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public class AutoArrayUsageAnalyzer : DiagnosticAnalyzer
2424
Title,
2525
MessageFormat,
2626
Category,
27-
DiagnosticSeverity.Error,
27+
DiagnosticSeverity.Warning,
2828
isEnabledByDefault: true,
2929
description: Description
3030
);

src/Weaviate.Client.Analyzers/VectorizerFactoryAnalyzer.cs

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ public class VectorizerFactoryAnalyzer : DiagnosticAnalyzer
1616
private const string Category = "Usage";
1717

1818
private static readonly LocalizableString MissingPropertyTitle =
19-
"Vectorizer factory method missing property initialization";
19+
"Vectorizer factory method missing property initialization or parameter";
2020
private static readonly LocalizableString MissingPropertyMessageFormat =
21-
"Factory method creating '{0}' does not initialize property '{1}'";
21+
"Factory method creating '{0}' does not have a way to set property '{1}'. Add a parameter for it or initialize it in the object initializer.";
2222
private static readonly LocalizableString MissingPropertyDescription =
23-
"All properties of a vectorizer config should be initializable through the factory method.";
23+
"All public properties of a vectorizer config should be initializable through factory method parameters or explicitly initialized in the object initializer to ensure completeness.";
2424

2525
private static readonly LocalizableString MissingWeightFieldTitle =
2626
"Vectorizer factory method missing field in Weights calculation";
@@ -34,7 +34,7 @@ public class VectorizerFactoryAnalyzer : DiagnosticAnalyzer
3434
MissingPropertyTitle,
3535
MissingPropertyMessageFormat,
3636
Category,
37-
DiagnosticSeverity.Warning,
37+
DiagnosticSeverity.Error,
3838
isEnabledByDefault: true,
3939
description: MissingPropertyDescription
4040
);
@@ -44,7 +44,7 @@ public class VectorizerFactoryAnalyzer : DiagnosticAnalyzer
4444
MissingWeightFieldTitle,
4545
MissingWeightFieldMessageFormat,
4646
Category,
47-
DiagnosticSeverity.Warning,
47+
DiagnosticSeverity.Error,
4848
isEnabledByDefault: true,
4949
description: MissingWeightFieldDescription
5050
);
@@ -169,24 +169,27 @@ SemanticModel semanticModel
169169
// Check if there's a corresponding parameter for this property
170170
var propertyNameLower = property.Name.ToLowerInvariant();
171171

172-
// Handle special mappings (e.g., BaseURL -> baseURL, VectorizeCollectionName -> vectorizeCollectionName)
172+
// Convert PascalCase to camelCase for property name
173+
var camelCasePropertyName =
174+
property.Name.Length > 0
175+
? char.ToLowerInvariant(property.Name[0]) + property.Name.Substring(1)
176+
: property.Name;
177+
173178
var hasCorrespondingParameter =
174179
parameterNames.Contains(propertyNameLower)
175-
|| parameterNames.Contains(
176-
property.Name.Substring(0, 1).ToLowerInvariant() + property.Name.Substring(1)
177-
);
178-
179-
// Only warn if there's a parameter but it's not being used
180-
if (hasCorrespondingParameter)
181-
{
182-
var diagnostic = Diagnostic.Create(
183-
MissingPropertyRule,
184-
methodDeclaration.Identifier.GetLocation(),
185-
namedType.Name,
186-
property.Name
187-
);
188-
context.ReportDiagnostic(diagnostic);
189-
}
180+
|| parameterNames.Contains(camelCasePropertyName.ToLowerInvariant());
181+
182+
// Warn if property is not initialized AND either:
183+
// 1. There's a corresponding parameter (parameter exists but not used), OR
184+
// 2. There's NO parameter and property isn't initialized (property can't be set via factory)
185+
// This ensures all properties can be set through the factory method
186+
var diagnostic = Diagnostic.Create(
187+
MissingPropertyRule,
188+
methodDeclaration.Identifier.GetLocation(),
189+
namedType.Name,
190+
property.Name
191+
);
192+
context.ReportDiagnostic(diagnostic);
190193
}
191194
}
192195

0 commit comments

Comments
 (0)