Skip to content

Commit e7aeb4e

Browse files
committed
Merge remote-tracking branch 'origin/master' into release/v5
Fix various nullability issues
2 parents ad5311a + 947a32a commit e7aeb4e

File tree

240 files changed

+2928
-2656
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

240 files changed

+2928
-2656
lines changed

CodeGen/Generators/UnitsNetGen/QuantityGenerator.cs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ private void GenerateStaticConstructor()
161161
}},
162162
BaseUnit, Zero, BaseDimensions);
163163
164+
DefaultConversionFunctions = new UnitConverter();
165+
164166
RegisterDefaultConversions(DefaultConversionFunctions);
165167
}}
166168
");
@@ -221,7 +223,7 @@ private void GenerateStaticProperties()
221223
/// <summary>
222224
/// The <see cref=""UnitConverter"" /> containing the default generated conversion functions for <see cref=""{_quantity.Name}"" /> instances.
223225
/// </summary>
224-
public static UnitConverter DefaultConversionFunctions {{ get; }} = new UnitConverter();
226+
public static UnitConverter DefaultConversionFunctions {{ get; }}
225227
226228
/// <inheritdoc cref=""IQuantity.QuantityInfo""/>
227229
public static QuantityInfo<{_unitEnumName}> Info {{ get; }}
@@ -352,14 +354,33 @@ internal static void RegisterDefaultConversions(UnitConverter unitConverter)
352354
if(unit.SingularName == _quantity.BaseUnit)
353355
continue;
354356

355-
var func = unit.FromUnitToBaseFunc.Replace("{x}", "quantity.Value");
356-
Writer.WL($@"
357+
var func = unit.FromUnitToBaseFunc.Replace("{x}", "quantity.Value");
358+
Writer.WL($@"
357359
unitConverter.SetConversionFunction<{_quantity.Name}>({_quantity.Name}Unit.{unit.SingularName}, {_unitEnumName}.{_quantity.BaseUnit}, quantity => new {_quantity.Name}({func}, {_unitEnumName}.{_quantity.BaseUnit}));");
358360
}
359361

360362
Writer.WL($@"
361363
}}
362364
365+
internal static void MapGeneratedLocalizations(UnitAbbreviationsCache unitAbbreviationsCache)
366+
{{");
367+
foreach(var unit in _quantity.Units)
368+
{
369+
foreach(var localization in unit.Localization)
370+
{
371+
// All units must have a unit abbreviation, so fallback to "" for units with no abbreviations defined in JSON
372+
var abbreviationParams = localization.Abbreviations.Any() ?
373+
string.Join(", ", localization.Abbreviations.Select(abbr => $@"""{abbr}""")) :
374+
$@"""""";
375+
376+
Writer.WL($@"
377+
unitAbbreviationsCache.MapUnitToAbbreviation({_unitEnumName}.{unit.SingularName}, new CultureInfo(""{localization.Culture}""), new string[]{{{abbreviationParams}}});");
378+
}
379+
}
380+
381+
Writer.WL($@"
382+
}}
383+
363384
/// <summary>
364385
/// Get unit abbreviation string.
365386
/// </summary>

CodeGen/Generators/UnitsNetGen/StaticQuantityGenerator.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,14 @@ public static bool TryParse(IFormatProvider? formatProvider, Type quantityType,
128128
return false;
129129
}
130130
}
131+
132+
internal static IEnumerable<Type> GetQuantityTypes()
133+
{");
134+
foreach (var quantity in _quantities)
135+
Writer.WL($@"
136+
yield return typeof({quantity.Name});");
137+
Writer.WL(@"
138+
}
131139
}
132140
}");
133141
return Writer.ToString();

CodeGen/Generators/UnitsNetGen/UnitAbbreviationsCacheGenerator.cs

Lines changed: 0 additions & 58 deletions
This file was deleted.

CodeGen/Generators/UnitsNetGen/UnitTestBaseClassGenerator.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -281,12 +281,8 @@ public void ToUnit_WithSameUnits_AreEqual({_unitEnumName} unit)
281281
[MemberData(nameof(UnitTypes))]
282282
public void ToUnit_FromNonBaseUnit_ReturnsQuantityWithGivenUnit({_unitEnumName} unit)
283283
{{
284-
// See if there is a unit available that is not the base unit.
285-
var fromUnit = {_quantity.Name}.Units.FirstOrDefault(u => u != {_quantity.Name}.BaseUnit && u != {_unitEnumName}.Undefined);
286-
287-
// If there is only one unit for the quantity, we must use the base unit.
288-
if(fromUnit == {_unitEnumName}.Undefined)
289-
fromUnit = {_quantity.Name}.BaseUnit;
284+
// See if there is a unit available that is not the base unit, fallback to base unit if it has only a single unit.
285+
var fromUnit = {_quantity.Name}.Units.FirstOrDefault(u => u != {_quantity.Name}.BaseUnit);
290286
291287
var quantity = {_quantity.Name}.From(3.0, fromUnit);
292288
var converted = quantity.ToUnit(unit);

CodeGen/Generators/UnitsNetGenerator.cs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ public static void Generate(string rootDir, Quantity[] quantities)
6666

6767
Log.Information("");
6868
GenerateIQuantityTests(quantities, $"{testProjectDir}/GeneratedCode/IQuantityTests.g.cs");
69-
GenerateUnitAbbreviationsCache(quantities, $"{outputDir}/UnitAbbreviationsCache.g.cs");
7069
GenerateStaticQuantity(quantities, $"{outputDir}/Quantity.g.cs");
7170

7271
var unitCount = quantities.SelectMany(q => q.Units).Count();
@@ -121,13 +120,6 @@ private static void GenerateIQuantityTests(Quantity[] quantities, string filePat
121120
Log.Information("✅ IQuantityTests.g.cs");
122121
}
123122

124-
private static void GenerateUnitAbbreviationsCache(Quantity[] quantities, string filePath)
125-
{
126-
var content = new UnitAbbreviationsCacheGenerator(quantities).Generate();
127-
File.WriteAllText(filePath, content);
128-
Log.Information("✅ UnitAbbreviationsCache.g.cs");
129-
}
130-
131123
private static void GenerateStaticQuantity(Quantity[] quantities, string filePath)
132124
{
133125
var content = new StaticQuantityGenerator(quantities).Generate();

UnitsNet.Serialization.JsonNet/AbbreviatedUnitsConverter.cs

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public class AbbreviatedUnitsConverter : JsonConverter<IQuantity>
2727
private const string TypeProperty = "Type";
2828

2929
private readonly UnitAbbreviationsCache _abbreviations;
30-
private readonly IEqualityComparer<string> _propertyComparer;
30+
private readonly IEqualityComparer<string?> _propertyComparer;
3131
private readonly IDictionary<string, QuantityInfo> _quantities;
3232
private readonly UnitParser _unitParser;
3333

@@ -43,7 +43,7 @@ public AbbreviatedUnitsConverter()
4343
/// Construct a converter using the default list of quantities and unit abbreviation provider
4444
/// </summary>
4545
/// <param name="comparer">The comparer used to compare the property/quantity names (e.g. StringComparer.OrdinalIgnoreCase) </param>
46-
public AbbreviatedUnitsConverter(IEqualityComparer<string> comparer)
46+
public AbbreviatedUnitsConverter(IEqualityComparer<string?> comparer)
4747
: this(new Dictionary<string, QuantityInfo>(Quantity.ByName, comparer), UnitAbbreviationsCache.Default, comparer)
4848
{
4949
}
@@ -54,7 +54,7 @@ public AbbreviatedUnitsConverter(IEqualityComparer<string> comparer)
5454
/// <param name="quantities">The dictionary of quantity names</param>
5555
/// <param name="abbreviations">The unit abbreviations used for the serialization </param>
5656
/// <param name="propertyComparer">The comparer used to compare the property names (e.g. StringComparer.OrdinalIgnoreCase) </param>
57-
public AbbreviatedUnitsConverter(IDictionary<string, QuantityInfo> quantities, UnitAbbreviationsCache abbreviations, IEqualityComparer<string> propertyComparer)
57+
public AbbreviatedUnitsConverter(IDictionary<string, QuantityInfo> quantities, UnitAbbreviationsCache abbreviations, IEqualityComparer<string?> propertyComparer)
5858
{
5959
_quantities = quantities;
6060
_abbreviations = abbreviations;
@@ -63,7 +63,7 @@ public AbbreviatedUnitsConverter(IDictionary<string, QuantityInfo> quantities, U
6363
}
6464

6565
/// <inheritdoc />
66-
public override void WriteJson(JsonWriter writer, IQuantity quantity, JsonSerializer serializer)
66+
public override void WriteJson(JsonWriter writer, IQuantity? quantity, JsonSerializer serializer)
6767
{
6868
if (quantity is null)
6969
{
@@ -110,17 +110,16 @@ protected string GetQuantityType(IQuantity quantity)
110110
}
111111

112112
/// <inheritdoc />
113-
public override IQuantity ReadJson(JsonReader reader, Type objectType, IQuantity existingValue, bool hasExistingValue, JsonSerializer serializer)
113+
public override IQuantity? ReadJson(JsonReader reader, Type objectType, IQuantity? existingValue, bool hasExistingValue, JsonSerializer serializer)
114114
{
115-
QuantityInfo quantityInfo;
115+
QuantityInfo? quantityInfo;
116116
if (reader.TokenType == JsonToken.Null)
117117
{
118-
// return null;
119118
return TryGetQuantity(objectType.Name, out quantityInfo) ? quantityInfo.Zero : default;
120119
}
121120

122-
string valueToken = null;
123-
string unitAbbreviation = null, quantityName = null;
121+
string? valueToken = null;
122+
string? unitAbbreviation = null, quantityName = null;
124123
if (reader.TokenType == JsonToken.StartObject)
125124
{
126125
while (reader.Read() && reader.TokenType != JsonToken.EndObject)
@@ -148,18 +147,23 @@ public override IQuantity ReadJson(JsonReader reader, Type objectType, IQuantity
148147
}
149148
}
150149

150+
151151
Enum unit;
152152
if (quantityName is null)
153153
{
154154
if (TryGetQuantity(objectType.Name, out quantityInfo))
155155
{
156156
unit = GetUnitOrDefault(unitAbbreviation, quantityInfo);
157157
}
158-
else // the objectType doesn't match any concrete quantity type (likely it is an IQuantity)
158+
else if (unitAbbreviation != null) // the objectType doesn't match any concrete quantity type (likely it is an IQuantity)
159159
{
160160
// failing back to an exhaustive search (it is possible that this converter was created with a short-list of non-ambiguous quantities
161161
unit = FindUnit(unitAbbreviation, out quantityInfo);
162162
}
163+
else
164+
{
165+
throw new FormatException("No unit abbreviation found in JSON.");
166+
}
163167
}
164168
else
165169
{
@@ -203,8 +207,8 @@ protected virtual Enum FindUnit(string unitAbbreviation, out QuantityInfo quanti
203207
throw new UnitNotFoundException("The unit abbreviation and quantity type cannot both be null");
204208
}
205209

206-
Enum unit = null;
207-
quantityInfo = default;
210+
Enum? unit = null;
211+
QuantityInfo? tempQuantityInfo = default;
208212
foreach (var targetQuantity in _quantities.Values)
209213
{
210214
if (!TryParse(unitAbbreviation, targetQuantity, out var unitMatched))
@@ -213,20 +217,21 @@ protected virtual Enum FindUnit(string unitAbbreviation, out QuantityInfo quanti
213217
}
214218

215219
if (unit != null &&
216-
!(targetQuantity == quantityInfo && Equals(unit, unitMatched))) // it is possible to have "synonyms": e.g. "Mass" and "Weight"
220+
!(targetQuantity == tempQuantityInfo && Equals(unit, unitMatched))) // it is possible to have "synonyms": e.g. "Mass" and "Weight"
217221
{
218222
throw new AmbiguousUnitParseException($"Multiple quantities found matching the provided abbreviation: {unit}, {unitMatched}");
219223
}
220224

221-
quantityInfo = targetQuantity;
225+
tempQuantityInfo = targetQuantity;
222226
unit = unitMatched;
223227
}
224228

225-
if (unit is null)
229+
if (unit is null || tempQuantityInfo is null)
226230
{
227231
throw new UnitNotFoundException($"No quantity found with abbreviation [{unitAbbreviation}].");
228232
}
229233

234+
quantityInfo = tempQuantityInfo;
230235
return unit;
231236
}
232237

@@ -254,7 +259,7 @@ protected string GetUnitAbbreviation(Enum unit)
254259
/// <returns>Unit enum value, such as <see cref="MassUnit.Kilogram" />.</returns>
255260
/// <exception cref="UnitNotFoundException">No units match the abbreviation.</exception>
256261
/// <exception cref="AmbiguousUnitParseException">More than one unit matches the abbreviation.</exception>
257-
protected virtual Enum GetUnitOrDefault(string unitAbbreviation, QuantityInfo quantityInfo)
262+
protected virtual Enum GetUnitOrDefault(string? unitAbbreviation, QuantityInfo quantityInfo)
258263
{
259264
return unitAbbreviation == null
260265
? quantityInfo.BaseUnitInfo.Value
@@ -269,7 +274,7 @@ protected virtual Enum GetUnitOrDefault(string unitAbbreviation, QuantityInfo qu
269274
/// <returns>Unit enum value, such as <see cref="MassUnit.Kilogram" />.</returns>
270275
/// <exception cref="UnitNotFoundException">No units match the abbreviation.</exception>
271276
/// <exception cref="AmbiguousUnitParseException">More than one unit matches the abbreviation.</exception>
272-
protected Enum Parse(string unitAbbreviation, QuantityInfo quantityInfo)
277+
protected Enum Parse(string? unitAbbreviation, QuantityInfo quantityInfo)
273278
{
274279
return _unitParser.Parse(unitAbbreviation, quantityInfo.UnitType, CultureInfo.InvariantCulture);
275280
}
@@ -283,7 +288,7 @@ protected Enum Parse(string unitAbbreviation, QuantityInfo quantityInfo)
283288
/// <returns>True if successful.</returns>
284289
/// <exception cref="UnitNotFoundException">No units match the abbreviation.</exception>
285290
/// <exception cref="AmbiguousUnitParseException">More than one unit matches the abbreviation.</exception>
286-
protected bool TryParse(string unitAbbreviation, QuantityInfo quantityInfo, out Enum unit)
291+
protected bool TryParse(string? unitAbbreviation, QuantityInfo quantityInfo, out Enum? unit)
287292
{
288293
return _unitParser.TryParse(unitAbbreviation, quantityInfo.UnitType, CultureInfo.InvariantCulture, out unit);
289294
}

UnitsNet.Tests/CustomCode/PressureTests.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -213,12 +213,6 @@ public void Reference_WithDefaultPressureReference_IsAbsolute()
213213
Equals(PressureReference.Absolute, refPressure.Reference);
214214
}
215215

216-
[Fact]
217-
public void ReferencesDoesNotContainUndefined()
218-
{
219-
Assert.DoesNotContain(PressureReference.Undefined, ReferencePressure.References);
220-
}
221-
222216
[Fact]
223217
public void Vacuum_WithDefaultPressureReference_IsOneLessAtmosphereNegative()
224218
{

UnitsNet.Tests/GeneratedCode/TestsBase/AccelerationTestsBase.g.cs

Lines changed: 2 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

UnitsNet.Tests/GeneratedCode/TestsBase/AmountOfSubstanceTestsBase.g.cs

Lines changed: 2 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

UnitsNet.Tests/GeneratedCode/TestsBase/AmplitudeRatioTestsBase.g.cs

Lines changed: 2 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)