Skip to content

Commit 50f4631

Browse files
committed
Update to C# 8 and add nullability analysis
1 parent 9ac16f9 commit 50f4631

13 files changed

+123
-1369
lines changed

src/FRC-Utilities/DisposableNativeString.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public unsafe struct DisposableNativeString : IDisposable
2020
/// </summary>
2121
public UIntPtr Length;
2222

23-
private string m_string;
23+
private readonly string m_string;
2424

2525
/// <summary>
2626
/// Creates a new UTF8 string from a managed string
@@ -49,7 +49,6 @@ public DisposableNativeString(string vStr)
4949
public unsafe void Dispose()
5050
{
5151
Marshal.FreeHGlobal((IntPtr)Buffer);
52-
m_string = null;
5352
}
5453

5554
/// <summary>

src/FRC-Utilities/FRC-Utilities.csproj

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<Description>FRC Utility Library</Description>
5-
<Copyright>Copyright 2016-2017 RobotDotNet</Copyright>
5+
<Copyright>Copyright 2016-2019 RobotDotNet</Copyright>
66
<AssemblyTitle>FRC Utilities</AssemblyTitle>
77
<Title>FRC Utilities</Title>
88
<Authors>RobotDotNet</Authors>
@@ -20,10 +20,18 @@
2020
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
2121
<RootNamespace>FRC</RootNamespace>
2222
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
23+
<LangVersion>8.0</LangVersion>
24+
<Nullable>enable</Nullable>
25+
</PropertyGroup>
26+
27+
<PropertyGroup>
28+
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
29+
<WarningsAsErrors />
30+
<Version>3.0.0</Version>
2331
</PropertyGroup>
2432

2533
<ItemGroup>
26-
<PackageReference Include="System.Reflection.Emit" Version="4.3.0" />
27-
<PackageReference Include="System.Reflection.Emit.ILGeneration" Version="4.3.0" />
34+
<PackageReference Include="System.Reflection.Emit" Version="4.6.0" />
35+
<PackageReference Include="System.Reflection.Emit.ILGeneration" Version="4.6.0" />
2836
</ItemGroup>
2937
</Project>

src/FRC-Utilities/ILGeneration/CalliILGenerator.cs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,17 @@
88

99
namespace FRC.ILGeneration
1010
{
11+
/// <summary>
12+
/// Generator for generating CallI IL calls
13+
/// </summary>
1114
public class CalliILGenerator : IILGenerator
1215
{
13-
private readonly object[] invokeArgs = new object[4];
16+
private readonly object?[] invokeArgs = new object?[4];
1417
private readonly MethodInfo methodInfo;
18+
19+
/// <summary>
20+
/// Construct a new Calli il generator
21+
/// </summary>
1522
public CalliILGenerator()
1623
{
1724
var emitMethod = typeof(ILGenerator).GetMethod(nameof(ILGenerator.EmitCalli), new Type[] { typeof(OpCode), typeof(CallingConvention), typeof(Type), typeof(Type[]) });
@@ -20,7 +27,15 @@ public CalliILGenerator()
2027
invokeArgs[1] = CallingConvention.Cdecl;
2128
}
2229

23-
public unsafe void GenerateMethod(ILGenerator generator, Type returnType, Type[] parameters, IntPtr nativeFp, bool isInstance = false)
30+
/// <summary>
31+
/// Generate a native calling method
32+
/// </summary>
33+
/// <param name="generator"></param>
34+
/// <param name="returnType"></param>
35+
/// <param name="parameters"></param>
36+
/// <param name="nativeFp"></param>
37+
/// <param name="isInstance"></param>
38+
public unsafe void GenerateMethod(ILGenerator generator, Type? returnType, Type[]? parameters, IntPtr nativeFp, bool isInstance = false)
2439
{
2540
ILHelpers.VerifyBlittableParameters(returnType, parameters);
2641
if (isInstance)
Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
using System;
22

33
namespace FRC.ILGeneration {
4-
public interface IFunctionPointerLoader {
5-
IntPtr GetProcAddress(string name);
6-
}
4+
/// <summary>
5+
/// Interface for loading a function pointer
6+
/// </summary>
7+
public interface IFunctionPointerLoader {
8+
/// <summary>
9+
/// Get a function pointer for a function name
10+
/// </summary>
11+
/// <param name="name"></param>
12+
/// <returns></returns>
13+
IntPtr GetProcAddress(string name);
14+
}
715
}

src/FRC-Utilities/ILGeneration/ILHelpers.cs

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,34 @@
55

66
namespace FRC.ILGeneration
77
{
8+
/// <summary>
9+
/// Helpers for IL testing
10+
/// </summary>
811
public static class ILHelpers
912
{
10-
public static void VerifyBlittableParameters(Type returnType, Type[] parameters)
13+
/// <summary>
14+
/// Test if parameters are blittable
15+
/// </summary>
16+
/// <param name="returnType"></param>
17+
/// <param name="parameters"></param>
18+
public static void VerifyBlittableParameters(Type? returnType, Type[]? parameters)
1119
{
1220
return;
13-
if (returnType != null && !returnType.IsValueType)
14-
{
15-
throw new InvalidOperationException("Cannot generate for returning a non blittable type");
16-
}
17-
if (parameters == null)
18-
{
19-
return;
20-
}
21-
foreach(var param in parameters)
22-
{
23-
if (!param.IsValueType)
24-
{
25-
throw new InvalidOperationException("Cannot generate parameter for a non blittable type");
26-
}
27-
}
21+
//if (returnType != null && !returnType.IsValueType)
22+
//{
23+
// throw new InvalidOperationException("Cannot generate for returning a non blittable type");
24+
//}
25+
//if (parameters == null)
26+
//{
27+
// return;
28+
//}
29+
//foreach(var param in parameters)
30+
//{
31+
// if (!param.IsValueType)
32+
// {
33+
// throw new InvalidOperationException("Cannot generate parameter for a non blittable type");
34+
// }
35+
//}
2836
}
2937
}
3038
}

src/FRC-Utilities/ILGeneration/InterfaceGenerator.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
namespace FRC.ILGeneration
1010
{
11-
internal class InterfaceGenerator<T>
11+
internal class InterfaceGenerator<T> where T : class
1212
{
1313
private readonly IFunctionPointerLoader functionPointerLoader;
1414
private readonly IILGenerator ilGenerator;
@@ -19,7 +19,7 @@ public InterfaceGenerator(IFunctionPointerLoader functionPointerLoader, IILGener
1919
this.ilGenerator = ilGenerator;
2020
}
2121

22-
public T GenerateImplementation()
22+
public T? GenerateImplementation()
2323
{
2424
Console.WriteLine("Generating Impl");
2525
AssemblyBuilder asmBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(typeof(T).Name + "Asm"), AssemblyBuilderAccess.Run);
@@ -33,7 +33,7 @@ public T GenerateImplementation()
3333
{
3434
var parameters = method.GetParameters().Select(x => x.ParameterType).ToArray();
3535
var methodBuilder = typeBuilder.DefineMethod(method.Name, MethodAttributes.Virtual | MethodAttributes.Public, method.ReturnType, parameters);
36-
var nativeCallAttribute = method.GetCustomAttribute<NativeCallAtrribute>();
36+
var nativeCallAttribute = method.GetCustomAttribute<NativeCallAttribute>();
3737
string nativeName = method.Name;
3838
if (nativeCallAttribute != null && nativeCallAttribute.NativeName != null)
3939
{
@@ -44,7 +44,7 @@ public T GenerateImplementation()
4444

4545
var typeInfo = typeBuilder.CreateTypeInfo();
4646

47-
return (T)typeInfo.GetConstructor(new Type[0]).Invoke(null);
47+
return (T?)typeInfo?.GetConstructor(new Type[0]).Invoke(null);
4848
}
4949
}
5050
}

src/FRC-Utilities/NativeLibraryUtilities/ILibraryInformation.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ public interface ILibraryInformation
88
/// <summary>
99
/// The LibraryLoader used to load this library
1010
/// </summary>
11-
ILibraryLoader LibraryLoader { get; }
11+
ILibraryLoader? LibraryLoader { get; }
1212
/// <summary>
1313
/// The location on disk of the native library
1414
/// </summary>
15-
string LibraryLocation { get; }
15+
string? LibraryLocation { get; }
1616
/// <summary>
1717
/// The OS Type of the loaded system.
1818
/// </summary>

src/FRC-Utilities/NativeLibraryUtilities/NativeCallAttribute.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,28 @@ namespace FRC.NativeLibraryUtilities
66
/// Specifies that the attributed field should be considered a target for native initialization
77
/// </summary>
88
[AttributeUsage(AttributeTargets.Field)]
9-
public class NativeCallAtrribute : Attribute
9+
public class NativeCallAttribute : Attribute
1010
{
1111
/// <summary>
1212
/// Gets the native name for this field if set.
1313
/// </summary>
14-
public string NativeName { get; }
14+
public string? NativeName { get; }
1515

1616
/// <summary>
17-
/// Initializes a new instance of <see cref="NativeCallAtrribute"/>,
17+
/// Initializes a new instance of <see cref="NativeCallAttribute"/>,
1818
/// using the name of the field as the native name.
1919
/// </summary>
20-
public NativeCallAtrribute()
20+
public NativeCallAttribute()
2121
{
2222
NativeName = null;
2323
}
2424

2525
/// <summary>
26-
/// Initializes a new instance of <see cref="NativeCallAtrribute"/>,
26+
/// Initializes a new instance of <see cref="NativeCallAttribute"/>,
2727
/// with the name of the native method passed in.
2828
/// </summary>
2929
/// <param name="nativeName"></param>
30-
public NativeCallAtrribute(string nativeName)
30+
public NativeCallAttribute(string nativeName)
3131
{
3232
NativeName = nativeName;
3333
}

src/FRC-Utilities/NativeLibraryUtilities/NativeLibraryLoader.cs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ public class NativeLibraryLoader : ILibraryInformation
1515
private readonly Dictionary<OsType, string> m_nativeLibraryName = new Dictionary<OsType, string>();
1616

1717
/// <inheritdoc/>
18-
public ILibraryLoader LibraryLoader { get; private set; }
18+
public ILibraryLoader? LibraryLoader { get; private set; }
1919
/// <inheritdoc/>
2020
public OsType OsType { get; } = GetOsType();
2121
/// <inheritdoc/>
2222
public bool UsingTempFile { get; private set; }
2323

2424
/// <inheritdoc/>
25-
public string LibraryLocation { get; private set; }
25+
public string? LibraryLocation { get; private set; }
2626

2727
/// <summary>
2828
/// Checks if the current system is a roboRIO
@@ -51,7 +51,7 @@ public void AddLibraryLocation(OsType osType, string libraryName)
5151
/// <param name="location">The file location. Can be either an embedded resource, or a direct file location</param>
5252
/// <param name="directLoad">True to load the file directly from disk, otherwise false to extract from embedded</param>
5353
/// <param name="extractLocation">The location to extract to if the file is embedded. On null, it extracts to a temp file</param>
54-
public void LoadNativeLibrary<T>(ILibraryLoader loader, string location, bool directLoad = false, string extractLocation = null)
54+
public void LoadNativeLibrary<T>(ILibraryLoader? loader, string location, bool directLoad = false, string? extractLocation = null)
5555
{
5656
if (loader == null)
5757
throw new ArgumentNullException(nameof(loader), "Library loader cannot be null");
@@ -75,9 +75,9 @@ public void LoadNativeLibrary<T>(ILibraryLoader loader, string location, bool di
7575
else
7676
// If we are loading from extraction, extract then load
7777
{
78-
ExtractNativeLibrary(location, extractLocation, typeof(T));
78+
ExtractNativeLibrary(location, extractLocation!, typeof(T));
7979
LibraryLoader = loader;
80-
loader.LoadLibrary(extractLocation);
80+
loader.LoadLibrary(extractLocation!);
8181
LibraryLocation = extractLocation;
8282
}
8383
}
@@ -89,7 +89,7 @@ public void LoadNativeLibrary<T>(ILibraryLoader loader, string location, bool di
8989
/// <param name="location">The file location. Can be either an embedded resource, or a direct file location</param>
9090
/// <param name="directLoad">True to load the file directly from disk, otherwise false to extract from embedded</param>
9191
/// <param name="extractLocation">The location to extract to if the file is embedded. On null, it extracts to a temp file</param>
92-
public void LoadNativeLibrary<T>(string location, bool directLoad = false, string extractLocation = null)
92+
public void LoadNativeLibrary<T>(string location, bool directLoad = false, string? extractLocation = null)
9393
{
9494
if (location == null)
9595
throw new ArgumentNullException(nameof(location), "Library location cannot be null");
@@ -133,7 +133,7 @@ public void LoadNativeLibrary<T>(string location, bool directLoad = false, strin
133133
/// <typeparam name="T">The type containing the native resource, if it is embedded.</typeparam>
134134
/// <param name="directLoad">True to load the file directly from disk, otherwise false to extract from embedded</param>
135135
/// <param name="extractLocation">The location to extract to if the file is embedded. On null, it extracts to a temp file</param>
136-
public void LoadNativeLibrary<T>(bool directLoad = false, string extractLocation = null)
136+
public void LoadNativeLibrary<T>(bool directLoad = false, string? extractLocation = null)
137137
{
138138
OsType osType = OsType;
139139

@@ -235,7 +235,12 @@ public void LoadNativeLibraryFromReflectedAssembly(string assemblyName, bool loc
235235
LibraryLocation = extractLocation;
236236
}
237237

238-
public T LoadNativeInterface<T>() where T : class {
238+
/// <summary>
239+
/// Load a native interface
240+
/// </summary>
241+
/// <typeparam name="T"></typeparam>
242+
/// <returns></returns>
243+
public T? LoadNativeInterface<T>() where T : class {
239244
if (!typeof(T).IsInterface) {
240245
throw new InvalidOperationException($"{typeof(T).Name} must be an interface");
241246
}

src/FRC-Utilities/NativeLibraryUtilities/Uname.cs

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,22 @@ namespace FRC.NativeLibraryUtilities
77
internal sealed class Utsname
88
: IEquatable<Utsname>
99
{
10-
public string sysname;
11-
public string nodename;
12-
public string release;
13-
public string version;
14-
public string machine;
15-
public string domainname;
10+
private readonly string sysname;
11+
private readonly string nodename;
12+
private readonly string release;
13+
private readonly string version;
14+
private readonly string machine;
15+
private readonly string domainname;
16+
17+
public Utsname(string sysname, string nodename, string release, string version, string machine, string domainname)
18+
{
19+
this.sysname = sysname;
20+
this.nodename = nodename;
21+
this.release = release;
22+
this.version = version;
23+
this.machine = machine;
24+
this.domainname = domainname;
25+
}
1626

1727
public override int GetHashCode()
1828
{
@@ -33,7 +43,6 @@ public override bool Equals(object obj)
3343

3444
public bool Equals(Utsname value)
3545
{
36-
if (value == null) return false;
3746
return value.sysname == sysname && value.nodename == nodename &&
3847
value.release == release && value.version == version &&
3948
value.machine == machine && value.domainname == domainname;
@@ -70,19 +79,18 @@ internal struct _Utsname
7079

7180
internal class Uname
7281
{
73-
private static void CopyUtsname(ref Utsname to, ref _Utsname from)
82+
private static void CopyUtsname(out Utsname to, ref _Utsname from)
7483
{
7584
try
7685
{
77-
to = new Utsname
78-
{
79-
sysname = Marshal.PtrToStringAnsi(from.sysname),
80-
nodename = Marshal.PtrToStringAnsi(from.nodename),
81-
release = Marshal.PtrToStringAnsi(from.release),
82-
version = Marshal.PtrToStringAnsi(from.version),
83-
machine = Marshal.PtrToStringAnsi(from.machine),
84-
domainname = Marshal.PtrToStringAnsi(from.domainname)
85-
};
86+
to = new Utsname(
87+
Marshal.PtrToStringAnsi(from.sysname),
88+
Marshal.PtrToStringAnsi(from.nodename),
89+
Marshal.PtrToStringAnsi(from.release),
90+
Marshal.PtrToStringAnsi(from.version),
91+
Marshal.PtrToStringAnsi(from.machine),
92+
Marshal.PtrToStringAnsi(from.domainname)
93+
);
8694
}
8795
finally
8896
{
@@ -101,14 +109,14 @@ private static void CopyUtsname(ref Utsname to, ref _Utsname from)
101109
EntryPoint = "Mono_Posix_Syscall_uname")]
102110
private static extern int sys_uname(out _Utsname buf);
103111

104-
public static int uname(out Utsname buf)
112+
public static int uname(out Utsname? buf)
105113
{
106114
_Utsname _buf;
107115
int r = sys_uname(out _buf);
108-
buf = new Utsname();
116+
buf = null;
109117
if (r == 0)
110118
{
111-
CopyUtsname(ref buf, ref _buf);
119+
CopyUtsname(out buf, ref _buf);
112120
}
113121
return r;
114122
}

0 commit comments

Comments
 (0)