Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Java.Interop] GetSimpleReferences():fallback for GetTypeSignatures() #1305

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/Java.Interop/Java.Interop/JavaArray.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

namespace Java.Interop
{
[JniTypeSignature ("java/lang/Object", ArrayRank=1, GenerateJavaPeer=false)]
public abstract class JavaArray<T> : JavaObject, IList, IList<T>
{
internal delegate TArray ArrayCreator<TArray> (ref JniObjectReference reference, JniObjectReferenceOptions transfer)
Expand Down Expand Up @@ -362,6 +363,7 @@ public void Dispose ()
}
}

[JniTypeSignature ("java/lang/Object", ArrayRank=1, GenerateJavaPeer=false)]
public abstract class JavaPrimitiveArray<
[DynamicallyAccessedMembers (Constructors)]
T
Expand Down
1 change: 1 addition & 0 deletions src/Java.Interop/Java.Interop/JavaObjectArray.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

namespace Java.Interop
{
[JniTypeSignature ("java/lang/Object", ArrayRank=1, GenerateJavaPeer=false)]
public class JavaObjectArray<
[DynamicallyAccessedMembers (Constructors)]
T
Expand Down
75 changes: 34 additions & 41 deletions src/Java.Interop/Java.Interop/JniRuntime.JniTypeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,36 +156,23 @@ public JniTypeSignature GetTypeSignature (Type type)
if (GetBuiltInTypeArraySignature (type, ref signature))
return signature.AddArrayRank (rank);

var simpleRef = GetSimpleReference (type);
if (simpleRef != null)
return new JniTypeSignature (simpleRef, rank, false);

var name = type.GetCustomAttribute<JniTypeSignatureAttribute> (inherit: false);
if (name != null) {
#if NET
var altRef = GetReplacementType (name.SimpleReference);
if (altRef != null) {
return new JniTypeSignature (altRef, name.ArrayRank + rank, name.IsKeyword);
}
#endif // NET
return new JniTypeSignature (name.SimpleReference, name.ArrayRank + rank, name.IsKeyword);
}

var isGeneric = type.IsGenericType;
var genericDef = isGeneric ? type.GetGenericTypeDefinition () : type;
if (isGeneric) {
if (genericDef == typeof (JavaArray<>) || genericDef == typeof (JavaObjectArray<>)) {
var r = GetTypeSignature (type.GenericTypeArguments [0]);
return r.AddArrayRank (rank + 1);
}
}

if (isGeneric) {
simpleRef = GetSimpleReference (genericDef);
if (simpleRef != null)
return new JniTypeSignature (simpleRef, rank, false);
var genericSimpleRef = GetSimpleReference (genericDef);
if (genericSimpleRef != null)
return new JniTypeSignature (genericSimpleRef, rank, false);
}

var simpleRef = GetSimpleReference (type);
if (simpleRef != null)
return new JniTypeSignature (simpleRef, rank, false);

return default;
}

Expand All @@ -194,44 +181,39 @@ public IEnumerable<JniTypeSignature> GetTypeSignatures (Type type)
{
AssertValid ();

if (type == null)
yield break;
if (type.ContainsGenericParameters)
throw new ArgumentException ($"'{type}' contains a generic type definition. This is not supported.", nameof (type));

type = GetUnderlyingType (type, out int rank);

var signature = new JniTypeSignature (null);
var signature = JniTypeSignature.Empty;
if (GetBuiltInTypeSignature (type, ref signature))
yield return signature.AddArrayRank (rank);
if (GetBuiltInTypeArraySignature (type, ref signature))
yield return signature.AddArrayRank (rank);

foreach (var simpleRef in GetSimpleReferences (type)) {
if (simpleRef == null)
continue;
yield return new JniTypeSignature (simpleRef, rank, false);
}

var name = type.GetCustomAttribute<JniTypeSignatureAttribute> (inherit: false);
if (name != null) {
yield return new JniTypeSignature (name.SimpleReference, name.ArrayRank + rank, name.IsKeyword);
}

var isGeneric = type.IsGenericType;
var genericDef = isGeneric ? type.GetGenericTypeDefinition () : type;
var isGeneric = type.IsGenericType;
var genericDef = isGeneric ? type.GetGenericTypeDefinition () : type;
if (isGeneric) {
if (genericDef == typeof(JavaArray<>) || genericDef == typeof(JavaObjectArray<>)) {
if (genericDef == typeof (JavaArray<>) || genericDef == typeof (JavaObjectArray<>)) {
var r = GetTypeSignature (type.GenericTypeArguments [0]);
yield return r.AddArrayRank (rank + 1);
}
}

if (isGeneric) {
foreach (var simpleRef in GetSimpleReferences (genericDef)) {
if (simpleRef == null)
foreach (var genericSimpleRef in GetSimpleReferences (genericDef)) {
if (genericSimpleRef == null)
continue;
yield return new JniTypeSignature (simpleRef, rank, false);
yield return new JniTypeSignature (genericSimpleRef, rank, false);
}
}

foreach (var simpleRef in GetSimpleReferences (type)) {
if (simpleRef == null)
continue;
yield return new JniTypeSignature (simpleRef, rank, false);
}
}

static Type GetUnderlyingType (Type type, out int rank)
Expand Down Expand Up @@ -266,7 +248,18 @@ protected virtual IEnumerable<string> GetSimpleReferences (Type type)
throw new ArgumentNullException (nameof (type));
if (type.IsArray)
throw new ArgumentException ("Array type '" + type.FullName + "' is not supported.", nameof (type));
return EmptyStringArray;

var name = type.GetCustomAttribute<JniTypeSignatureAttribute> (inherit: false);
if (name != null) {
var altRef = GetReplacementType (name.SimpleReference);
if (altRef != null) {
yield return altRef;
} else {
yield return name.SimpleReference;
}
}

yield break;
}

static readonly string[] EmptyStringArray = Array.Empty<string> ();
Expand Down
13 changes: 11 additions & 2 deletions tests/Java.Interop-Tests/Java.Interop/JniTypeManagerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,24 @@ public void GetTypeSignature_Type ()

#if !__ANDROID__
// Re-enable once typemap files contain `JavaObject` subclasses, not just Java.Lang.Object subclasses
//
// Note: dotnet/android@5c23bcda updates Java.Lang.Object to inherit JavaObject; this is not enough,
// as `<GenerateJavaStubs/>` only processes assemblies if they reference Mono.Android.dll.
AssertGetJniTypeInfoForType (typeof (GenericHolder<int>), GenericHolder<int>.JniTypeName, false, 0);
#endif // !__ANDROID__
}

static void AssertGetJniTypeInfoForType (Type type, string jniType, bool isKeyword, int arrayRank)
{
var info = JniRuntime.CurrentRuntime.TypeManager.GetTypeSignature (type);
Assert.AreEqual (jniType, info.Name);
Assert.AreEqual (arrayRank, info.ArrayRank);

// `GetTypeSignature() and `GetTypeSignatures()` should be "in sync"; verify that!
var info2 = JniRuntime.CurrentRuntime.TypeManager.GetTypeSignatures (type).FirstOrDefault ();

Assert.AreEqual (jniType, info.Name, $"info.Name for `{type}`");
Assert.AreEqual (jniType, info2.Name, $"info.Name for `{type}`");
Assert.AreEqual (arrayRank, info.ArrayRank, $"info.ArrayRank for `{type}`");
Assert.AreEqual (arrayRank, info2.ArrayRank, $"info.ArrayRank for `{type}`");
}

[Test]
Expand Down