/// <summary> /// Generate source code for UnitsNet project for the given parsed quantities. /// Outputs files relative to the given root dir to these locations: /// <list type="bullet"> /// <item> /// <description>UnitsNet/GeneratedCode (quantity and unit types, Quantity, UnitAbbreviationCache)</description> /// </item> /// <item> /// <description>UnitsNet.Tests/GeneratedCode (tests)</description> /// </item> /// <item> /// <description>UnitsNet.Tests/CustomCode (test stubs, one for each quantity if not already created)</description> /// </item> /// </list> /// </summary> /// <param name="rootDir">Path to repository root directory.</param> /// <param name="quantities">The parsed quantities.</param> /// <param name="quantityNameToUnitEnumValues">Allocated unit enum values for generating unit enum types.</param> public static void Generate(string rootDir, Quantity[] quantities, QuantityNameToUnitEnumValues quantityNameToUnitEnumValues) { var outputDir = $"{rootDir}/UnitsNet/GeneratedCode"; var extensionsOutputDir = $"{rootDir}/UnitsNet.NumberExtensions/GeneratedCode"; var extensionsTestOutputDir = $"{rootDir}/UnitsNet.NumberExtensions.Tests/GeneratedCode"; var testProjectDir = $"{rootDir}/UnitsNet.Tests"; // Ensure output directories exist Directory.CreateDirectory($"{outputDir}/Quantities"); Directory.CreateDirectory($"{outputDir}/Units"); Directory.CreateDirectory($"{extensionsOutputDir}"); Directory.CreateDirectory($"{extensionsTestOutputDir}"); Directory.CreateDirectory($"{testProjectDir}/GeneratedCode"); Directory.CreateDirectory($"{testProjectDir}/GeneratedCode/TestsBase"); Directory.CreateDirectory($"{testProjectDir}/GeneratedCode/QuantityTests"); foreach (var quantity in quantities) { UnitEnumNameToValue unitEnumValues = quantityNameToUnitEnumValues[quantity.Name]; GenerateQuantity(quantity, $"{outputDir}/Quantities/{quantity.Name}.g.cs"); GenerateUnitType(quantity, $"{outputDir}/Units/{quantity.Name}Unit.g.cs", unitEnumValues); GenerateNumberToExtensions(quantity, $"{extensionsOutputDir}/NumberTo{quantity.Name}Extensions.g.cs"); GenerateNumberToExtensionsTestClass(quantity, $"{extensionsTestOutputDir}/NumberTo{quantity.Name}ExtensionsTest.g.cs"); // Example: CustomCode/Quantities/LengthTests inherits GeneratedCode/TestsBase/LengthTestsBase // This way when new units are added to the quantity JSON definition, we auto-generate the new // conversion function tests that needs to be manually implemented by the developer to fix the compile error // so it cannot be forgotten. GenerateQuantityTestBaseClass(quantity, $"{testProjectDir}/GeneratedCode/TestsBase/{quantity.Name}TestsBase.g.cs"); GenerateQuantityTestClassIfNotExists(quantity, $"{testProjectDir}/CustomCode/{quantity.Name}Tests.cs"); Log.Information("✅ {Quantity}", quantity.Name); } Log.Information(""); GenerateIQuantityTests(quantities, $"{testProjectDir}/GeneratedCode/IQuantityTests.g.cs"); GenerateQuantityType(quantities, $"{outputDir}/QuantityType.g.cs"); GenerateStaticQuantity(quantities, $"{outputDir}/Quantity.g.cs"); var unitCount = quantities.SelectMany(q => q.Units).Count(); Log.Information(""); Log.Information("Total of {UnitCount} units and {QuantityCount} quantities", unitCount, quantities.Length); Log.Information(""); }
public UnitTypeGenerator(Quantity quantity, UnitEnumNameToValue unitEnumNameToValue) { _quantity = quantity; _unitEnumNameToValue = unitEnumNameToValue; _unitEnumName = $"{quantity.Name}Unit"; }
private static void GenerateUnitType(Quantity quantity, string filePath, UnitEnumNameToValue unitEnumValues) { var content = new UnitTypeGenerator(quantity, unitEnumValues).Generate(); File.WriteAllText(filePath, content); }