Skip to content

Commit

Permalink
Fix property setter generation
Browse files Browse the repository at this point in the history
Context: dotnet/android#8339

While testing on dotnet/android#8339, we hit this error
(among others, to be addressed later):

	src/Mono.Android/obj/Debug/net8.0/android-34/mcw/Android.Views.IWindowInsetsController.cs(304,41): error CS0103: The name 'behavior' does not exist in the current context

This was caused because of code such as:

	public partial interface IWindowInsetsController {
		public unsafe int SystemBarsBehavior {
			get {
				const string __id = "getSystemBarsBehavior.()I";
				try {
					var __rm = _members_IWindowInsetsController.InstanceMethods.InvokeAbstractInt32Method (__id, this, null);
					return __rm;
				} finally {
				}
			}
			set {
				const string __id = "setSystemBarsBehavior.(I)V";
				try {
					JniArgumentValue* __args = stackalloc JniArgumentValue [1];
					__args [0] = new JniArgumentValue (behavior);
					_members_IWindowInsetsController.InstanceMethods.InvokeAbstractVoidMethod (__id, this, __args);
				} finally {
				}
			}
		}
	}

This happened because when emitting the property setter, we need
to update the `set*` method's parameter name to be `value` so that
the normal property setter body is emitted properly.

Update `InterfaceInvokerProperty.cs` so that the parameter name
is set to `value`.

Update `tests/generator-Tests/Integration-Tests/Interfaces.cs`
so that we test interface generation for JavaInterop1.

Update `tests/generator-Tests/SupportFiles/*.cs` so that
`Interfaces.cs` test output can be compiled.

Update `tests/generator-Tests/expected.ji/TestInterface/TestInterface.xml`
so that some parameter names for `set*()` methods are *not* already
named `value`, to induce the original error.

Flush `tests/generator-Tests/expected.ji/TestInterface`.
  • Loading branch information
jonpryor committed Oct 4, 2023
1 parent 4a5bbae commit 7f77a70
Show file tree
Hide file tree
Showing 19 changed files with 280 additions and 78 deletions.
2 changes: 1 addition & 1 deletion tests/generator-Tests/Integration-Tests/Interfaces.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace generatortests
[TestFixture]
public class Interfaces : BaseGeneratorTest
{
protected override bool TryJavaInterop1 => false;
protected override bool TryJavaInterop1 => true;

[Test]
public void Generated_OK ()
Expand Down
12 changes: 6 additions & 6 deletions tests/generator-Tests/SupportFiles/Java_Lang_ICharSequence.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
#if !JAVA_INTEROP1


using System;
using Android.Runtime;
using Java.Interop;

namespace Java.Lang {

public partial interface ICharSequence : IJavaObject
public partial interface ICharSequence : IJavaPeerable
#if !JAVA_INTEROP1
, Android.Runtime.IJavaObject
#endif // !JAVA_INTEROP1
{
char CharAt (int index);
int Length ();
Java.Lang.ICharSequence SubSequenceFormatted (int start, int end);
string ToString ();
}
}

#endif // !JAVA_INTEROP1
13 changes: 6 additions & 7 deletions tests/generator-Tests/SupportFiles/Java_Lang_String.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
#if !JAVA_INTEROP1

using System;
using System;
using System.Collections;
using System.Collections.Generic;

namespace Java.Lang {

public sealed partial class String : global::Java.Lang.Object, Java.Lang.ICharSequence
public sealed partial class String : global::Java.Lang.Object, Java.Lang.ICharSequence, IEnumerable
{
public String (string value)
public unsafe String (string value)
#if JAVA_INTEROP1
: base (ref *InvalidJniObjectReference, Java.Interop.JniObjectReferenceOptions.None)
#endif // JAVA_INTEROP1
{
}

Expand Down Expand Up @@ -43,5 +44,3 @@ IEnumerator IEnumerable.GetEnumerator ()
}
}
}

#endif // !JAVA_INTEROP1
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

#nullable restore
using System;
using System.Collections.Generic;
using Java.Interop;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

#nullable restore
using System;
using System.Collections.Generic;
using Java.Interop;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

#nullable restore
using System;
using System.Collections.Generic;
using Java.Interop;
Expand Down Expand Up @@ -36,22 +46,27 @@ public unsafe GenericImplementation () : base (ref *InvalidJniObjectReference, J
}

// Metadata.xml XPath method reference: path="/api/package[@name='test.me']/class[@name='GenericImplementation']/method[@name='SetObject' and count(parameter)=1 and parameter[1][@type='byte[]']]"
[global::Java.Interop.JniMethodSignature ("SetObject", "([B)V")]
public virtual unsafe void SetObject (global::Java.Interop.JavaSByteArray value)
{
const string __id = "SetObject.([B)V";
var native_value = global::Java.Interop.JniEnvironment.Arrays.CreateMarshalSByteArray (value);
try {
JniArgumentValue* __args = stackalloc JniArgumentValue [1];
__args [0] = new JniArgumentValue (value);
__args [0] = new JniArgumentValue (native_value);
_members.InstanceMethods.InvokeVirtualVoidMethod (__id, this, __args);
} finally {
if (native_value != null) {
native_value.DisposeUnlessReferenced ();
}
global::System.GC.KeepAlive (value);
}
}

// This method is explicitly implemented as a member of an instantiated Test.ME.IGenericInterface
void global::Test.ME.IGenericInterface.SetObject (global::Java.Lang.Object value)
{
SetObject (global::Java.Interop.JavaObjectExtensions.JavaCast<global::Java.Interop.JavaSByteArray>(value));
SetObject (global::Java.Interop.JniEnvironment.Runtime.ValueManager.GetValue<global::Java.Interop.JavaSByteArray>((value?.PeerReference ?? default).Handle));
}

}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

#nullable restore
using System;
using System.Collections.Generic;
using Java.Interop;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

#nullable restore
using System;
using System.Collections.Generic;
using Java.Interop;
Expand Down Expand Up @@ -36,22 +46,27 @@ public unsafe GenericStringImplementation () : base (ref *InvalidJniObjectRefere
}

// Metadata.xml XPath method reference: path="/api/package[@name='test.me']/class[@name='GenericStringImplementation']/method[@name='SetObject' and count(parameter)=1 and parameter[1][@type='java.lang.String[]']]"
[global::Java.Interop.JniMethodSignature ("SetObject", "([Ljava/lang/String;)V")]
public virtual unsafe void SetObject (global::Java.Interop.JavaObjectArray<string> value)
{
const string __id = "SetObject.([Ljava/lang/String;)V";
var native_value = global::Java.Interop.JniEnvironment.Arrays.CreateMarshalObjectArray<string> (value);
try {
JniArgumentValue* __args = stackalloc JniArgumentValue [1];
__args [0] = new JniArgumentValue (value);
__args [0] = new JniArgumentValue (native_value);
_members.InstanceMethods.InvokeVirtualVoidMethod (__id, this, __args);
} finally {
if (native_value != null) {
native_value.DisposeUnlessReferenced ();
}
global::System.GC.KeepAlive (value);
}
}

// This method is explicitly implemented as a member of an instantiated Test.ME.IGenericInterface
void global::Test.ME.IGenericInterface.SetObject (global::Java.Lang.Object value)
{
SetObject (global::Java.Interop.JavaObjectExtensions.JavaCast<global::Java.Interop.JavaObjectArray<string>>(value));
SetObject (global::Java.Interop.JniEnvironment.Runtime.ValueManager.GetValue<global::Java.Interop.JavaObjectArray<string>>((value?.PeerReference ?? default).Handle));
}

}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

#nullable restore
using System;
using System.Collections.Generic;
using Java.Interop;
Expand Down Expand Up @@ -62,11 +72,9 @@ public virtual unsafe string Object {
// This method is explicitly implemented as a member of an instantiated Test.ME.IGenericPropertyInterface
global::Java.Lang.Object global::Test.ME.IGenericPropertyInterface.Object {
// Metadata.xml XPath method reference: path="/api/package[@name='test.me']/interface[@name='GenericPropertyInterface']/method[@name='getObject' and count(parameter)=0]"
[Register ("getObject", "()Ljava/lang/Object;", "GetGetObjectHandler:Test.ME.IGenericPropertyInterfaceInvoker, Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null")]
get { return Object; }
get { return new Java.Lang.String (Object); }
// Metadata.xml XPath method reference: path="/api/package[@name='test.me']/interface[@name='GenericPropertyInterface']/method[@name='setObject' and count(parameter)=1 and parameter[1][@type='T']]"
[Register ("setObject", "(Ljava/lang/Object;)V", "GetSetObject_Ljava_lang_Object_Handler:Test.ME.IGenericPropertyInterfaceInvoker, Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null")]
set { Object = value.ToString (); }
set { Object = value?.ToString (); }
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,37 @@ namespace Test.ME {
[global::Java.Interop.JavaTypeParameters (new string [] {"T"})]
public partial interface IGenericInterface : IJavaPeerable {
// Metadata.xml XPath method reference: path="/api/package[@name='test.me']/interface[@name='GenericInterface']/method[@name='SetObject' and count(parameter)=1 and parameter[1][@type='T']]"
[global::Java.Interop.JniMethodSignature ("SetObject", "(Ljava/lang/Object;)V")]
void SetObject (global::Java.Lang.Object value);

}

[global::Java.Interop.JniTypeSignature ("test/me/GenericInterface", GenerateJavaPeer=false)]
internal partial class IGenericInterfaceInvoker : global::Java.Lang.Object, IGenericInterface {
[global::System.Diagnostics.DebuggerBrowsable (global::System.Diagnostics.DebuggerBrowsableState.Never)]
[global::System.ComponentModel.EditorBrowsable (global::System.ComponentModel.EditorBrowsableState.Never)]
public override global::Java.Interop.JniPeerMembers JniPeerMembers {
get { return _members_IGenericInterface; }
}

static readonly JniPeerMembers _members_IGenericInterface = new JniPeerMembers ("test/me/GenericInterface", typeof (IGenericInterfaceInvoker));

public IGenericInterfaceInvoker (ref JniObjectReference reference, JniObjectReferenceOptions options) : base (ref reference, options)
{
}

public unsafe void SetObject (global::Java.Lang.Object value)
{
const string __id = "SetObject.(Ljava/lang/Object;)V";
var native_value = (value?.PeerReference ?? default);
try {
JniArgumentValue* __args = stackalloc JniArgumentValue [1];
__args [0] = new JniArgumentValue (native_value);
_members_IGenericInterface.InstanceMethods.InvokeAbstractVoidMethod (__id, this, __args);
} finally {
global::System.GC.KeepAlive (value);
}
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,51 @@ namespace Test.ME {
public partial interface IGenericPropertyInterface : IJavaPeerable {
global::Java.Lang.Object Object {
// Metadata.xml XPath method reference: path="/api/package[@name='test.me']/interface[@name='GenericPropertyInterface']/method[@name='getObject' and count(parameter)=0]"
[global::Java.Interop.JniMethodSignature ("getObject", "()Ljava/lang/Object;")]
get;

// Metadata.xml XPath method reference: path="/api/package[@name='test.me']/interface[@name='GenericPropertyInterface']/method[@name='setObject' and count(parameter)=1 and parameter[1][@type='T']]"
[global::Java.Interop.JniMethodSignature ("setObject", "(Ljava/lang/Object;)V")]
set;
}

}

[global::Java.Interop.JniTypeSignature ("test/me/GenericPropertyInterface", GenerateJavaPeer=false)]
internal partial class IGenericPropertyInterfaceInvoker : global::Java.Lang.Object, IGenericPropertyInterface {
[global::System.Diagnostics.DebuggerBrowsable (global::System.Diagnostics.DebuggerBrowsableState.Never)]
[global::System.ComponentModel.EditorBrowsable (global::System.ComponentModel.EditorBrowsableState.Never)]
public override global::Java.Interop.JniPeerMembers JniPeerMembers {
get { return _members_IGenericPropertyInterface; }
}

static readonly JniPeerMembers _members_IGenericPropertyInterface = new JniPeerMembers ("test/me/GenericPropertyInterface", typeof (IGenericPropertyInterfaceInvoker));

public IGenericPropertyInterfaceInvoker (ref JniObjectReference reference, JniObjectReferenceOptions options) : base (ref reference, options)
{
}

public unsafe global::Java.Lang.Object Object {
get {
const string __id = "getObject.()Ljava/lang/Object;";
try {
var __rm = _members_IGenericPropertyInterface.InstanceMethods.InvokeAbstractObjectMethod (__id, this, null);
return global::Java.Interop.JniEnvironment.Runtime.ValueManager.GetValue<global::Java.Lang.Object>(ref __rm, JniObjectReferenceOptions.CopyAndDispose);
} finally {
}
}
set {
const string __id = "setObject.(Ljava/lang/Object;)V";
var native_value = (value?.PeerReference ?? default);
try {
JniArgumentValue* __args = stackalloc JniArgumentValue [1];
__args [0] = new JniArgumentValue (native_value);
_members_IGenericPropertyInterface.InstanceMethods.InvokeAbstractVoidMethod (__id, this, __args);
} finally {
global::System.GC.KeepAlive (value);
}
}
}

}
}
Loading

0 comments on commit 7f77a70

Please sign in to comment.