Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 30 additions & 4 deletions Semantics.SourceGenerators/Generators/QuantitiesGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@
[Generator]
public class QuantitiesGenerator : GeneratorBase<DimensionsMetadata>
{
private static readonly DiagnosticDescriptor UnknownDimensionReference = new(
id: "SEM001",

Check failure on line 24 in Semantics.SourceGenerators/Generators/QuantitiesGenerator.cs

View workflow job for this annotation

GitHub Actions / Build, Test & Release

Enable analyzer release tracking for the analyzer project containing rule 'SEM001' (https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md)

Check failure on line 24 in Semantics.SourceGenerators/Generators/QuantitiesGenerator.cs

View workflow job for this annotation

GitHub Actions / Build, Test & Release

Enable analyzer release tracking for the analyzer project containing rule 'SEM001' (https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md)
title: "Unknown dimension reference in physics relationship",
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.",
category: "Semantics.SourceGenerators",
defaultSeverity: DiagnosticSeverity.Warning,
isEnabledByDefault: true);

public QuantitiesGenerator() : base("dimensions.json") { }

protected override void Generate(SourceProductionContext context, DimensionsMetadata metadata, CodeBlocker codeBlocker)
Expand All @@ -32,8 +40,8 @@
// Phase A: Build maps and collect operators
Dictionary<string, PhysicalDimension> dimensionMap = BuildDimensionMap(metadata);
Dictionary<string, int> typeFormMap = BuildTypeFormMap(metadata);
List<OperatorInfo> allOperators = CollectAllOperators(metadata, dimensionMap);
List<ProductInfo> allProducts = CollectAllProducts(metadata, dimensionMap);
List<OperatorInfo> allOperators = CollectAllOperators(context, metadata, dimensionMap);
List<ProductInfo> allProducts = CollectAllProducts(context, metadata, dimensionMap);
Dictionary<string, List<OperatorInfo>> operatorsByOwner = GroupBy(allOperators, o => o.OwnerTypeName);
Dictionary<string, List<ProductInfo>> productsByOwner = GroupBy(allProducts, p => p.SelfTypeName);

Expand Down Expand Up @@ -112,7 +120,7 @@
return map;
}

private static List<OperatorInfo> CollectAllOperators(DimensionsMetadata metadata, Dictionary<string, PhysicalDimension> dimMap)
private static List<OperatorInfo> CollectAllOperators(SourceProductionContext context, DimensionsMetadata metadata, Dictionary<string, PhysicalDimension> dimMap)
{
HashSet<string> seen = [];
List<OperatorInfo> result = [];
Expand All @@ -124,11 +132,13 @@
{
if (!dimMap.TryGetValue(integral.Other, out PhysicalDimension? otherDim))
{
ReportUnknownReference(context, dim.Name, integral.Other, $"integrals[{integral.Other} -> {integral.Result}].other");
continue;
}

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

Expand Down Expand Up @@ -168,11 +178,13 @@
{
if (!dimMap.TryGetValue(derivative.Other, out PhysicalDimension? otherDim))
{
ReportUnknownReference(context, dim.Name, derivative.Other, $"derivatives[{derivative.Other} -> {derivative.Result}].other");
continue;
}

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

Expand Down Expand Up @@ -205,7 +217,7 @@
return result;
}

private static List<ProductInfo> CollectAllProducts(DimensionsMetadata metadata, Dictionary<string, PhysicalDimension> dimMap)
private static List<ProductInfo> CollectAllProducts(SourceProductionContext context, DimensionsMetadata metadata, Dictionary<string, PhysicalDimension> dimMap)
{
HashSet<string> seen = [];
List<ProductInfo> result = [];
Expand All @@ -217,11 +229,13 @@
{
if (!dimMap.TryGetValue(dot.Other, out PhysicalDimension? otherDim))
{
ReportUnknownReference(context, dim.Name, dot.Other, $"dotProducts[{dot.Other} -> {dot.Result}].other");
continue;
}

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

Expand Down Expand Up @@ -255,11 +269,13 @@
{
if (!dimMap.TryGetValue(cross.Other, out PhysicalDimension? otherDim))
{
ReportUnknownReference(context, dim.Name, cross.Other, $"crossProducts[{cross.Other} -> {cross.Result}].other");
continue;
}

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

Expand Down Expand Up @@ -297,6 +313,16 @@
}
}

private static void ReportUnknownReference(SourceProductionContext context, string owningDimension, string unknownReference, string fieldPath)
{
context.ReportDiagnostic(Diagnostic.Create(
UnknownDimensionReference,
Location.None,
owningDimension,
unknownReference,
fieldPath));
}

private static Dictionary<string, List<T>> GroupBy<T>(List<T> items, Func<T, string> keySelector)
{
Dictionary<string, List<T>> groups = [];
Expand Down
Loading