Skip to content

Commit 85e6b25

Browse files
Merge pull request #65 from ktsu-dev/work/issue-56
feat(generator): emit SEM001 diagnostic for unknown dimension references
2 parents 5452dba + c74f567 commit 85e6b25

1 file changed

Lines changed: 30 additions & 4 deletions

File tree

Semantics.SourceGenerators/Generators/QuantitiesGenerator.cs

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ namespace Semantics.SourceGenerators;
2020
[Generator]
2121
public class QuantitiesGenerator : GeneratorBase<DimensionsMetadata>
2222
{
23+
private static readonly DiagnosticDescriptor UnknownDimensionReference = new(
24+
id: "SEM001",
25+
title: "Unknown dimension reference in physics relationship",
26+
messageFormat: "Dimension '{0}' references unknown dimension '{1}' in {2}; the operator will not be generated. Check spelling and that the referenced dimension exists in dimensions.json.",
27+
category: "Semantics.SourceGenerators",
28+
defaultSeverity: DiagnosticSeverity.Warning,
29+
isEnabledByDefault: true);
30+
2331
public QuantitiesGenerator() : base("dimensions.json") { }
2432

2533
protected override void Generate(SourceProductionContext context, DimensionsMetadata metadata, CodeBlocker codeBlocker)
@@ -32,8 +40,8 @@ protected override void Generate(SourceProductionContext context, DimensionsMeta
3240
// Phase A: Build maps and collect operators
3341
Dictionary<string, PhysicalDimension> dimensionMap = BuildDimensionMap(metadata);
3442
Dictionary<string, int> typeFormMap = BuildTypeFormMap(metadata);
35-
List<OperatorInfo> allOperators = CollectAllOperators(metadata, dimensionMap);
36-
List<ProductInfo> allProducts = CollectAllProducts(metadata, dimensionMap);
43+
List<OperatorInfo> allOperators = CollectAllOperators(context, metadata, dimensionMap);
44+
List<ProductInfo> allProducts = CollectAllProducts(context, metadata, dimensionMap);
3745
Dictionary<string, List<OperatorInfo>> operatorsByOwner = GroupBy(allOperators, o => o.OwnerTypeName);
3846
Dictionary<string, List<ProductInfo>> productsByOwner = GroupBy(allProducts, p => p.SelfTypeName);
3947

@@ -112,7 +120,7 @@ private static Dictionary<string, int> BuildTypeFormMap(DimensionsMetadata metad
112120
return map;
113121
}
114122

115-
private static List<OperatorInfo> CollectAllOperators(DimensionsMetadata metadata, Dictionary<string, PhysicalDimension> dimMap)
123+
private static List<OperatorInfo> CollectAllOperators(SourceProductionContext context, DimensionsMetadata metadata, Dictionary<string, PhysicalDimension> dimMap)
116124
{
117125
HashSet<string> seen = [];
118126
List<OperatorInfo> result = [];
@@ -124,11 +132,13 @@ private static List<OperatorInfo> CollectAllOperators(DimensionsMetadata metadat
124132
{
125133
if (!dimMap.TryGetValue(integral.Other, out PhysicalDimension? otherDim))
126134
{
135+
ReportUnknownReference(context, dim.Name, integral.Other, $"integrals[{integral.Other} -> {integral.Result}].other");
127136
continue;
128137
}
129138

130139
if (!dimMap.TryGetValue(integral.Result, out PhysicalDimension? resultDim))
131140
{
141+
ReportUnknownReference(context, dim.Name, integral.Result, $"integrals[{integral.Other} -> {integral.Result}].result");
132142
continue;
133143
}
134144

@@ -168,11 +178,13 @@ private static List<OperatorInfo> CollectAllOperators(DimensionsMetadata metadat
168178
{
169179
if (!dimMap.TryGetValue(derivative.Other, out PhysicalDimension? otherDim))
170180
{
181+
ReportUnknownReference(context, dim.Name, derivative.Other, $"derivatives[{derivative.Other} -> {derivative.Result}].other");
171182
continue;
172183
}
173184

174185
if (!dimMap.TryGetValue(derivative.Result, out PhysicalDimension? resultDim))
175186
{
187+
ReportUnknownReference(context, dim.Name, derivative.Result, $"derivatives[{derivative.Other} -> {derivative.Result}].result");
176188
continue;
177189
}
178190

@@ -205,7 +217,7 @@ private static List<OperatorInfo> CollectAllOperators(DimensionsMetadata metadat
205217
return result;
206218
}
207219

208-
private static List<ProductInfo> CollectAllProducts(DimensionsMetadata metadata, Dictionary<string, PhysicalDimension> dimMap)
220+
private static List<ProductInfo> CollectAllProducts(SourceProductionContext context, DimensionsMetadata metadata, Dictionary<string, PhysicalDimension> dimMap)
209221
{
210222
HashSet<string> seen = [];
211223
List<ProductInfo> result = [];
@@ -217,11 +229,13 @@ private static List<ProductInfo> CollectAllProducts(DimensionsMetadata metadata,
217229
{
218230
if (!dimMap.TryGetValue(dot.Other, out PhysicalDimension? otherDim))
219231
{
232+
ReportUnknownReference(context, dim.Name, dot.Other, $"dotProducts[{dot.Other} -> {dot.Result}].other");
220233
continue;
221234
}
222235

223236
if (!dimMap.TryGetValue(dot.Result, out PhysicalDimension? resultDim))
224237
{
238+
ReportUnknownReference(context, dim.Name, dot.Result, $"dotProducts[{dot.Other} -> {dot.Result}].result");
225239
continue;
226240
}
227241

@@ -255,11 +269,13 @@ private static List<ProductInfo> CollectAllProducts(DimensionsMetadata metadata,
255269
{
256270
if (!dimMap.TryGetValue(cross.Other, out PhysicalDimension? otherDim))
257271
{
272+
ReportUnknownReference(context, dim.Name, cross.Other, $"crossProducts[{cross.Other} -> {cross.Result}].other");
258273
continue;
259274
}
260275

261276
if (!dimMap.TryGetValue(cross.Result, out PhysicalDimension? resultDim))
262277
{
278+
ReportUnknownReference(context, dim.Name, cross.Result, $"crossProducts[{cross.Other} -> {cross.Result}].result");
263279
continue;
264280
}
265281

@@ -297,6 +313,16 @@ private static void AddOp(List<OperatorInfo> list, HashSet<string> seen, string
297313
}
298314
}
299315

316+
private static void ReportUnknownReference(SourceProductionContext context, string owningDimension, string unknownReference, string fieldPath)
317+
{
318+
context.ReportDiagnostic(Diagnostic.Create(
319+
UnknownDimensionReference,
320+
Location.None,
321+
owningDimension,
322+
unknownReference,
323+
fieldPath));
324+
}
325+
300326
private static Dictionary<string, List<T>> GroupBy<T>(List<T> items, Func<T, string> keySelector)
301327
{
302328
Dictionary<string, List<T>> groups = [];

0 commit comments

Comments
 (0)