@@ -20,6 +20,14 @@ namespace Semantics.SourceGenerators;
2020[ Generator ]
2121public 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