diff --git a/src/Java.Interop.Localization/Java.Interop.Localization.csproj b/src/Java.Interop.Localization/Java.Interop.Localization.csproj index 0e0466f99..0e9cb2f5a 100644 --- a/src/Java.Interop.Localization/Java.Interop.Localization.csproj +++ b/src/Java.Interop.Localization/Java.Interop.Localization.csproj @@ -2,6 +2,9 @@ netstandard2.0 + 8.0 + enable + INTERNAL_NULLABLE_ATTRIBUTES @@ -16,6 +19,10 @@ + + + + PublicResXFileCodeGenerator diff --git a/src/Java.Interop.Tools.Cecil/Java.Interop.Tools.Cecil.csproj b/src/Java.Interop.Tools.Cecil/Java.Interop.Tools.Cecil.csproj index bedf3d64e..8b9f559fd 100644 --- a/src/Java.Interop.Tools.Cecil/Java.Interop.Tools.Cecil.csproj +++ b/src/Java.Interop.Tools.Cecil/Java.Interop.Tools.Cecil.csproj @@ -2,6 +2,9 @@ netstandard2.0 + 8.0 + enable + INTERNAL_NULLABLE_ATTRIBUTES @@ -10,6 +13,10 @@ $(ToolOutputFullPath) + + + + diff --git a/src/Java.Interop.Tools.Cecil/Java.Interop.Tools.Cecil/DirectoryAssemblyResolver.cs b/src/Java.Interop.Tools.Cecil/Java.Interop.Tools.Cecil/DirectoryAssemblyResolver.cs index cc8f8436d..54313faa7 100644 --- a/src/Java.Interop.Tools.Cecil/Java.Interop.Tools.Cecil/DirectoryAssemblyResolver.cs +++ b/src/Java.Interop.Tools.Cecil/Java.Interop.Tools.Cecil/DirectoryAssemblyResolver.cs @@ -61,7 +61,7 @@ public class DirectoryAssemblyResolver : IAssemblyResolver { public ICollection SearchDirectories {get; private set;} - Dictionary cache; + Dictionary cache; bool loadDebugSymbols; Action logger; @@ -71,18 +71,18 @@ public class DirectoryAssemblyResolver : IAssemblyResolver { }; [Obsolete ("Use DirectoryAssemblyResolver(Action, bool, ReaderParameters)")] - public DirectoryAssemblyResolver (Action logWarnings, bool loadDebugSymbols, ReaderParameters loadReaderParameters = null) + public DirectoryAssemblyResolver (Action logWarnings, bool loadDebugSymbols, ReaderParameters? loadReaderParameters = null) : this ((TraceLevel level, string value) => logWarnings?.Invoke ("{0}", new[]{value}), loadDebugSymbols, loadReaderParameters) { if (logWarnings == null) throw new ArgumentNullException (nameof (logWarnings)); } - public DirectoryAssemblyResolver (Action logger, bool loadDebugSymbols, ReaderParameters loadReaderParameters = null) + public DirectoryAssemblyResolver (Action logger, bool loadDebugSymbols, ReaderParameters? loadReaderParameters = null) { if (logger == null) throw new ArgumentNullException (nameof (logger)); - cache = new Dictionary (); + cache = new Dictionary (); this.loadDebugSymbols = loadDebugSymbols; this.logger = logger; SearchDirectories = new List (); @@ -100,14 +100,14 @@ protected virtual void Dispose (bool disposing) if (!disposing || cache == null) return; foreach (var e in cache) { - e.Value.Dispose (); + e.Value?.Dispose (); } - cache = null; + cache.Clear (); } - public Dictionary ToResolverCache () + public Dictionary ToResolverCache () { - return new Dictionary(cache); + return new Dictionary(cache); } public bool AddToCache (AssemblyDefinition assembly) @@ -122,12 +122,12 @@ public bool AddToCache (AssemblyDefinition assembly) return true; } - public virtual AssemblyDefinition Load (string fileName, bool forceLoad = false) + public virtual AssemblyDefinition? Load (string fileName, bool forceLoad = false) { if (!File.Exists (fileName)) return null; - AssemblyDefinition assembly = null; + AssemblyDefinition? assembly = null; var name = Path.GetFileNameWithoutExtension (fileName); if (!forceLoad && cache.TryGetValue (name, out assembly)) return assembly; @@ -181,7 +181,7 @@ public AssemblyDefinition Resolve (string fullName) return Resolve (fullName, null); } - public AssemblyDefinition Resolve (string fullName, ReaderParameters parameters) + public AssemblyDefinition Resolve (string fullName, ReaderParameters? parameters) { return Resolve (AssemblyNameReference.Parse (fullName), parameters); } @@ -200,7 +200,7 @@ public string FindAssemblyFile (AssemblyNameReference reference) { var name = reference.Name; - string assembly; + string? assembly; foreach (var dir in SearchDirectories) if ((assembly = SearchDirectory (name, dir)) != null) return assembly; @@ -216,20 +216,24 @@ public string FindAssemblyFile (AssemblyNameReference reference) name + ".dll"); } - public AssemblyDefinition Resolve (AssemblyNameReference reference, ReaderParameters parameters) + public AssemblyDefinition Resolve (AssemblyNameReference reference, ReaderParameters? parameters) { var name = reference.Name; - AssemblyDefinition assembly; - if (cache.TryGetValue (name, out assembly)) + AssemblyDefinition? assembly; + if (cache.TryGetValue (name, out assembly)) { + if (assembly is null) + throw CreateLoadException (reference); + return assembly; + } - string assemblyFile; - AssemblyDefinition candidate = null; + string? assemblyFile; + AssemblyDefinition? candidate = null; foreach (var dir in SearchDirectories) { if ((assemblyFile = SearchDirectory (name, dir)) != null) { var loaded = Load (assemblyFile); - if (Array.Equals (loaded.Name.MetadataToken, reference.MetadataToken)) + if (Array.Equals (loaded?.Name.MetadataToken, reference.MetadataToken)) return loaded; candidate = candidate ?? loaded; } @@ -238,18 +242,23 @@ public AssemblyDefinition Resolve (AssemblyNameReference reference, ReaderParame if (candidate != null) return candidate; - throw new System.IO.FileNotFoundException ( + throw CreateLoadException (reference); + } + + static FileNotFoundException CreateLoadException (AssemblyNameReference reference) + { + return new System.IO.FileNotFoundException ( string.Format ("Could not load assembly '{0}, Version={1}, Culture={2}, PublicKeyToken={3}'. Perhaps it doesn't exist in the Mono for Android profile?", - name, - reference.Version, - string.IsNullOrEmpty (reference.Culture) ? "neutral" : reference.Culture, + reference.Name, + reference.Version, + string.IsNullOrEmpty (reference.Culture) ? "neutral" : reference.Culture, reference.PublicKeyToken == null ? "null" - : string.Join ("", reference.PublicKeyToken.Select(b => b.ToString ("x2")))), - name + ".dll"); + : string.Join ("", reference.PublicKeyToken.Select (b => b.ToString ("x2")))), + reference.Name + ".dll"); } - string SearchDirectory (string name, string directory) + string? SearchDirectory (string name, string directory) { if (Path.IsPathRooted (name) && File.Exists (name)) return name; diff --git a/src/Java.Interop.Tools.Cecil/Java.Interop.Tools.Cecil/MethodDefinitionRocks.cs b/src/Java.Interop.Tools.Cecil/Java.Interop.Tools.Cecil/MethodDefinitionRocks.cs index 9dcc98d81..74855f52e 100644 --- a/src/Java.Interop.Tools.Cecil/Java.Interop.Tools.Cecil/MethodDefinitionRocks.cs +++ b/src/Java.Interop.Tools.Cecil/Java.Interop.Tools.Cecil/MethodDefinitionRocks.cs @@ -13,7 +13,7 @@ public static class MethodDefinitionRocks public static MethodDefinition GetBaseDefinition (this MethodDefinition method) => GetBaseDefinition (method, cache: null); - public static MethodDefinition GetBaseDefinition (this MethodDefinition method, TypeDefinitionCache cache) + public static MethodDefinition GetBaseDefinition (this MethodDefinition method, TypeDefinitionCache? cache) { if (method.IsStatic || method.IsNewSlot || !method.IsVirtual) return method; @@ -35,7 +35,7 @@ public static MethodDefinition GetBaseDefinition (this MethodDefinition method, public static IEnumerable GetOverriddenMethods (MethodDefinition method, bool inherit) => GetOverriddenMethods (method, inherit, cache: null); - public static IEnumerable GetOverriddenMethods (MethodDefinition method, bool inherit, TypeDefinitionCache cache) + public static IEnumerable GetOverriddenMethods (MethodDefinition method, bool inherit, TypeDefinitionCache? cache) { yield return method; if (inherit) { @@ -51,7 +51,7 @@ public static IEnumerable GetOverriddenMethods (MethodDefiniti public static bool AreParametersCompatibleWith (this Collection a, Collection b) => AreParametersCompatibleWith (a, b, cache: null); - public static bool AreParametersCompatibleWith (this Collection a, Collection b, TypeDefinitionCache cache) + public static bool AreParametersCompatibleWith (this Collection a, Collection b, TypeDefinitionCache? cache) { if (a.Count != b.Count) return false; @@ -66,7 +66,7 @@ public static bool AreParametersCompatibleWith (this Collection + public static TypeDefinition? GetBaseType (this TypeDefinition type) => GetBaseType (type, cache: null); - public static TypeDefinition GetBaseType (this TypeDefinition type, TypeDefinitionCache cache) + public static TypeDefinition? GetBaseType (this TypeDefinition type, TypeDefinitionCache? cache) { var bt = type.BaseType; if (bt == null) @@ -25,11 +25,13 @@ public static TypeDefinition GetBaseType (this TypeDefinition type, TypeDefiniti public static IEnumerable GetTypeAndBaseTypes (this TypeDefinition type) => GetTypeAndBaseTypes (type, cache: null); - public static IEnumerable GetTypeAndBaseTypes (this TypeDefinition type, TypeDefinitionCache cache) + public static IEnumerable GetTypeAndBaseTypes (this TypeDefinition type, TypeDefinitionCache? cache) { - while (type != null) { - yield return type; - type = type.GetBaseType (cache); + TypeDefinition? t = type; + + while (t != null) { + yield return t; + t = t.GetBaseType (cache); } } @@ -37,10 +39,12 @@ public static IEnumerable GetTypeAndBaseTypes (this TypeDefiniti public static IEnumerable GetBaseTypes (this TypeDefinition type) => GetBaseTypes (type, cache: null); - public static IEnumerable GetBaseTypes (this TypeDefinition type, TypeDefinitionCache cache) + public static IEnumerable GetBaseTypes (this TypeDefinition type, TypeDefinitionCache? cache) { - while ((type = type.GetBaseType (cache)) != null) { - yield return type; + TypeDefinition? t = type; + + while ((t = t.GetBaseType (cache)) != null) { + yield return t; } } @@ -48,7 +52,7 @@ public static IEnumerable GetBaseTypes (this TypeDefinition type public static bool IsAssignableFrom (this TypeReference type, TypeReference c) => IsAssignableFrom (type, c, cache: null); - public static bool IsAssignableFrom (this TypeReference type, TypeReference c, TypeDefinitionCache cache) + public static bool IsAssignableFrom (this TypeReference type, TypeReference c, TypeDefinitionCache? cache) { if (type.FullName == c.FullName) return true; @@ -71,7 +75,7 @@ public static bool IsAssignableFrom (this TypeReference type, TypeReference c, T public static bool IsSubclassOf (this TypeDefinition type, string typeName) => IsSubclassOf (type, typeName, cache: null); - public static bool IsSubclassOf (this TypeDefinition type, string typeName, TypeDefinitionCache cache) + public static bool IsSubclassOf (this TypeDefinition type, string typeName, TypeDefinitionCache? cache) { foreach (var t in type.GetTypeAndBaseTypes (cache)) { if (t.FullName == typeName) { @@ -85,7 +89,7 @@ public static bool IsSubclassOf (this TypeDefinition type, string typeName, Type public static bool ImplementsInterface (this TypeDefinition type, string interfaceName) => ImplementsInterface (type, interfaceName, cache: null); - public static bool ImplementsInterface (this TypeDefinition type, string interfaceName, TypeDefinitionCache cache) + public static bool ImplementsInterface (this TypeDefinition type, string interfaceName, TypeDefinitionCache? cache) { foreach (var t in type.GetTypeAndBaseTypes (cache)) { foreach (var i in t.Interfaces) { @@ -101,7 +105,7 @@ public static bool ImplementsInterface (this TypeDefinition type, string interfa public static string GetPartialAssemblyName (this TypeReference type) => GetPartialAssemblyName (type, cache: null); - public static string GetPartialAssemblyName (this TypeReference type, TypeDefinitionCache cache) + public static string GetPartialAssemblyName (this TypeReference type, TypeDefinitionCache? cache) { TypeDefinition def = cache != null ? cache.Resolve (type) : type.Resolve (); return (def ?? type).Module.Assembly.Name.Name; @@ -111,7 +115,7 @@ public static string GetPartialAssemblyName (this TypeReference type, TypeDefini public static string GetPartialAssemblyQualifiedName (this TypeReference type) => GetPartialAssemblyQualifiedName (type, cache: null); - public static string GetPartialAssemblyQualifiedName (this TypeReference type, TypeDefinitionCache cache) + public static string GetPartialAssemblyQualifiedName (this TypeReference type, TypeDefinitionCache? cache) { return string.Format ("{0}, {1}", // Cecil likes to use '/' as the nested type separator, while @@ -124,7 +128,7 @@ public static string GetPartialAssemblyQualifiedName (this TypeReference type, T public static string GetAssemblyQualifiedName (this TypeReference type) => GetAssemblyQualifiedName (type, cache: null); - public static string GetAssemblyQualifiedName (this TypeReference type, TypeDefinitionCache cache) + public static string GetAssemblyQualifiedName (this TypeReference type, TypeDefinitionCache? cache) { TypeDefinition def = cache != null ? cache.Resolve (type) : type.Resolve (); return string.Format ("{0}, {1}", @@ -134,7 +138,7 @@ public static string GetAssemblyQualifiedName (this TypeReference type, TypeDefi (def ?? type).Module.Assembly.Name.FullName); } - public static TypeDefinition GetNestedType (this TypeDefinition type, string name) + public static TypeDefinition? GetNestedType (this TypeDefinition type, string name) { if (type == null) return null; @@ -147,7 +151,7 @@ public static TypeDefinition GetNestedType (this TypeDefinition type, string nam } // Note: this is not recursive, so it will not find nested types. - public static TypeDefinition FindType (this ModuleDefinition module, string name) + public static TypeDefinition? FindType (this ModuleDefinition module, string name) { if (module == null) return null; diff --git a/src/Java.Interop.Tools.Diagnostics/Java.Interop.Tools.Diagnostics.csproj b/src/Java.Interop.Tools.Diagnostics/Java.Interop.Tools.Diagnostics.csproj index 5ae7d40b9..7167106bf 100644 --- a/src/Java.Interop.Tools.Diagnostics/Java.Interop.Tools.Diagnostics.csproj +++ b/src/Java.Interop.Tools.Diagnostics/Java.Interop.Tools.Diagnostics.csproj @@ -2,6 +2,9 @@ netstandard2.0 + 8.0 + enable + INTERNAL_NULLABLE_ATTRIBUTES @@ -10,4 +13,8 @@ $(ToolOutputFullPath) + + + + diff --git a/src/Java.Interop.Tools.Diagnostics/Java.Interop.Tools.Diagnostics/XamarinAndroidException.cs b/src/Java.Interop.Tools.Diagnostics/Java.Interop.Tools.Diagnostics/XamarinAndroidException.cs index 43ceb36a5..7cea2dfa1 100644 --- a/src/Java.Interop.Tools.Diagnostics/Java.Interop.Tools.Diagnostics/XamarinAndroidException.cs +++ b/src/Java.Interop.Tools.Diagnostics/Java.Interop.Tools.Diagnostics/XamarinAndroidException.cs @@ -24,7 +24,7 @@ static string GetMessage (int code, string message, object [] args) return m.ToString (); } - public XamarinAndroidException (int code, Exception innerException, string message, params object [] args) + public XamarinAndroidException (int code, Exception? innerException, string message, params object [] args) : base (GetMessage (code, message, args), innerException) { Code = code; @@ -35,10 +35,10 @@ public XamarinAndroidException (int code, Exception innerException, string messa public int Code { get; private set; } - public SequencePoint Location { get; set; } + public SequencePoint? Location { get; set; } - public string SourceFile { - get { return Location == null ? null : Location.Document.Url; } + public string? SourceFile { + get { return Location?.Document.Url; } } public int SourceLine { diff --git a/src/Java.Interop.Tools.Generator/Enumification/ConstantEntry.cs b/src/Java.Interop.Tools.Generator/Enumification/ConstantEntry.cs index a0bcff11e..4a35f259a 100644 --- a/src/Java.Interop.Tools.Generator/Enumification/ConstantEntry.cs +++ b/src/Java.Interop.Tools.Generator/Enumification/ConstantEntry.cs @@ -10,10 +10,10 @@ public class ConstantEntry { public ConstantAction Action { get; set; } public int ApiLevel { get; set; } - public string JavaSignature { get; set; } - public string Value { get; set; } - public string EnumFullType { get; set; } - public string EnumMember { get; set; } + public string? JavaSignature { get; set; } + public string? Value { get; set; } + public string? EnumFullType { get; set; } + public string? EnumMember { get; set; } public FieldAction FieldAction { get; set; } public bool IsFlags { get; set; } @@ -76,7 +76,7 @@ public string JavaType { public string JavaName { get { - if (!JavaSignature.HasValue ()) + if (!JavaSignature.HasValue ()) return string.Empty; var index = JavaSignature.LastIndexOf ('.'); diff --git a/src/Java.Interop.Tools.Generator/Extensions/UtilityExtensions.cs b/src/Java.Interop.Tools.Generator/Extensions/UtilityExtensions.cs index c5fee4130..38c8c372a 100644 --- a/src/Java.Interop.Tools.Generator/Extensions/UtilityExtensions.cs +++ b/src/Java.Interop.Tools.Generator/Extensions/UtilityExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.CodeAnalysis; namespace Java.Interop.Tools.Generator { @@ -6,6 +7,9 @@ public static class UtilityExtensions { public static bool In (this T enumeration, params T [] values) { + if (enumeration is null) + return false; + foreach (var en in values) if (enumeration.Equals (en)) return true; @@ -21,7 +25,7 @@ public static bool StartsWithAny (this string value, params string [] values) return false; } - - public static bool HasValue (this string str) => !string.IsNullOrEmpty (str); + + public static bool HasValue ([NotNullWhen (true)]this string? str) => !string.IsNullOrEmpty (str); } } diff --git a/src/Java.Interop.Tools.Generator/Java.Interop.Tools.Generator.csproj b/src/Java.Interop.Tools.Generator/Java.Interop.Tools.Generator.csproj index 4fee86360..8527af75c 100644 --- a/src/Java.Interop.Tools.Generator/Java.Interop.Tools.Generator.csproj +++ b/src/Java.Interop.Tools.Generator/Java.Interop.Tools.Generator.csproj @@ -3,10 +3,16 @@ netstandard2.0 8.0 + enable + INTERNAL_NULLABLE_ATTRIBUTES $(UtilityOutputFullPath) + + + + diff --git a/src/Java.Interop.Tools.Generator/Utilities/NamingConverter.cs b/src/Java.Interop.Tools.Generator/Utilities/NamingConverter.cs index 93f98f761..5a5fcd99d 100644 --- a/src/Java.Interop.Tools.Generator/Utilities/NamingConverter.cs +++ b/src/Java.Interop.Tools.Generator/Utilities/NamingConverter.cs @@ -7,7 +7,7 @@ public static class NamingConverter /// /// Converts a 'merge.SourceFile' attribute to an API level. (ex. "..\..\bin\BuildDebug\api\api-28.xml.in") /// - public static int ParseApiLevel (string value) + public static int ParseApiLevel (string? value) { if (!value.HasValue ()) return 0;