Skip to content

Commit 5db30a8

Browse files
jpobstjonpryor
authored andcommitted
[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 e92f341 commit 5db30a8

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

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
<class abstract="false" deprecated="not deprecated" extends="xamarin.test.PackageClass" extends-generic-aware="xamarin.test.PackageClass" final="false" name="PublicClass" static="false" visibility="public">
2429
<constructor deprecated="not deprecated" final="false" name="PublicClass" static="false" visibility="public" />
2530
<method abstract="false" deprecated="not deprecated" final="false" name="foo" native="false" return="void" static="false" synchronized="false" visibility="public">
2631
</method>
2732
</class>
33+
<interface abstract="true" deprecated="not deprecated" final="false" name="PublicClass.OnPressedChangeListener" static="true" visibility="" >
34+
<method abstract="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 = new List<GenBase> ();
235+
var nested_removes = new List<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 (var gen in gens) {
261+
foreach (var nest in gen.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 (var nest in nested_removes)
270+
gen.NestedTypes.Remove (nest);
271+
272+
nested_removes.Clear ();
273+
}
274+
257275
foreach (GenBase gen in removed)
258276
gens.Remove (gen);
259277
} while (removed.Count > 0);

0 commit comments

Comments
 (0)