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

Commit fa10e98

Browse files
authored
[generator] Do bind package-private nested types (#575)
Fixes: #572 Do not bind ["package private"][0] nested types For example, given: public class OuterExample { /* package */ static class InnerExample { } } The type `OuterExample.InnerExample` *should not be bound*. Previously `OuterExample.InnerExample` *would* be bound as a *`public`* type (?!), which could result in later Java Callable Wrapper compilation errors, if/when they attempted to access the package-private types This change causes package-private nested types to behave the same as top-level package-private types, which were never bound. [0]: https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
1 parent b81cfbb commit fa10e98

2 files changed

Lines changed: 26 additions & 0 deletions

File tree

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,21 @@
1818
public class PublicClass extends PackageClass {
1919
@Override
2020
public void foo();
21+
22+
// This nested type should not be generated because it is package-private
23+
/* package */ static interface OnPressedChangeListener {
24+
void onPressedChanged ();
25+
}
2126
}
2227
-->
2328
<classabstract="false"deprecated="not deprecated"extends="xamarin.test.PackageClass"extends-generic-aware="xamarin.test.PackageClass"final="false"name="PublicClass"static="false"visibility="public">
2429
<constructordeprecated="not deprecated"final="false"name="PublicClass"static="false"visibility="public" />
2530
<methodabstract="false"deprecated="not deprecated"final="false"name="foo"native="false"return="void"static="false"synchronized="false"visibility="public">
2631
</method>
2732
</class>
33+
<interfaceabstract="true"deprecated="not deprecated"final="false"name="PublicClass.OnPressedChangeListener"static="true"visibility="" >
34+
<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" />
35+
</interface>
2836
<!--
2937
/* package */ abstract class ExtendPackageClass extends PackageClass {
3038
}

‎tools/generator/CodeGenerator.cs‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,8 @@ static void Validate (List<GenBase> gens, CodeGenerationOptions opt, CodeGenerat
232232
{
233233
//int cycle = 1;
234234
List<GenBase>removed=newList<GenBase>();
235+
varnested_removes=newList<GenBase>();
236+
235237
// This loop is required because we cannot really split type validation and member
236238
// validation apart (unlike C# compiler), because invalidated members will result
237239
// in the entire interface invalidation (since we cannot implement it), and use of
@@ -254,6 +256,22 @@ static void Validate (List<GenBase> gens, CodeGenerationOptions opt, CodeGenerat
254256
removed.Add(gen);
255257
}
256258

259+
// Remove any nested types that are package-private
260+
foreach(vargeningens){
261+
foreach(varnestingen.NestedTypes)
262+
if(opt.IgnoreNonPublicType&&(nest.RawVisibility!="public"&&nest.RawVisibility!="internal")){
263+
// We still add it to "removed" even though the removal
264+
// code later won't work, so that it triggers a new cycle
265+
removed.Add(nest);
266+
nested_removes.Add(nest);
267+
}
268+
269+
foreach(varnestinnested_removes)
270+
gen.NestedTypes.Remove(nest);
271+
272+
nested_removes.Clear();
273+
}
274+
257275
foreach(GenBasegeninremoved)
258276
gens.Remove(gen);
259277
}while(removed.Count>0);

0 commit comments

Comments
 (0)