Skip to content
This repository was archived by the owner on Jul 6, 2026. It is now read-only.

Commit cd33da6

Browse files
authored
[generator] Bind protected nested types (#578)
In commit fa10e98, we stopped binding nested types that are **not** `public` or `internal`. However, we also need to bind nested types that are `protected`. Note that internally `protected` is stored as `protected internal`: https://github.com/xamarin/java.interop/blob/fa10e98bb42a92229281056cf3e74d0576f4d9f8/tools/generator/Java.Interop.Tools.Generator.Importers/XmlApiImporter.cs#L143-L144
1 parent fa10e98 commit cd33da6

4 files changed

Lines changed: 177 additions & 1 deletion

File tree

‎tests/generator-Tests/expected.ji/AccessModifiers/Xamarin.Test.PublicClass.cs‎

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,94 @@ namespace Xamarin.Test {
99
[global::Android.Runtime.Register("xamarin/test/PublicClass",DoNotGenerateAcw=true)]
1010
publicpartialclassPublicClass:global::Java.Lang.Object{
1111

12+
// Metadata.xml XPath interface reference: path="/api/package[@name='xamarin.test']/interface[@name='PublicClass.ProtectedInterface']"
13+
[Register("xamarin/test/PublicClass$ProtectedInterface","","Xamarin.Test.PublicClass/IProtectedInterfaceInvoker")]
14+
protectedinternalpartialinterfaceIProtectedInterface:IJavaObject,IJavaPeerable{
15+
16+
// Metadata.xml XPath method reference: path="/api/package[@name='xamarin.test']/interface[@name='PublicClass.ProtectedInterface']/method[@name='foo' and count(parameter)=0]"
17+
[Register("foo","()V","GetFooHandler:Xamarin.Test.PublicClass/IProtectedInterfaceInvoker, Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null")]
18+
voidFoo();
19+
20+
}
21+
22+
[global::Android.Runtime.Register("xamarin/test/PublicClass$ProtectedInterface",DoNotGenerateAcw=true)]
23+
internalpartialclassIProtectedInterfaceInvoker:global::Java.Lang.Object,IProtectedInterface{
24+
25+
staticreadonlyJniPeerMembers_members=newJniPeerMembers("xamarin/test/PublicClass$ProtectedInterface",typeof(IProtectedInterfaceInvoker));
26+
27+
staticIntPtrjava_class_ref{
28+
get{return_members.JniPeerType.PeerReference.Handle;}
29+
}
30+
31+
publicoverrideglobal::Java.Interop.JniPeerMembersJniPeerMembers{
32+
get{return_members;}
33+
}
34+
35+
protectedoverrideIntPtrThresholdClass{
36+
get{returnclass_ref;}
37+
}
38+
39+
protectedoverrideglobal::System.TypeThresholdType{
40+
get{return_members.ManagedPeerType;}
41+
}
42+
43+
newIntPtrclass_ref;
44+
45+
publicstaticIProtectedInterfaceGetObject(IntPtrhandle,JniHandleOwnershiptransfer)
46+
{
47+
returnglobal::Java.Lang.Object.GetObject<IProtectedInterface>(handle,transfer);
48+
}
49+
50+
staticIntPtrValidate(IntPtrhandle)
51+
{
52+
if(!JNIEnv.IsInstanceOf(handle,java_class_ref))
53+
thrownewInvalidCastException(string.Format("Unable to convert instance of type '{0}' to type '{1}'.",
54+
JNIEnv.GetClassNameFromInstance(handle),"xamarin.test.PublicClass.ProtectedInterface"));
55+
returnhandle;
56+
}
57+
58+
protectedoverridevoidDispose(booldisposing)
59+
{
60+
if(this.class_ref!=IntPtr.Zero)
61+
JNIEnv.DeleteGlobalRef(this.class_ref);
62+
this.class_ref=IntPtr.Zero;
63+
base.Dispose(disposing);
64+
}
65+
66+
publicIProtectedInterfaceInvoker(IntPtrhandle,JniHandleOwnershiptransfer):base(Validate(handle),transfer)
67+
{
68+
IntPtrlocal_ref=JNIEnv.GetObjectClass(((global::Java.Lang.Object)this).Handle);
69+
this.class_ref=JNIEnv.NewGlobalRef(local_ref);
70+
JNIEnv.DeleteLocalRef(local_ref);
71+
}
72+
73+
staticDelegatecb_foo;
74+
#pragma warning disable 0169
75+
staticDelegateGetFooHandler()
76+
{
77+
if(cb_foo==null)
78+
cb_foo=JNINativeWrapper.CreateDelegate((Action<IntPtr,IntPtr>)n_Foo);
79+
returncb_foo;
80+
}
81+
82+
staticvoidn_Foo(IntPtrjnienv,IntPtrnative__this)
83+
{
84+
global::Xamarin.Test.PublicClass.IProtectedInterface__this=global::Java.Lang.Object.GetObject<global::Xamarin.Test.PublicClass.IProtectedInterface>(jnienv,native__this,JniHandleOwnership.DoNotTransfer);
85+
__this.Foo();
86+
}
87+
#pragma warning restore 0169
88+
89+
IntPtrid_foo;
90+
publicunsafevoidFoo()
91+
{
92+
if(id_foo==IntPtr.Zero)
93+
id_foo=JNIEnv.GetMethodID(class_ref,"foo","()V");
94+
JNIEnv.CallVoidMethod(((global::Java.Lang.Object)this).Handle,id_foo);
95+
}
96+
97+
}
98+
99+
12100
staticreadonlyJniPeerMembers_members=newJniPeerMembers("xamarin/test/PublicClass",typeof(PublicClass));
13101
internalstaticnewIntPtrclass_ref{
14102
get{

‎tests/generator-Tests/expected/AccessModifiers/AccessModifiers.xml‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@
2323
/* package */ static interface OnPressedChangeListener {
2424
void onPressedChanged ();
2525
}
26+
27+
// This nested type should be generated because it is protected
28+
protected interface ProtectedInterface {
29+
void foo ();
30+
}
2631
}
2732
-->
2833
<classabstract="false"deprecated="not deprecated"extends="xamarin.test.PackageClass"extends-generic-aware="xamarin.test.PackageClass"final="false"name="PublicClass"static="false"visibility="public">
@@ -33,6 +38,9 @@
3338
<interfaceabstract="true"deprecated="not deprecated"final="false"name="PublicClass.OnPressedChangeListener"static="true"visibility="" >
3439
<methodabstract="true"deprecated="not deprecated"final="false"name="onPressedChanged"jni-signature="V"bridge="false"native="false"return="void"jni-return="V"static="false"synchronized="false"synthetic="false"visibility="public" />
3540
</interface>
41+
<interfaceabstract="true"deprecated="not deprecated"final="false"name="PublicClass.ProtectedInterface"static="true"visibility="protected" >
42+
<methodabstract="true"deprecated="not deprecated"final="false"name="foo"jni-signature="V"bridge="false"native="false"return="void"jni-return="V"static="false"synchronized="false"synthetic="false"visibility="public" />
43+
</interface>
3644
<!--
3745
/* package */ abstract class ExtendPackageClass extends PackageClass {
3846
}

‎tests/generator-Tests/expected/AccessModifiers/Xamarin.Test.PublicClass.cs‎

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,86 @@ namespace Xamarin.Test {
88
[global::Android.Runtime.Register("xamarin/test/PublicClass",DoNotGenerateAcw=true)]
99
publicpartialclassPublicClass:global::Java.Lang.Object{
1010

11+
// Metadata.xml XPath interface reference: path="/api/package[@name='xamarin.test']/interface[@name='PublicClass.ProtectedInterface']"
12+
[Register("xamarin/test/PublicClass$ProtectedInterface","","Xamarin.Test.PublicClass/IProtectedInterfaceInvoker")]
13+
protectedinternalpartialinterfaceIProtectedInterface:IJavaObject{
14+
15+
// Metadata.xml XPath method reference: path="/api/package[@name='xamarin.test']/interface[@name='PublicClass.ProtectedInterface']/method[@name='foo' and count(parameter)=0]"
16+
[Register("foo","()V","GetFooHandler:Xamarin.Test.PublicClass/IProtectedInterfaceInvoker, Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null")]
17+
voidFoo();
18+
19+
}
20+
21+
[global::Android.Runtime.Register("xamarin/test/PublicClass$ProtectedInterface",DoNotGenerateAcw=true)]
22+
internalpartialclassIProtectedInterfaceInvoker:global::Java.Lang.Object,IProtectedInterface{
23+
24+
staticIntPtrjava_class_ref=JNIEnv.FindClass("xamarin/test/PublicClass$ProtectedInterface");
25+
26+
protectedoverrideIntPtrThresholdClass{
27+
get{returnclass_ref;}
28+
}
29+
30+
protectedoverrideglobal::System.TypeThresholdType{
31+
get{returntypeof(IProtectedInterfaceInvoker);}
32+
}
33+
34+
newIntPtrclass_ref;
35+
36+
publicstaticIProtectedInterfaceGetObject(IntPtrhandle,JniHandleOwnershiptransfer)
37+
{
38+
returnglobal::Java.Lang.Object.GetObject<IProtectedInterface>(handle,transfer);
39+
}
40+
41+
staticIntPtrValidate(IntPtrhandle)
42+
{
43+
if(!JNIEnv.IsInstanceOf(handle,java_class_ref))
44+
thrownewInvalidCastException(string.Format("Unable to convert instance of type '{0}' to type '{1}'.",
45+
JNIEnv.GetClassNameFromInstance(handle),"xamarin.test.PublicClass.ProtectedInterface"));
46+
returnhandle;
47+
}
48+
49+
protectedoverridevoidDispose(booldisposing)
50+
{
51+
if(this.class_ref!=IntPtr.Zero)
52+
JNIEnv.DeleteGlobalRef(this.class_ref);
53+
this.class_ref=IntPtr.Zero;
54+
base.Dispose(disposing);
55+
}
56+
57+
publicIProtectedInterfaceInvoker(IntPtrhandle,JniHandleOwnershiptransfer):base(Validate(handle),transfer)
58+
{
59+
IntPtrlocal_ref=JNIEnv.GetObjectClass(((global::Java.Lang.Object)this).Handle);
60+
this.class_ref=JNIEnv.NewGlobalRef(local_ref);
61+
JNIEnv.DeleteLocalRef(local_ref);
62+
}
63+
64+
staticDelegatecb_foo;
65+
#pragma warning disable 0169
66+
staticDelegateGetFooHandler()
67+
{
68+
if(cb_foo==null)
69+
cb_foo=JNINativeWrapper.CreateDelegate((Action<IntPtr,IntPtr>)n_Foo);
70+
returncb_foo;
71+
}
72+
73+
staticvoidn_Foo(IntPtrjnienv,IntPtrnative__this)
74+
{
75+
global::Xamarin.Test.PublicClass.IProtectedInterface__this=global::Java.Lang.Object.GetObject<global::Xamarin.Test.PublicClass.IProtectedInterface>(jnienv,native__this,JniHandleOwnership.DoNotTransfer);
76+
__this.Foo();
77+
}
78+
#pragma warning restore 0169
79+
80+
IntPtrid_foo;
81+
publicunsafevoidFoo()
82+
{
83+
if(id_foo==IntPtr.Zero)
84+
id_foo=JNIEnv.GetMethodID(class_ref,"foo","()V");
85+
JNIEnv.CallVoidMethod(((global::Java.Lang.Object)this).Handle,id_foo);
86+
}
87+
88+
}
89+
90+
1191
internalstaticnewIntPtrjava_class_handle;
1292
internalstaticnewIntPtrclass_ref{
1393
get{

‎tools/generator/CodeGenerator.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ static void Validate (List<GenBase> gens, CodeGenerationOptions opt, CodeGenerat
259259
// Remove any nested types that are package-private
260260
foreach(vargeningens){
261261
foreach(varnestingen.NestedTypes)
262-
if(opt.IgnoreNonPublicType&&(nest.RawVisibility!="public"&&nest.RawVisibility!="internal")){
262+
if(opt.IgnoreNonPublicType&&(nest.RawVisibility!="public"&&nest.RawVisibility!="internal"&&nest.RawVisibility!="protected internal")){
263263
// We still add it to "removed" even though the removal
264264
// code later won't work, so that it triggers a new cycle
265265
removed.Add(nest);

0 commit comments

Comments
 (0)