Skip to content

Commit ffbb2dc

Browse files
jonathanpeppersjonpryor
authored andcommitted
[jnimarshalmethod-gen] fixes for interfaces (dotnet#472)
When bumping xamarin-android to java.interop/master, we are hitting a failure: Instance property 'PeerReference' is not defined for type 'Android.Widget.IListAdapter' Parameter name: propertyName System.ArgumentException: Instance property 'PeerReference' is not defined for type 'Android.Widget.IListAdapter' Parameter name: propertyName at System.Linq.Expressions.Expression.Property (System.Linq.Expressions.Expression expression, System.String propertyName) at Java.Interop.JavaPeerableValueMarshaler.CreateIntermediaryExpressionFromManagedExpression (Java.Interop.Expressions.JniValueMarshalerContext context, System.Linq.Expressions.ParameterExpression sourceValue) at Java.Interop.JavaPeerableValueMarshaler.CreateReturnValueFromManagedExpression (Java.Interop.Expressions.JniValueMarshalerContext context, System.Linq.Expressions.ParameterExpression sourceValue) at Java.Interop.MarshalMemberBuilder.CreateMarshalToManagedExpression (System.Reflection.MethodInfo method, Java.Interop.JavaCallableAttribute callable, System.Type type) at Java.Interop.MarshalMemberBuilder.CreateMarshalToManagedExpression (System.Reflection.MethodInfo method) at Xamarin.Android.Tools.JniMarshalMethodGenerator.App.CreateMarshalMethodAssembly (System.String path) at Xamarin.Android.Tools.JniMarshalMethodGenerator.App.ProcessAssemblies (System.Collections.Generic.List`1[T] assemblies) Since ef092a8 introduced some changes to interfaces, there are a couple spots in `jnimarshalmethod-gen.exe` that need a fix. First, there was an additional cast needed where an interface might extend `IJavaPeerable`: interface IListAdapter : IJavaPeerable { } Update `JavaPeerableValueMarshaler.CreateIntermediaryExpressionFromManagedExpression()` to insert an intermediate cast to `IJavaPeerable` to fix the `ArgumentException`. After inserting the cast, we got a new error: System.ArgumentException: 'this' type cannot be an interface itself at System.RuntimeType.GetInterfaceMap (System.Type ifaceType) [0x00069] in <2d5573434b724f28896144eecd6f4489>:0 at Xamarin.Android.Tools.JniMarshalMethodGenerator.Extensions.NeedsMarshalMethod (Mono.Cecil.MethodDefinition md, Java.Interop.Tools.Cecil.DirectoryAssemblyResolver resolver, System.Reflection.MethodInfo method, System.String& name, System.String& methodName, System.String& signature) [0x0006b] in external/Java.Interop/tools/jnimarshalmethod-gen/App.cs:642 at Xamarin.Android.Tools.JniMarshalMethodGenerator.App.CreateMarshalMethodAssembly (System.String path) [0x00370] in external/Java.Interop/tools/jnimarshalmethod-gen/App.cs:374 at Xamarin.Android.Tools.JniMarshalMethodGenerator.App.ProcessAssemblies (System.Collections.Generic.List`1[T] assemblies) [0x00150] in external/Java.Interop/tools/jnimarshalmethod-gen/App.cs:186 For this one, we can actually skip processing of interfaces -- we don't need to generate marshal methods for interfaces at all. I also updated `ExportTest.cs` so it included a problematic interface, which triggers both of the above error conditions.
1 parent 7a31216 commit ffbb2dc

File tree

4 files changed

+8
-3
lines changed

4 files changed

+8
-3
lines changed

src/Java.Interop.Export/Tests/Java.Interop/ExportTest.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,11 @@ public MyLegacyColor (int value)
107107
}
108108
}
109109

110+
public interface MyInterface : IJavaPeerable
111+
{
112+
void MyMethod ();
113+
}
114+
110115
public class MyColorValueMarshaler : JniValueMarshaler<MyColor> {
111116

112117
public override Type MarshalType {

src/Java.Interop.Export/Tests/Java.Interop/MarshalMemberBuilderTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ public void CreateMarshalFromJniMethodExpression_FuncIJavaObject ()
465465
}
466466
else
467467
{
468-
return __mret_ref = __mret.PeerReference;
468+
return __mret_ref = (IJavaPeerable)__mret.PeerReference;
469469
}
470470
__mret_rtn = References.NewReturnToJniRef(__mret_ref);
471471
return __mret_rtn;

src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -621,7 +621,7 @@ Expression CreateIntermediaryExpressionFromManagedExpression (JniValueMarshalerC
621621
Expression.IfThenElse (
622622
test: Expression.Equal (Expression.Constant (null), sourceValue),
623623
ifTrue: Expression.Assign (r, Expression.New (typeof (JniObjectReference))),
624-
ifFalse: Expression.Assign (r, Expression.Property (sourceValue, "PeerReference"))));
624+
ifFalse: Expression.Assign (r, Expression.Property (Expression.Convert (sourceValue, typeof (IJavaPeerable)), "PeerReference"))));
625625

626626
return r;
627627
}

tools/jnimarshalmethod-gen/App.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ void CreateMarshalMethodAssembly (string path)
330330
continue;
331331
}
332332

333-
if (type.IsGenericType || type.IsGenericTypeDefinition)
333+
if (type.IsInterface || type.IsGenericType || type.IsGenericTypeDefinition)
334334
continue;
335335

336336
var td = FindType (type);

0 commit comments

Comments
 (0)