diff --git a/src/Java.Interop.Tools.JavaSource/Java.Interop.Tools.JavaSource.csproj b/src/Java.Interop.Tools.JavaSource/Java.Interop.Tools.JavaSource.csproj index 06e032366..ea4be696a 100644 --- a/src/Java.Interop.Tools.JavaSource/Java.Interop.Tools.JavaSource.csproj +++ b/src/Java.Interop.Tools.JavaSource/Java.Interop.Tools.JavaSource.csproj @@ -2,6 +2,9 @@ netstandard2.0 + 8.0 + enable + INTERNAL_NULLABLE_ATTRIBUTES {5C0B3562-8DA0-4726-9762-75B9709ED6B7} Java.Interop.Tools.JavaSource Microsoft Corporation @@ -11,6 +14,9 @@ $(ToolOutputFullPath) + + + diff --git a/src/Java.Interop.Tools.JavaSource/Java.Interop.Tools.JavaSource/JavaStubParser.cs b/src/Java.Interop.Tools.JavaSource/Java.Interop.Tools.JavaSource/JavaStubParser.cs index dc7031187..5defff6a5 100644 --- a/src/Java.Interop.Tools.JavaSource/Java.Interop.Tools.JavaSource/JavaStubParser.cs +++ b/src/Java.Interop.Tools.JavaSource/Java.Interop.Tools.JavaSource/JavaStubParser.cs @@ -421,7 +421,9 @@ public JavaStubGrammar () var packageTokens = s.Split ('.').TakeWhile (t => !t.Any (c => Char.IsUpper (c))); return s.Substring (Enumerable.Sum (packageTokens.Select (t => t.Length)) + packageTokens.Count ()); }; - method.Exceptions = ((IEnumerable)node.ChildNodes [ctor ? 6 : 7].AstNode)?.Select (s => new JavaException { Type = s, Name = stripPackage (s) })?.ToArray (); + method.Exceptions = ((IEnumerable)node.ChildNodes [ctor ? 6 : 7].AstNode) + ?.Select (s => new JavaException { Type = s, Name = stripPackage (s) }) + ?.ToArray (); method.Deprecated = ((IEnumerable)node.ChildNodes [0].AstNode).Any (v => v == "java.lang.Deprecated" || v == "Deprecated") ? "deprecated" : "not deprecated"; method.Final = mods.Contains ("final"); method.TypeParameters = modsOrTps.OfType ().FirstOrDefault (); @@ -501,7 +503,7 @@ public JavaStubGrammar () assignment.AstConfig.NodeCreator = SelectChildValueAt (0); assign_expr.AstConfig.NodeCreator = (ctx, node) => { ProcessChildren (ctx, node); - node.AstNode = new KeyValuePair ((string)node.ChildNodes [0].AstNode, node.ChildNodes [2].AstNode?.ToString ()); + node.AstNode = new KeyValuePair ((string)node.ChildNodes [0].AstNode, node.ChildNodes [2].AstNode?.ToString ()); }; rvalue_expressions.AstConfig.NodeCreator = CreateArrayCreator (); rvalue_expression.AstConfig.NodeCreator = SelectSingleChild; @@ -542,7 +544,7 @@ public JavaStubGrammar () }; generic_definition_arguments.AstConfig.NodeCreator = (ctx, node) => { ProcessChildren (ctx, node); - node.AstNode = new JavaTypeParameters ((JavaMethod) null) { TypeParameters = node.ChildNodes.Select (c => c.AstNode).Cast ().ToList () }; + node.AstNode = new JavaTypeParameters ((JavaMethod?) null) { TypeParameters = node.ChildNodes.Select (c => c.AstNode).Cast ().ToList () }; }; generic_definition_argument.AstConfig.NodeCreator = (ctx, node) => { ProcessChildren (ctx, node); @@ -557,7 +559,7 @@ public JavaStubGrammar () generic_instance_identifier_or_q.AstConfig.NodeCreator = SelectSingleChild; generic_instance_constraints.AstConfig.NodeCreator = (ctx, node) => { ProcessChildren (ctx, node); - var c = (JavaGenericConstraints) node.ChildNodes.FirstOrDefault ()?.AstNode; + var c = (JavaGenericConstraints?) node.ChildNodes.FirstOrDefault ()?.AstNode; if (c != null) node.AstNode = " " + c.BoundsType + " " + string.Join (" & ", c.GenericConstraints.Select (cc => cc.Type)); }; @@ -602,27 +604,27 @@ public JavaStubParser () } - public JavaPackage TryLoad (string uri) + public JavaPackage? TryLoad (string uri) { return TryLoad (uri, out var _); } - public JavaPackage TryLoad (string uri, out ParseTree parseTree) + public JavaPackage? TryLoad (string uri, out ParseTree parseTree) { return TryParse (File.ReadAllText (uri), uri, out parseTree); } - public JavaPackage TryParse (string text) + public JavaPackage? TryParse (string text) { return TryParse (text, null, out var _); } - public JavaPackage TryParse (string text, out ParseTree parseTree) + public JavaPackage? TryParse (string text, out ParseTree parseTree) { return TryParse (text, null, out parseTree); } - public JavaPackage TryParse (string text, string fileName, out ParseTree parseTree) + public JavaPackage? TryParse (string text, string? fileName, out ParseTree parseTree) { parseTree = base.Parse (text, fileName); if (parseTree.HasErrors ()) @@ -634,32 +636,35 @@ public JavaPackage TryParse (string text, string fileName, out ParseTree parseTr void FlattenNestedTypes (JavaPackage package) { - Action,JavaType> flatten = null; - flatten = (list, t) => { + var results = new List (); + foreach (var t in package.Types) + Flatten (results, t); + package.Types = results.ToList (); + + void Flatten (List list, JavaType t) + { list.Add (t); foreach (var nt in t.Members.OfType ()) { + if (nt.Type == null) + continue; nt.Type.Name = t.Name + '.' + nt.Type.Name; foreach (var nc in nt.Type.Members.OfType ()) nc.Name = nt.Type.Name; - flatten (list, nt.Type); + Flatten (list, nt.Type); } t.Members = t.Members.Where (_ => !(_ is JavaNestedType)).ToArray (); - }; - var results = new List (); - foreach (var t in package.Types) - flatten (results, t); - package.Types = results.ToList (); + } } } class JavaNestedType : JavaMember { - public JavaNestedType (JavaType type) + public JavaNestedType (JavaType? type) : base (type) { } - public JavaType Type { get; set; } + public JavaType? Type { get; set; } } } diff --git a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApi.RelationAnalysisModel.cs b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApi.RelationAnalysisModel.cs index 64a004e02..29cbf6516 100644 --- a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApi.RelationAnalysisModel.cs +++ b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApi.RelationAnalysisModel.cs @@ -7,47 +7,48 @@ namespace Xamarin.Android.Tools.ApiXmlAdjuster public partial class JavaClass { - public JavaTypeReference ResolvedExtends { get; set; } + public JavaTypeReference? ResolvedExtends { get; set; } } public partial class JavaImplements { - public JavaTypeReference ResolvedName { get; set; } + public JavaTypeReference? ResolvedName { get; set; } } public partial class JavaField { - public JavaTypeReference ResolvedType { get; set; } + public JavaTypeReference? ResolvedType { get; set; } } public partial class JavaMethod { - public JavaTypeReference ResolvedReturnType { get; set; } + public JavaTypeReference? ResolvedReturnType { get; set; } } public partial class JavaParameter { - public JavaTypeReference ResolvedType { get; set; } + public JavaTypeReference? ResolvedType { get; set; } } public partial class JavaGenericConstraint { - public JavaTypeReference ResolvedType { get; set; } + public JavaTypeReference? ResolvedType { get; set; } } // GenericInheritanceMapper extensibility public partial class JavaClass { - public IDictionary GenericInheritanceMapping { get; set; } + public IDictionary? + GenericInheritanceMapping { get; set; } } // OverrideMarker extensibility public partial class JavaMethod { - public JavaMethodReference BaseMethod { get; set; } - public IList ImplementedInterfaces { get; set; } + public JavaMethodReference? BaseMethod { get; set; } + public IList? ImplementedInterfaces { get; set; } } public partial class JavaMethodReference @@ -57,12 +58,12 @@ public JavaMethodReference (JavaMethod candidate) this.Method = candidate; } - public JavaMethod Method { get; set; } + public JavaMethod? Method { get; set; } } public partial class JavaParameter { - public string InstantiatedGenericArgumentName { get; set; } + public string? InstantiatedGenericArgumentName { get; set; } } } diff --git a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApi.XmlModel.cs b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApi.XmlModel.cs index cf9c8cde7..e93e64c50 100644 --- a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApi.XmlModel.cs +++ b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApi.XmlModel.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Xml; @@ -12,25 +13,25 @@ public JavaApi () Packages = new List (); } - public string ExtendedApiSource { get; set; } - public string Platform { get; set; } - public IList Packages { get; set; } + public string? ExtendedApiSource { get; set; } + public string? Platform { get; set; } + public IList Packages { get; set; } } public partial class JavaPackage { - public JavaPackage (JavaApi parent) + public JavaPackage (JavaApi? parent) { Parent = parent; Types = new List (); } - public JavaApi Parent { get; private set; } + public JavaApi? Parent { get; private set; } - public string Name { get; set; } - public string JniName { get; set; } - public IList Types { get; set; } + public string? Name { get; set; } + public string? JniName { get; set; } + public IList Types { get; set; } // Content of this value is not stable. public override string ToString () @@ -41,7 +42,7 @@ public override string ToString () public abstract partial class JavaType { - protected JavaType (JavaPackage parent) + protected JavaType (JavaPackage? parent) { Parent = parent; @@ -49,22 +50,22 @@ protected JavaType (JavaPackage parent) Members = new List (); } - public JavaPackage Parent { get; private set; } + public JavaPackage? Parent { get; private set; } - public bool IsReferenceOnly { get; set; } + public bool IsReferenceOnly { get; set; } - public bool Abstract { get; set; } - public string Deprecated { get; set; } - public bool Final { get; set; } - public string Name { get; set; } - public bool Static { get; set; } - public string Visibility { get; set; } + public bool Abstract { get; set; } + public string? Deprecated { get; set; } + public bool Final { get; set; } + public string? Name { get; set; } + public bool Static { get; set; } + public string? Visibility { get; set; } - public string ExtendedJniSignature { get; set; } + public string? ExtendedJniSignature { get; set; } - public IList Implements { get; set; } - public JavaTypeParameters TypeParameters { get; set; } - public IList Members { get; set; } + public IList Implements { get; set; } + public JavaTypeParameters? TypeParameters { get; set; } + public IList Members { get; set; } public string FullName { get { return Parent?.Name + ((Parent?.Name?.Length ?? 0) > 0 ? "." : string.Empty) + Name; } @@ -74,13 +75,14 @@ public string FullName { public string ToStringHelper () { // FIXME: add type attributes. - return Parent.Name + "." + Name; + return (Parent?.Name == null ? "" : Parent.Name + ".") + + (Name ?? ""); } } public partial class JavaInterface : JavaType { - public JavaInterface (JavaPackage parent) + public JavaInterface (JavaPackage? parent) : base (parent) { } @@ -94,14 +96,14 @@ public override string ToString () public partial class JavaClass : JavaType { - public JavaClass (JavaPackage parent) + public JavaClass (JavaPackage? parent) : base (parent) { } - public string Extends { get; set; } - public string ExtendsGeneric { get; set; } - public string ExtendedJniExtends { get; set; } + public string? Extends { get; set; } + public string? ExtendsGeneric { get; set; } + public string? ExtendedJniExtends { get; set; } // Content of this value is not stable. public override string ToString () @@ -147,42 +149,42 @@ public ManagedType (JavaPackage package) : base (package) public partial class JavaImplements { - public string Name { get; set; } - public string NameGeneric { get; set; } - - public string ExtendedJniType { get; set; } + public string? Name { get; set; } + public string? NameGeneric { get; set; } + + public string? ExtendedJniType { get; set; } } public partial class JavaMember { - protected JavaMember (JavaType parent) + protected JavaMember (JavaType? parent) { Parent = parent; } - public JavaType Parent { get; private set; } - - public string Deprecated { get; set; } - public bool Final { get; set; } - public string Name { get; set; } - public bool Static { get; set; } - public string Visibility { get; set; } - public string ExtendedJniSignature { get; set; } + public JavaType? Parent { get; private set; } + + public string? Deprecated { get; set; } + public bool Final { get; set; } + public string? Name { get; set; } + public bool Static { get; set; } + public string? Visibility { get; set; } + public string? ExtendedJniSignature { get; set; } } public partial class JavaField : JavaMember { - public JavaField (JavaType parent) + public JavaField (JavaType? parent) : base (parent) { } - public bool NotNull { get; set; } - public bool Transient { get; set; } - public string Type { get; set; } - public string TypeGeneric { get; set; } - public string Value { get; set; } - public bool Volatile { get; set; } + public bool NotNull { get; set; } + public bool Transient { get; set; } + public string? Type { get; set; } + public string? TypeGeneric { get; set; } + public string? Value { get; set; } + public bool Volatile { get; set; } // Content of this value is not stable. public override string ToString () @@ -193,23 +195,29 @@ public override string ToString () public partial class JavaMethodBase : JavaMember { - protected JavaMethodBase (JavaType parent) + protected JavaMethodBase (JavaType? parent) : base (parent) { Parameters = new List (); - Exceptions = new List (); } - public IList Parameters { get; set; } - public IList Exceptions { get; set; } - public JavaTypeParameters TypeParameters { get; set; } + IList? exceptions; + + public IList Parameters { get; set; } + public JavaTypeParameters? TypeParameters { get; set; } - public bool ExtendedBridge { get; set; } - public string ExtendedJniReturn { get; set; } - public bool ExtendedSynthetic { get; set; } + public bool ExtendedBridge { get; set; } + public string? ExtendedJniReturn { get; set; } + public bool ExtendedSynthetic { get; set; } + + [NotNull] + public IList? Exceptions { + get => exceptions ?? (exceptions = new List()); + set => exceptions = value; + } // Content of this value is not stable. - public string ToStringHelper (string returnType, string name, JavaTypeParameters typeParameters) + public string ToStringHelper (string? returnType, string? name, JavaTypeParameters? typeParameters) { return string.Format ("{0}{1}{2}{3}{4}{5}({6})", returnType, @@ -224,33 +232,33 @@ public string ToStringHelper (string returnType, string name, JavaTypeParameters public partial class JavaConstructor : JavaMethodBase { - public JavaConstructor (JavaType parent) + public JavaConstructor (JavaType? parent) : base (parent) { } // it was required in the original API XML, but removed in class-parsed... - public string Type { get; set; } + public string? Type { get; set; } // Content of this value is not stable. public override string ToString () { - return "[Constructor] " + ToStringHelper (null, Parent.Name, null); + return "[Constructor] " + ToStringHelper (null, Parent?.Name, null); } } public partial class JavaMethod : JavaMethodBase { - public JavaMethod (JavaType parent) + public JavaMethod (JavaType? parent) : base (parent) { } - public bool Abstract { get; set; } - public bool Native { get; set; } - public string Return { get; set; } - public bool ReturnNotNull { get; set; } - public bool Synchronized { get; set; } + public bool Abstract { get; set; } + public bool Native { get; set; } + public string? Return { get; set; } + public bool ReturnNotNull { get; set; } + public bool Synchronized { get; set; } // Content of this value is not stable. public override string ToString () @@ -261,16 +269,16 @@ public override string ToString () public partial class JavaParameter { - public JavaParameter (JavaMethodBase parent) + public JavaParameter (JavaMethodBase? parent) { Parent = parent; } - public JavaMethodBase Parent { get; private set; } - public string Name { get; set; } - public string Type { get; set; } - public string JniType { get; set; } - public bool NotNull { get; set; } + public JavaMethodBase? Parent { get; private set; } + public string? Name { get; set; } + public string? Type { get; set; } + public string? JniType { get; set; } + public bool NotNull { get; set; } // Content of this value is not stable. public override string ToString () @@ -281,9 +289,9 @@ public override string ToString () public partial class JavaException { - public string Name { get; set; } - public string Type { get; set; } - public string TypeGenericAware { get; set; } + public string? Name { get; set; } + public string? Type { get; set; } + public string? TypeGenericAware { get; set; } } public partial class JavaTypeParameters @@ -294,39 +302,39 @@ public JavaTypeParameters (JavaType parent) TypeParameters = new List (); } - public JavaTypeParameters (JavaMethodBase parent) + public JavaTypeParameters (JavaMethodBase? parent) { ParentMethod = parent; TypeParameters = new List (); } - public JavaType ParentType { get; set; } - public JavaMethodBase ParentMethod { get; set; } + public JavaType? ParentType { get; set; } + public JavaMethodBase? ParentMethod { get; set; } - public IList TypeParameters { get; set; } + public IList TypeParameters { get; set; } } public partial class JavaTypeParameter { - public JavaTypeParameter (JavaTypeParameters parent) + public JavaTypeParameter (JavaTypeParameters? parent) { Parent = parent; } - public JavaTypeParameters Parent { get; set; } + public JavaTypeParameters? Parent { get; set; } - public string Name { get; set; } - - public string ExtendedJniClassBound { get; set; } - public string ExtendedClassBound { get; set; } - public string ExtendedInterfaceBounds { get; set; } - public string ExtendedJniInterfaceBounds { get; set; } + public string? Name { get; set; } + + public string? ExtendedJniClassBound { get; set; } + public string? ExtendedClassBound { get; set; } + public string? ExtendedInterfaceBounds { get; set; } + public string? ExtendedJniInterfaceBounds { get; set; } - public JavaGenericConstraints GenericConstraints { get; set; } + public JavaGenericConstraints? GenericConstraints { get; set; } public override string ToString () { - return Name; + return Name ?? ""; } } @@ -337,9 +345,15 @@ public JavaGenericConstraints () GenericConstraints = new List (); } - public string BoundsType { get; set; } // extends / super + public string? BoundsType { get; set; } // extends / super - public IList GenericConstraints { get; set; } + IList? genericConstraints; + + [NotNull] + public IList? GenericConstraints { + get => genericConstraints ?? (genericConstraints = new List ()); + set => genericConstraints = value; + } public override string ToString () { @@ -352,11 +366,11 @@ public override string ToString () public partial class JavaGenericConstraint { - public string Type { get; set; } + public string? Type { get; set; } public override string ToString () { - return Type; + return Type ?? ""; } } } diff --git a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiDefectFinderExtensions.cs b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiDefectFinderExtensions.cs index 5050d9082..949a41c83 100644 --- a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiDefectFinderExtensions.cs +++ b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiDefectFinderExtensions.cs @@ -21,7 +21,8 @@ static void FindParametersDefects (this JavaMethodBase methodBase) { int dummy; foreach (var p in methodBase.Parameters) { - if (p.Name.StartsWith ("p", StringComparison.Ordinal) && int.TryParse (p.Name.Substring (1), out dummy)) { + if ((p.Name?.StartsWith ("p", StringComparison.Ordinal) ?? false) && + int.TryParse (p.Name.Substring (1), out dummy)) { Log.LogWarning ("Warning: {0} in {1} has 'unnamed' parameters", methodBase.Parent, methodBase); break; // reporting once is enough. } diff --git a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiFixVisibilityExtensions.cs b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiFixVisibilityExtensions.cs index 52b3edc6b..d68d83ad2 100644 --- a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiFixVisibilityExtensions.cs +++ b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiFixVisibilityExtensions.cs @@ -5,33 +5,33 @@ namespace Xamarin.Android.Tools.ApiXmlAdjuster { public static class JavaApiFixVisibilityExtensions { - public static string GetVisibleTypeName (this JavaParameter parameter) + public static string? GetVisibleTypeName (this JavaParameter parameter) { var r = GetVisibleNonSpecialType (parameter); return r != null ? r.ToString () : parameter.Type; } - public static string GetVisibleReturnTypeName (this JavaMethod method) + public static string? GetVisibleReturnTypeName (this JavaMethod method) { var r = GetVisibleNonSpecialReturnType (method); return r != null ? r.ToString () : method.Return; } - public static JavaTypeReference GetVisibleNonSpecialType (this JavaParameter parameter) + public static JavaTypeReference? GetVisibleNonSpecialType (this JavaParameter parameter) { return GetVisibleNonSpecialType (parameter.Parent, parameter.ResolvedType); } - public static JavaTypeReference GetVisibleNonSpecialReturnType (this JavaMethod method) + public static JavaTypeReference? GetVisibleNonSpecialReturnType (this JavaMethod method) { return GetVisibleNonSpecialType (method, method.ResolvedReturnType); } - static JavaTypeReference GetVisibleNonSpecialType (this JavaMethodBase method, JavaTypeReference r) + static JavaTypeReference? GetVisibleNonSpecialType (this JavaMethodBase? method, JavaTypeReference? r) { if (r == null || r.SpecialName != null || r.ReferencedTypeParameter != null || r.ArrayPart != null) return null; - var requiredVisibility = method.Visibility == "public" && method.Parent.Visibility == "public" ? "public" : method.Visibility; + var requiredVisibility = method?.Visibility == "public" && method.Parent?.Visibility == "public" ? "public" : method?.Visibility; for (var t = r; t != null; t = (t.ReferencedType as JavaClass)?.ResolvedExtends) { if (t.ReferencedType == null) break; @@ -41,7 +41,7 @@ static JavaTypeReference GetVisibleNonSpecialType (this JavaMethodBase method, J return null; } - static bool IsAcceptableVisibility (string required, string actual) + static bool IsAcceptableVisibility (string? required, string? actual) { if (required == "public") return actual == "public"; diff --git a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiGeneralExtensions.cs b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiGeneralExtensions.cs index 903085614..4db00db16 100644 --- a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiGeneralExtensions.cs +++ b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiGeneralExtensions.cs @@ -8,12 +8,12 @@ public static class JavaApiGeneralExtensions { public static JavaApi GetApi (this JavaType type) { - return type.Parent.Parent; + return type.Parent?.Parent ?? throw new InvalidOperationException ("`JavaApi` via JavaType.Parent.Parent not set!"); } public static JavaApi GetApi (this JavaMember member) { - return member.Parent.Parent.Parent; + return member.Parent?.Parent?.Parent ?? throw new InvalidOperationException ("`JavaApi` via JavaMethod.Parent.Parent.Parent not set!");; } } diff --git a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiGenericInheritanceMapperExtensions.cs b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiGenericInheritanceMapperExtensions.cs index 3eb4fd91a..7ef0768ba 100644 --- a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiGenericInheritanceMapperExtensions.cs +++ b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiGenericInheritanceMapperExtensions.cs @@ -26,16 +26,16 @@ static void PrepareGenericInheritanceMapping (this JavaClass cls) // begin processing from the base class. bt.PrepareGenericInheritanceMapping (); - if (cls.ResolvedExtends.TypeParameters == null) + if (cls.ResolvedExtends?.TypeParameters == null) cls.GenericInheritanceMapping = empty; - else if (cls.ResolvedExtends.ReferencedType.TypeParameters == null) { + else if (cls.ResolvedExtends?.ReferencedType?.TypeParameters == null) { // FIXME: I guess this should not happen. But this still happens. Log.LogWarning ("Warning: '{0}' is referenced as base type of '{1}' and expected to have generic type parameters, but it does not.", cls.ExtendsGeneric, cls.FullName); cls.GenericInheritanceMapping = empty; } else { if (cls.ResolvedExtends.ReferencedType.TypeParameters.TypeParameters.Count != cls.ResolvedExtends.TypeParameters.Count) throw new Exception (string.Format ("On {0}.{1}, referenced generic arguments count do not match the base type parameters definition", - cls.Parent.Name, cls.Name)); + cls.Parent?.Name, cls.Name)); var dic = empty; foreach (var kvp in cls.ResolvedExtends.ReferencedType.TypeParameters.TypeParameters.Zip ( cls.ResolvedExtends.TypeParameters, diff --git a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiNonBindableStripper.cs b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiNonBindableStripper.cs index f28f33063..c6d289795 100644 --- a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiNonBindableStripper.cs +++ b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiNonBindableStripper.cs @@ -13,7 +13,7 @@ public static void StripNonBindables (this JavaApi api) .SelectMany (t => t.Members).Where (m => m.Name != null && m.Name.Contains ('$'))) invalids.Add (member); foreach (var invalid in invalids) - invalid.Parent.Members.Remove (invalid); + invalid.Parent?.Members.Remove (invalid); } } } diff --git a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiOverrideMarkerExtensions.cs b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiOverrideMarkerExtensions.cs index e882a4b60..c626a732d 100644 --- a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiOverrideMarkerExtensions.cs +++ b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiOverrideMarkerExtensions.cs @@ -34,7 +34,7 @@ static void MarkOverrides (this JavaClass cls, HashSet doneList) static void MarkBaseMethod (this JavaClass cls, JavaMethod method) { - JavaClass k = cls; + JavaClass? k = cls; while (true) { k = k.ResolvedExtends != null ? k.ResolvedExtends.ReferencedType as JavaClass : null; if (k == null) @@ -44,14 +44,14 @@ static void MarkBaseMethod (this JavaClass cls, JavaMethod method) var candidates = k.Members.OfType ().Where (_ => _.Name == method.Name); // Then we find exact parameter type matches. // No need to check returns. We only care about Java. - var candidate = candidates.FirstOrDefault (c => method.IsImplementing (c, cls.GenericInheritanceMapping)); + var candidate = candidates.FirstOrDefault (c => method.IsImplementing (c, cls.GenericInheritanceMapping ?? throw new InvalidOperationException ($"missing {nameof(cls.GenericInheritanceMapping)}!"))); if (candidate != null) { method.BaseMethod = new JavaMethodReference (candidate); for (int i = 0; i < candidate.Parameters.Count; i++) - if (candidate.Parameters [i].ResolvedType.ReferencedTypeParameter != null && - method.Parameters [i].ResolvedType.ReferencedTypeParameter == null) - method.Parameters [i].InstantiatedGenericArgumentName = candidate.Parameters [i].ResolvedType.ReferencedTypeParameter.Name; + if (candidate.Parameters [i].ResolvedType?.ReferencedTypeParameter != null && + method.Parameters [i].ResolvedType?.ReferencedTypeParameter == null) + method.Parameters [i].InstantiatedGenericArgumentName = candidate.Parameters [i].ResolvedType?.ReferencedTypeParameter?.Name; break; } } diff --git a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiTypeResolverExtensions.cs b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiTypeResolverExtensions.cs index f06430c0a..15c84994c 100644 --- a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiTypeResolverExtensions.cs +++ b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiTypeResolverExtensions.cs @@ -13,15 +13,17 @@ public JavaTypeResolutionException (string message) : base (message) public static class JavaApiTypeResolverExtensions { - public static JavaTypeReference Parse (this JavaApi api, string name, params JavaTypeParameters [] contextTypeParameters) + public static JavaTypeReference Parse (this JavaApi api, string name, params JavaTypeParameters?[] contextTypeParameters) { var tn = JavaTypeName.Parse (name); return JavaTypeNameToReference (api, tn, contextTypeParameters); } - static JavaTypeReference JavaTypeNameToReference (this JavaApi api, JavaTypeName tn, params JavaTypeParameters [] contextTypeParameters) + static JavaTypeReference JavaTypeNameToReference (this JavaApi api, JavaTypeName tn, params JavaTypeParameters?[] contextTypeParameters) { - var tp = contextTypeParameters.Where (tps => tps != null).SelectMany (tps => tps.TypeParameters).FirstOrDefault (_ => _.Name == tn.DottedName); + var tp = contextTypeParameters.Where (tps => tps != null) + .SelectMany (tps => tps!.TypeParameters) + .FirstOrDefault (xp => xp.Name == tn.DottedName); if (tp != null) return new JavaTypeReference (tp, tn.ArrayPart); if (tn.DottedName == JavaTypeReference.GenericWildcard.SpecialName) @@ -35,11 +37,11 @@ static JavaTypeReference JavaTypeNameToReference (this JavaApi api, JavaTypeName tn.ArrayPart); } - public static JavaType FindNonGenericType (this JavaApi api, string name) + public static JavaType FindNonGenericType (this JavaApi api, string? name) { - var ret = FindPackages (api, name) + var ret = FindPackages (api, name ?? "") .SelectMany (p => p.Types) - .FirstOrDefault (t => name == t.Parent.Name + '.' + t.Name); + .FirstOrDefault (t => name == (t.Parent?.Name != null ? t.Parent.Name + "." : "") + t.Name); if (ret == null) ret = ManagedType.DummyManagedPackages .SelectMany (p => p.Types) @@ -78,9 +80,22 @@ public static void Resolve (this JavaApi api) while (true) { bool errors = false; foreach (var t in api.Packages.SelectMany (p => p.Types).OfType ().ToArray ()) - try { t.Resolve (); } catch (JavaTypeResolutionException ex) { Log.LogError ("Error while processing type '{0}': {1}", t, ex.Message); errors = true; t.Parent.Types.Remove (t); } + try { + t.Resolve (); + } + catch (JavaTypeResolutionException ex) { + Log.LogError ("Error while processing type '{0}': {1}", t, ex.Message); + errors = true; + t.Parent?.Types.Remove (t); + } foreach (var t in api.Packages.SelectMany (p => p.Types).OfType ().ToArray ()) - try { t.Resolve (); } catch (JavaTypeResolutionException ex) { Log.LogError ("Error while processing type '{0}': {1}", t, ex.Message); errors = true; t.Parent.Types.Remove (t); } + try { + t.Resolve (); + } catch (JavaTypeResolutionException ex) { + Log.LogError ("Error while processing type '{0}': {1}", t, ex.Message); + errors = true; + t.Parent?.Types.Remove (t); + } if (!errors) break; } @@ -90,8 +105,11 @@ static void ResolveType (this JavaType type) { if (type.TypeParameters != null) type.TypeParameters.Resolve (type.GetApi (), type.TypeParameters); - foreach (var t in type.Implements) + foreach (var t in type.Implements) { + if (t.NameGeneric == null) + continue; t.ResolvedName = type.GetApi ().Parse (t.NameGeneric, type.TypeParameters); + } foreach (var m in type.Members.OfType ().ToArray ()) ResolveWithTryCatch (m.Resolve, m); @@ -114,7 +132,7 @@ static void ResolveWithTryCatch (Action resolve, JavaMember m) resolve (); } catch (JavaTypeResolutionException ex) { Log.LogError ("Error while processing '{0}' in '{1}': {2}", m, m.Parent, ex.Message); - m.Parent.Members.Remove (m); + m.Parent?.Members.Remove (m); } } @@ -125,21 +143,28 @@ public static void Resolve (this JavaInterface i) public static void Resolve (this JavaField f) { - f.ResolvedType = f.GetApi ().Parse (f.TypeGeneric, f.Parent.TypeParameters); + if (f.TypeGeneric == null) + return; + f.ResolvedType = f.GetApi ().Parse (f.TypeGeneric, f.Parent?.TypeParameters); } static void ResolveMethodBase (this JavaMethodBase m) { if (m.TypeParameters != null) m.TypeParameters.Resolve (m.GetApi (), m.TypeParameters); - foreach (var p in m.Parameters) - p.ResolvedType = m.GetApi ().Parse (p.Type, m.Parent.TypeParameters, m.TypeParameters); + foreach (var p in m.Parameters) { + if (p.Type == null) + continue; + p.ResolvedType = m.GetApi ().Parse (p.Type, m.Parent?.TypeParameters, m.TypeParameters); + } } public static void Resolve (this JavaMethod m) { m.ResolveMethodBase (); - m.ResolvedReturnType = m.GetApi ().Parse (m.Return, m.Parent.TypeParameters, m.TypeParameters); + if (m.Return == null) + return; + m.ResolvedReturnType = m.GetApi ().Parse (m.Return, m.Parent?.TypeParameters, m.TypeParameters); } public static void Resolve (this JavaConstructor c) @@ -147,12 +172,22 @@ public static void Resolve (this JavaConstructor c) c.ResolveMethodBase (); } - static void Resolve (this JavaTypeParameters tp, JavaApi api, params JavaTypeParameters [] additionalTypeParameters) + static void Resolve (this JavaTypeParameters tp, JavaApi api, params JavaTypeParameters?[] additionalTypeParameters) { - foreach (var t in tp.TypeParameters) - if (t.GenericConstraints != null) - foreach (var g in t.GenericConstraints.GenericConstraints) - try { g.ResolvedType = api.Parse (g.Type, additionalTypeParameters); } catch (JavaTypeResolutionException ex) { Log.LogWarning ("Warning: failed to resolve generic constraint: '{0}': {1}", g.Type, ex.Message); } + foreach (var t in tp.TypeParameters) { + if (t.GenericConstraints == null || t.GenericConstraints.GenericConstraints == null) + continue; + foreach (var g in t.GenericConstraints.GenericConstraints) { + if (g.Type == null) + continue; + try { + g.ResolvedType = api.Parse (g.Type, additionalTypeParameters); + } + catch (JavaTypeResolutionException ex) { + Log.LogDebug ("Warning: failed to resolve generic constraint: '{0}': {1}", g.Type, ex.Message); + } + } + } } } } diff --git a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiXmlGeneratorExtensions.cs b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiXmlGeneratorExtensions.cs index 83e44f7db..a76352405 100644 --- a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiXmlGeneratorExtensions.cs +++ b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaApiXmlGeneratorExtensions.cs @@ -55,7 +55,7 @@ static void Save (this JavaInterface iface, XmlWriter writer) SaveTypeCommon (iface, writer, "interface", "true", null, null, null); } - static void SaveTypeCommon (this JavaType cls, XmlWriter writer, string elementName, string abs, string ext, string extgen, string jniExt) + static void SaveTypeCommon (this JavaType cls, XmlWriter writer, string elementName, string abs, string? ext, string? extgen, string? jniExt) { writer.WriteStartElement (elementName); if (abs != null) @@ -166,12 +166,12 @@ static void Save (this JavaField field, XmlWriter writer) static void Save (this JavaConstructor ctor, XmlWriter writer) { - SaveCommon (ctor, writer, "constructor", null, null, null, null, null, ctor.Type ?? ctor.Parent.FullName, null, null, null, ctor.TypeParameters, ctor.Parameters, ctor.Exceptions, ctor.ExtendedBridge, ctor.ExtendedJniReturn, ctor.ExtendedSynthetic, null); + SaveCommon (ctor, writer, "constructor", null, null, null, null, null, ctor.Type ?? ctor.Parent?.FullName, null, null, null, ctor.TypeParameters, ctor.Parameters, ctor.Exceptions, ctor.ExtendedBridge, ctor.ExtendedJniReturn, ctor.ExtendedSynthetic, null); } static void Save (this JavaMethod method, XmlWriter writer) { - Func check = _ => _.BaseMethod.Method.Parent.Visibility == "public" && + Func check = _ => _.BaseMethod?.Method?.Parent?.Visibility == "public" && !method.Static && method.Parameters.All (p => p.InstantiatedGenericArgumentName == null); @@ -194,7 +194,7 @@ static void Save (this JavaMethod method, XmlWriter writer) // - the base method is in the NON-public class. // - none of the arguments are type parameters. // - finally, it is the synthetic method already checked above. - if (method.BaseMethod != null && + if (method.BaseMethod != null && method.BaseMethod.Method != null && !method.BaseMethod.Method.Abstract && method.BaseMethod.Method.Visibility == method.Visibility && method.BaseMethod.Method.Abstract == method.Abstract && @@ -223,16 +223,16 @@ static void Save (this JavaMethod method, XmlWriter writer) } static void SaveCommon (this JavaMember m, XmlWriter writer, string elementName, - string abs, string native, string ret, string sync, - string transient, string type, string typeGeneric, - string value, string volat, - JavaTypeParameters typeParameters, - IEnumerable parameters, - IEnumerable exceptions, - bool? extBridge, string jniReturn, bool? extSynthetic, bool? notNull) + string? abs, string? native, string? ret, string? sync, + string? transient, string? type, string? typeGeneric, + string? value, string? volat, + JavaTypeParameters? typeParameters, + IEnumerable? parameters, + IEnumerable? exceptions, + bool? extBridge, string? jniReturn, bool? extSynthetic, bool? notNull) { // If any of the parameters contain reference to non-public type, it cannot be generated. - if (parameters != null && parameters.Any (p => p.ResolvedType.ReferencedType != null && string.IsNullOrEmpty (p.ResolvedType.ReferencedType.Visibility))) + if (parameters != null && parameters.Any (p => p.ResolvedType?.ReferencedType != null && string.IsNullOrEmpty (p.ResolvedType.ReferencedType.Visibility))) return; writer.WriteStartElement (elementName); @@ -289,9 +289,9 @@ static void SaveCommon (this JavaMember m, XmlWriter writer, string elementName, } if (exceptions != null) { - foreach (var e in exceptions.OrderBy (e => e.Name.Substring (e.Name.LastIndexOf ('/') + 1).Replace ('$', '.'), StringComparer.Ordinal)) { + foreach (var e in exceptions.OrderBy (e => GetName (e.Name), StringComparer.Ordinal)) { writer.WriteStartElement ("exception"); - writer.WriteAttributeString ("name", e.Name.Substring (e.Name.LastIndexOf ('/') + 1).Replace ('$', '.')); + writer.WriteAttributeString ("name", GetName (e.Name)); writer.WriteAttributeString ("type", e.Type); if (!string.IsNullOrEmpty (e.TypeGenericAware)) { writer.WriteAttributeString ("type-generic-aware", e.TypeGenericAware); @@ -304,6 +304,18 @@ static void SaveCommon (this JavaMember m, XmlWriter writer, string elementName, writer.WriteString ("\n "); writer.WriteFullEndElement (); } + + static string? GetName (string? jniName) + { + if (jniName == null) + return null; + + int slash = jniName.LastIndexOf ('/'); + var name = slash >= 0 + ? jniName.Substring (slash + 1) + : jniName; + return name; + } } } diff --git a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaTypeName.cs b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaTypeName.cs index adc9e6414..99b7d9942 100644 --- a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaTypeName.cs +++ b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaTypeName.cs @@ -131,14 +131,14 @@ static IEnumerable ParseCommaSeparatedTypeNames (string args) } } - public JavaTypeName GenericParent { get; set; } - public string DottedName { get; set; } - public string BoundsType { get; set; } // " extends " / " super " - public IList GenericConstraints { get; private set; } - public IList GenericArguments { get; private set; } - public string ArrayPart { get; set; } + public JavaTypeName? GenericParent { get; set; } + public string? DottedName { get; set; } + public string? BoundsType { get; set; } // " extends " / " super " + public IList? GenericConstraints { get; private set; } + public IList? GenericArguments { get; private set; } + public string? ArrayPart { get; set; } - public string FullNameNonGeneric { + public string? FullNameNonGeneric { get { if (GenericParent != null) return GenericParent.FullNameNonGeneric + "." + DottedName; diff --git a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaTypeReference.cs b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaTypeReference.cs index 877b7d58b..8ca86ff2d 100644 --- a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaTypeReference.cs +++ b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaTypeReference.cs @@ -21,7 +21,7 @@ public class JavaTypeReference public static readonly JavaTypeReference ULong; public static readonly JavaTypeReference UByte; - internal static JavaTypeReference GetSpecialType (string name) + internal static JavaTypeReference? GetSpecialType (string? name) { switch (name) { case "void": return Void; @@ -60,12 +60,12 @@ static JavaTypeReference () UByte = new JavaTypeReference ("ubyte"); } - JavaTypeReference (string specialName) + JavaTypeReference (string? specialName) { SpecialName = specialName; } - public JavaTypeReference (string constraintLabel, IEnumerable wildcardConstraints, string arrayPart) + public JavaTypeReference (string? constraintLabel, IEnumerable? wildcardConstraints, string? arrayPart) { SpecialName = GenericWildcard.SpecialName; ArrayPart = arrayPart; @@ -73,7 +73,7 @@ public JavaTypeReference (string constraintLabel, IEnumerable WildcardConstraints = wildcardConstraints != null && wildcardConstraints.Any () ? wildcardConstraints.ToList () : null; } - public JavaTypeReference (JavaTypeReference referencedType, string arrayPart, string wildcardBoundsType, IEnumerable wildcardConstraints) + public JavaTypeReference (JavaTypeReference referencedType, string? arrayPart, string? wildcardBoundsType, IEnumerable? wildcardConstraints) { if (referencedType == null) throw new ArgumentNullException ("referencedType"); @@ -86,7 +86,7 @@ public JavaTypeReference (JavaTypeReference referencedType, string arrayPart, st ArrayPart = arrayPart; } - public JavaTypeReference (JavaTypeParameter referencedTypeParameter, string arrayPart) + public JavaTypeReference (JavaTypeParameter referencedTypeParameter, string? arrayPart) { if (referencedTypeParameter == null) throw new ArgumentNullException ("referencedTypeParameter"); @@ -94,7 +94,7 @@ public JavaTypeReference (JavaTypeParameter referencedTypeParameter, string arra ArrayPart = arrayPart; } - public JavaTypeReference (JavaType referencedType, IList typeParameters, string arrayPart) + public JavaTypeReference (JavaType referencedType, IList? typeParameters, string? arrayPart) { if (referencedType == null) throw new ArgumentNullException ("referencedType"); @@ -103,15 +103,15 @@ public JavaTypeReference (JavaType referencedType, IList type ArrayPart = arrayPart; } - public string SpecialName { get; private set; } + public string? SpecialName { get; private set; } - public string WildcardBoundsType { get; private set; } - public IList WildcardConstraints { get; private set; } + public string? WildcardBoundsType { get; private set; } + public IList? WildcardConstraints { get; private set; } - public JavaType ReferencedType { get; private set; } - public JavaTypeParameter ReferencedTypeParameter { get; private set; } - public IList TypeParameters { get; private set; } - public string ArrayPart { get; private set; } + public JavaType? ReferencedType { get; private set; } + public JavaTypeParameter? ReferencedTypeParameter { get; private set; } + public IList? TypeParameters { get; private set; } + public string? ArrayPart { get; private set; } public override string ToString () { @@ -123,9 +123,9 @@ public override string ToString () return ReferencedTypeParameter.ToString () + ArrayPart; else return string.Format ("{0}{1}{2}{3}{4}", - ReferencedType.Parent.Name, - string.IsNullOrEmpty (ReferencedType.Parent.Name) ? string.Empty : ".", - ReferencedType.Name, + ReferencedType?.Parent?.Name, + string.IsNullOrEmpty (ReferencedType?.Parent?.Name) ? string.Empty : ".", + ReferencedType?.Name, TypeParameters == null ? null : '<' + string.Join (", ", TypeParameters.Select (_ => _.ToString ())) + '>', ArrayPart); } @@ -135,12 +135,12 @@ public override int GetHashCode () // it's skipping TypeParameters because it's too annoying... if (SpecialName != null) return SpecialName.GetHashCode (); - return (ReferencedType != null ? ReferencedType.Name.GetHashCode () : 0) << 15 + - (ReferencedTypeParameter != null ? ReferencedTypeParameter.Name.GetHashCode () : 0) << 7 + + return (ReferencedType != null ? ReferencedType.Name?.GetHashCode () ?? 0 : 0) << 15 + + (ReferencedTypeParameter != null ? ReferencedTypeParameter.Name?.GetHashCode () ?? 0 : 0) << 7 + (ArrayPart != null ? ArrayPart.GetHashCode () : 0); } - public override bool Equals (object obj) + public override bool Equals (object? obj) { return AreEqual (this, obj as JavaTypeReference); } @@ -149,7 +149,7 @@ public override bool Equals (object obj) // Note that it is to compare them as a type reference, not as its object entity. // So, for example, if one has a TypeParameter with T with some contraint and // the other has a TypeParameter with T somehow without it, they are still "same". - public static bool AreEqual (JavaTypeReference tr1, JavaTypeReference tr2) + public static bool AreEqual (JavaTypeReference tr1, JavaTypeReference? tr2) { if (tr1 == null) return tr2 == null; diff --git a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaTypeResolutionUtil.cs b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaTypeResolutionUtil.cs index c441b4089..02c1bf1eb 100644 --- a/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaTypeResolutionUtil.cs +++ b/src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaTypeResolutionUtil.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; namespace Xamarin.Android.Tools.ApiXmlAdjuster @@ -7,6 +8,7 @@ namespace Xamarin.Android.Tools.ApiXmlAdjuster public static class JavaTypeResolutionUtil { + [return: MaybeNull] static V Get (this IDictionary dic, K key) { V v; @@ -43,28 +45,28 @@ static bool IsParameterAssignableTo (this JavaParameter dp, JavaParameter bp, Ja // but rather like "this method is an override, but it should be still generated in the resulting XML". // For example, this results in that java.util.EnumMap#put() is NOT an override of // java.util.AbstractMap#put(), it is an override, not just that it is still generated in the XML. - if (bp.ResolvedType.ReferencedTypeParameter != null && dp.ResolvedType.ReferencedTypeParameter != null && + if (bp.ResolvedType?.ReferencedTypeParameter != null && dp.ResolvedType?.ReferencedTypeParameter != null && bp.ResolvedType.ReferencedTypeParameter.ToString () != dp.ResolvedType.ReferencedTypeParameter.ToString ()) return false; if (bp.Type == dp.Type) return true; - if (bp.ResolvedType.ArrayPart != bp.ResolvedType.ArrayPart) + if (bp.ResolvedType?.ArrayPart != bp.ResolvedType?.ArrayPart) return false; // if base is type with generic type parameters and derived is without any generic args, that's OK. // java.lang.Class should match java.lang.Class. - if (bp.ResolvedType.ReferencedType != null && dp.ResolvedType.ReferencedType != null && - bp.ResolvedType.ReferencedType.FullName == dp.ResolvedType.ReferencedType.FullName && - dp.ResolvedType.TypeParameters == null) + if (bp.ResolvedType?.ReferencedType != null && dp.ResolvedType?.ReferencedType != null && + bp.ResolvedType?.ReferencedType.FullName == dp.ResolvedType?.ReferencedType.FullName && + dp.ResolvedType?.TypeParameters == null) return true; // generic instantiation check. - var baseGTP = bp.ResolvedType.ReferencedTypeParameter; + var baseGTP = bp.ResolvedType?.ReferencedTypeParameter; if (baseGTP != null) { - if (baseGTP.Parent.ParentMethod != null && baseGTP.IsConformantType (dp.ResolvedType)) + if (baseGTP.Parent?.ParentMethod != null && baseGTP.IsConformantType (dp.ResolvedType)) return true; - var k = genericInstantiation.Keys.FirstOrDefault (tr => bp.ResolvedType.Equals (tr)); + var k = genericInstantiation.Keys.FirstOrDefault (tr => bp.ResolvedType?.Equals (tr) ?? false); if (k == null) // the specified generic type parameter is not part of // the mappings e.g. non-instantiated ones. @@ -80,13 +82,13 @@ static bool IsParameterAssignableTo (this JavaParameter dp, JavaParameter bp, Ja return false; } - static bool IsConformantType (this JavaTypeParameter typeParameter, JavaTypeReference examinedType) + static bool IsConformantType (this JavaTypeParameter typeParameter, JavaTypeReference? examinedType) { if (typeParameter.GenericConstraints == null) return true; // FIXME: implement correct generic constraint conformance check. Log.LogDebug ("NOTICE: generic constraint conformance check is not implemented, so the type might be actually compatible. Type parameter: {0}{1}, examined type: {2}", - typeParameter.Name, typeParameter.Parent.ParentMethod?.Name ?? typeParameter.Parent.ParentType?.Name, examinedType); + typeParameter.Name, typeParameter.Parent?.ParentMethod?.Name ?? typeParameter.Parent?.ParentType?.Name, examinedType); return false; } } diff --git a/src/Xamarin.Android.Tools.ApiXmlAdjuster/Log.cs b/src/Xamarin.Android.Tools.ApiXmlAdjuster/Log.cs index 05caacca6..00f74968a 100644 --- a/src/Xamarin.Android.Tools.ApiXmlAdjuster/Log.cs +++ b/src/Xamarin.Android.Tools.ApiXmlAdjuster/Log.cs @@ -15,11 +15,11 @@ public enum LoggingLevel static Action write_default = s => (DefaultWriter ?? Console.Out).WriteLine (s); - static Action e, w, d; + static Action? e, w, d; - public static TextWriter DefaultWriter { get; set; } + public static TextWriter? DefaultWriter { get; set; } - public static LoggingLevel Verbosity { get; set; } = LoggingLevel.Error; + public static LoggingLevel Verbosity { get; set; } = LoggingLevel.Error; public static Action LogErrorAction { get { return e ?? write_default; } @@ -34,19 +34,19 @@ public static Action LogDebugAction { set { d = value; } } - public static void LogError (string format, params object [] args) + public static void LogError (string format, params object?[] args) { if ((int) Verbosity >= (int) LoggingLevel.Error) LogErrorAction (args.Length > 0 ? string.Format (format, args) : format); } - public static void LogWarning (string format, params object [] args) + public static void LogWarning (string format, params object?[] args) { if ((int)Verbosity >= (int)LoggingLevel.Warning) LogWarningAction (args.Length > 0 ? string.Format (format, args) : format); } - public static void LogDebug (string format, params object [] args) + public static void LogDebug (string format, params object?[] args) { if ((int)Verbosity >= (int)LoggingLevel.Debug) LogDebugAction (args.Length > 0 ? string.Format (format, args) : format); diff --git a/src/Xamarin.Android.Tools.ApiXmlAdjuster/Xamarin.Android.Tools.ApiXmlAdjuster.csproj b/src/Xamarin.Android.Tools.ApiXmlAdjuster/Xamarin.Android.Tools.ApiXmlAdjuster.csproj index 92ac86522..bc8a8ff39 100644 --- a/src/Xamarin.Android.Tools.ApiXmlAdjuster/Xamarin.Android.Tools.ApiXmlAdjuster.csproj +++ b/src/Xamarin.Android.Tools.ApiXmlAdjuster/Xamarin.Android.Tools.ApiXmlAdjuster.csproj @@ -2,10 +2,17 @@ netstandard2.0 + 8.0 + enable + INTERNAL_NULLABLE_ATTRIBUTES $(TestOutputFullPath) + + + + diff --git a/src/Xamarin.Android.Tools.ApiXmlAdjuster/XmlUtil.cs b/src/Xamarin.Android.Tools.ApiXmlAdjuster/XmlUtil.cs index 7a5f1dff7..6e92c7274 100644 --- a/src/Xamarin.Android.Tools.ApiXmlAdjuster/XmlUtil.cs +++ b/src/Xamarin.Android.Tools.ApiXmlAdjuster/XmlUtil.cs @@ -11,10 +11,10 @@ class XmlUtil static string GetLocation (XmlReader reader) { var li = reader as IXmlLineInfo; - return string.Format ("{0} ({1},{2})", string.IsNullOrEmpty (reader.BaseURI) ? null : new Uri (reader.BaseURI).LocalPath, li.LineNumber, li.LinePosition); + return string.Format ("{0} ({1},{2})", string.IsNullOrEmpty (reader.BaseURI) ? null : new Uri (reader.BaseURI).LocalPath, li?.LineNumber ?? 0, li?.LinePosition ?? 0); } - public static Exception UnexpectedElementOrContent (string elementName, XmlReader reader, params string [] expected) + public static Exception UnexpectedElementOrContent (string? elementName, XmlReader reader, params string?[] expected) { return new Exception (string.Format ("{0}: Unexpected element or content in '{1}': node is {2}, name is '{3}'. Expected elements are: {4}", GetLocation (reader), elementName ?? "(top level)", reader.NodeType, reader.LocalName, string.Join (", ", expected)));