Skip to content

Commit 6abb5f4

Browse files
OleRossangularsen
andauthored
✨Set IsAotCompatible for net7.0 or later (#1543)
Fixes IL warnings when building with AOT. - Add `EnumHelper.GetValues<>` to simplify enumerating enum values for netstandard and net7+, AOT compatible - Replace reflection in `UnitConverter.RegisterDefaultConversions()` with generated code in `Quantity.DefaultProvider.RegisterUnitConversions()` - Add attributes to warn about incompatibilities to Native AOT compilation for `UnitsNet.Serialization.JsonNet`, requires more changes I tried to make minimal changes only, but possibly breaking changes are - the addition of a `struct` constraint to generic enum-constrained methods --------- Co-authored-by: Andreas Gullberg Larsen <[email protected]>
1 parent 7264a1f commit 6abb5f4

File tree

17 files changed

+243
-17
lines changed

17 files changed

+243
-17
lines changed

CodeGen/Generators/UnitsNetGen/StaticQuantityGenerator.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,17 @@ internal static class DefaultProvider
4040
{quantity.Name}.Info,");
4141
Writer.WL(@"
4242
];
43+
44+
internal static void RegisterUnitConversions(UnitConverter unitConverter)
45+
{");
46+
foreach (Quantity quantity in _quantities)
47+
{
48+
Writer.WL($@"
49+
{quantity.Name}.RegisterDefaultConversions(unitConverter);");
50+
}
51+
52+
Writer.WL(@"
53+
}
4354
}
4455
}");
4556
return Writer.ToString();
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net9.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
<RootNamespace>perftest</RootNamespace>
9+
10+
<PublishAot>true</PublishAot>
11+
</PropertyGroup>
12+
13+
<ItemGroup>
14+
<ProjectReference Include="..\..\UnitsNet\UnitsNet.csproj" />
15+
</ItemGroup>
16+
17+
</Project>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
using UnitsNet;
2+
using UnitsNet.Units;
3+
4+
Console.WriteLine(Power.From(5, PowerUnit.Watt));
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/usr/bin/env bash
2+
# shellcheck disable=SC2155
3+
declare -r dirname=$(dirname -- "$0")
4+
5+
pushd "$dirname" || exit
6+
dotnet publish
7+
dotnet timeit "$dirname/timeit.json"
8+
popd || exit
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"warmUpCount": 10,
3+
"count": 20,
4+
"scenarios": [{ "name": "Default" }],
5+
"processName": "../../Artifacts/PerfTest_Startup_Aot/net9.0/win-x64/publish/PerfTest_Startup_Aot.exe",
6+
"workingDirectory": "$(CWD)/",
7+
"processTimeout": 15
8+
}

UnitsNet.NumberExtensions/UnitsNet.NumberExtensions.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
<Nullable>enable</Nullable>
2828
<RootNamespace>UnitsNet</RootNamespace>
2929
<TargetFrameworks>netstandard2.0;net8.0;net9.0</TargetFrameworks>
30+
<IsAotCompatible Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net7.0'))">true</IsAotCompatible>
3031
</PropertyGroup>
3132

3233
<ItemGroup>

UnitsNet.Serialization.JsonNet/UnitsNet.Serialization.JsonNet.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
<Nullable>enable</Nullable>
2929
<RootNamespace>UnitsNet.Serialization.JsonNet</RootNamespace>
3030
<TargetFrameworks>netstandard2.0;net8.0;net9.0</TargetFrameworks>
31+
<IsAotCompatible Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net7.0'))">true</IsAotCompatible>
3132
</PropertyGroup>
3233

3334
<!-- Strong name signing -->

UnitsNet.Serialization.JsonNet/UnitsNetBaseJsonConverter.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
using System;
55
using System.Collections.Concurrent;
6-
using System.Globalization;
6+
using System.Diagnostics.CodeAnalysis;
77
using System.Linq;
88
using Newtonsoft.Json;
99
using Newtonsoft.Json.Linq;
@@ -15,6 +15,10 @@ namespace UnitsNet.Serialization.JsonNet
1515
/// Contains shared functionality used by <see cref="UnitsNetIQuantityJsonConverter"/> and <see cref="UnitsNetIComparableJsonConverter"/>
1616
/// </summary>
1717
/// <typeparam name="T">The type being converted. Should either be <see cref="IQuantity"/> or <see cref="IComparable"/></typeparam>
18+
#if NET
19+
[RequiresDynamicCode("The native code for this instantiation might not be available at runtime.")]
20+
[RequiresUnreferencedCode("If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), trimming can't validate that the requirements of those annotations are met.")]
21+
#endif
1822
public abstract class UnitsNetBaseJsonConverter<T> : NullableQuantityConverter<T>
1923
{
2024
private readonly ConcurrentDictionary<string, (Type Quantity, Type Unit)> _registeredTypes = new();

UnitsNet.Serialization.JsonNet/UnitsNetIComparableJsonConverter.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Copyright 2013 Andreas Gullberg Larsen ([email protected]). Maintained at https://github.com/angularsen/UnitsNet.
33

44
using System;
5+
using System.Diagnostics.CodeAnalysis;
56
using Newtonsoft.Json;
67
using Newtonsoft.Json.Linq;
78

@@ -15,6 +16,10 @@ namespace UnitsNet.Serialization.JsonNet
1516
/// Should only be used when UnitsNet types are assigned to properties of type IComparable.
1617
/// Requires TypeNameHandling on <see cref="JsonSerializerSettings"/> to be set to something other than <see cref="TypeNameHandling.None"/> so that it outputs $type when serializing.
1718
/// </summary>
19+
#if NET
20+
[RequiresDynamicCode("The native code for this instantiation might not be available at runtime.")]
21+
[RequiresUnreferencedCode("If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), trimming can't validate that the requirements of those annotations are met.")]
22+
#endif
1823
public sealed class UnitsNetIComparableJsonConverter : UnitsNetBaseJsonConverter<IComparable?>
1924
{
2025
/// <summary>

UnitsNet.Serialization.JsonNet/UnitsNetIQuantityJsonConverter.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Copyright 2013 Andreas Gullberg Larsen ([email protected]). Maintained at https://github.com/angularsen/UnitsNet.
33

44
using System;
5+
using System.Diagnostics.CodeAnalysis;
56
using Newtonsoft.Json;
67
using Newtonsoft.Json.Linq;
78

@@ -12,6 +13,10 @@ namespace UnitsNet.Serialization.JsonNet
1213
/// JSON.net converter for IQuantity types (e.g. all units in UnitsNet)
1314
/// Use this converter to serialize and deserialize UnitsNet types to and from JSON
1415
/// </summary>
16+
#if NET
17+
[RequiresDynamicCode("The native code for this instantiation might not be available at runtime.")]
18+
[RequiresUnreferencedCode("If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), trimming can't validate that the requirements of those annotations are met.")]
19+
#endif
1520
public sealed class UnitsNetIQuantityJsonConverter : UnitsNetBaseJsonConverter<IQuantity?>
1621
{
1722
/// <summary>

0 commit comments

Comments
 (0)