Skip to content

Commit 12c9c82

Browse files
committed
Add test around interface method inheritance
Context: 1adb796 Context: #1183 While reviewing #1261, I noticed this change: ```diff diff --git a/tests/generator-Tests/expected.ji/AccessModifiers/Xamarin.Test.IExtendedInterface.cs b/tests/generator-Tests/expected.ji/AccessModifiers/Xamarin.Test.IExtendedInterface.cs index 3ea50e6bd..83d01f24a 100644 --- a/tests/generator-Tests/expected.ji/AccessModifiers/Xamarin.Test.IExtendedInterface.cs +++ b/tests/generator-Tests/expected.ji/AccessModifiers/Xamarin.Test.IExtendedInterface.cs @@ -46,7 +46,7 @@ public unsafe void BaseMethod () { const string __id = "baseMethod.()V"; try { - _members_xamarin_test_BaseInterface.InstanceMethods.InvokeAbstractVoidMethod (__id, this, null); + _members_xamarin_test_ExtendedInterface.InstanceMethods.InvokeAbstractVoidMethod (__id, this, null); } finally { } } ``` and went "hmm". Recall and consider 1adb796: if we invoke the interface method on the "wrong" declaring type, things break. This is why 1adb796 updated interface invokers to only invoke methods upon their declared interfaces. The concern comes around *non-`public`* interface method invocation: /* package */ interface PackagePrivateInterface { void m(); } public interface PublicInterface extends PackagePrivateInterface { } With commit 63dcf36, attempts to invoke `m()` are made upon `PublicInterface`, not `PackagePrivateInterface`. Is this a problem? Begin partially implementing #1183, adding a new `build-tools/Java.Interop.Sdk` (not quite a) "project", which has an `Sdk.props` and `Sdk.targets` file, which combined add support for: * A `@(JavaCompile)` build action, for Java source. * A `@(JavaReference)` build action, for Java libraries. * As a pre-Compile step, files with `%(JavaCompile.Bind)`=True or `%(JavaReference.Bind)`=True will be automatically bound, via `class-parse` + `generator`. * As a post-Compile step, the assembly will be processed with `jcw-gen` to generate Java Callable Wrappers, which will be compiled into `$(AssemblyName).jar`. Then, update `tests/Java.Base-Tests` to use this new functionality, adding a test case to hit the "invoke method declared in a private interface upon the public interface" scenario. Result: it works! Of partial interest is `IInterfaceMethodInheritanceInvoker`: internal partial class IInterfaceMethodInheritanceInvoker : global::Java.Lang.Object, IInterfaceMethodInheritance { static readonly JniPeerMembers _members_net_dot_jni_test_BaseInterface = new JniPeerMembers ("net/dot/jni/test/BaseInterface", typeof (IInterfaceMethodInheritanceInvoker)); static readonly JniPeerMembers _members_net_dot_jni_test_InterfaceMethodInheritance = new JniPeerMembers ("net/dot/jni/test/InterfaceMethodInheritance", typeof (IInterfaceMethodInheritanceInvoker)); static readonly JniPeerMembers _members_net_dot_jni_test_InternalInterface = new JniPeerMembers ("net/dot/jni/test/InternalInterface", typeof (IInterfaceMethodInheritanceInvoker)); static readonly JniPeerMembers _members_net_dot_jni_test_PublicInterface = new JniPeerMembers ("net/dot/jni/test/PublicInterface", typeof (IInterfaceMethodInheritanceInvoker)); } Of these four fields, two are for internal types: `_members_net_dot_jni_test_BaseInterface` and `_members_net_dot_jni_test_InternalInterface`. Fortunately those types aren't otherwise used. Of concern, though, is that the constructor invocation *does* result in a `JNIEnv::FindClass()` invocation, meaning these bindings would look up (ostensibly) "private" types, which could change! This presents a compatibility concern: if (when?) those type names change, then the generated bindings will break. TODO: * Test this puppy in dotnet/android. Just because "it works" on Desktop JDK doesn't mean it does *on Android*. * Update `generator` output to *not* emit the `static readonly JniPeerMembers` fields for internal types.
1 parent 63dcf36 commit 12c9c82

File tree

8 files changed

+305
-47
lines changed

8 files changed

+305
-47
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<Project>
2+
<PropertyGroup>
3+
<JavaPathSeparator Condition=" $([MSBuild]::IsOSPlatform('windows')) ">;</JavaPathSeparator>
4+
<JavaPathSeparator Condition=" '$(JavacClasspathSeparator)' == '' ">:</JavaPathSeparator>
5+
</PropertyGroup>
6+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
<Project>
2+
3+
<ItemDefinitionGroup>
4+
<JavaCompile>
5+
<Bind>True</Bind>
6+
</JavaCompile>
7+
<JavaReference>
8+
<Bind>True</Bind>
9+
</JavaReference>
10+
</ItemDefinitionGroup>
11+
12+
<PropertyGroup>
13+
<JavaOutputJar Condition=" '$(JavaOutputJar)' == '' ">$(OutputPath)$(AssemblyName).jar</JavaOutputJar>
14+
</PropertyGroup>
15+
16+
<PropertyGroup>
17+
<JavaCreateManagedBindingsDependsOn>
18+
_BuildJavaCompileForManagedBinding;
19+
_GenerateApiDescription;
20+
_GenerateManagedBinding;
21+
_CleanupManagedBinding;
22+
</JavaCreateManagedBindingsDependsOn>
23+
<JavaCreateJavaCallableWrappersDependsOn>
24+
_JavaCreateJcws;
25+
_JavaCreateOutputJar;
26+
</JavaCreateJavaCallableWrappersDependsOn>
27+
</PropertyGroup>
28+
29+
<Target Name="JavaCreateManagedBindings"
30+
BeforeTargets="CoreCompile"
31+
DependsOnTargets="$(JavaCreateManagedBindingsDependsOn)">
32+
</Target>
33+
34+
<Target Name="JavaCreateJavaCallableWrappers"
35+
AfterTargets="CoreCompile"
36+
DependsOnTargets="$(JavaCreateJavaCallableWrappersDependsOn)">
37+
</Target>
38+
39+
<PropertyGroup>
40+
<_GeneratorPath>$(UtilityOutputFullPath)generator.dll</_GeneratorPath>
41+
<_JavaIntermediateDir>$(IntermediateOutputPath)_ji\</_JavaIntermediateDir>
42+
<_JavaManagedBindingInput>$(_JavaIntermediateDir)o.jar</_JavaManagedBindingInput>
43+
<_JavaManagedBindingDir>$(_JavaIntermediateDir)mcw\</_JavaManagedBindingDir>
44+
<_JavaJcwClassesDir>$(_JavaIntermediateDir)classes\</_JavaJcwClassesDir>
45+
<_JavaJcwSourcesDir>$(_JavaIntermediateDir)java\</_JavaJcwSourcesDir>
46+
</PropertyGroup>
47+
48+
<Target Name="_CollectJavaCompileForManagedBindingInputs">
49+
<ItemGroup>
50+
<_JavaCompileForBindingInputs
51+
Condition=" '%(JavaCompile.Bind)' == 'True' "
52+
Include="@(JavaCompile)"
53+
/>
54+
</ItemGroup>
55+
</Target>
56+
57+
<Target Name="_JavaCollectJavacRefs">
58+
<ItemGroup>
59+
<_JavacRefs Include="$(ToolOutputFullPath)java-interop.jar" />
60+
<_JavacRefs Include="@(JavaReference)" />
61+
<_JavacRefsWithForwardSlash Include="@(_JavacRefs->Replace('%5c', '/'))" />
62+
</ItemGroup>
63+
</Target>
64+
65+
<Target Name="_BuildJavaCompileForManagedBinding"
66+
DependsOnTargets="_CollectJavaCompileForManagedBindingInputs;_JavaCollectJavacRefs"
67+
Inputs="@(_JavaCompileForBindingInputs)"
68+
Outputs="$(_JavaManagedBindingInput)">
69+
<PropertyGroup>
70+
<_ClassesDir>$(_JavaIntermediateDir)\bound-classes</_ClassesDir>
71+
<_ResponseFile>$(_JavaIntermediateDir)r.txt</_ResponseFile>
72+
<_Classpath>@(_JavacRefsWithForwardSlash, '$(JavaPathSeparator)')</_Classpath>
73+
</PropertyGroup>
74+
<MakeDir Directories="$(_ClassesDir)" />
75+
<ItemGroup>
76+
<_Response Include="-classpath" />
77+
<_Response Include="&quot;$(_Classpath)&quot;" />
78+
<_Response Include="@(_JavaCompileForBindingInputs->Replace('%5c', '/'))" />
79+
</ItemGroup>
80+
<WriteLinesToFile
81+
File="$(_ResponseFile)"
82+
Lines="@(_Response)"
83+
Overwrite="True"
84+
/>
85+
<Message Text="`javac` response file contents:" Importance="Low" />
86+
<Message Text="@(_Response, '
87+
')" Importance="Low" />
88+
<Exec Command="&quot;$(JavaCPath)&quot; $(_JavacSourceOptions) -d &quot;$(_ClassesDir)&quot; &quot;@$(_ResponseFile)&quot;" />
89+
<Delete Files="$(_ResponseFile)" />
90+
<Exec Command="&quot;$(JarPath)&quot; cf &quot;$(_JavaManagedBindingInput)&quot; -C &quot;$(_ClassesDir)&quot; ." />
91+
</Target>
92+
93+
<Target Name="_CollectClassParseInputs">
94+
<ItemGroup>
95+
<_ClassParseInputs
96+
Condition=" Exists($(_JavaManagedBindingInput))"
97+
Include="$(_JavaManagedBindingInput)"
98+
/>
99+
<_ClassParseInputs
100+
Condition=" '%(JavaReference.Bind)' == 'True' "
101+
Include="@(JavaReference)"
102+
/>
103+
</ItemGroup>
104+
</Target>
105+
106+
<Target Name="_GenerateApiDescription"
107+
DependsOnTargets="_CollectClassParseInputs"
108+
Inputs="@(_ClassParseInputs)"
109+
Outputs="$(_JavaManagedBindingDir)api.xml">
110+
<MakeDir Directories="$(_JavaManagedBindingDir)" />
111+
<PropertyGroup>
112+
<_ClassParse>"$(UtilityOutputFullPath)class-parse.dll"</_ClassParse>
113+
<_Inputs>@(_ClassParseInputs, ' ')</_Inputs>
114+
<_Output>"-o=$(_JavaManagedBindingDir)api.xml"</_Output>
115+
</PropertyGroup>
116+
<Exec
117+
Command="$(DotnetToolPath) $(_ClassParse) $(_Inputs) $(_Output)"
118+
/>
119+
</Target>
120+
121+
<Target Name="_GenerateManagedBinding"
122+
DependsOnTargets="_GenerateApiDescription"
123+
Inputs="$(_JavaManagedBindingDir)api.xml"
124+
Outputs="$(_JavaManagedBindingDir)$(AssemblyName).projitems">
125+
<MakeDir Directories="$(_JavaManagedBindingDir)" />
126+
<PropertyGroup>
127+
<Generator>"$(_GeneratorPath)"</Generator>
128+
<_GenFlags>--public --global</_GenFlags>
129+
<_Out>-o "$(_JavaManagedBindingDir)"</_Out>
130+
<_Codegen>--codegen-target=JavaInterop1</_Codegen>
131+
<_Assembly>"--assembly=$(AssemblyName)"</_Assembly>
132+
<_TypeMap>--type-map-report=$(_JavaManagedBindingDir)type-mapping.txt</_TypeMap>
133+
<_Api>$(_JavaManagedBindingDir)api.xml</_Api>
134+
<_Dirs>--enumdir=$(_JavaManagedBindingDir)</_Dirs>
135+
<_FullIntermediateOutputPath>$([System.IO.Path]::GetFullPath('$(_JavaManagedBindingDir)'))</_FullIntermediateOutputPath>
136+
<_LangFeatures>--lang-features=nullable-reference-types,default-interface-methods,nested-interface-types,interface-constants</_LangFeatures>
137+
</PropertyGroup>
138+
<ItemGroup>
139+
<!-- I can't find a good way to trim the trailing `\`, so append with `.` so we can sanely quote for $(_Libpath) -->
140+
<_RefAsmDir Include="@(ReferencePathWithRefAssemblies->'%(RootDir)%(Directory).'->Distinct())" />
141+
<_Lib Include="@(_RefAsmDir->'-L &quot;%(Identity)&quot;')" />
142+
<_JavaBaseRef Include="@(ReferencePathWithRefAssemblies)"
143+
Condition=" '%(FileName)' == 'Java.Base' "
144+
/>
145+
<_Ref Include="@(_JavaBaseRef->'-r &quot;%(FullPath)&quot;')" />
146+
</ItemGroup>
147+
<Exec
148+
Command="$(DotnetToolPath) $(Generator) $(_GenFlags) $(_ApiLevel) $(_Out) @(_Lib, ' ') @(_Ref, ' ') $(_Codegen) $(_Assembly) $(_TypeMap) $(_LangFeatures) $(_Dirs) $(_Api) $(_WithJavadocXml)"
149+
IgnoreStandardErrorWarningFormat="True"
150+
/>
151+
<ItemGroup>
152+
<Compile Include="$(_FullIntermediateOutputPath)\**\*.cs" KeepDuplicates="False" />
153+
<FileWrites Include="$(_FullIntermediateOutputPath)\**\*.cs" />
154+
</ItemGroup>
155+
<XmlPeek
156+
Namespaces="&lt;Namespace Prefix='msbuild' Uri='http://schemas.microsoft.com/developer/msbuild/2003' /&gt;"
157+
XmlInputPath="$(_JavaManagedBindingDir)$(AssemblyName).projitems"
158+
Query="/msbuild:Project/msbuild:PropertyGroup/msbuild:DefineConstants/text()" >
159+
<Output TaskParameter="Result" PropertyName="_GeneratedDefineConstants" />
160+
</XmlPeek>
161+
<PropertyGroup>
162+
<DefineConstants>$(DefineConstants);$([System.String]::Copy('$(_GeneratedDefineConstants)').Replace ('%24(DefineConstants);', ''))</DefineConstants>
163+
</PropertyGroup>
164+
</Target>
165+
166+
<Target Name="_CleanupManagedBinding" />
167+
168+
<Target Name="_JavaCreateJcws"
169+
Condition=" '$(TargetPath)' != '' And Exists($(TargetPath))"
170+
Inputs="$(TargetPath)"
171+
Outputs="$(_JavaJcwSourcesDir).stamp">
172+
<RemoveDir Directories="$(_JavaJcwSourcesDir)" />
173+
<MakeDir Directories="$(_JavaJcwSourcesDir)" />
174+
<ItemGroup>
175+
<!-- I can't find a good way to trim the trailing `\`, so append with `.` so we can sanely quote for $(_Libpath) -->
176+
<_RefAsmDirs Include="@(ReferencePathWithRefAssemblies->'%(RootDir)%(Directory).'->Distinct())" />
177+
</ItemGroup>
178+
<PropertyGroup>
179+
<_JcwGen>"$(UtilityOutputFullPath)/jcw-gen.dll"</_JcwGen>
180+
<_Target>--codegen-target JavaInterop1</_Target>
181+
<_Output>-o "$(_JavaJcwSourcesDir)"</_Output>
182+
<_Libpath>@(_RefAsmDirs->'-L "%(Identity)"', ' ')</_Libpath>
183+
</PropertyGroup>
184+
<Exec Command="$(DotnetToolPath) $(_JcwGen) -v &quot;$(TargetPath)&quot; $(_Target) $(_Output) $(_Libpath)" />
185+
<Touch Files="$(_JavaJcwSourcesDir).stamp" AlwaysCreate="True" />
186+
</Target>
187+
188+
<Target Name="_JavaCollectGeneratdJcwSource">
189+
<ItemGroup>
190+
<_JavaGeneratedJcwSource Include="$(_JavaJcwSourcesDir)**\*.java" />
191+
</ItemGroup>
192+
</Target>
193+
194+
<Target Name="_JavaCreateOutputJar"
195+
DependsOnTargets="_JavaCollectGeneratdJcwSource;_JavaCollectJavacRefs"
196+
Inputs="@(_JavaGeneratedJcwSource)"
197+
Outputs="$(JavaOutputJar)">
198+
<RemoveDir Directories="$(_JavaJcwClassesDir)" />
199+
<MakeDir Directories="$(_JavaJcwClassesDir)" />
200+
<PropertyGroup>
201+
<_ResponseFile>$(_JavaIntermediateDir)r.txt</_ResponseFile>
202+
<_Classpath>@(_JavacRefsWithForwardSlash, '$(JavaPathSeparator)')</_Classpath>
203+
</PropertyGroup>
204+
<ItemGroup>
205+
<_Source Include="@(JavaCompile->Replace('%5c', '/'))" />
206+
<_Source Include="@(_JavaGeneratedJcwSource->Replace('%5c', '/'))" />
207+
</ItemGroup>
208+
<WriteLinesToFile
209+
File="$(_JavaIntermediateDir)_java_sources.txt"
210+
Lines="@(_Source)"
211+
Overwrite="True"
212+
/>
213+
<Exec Command="&quot;$(JavaCPath)&quot; $(_JavacSourceOptions) -d &quot;$(_JavaJcwClassesDir)&quot; -classpath &quot;$(_Classpath)&quot; &quot;@$(_JavaIntermediateDir)_java_sources.txt&quot;" />
214+
<Delete Files="$(_JavaIntermediateDir)_java_sources.txt" />
215+
<Exec Command="&quot;$(JarPath)&quot; cf &quot;$(JavaOutputJar)&quot; -C &quot;$(_JavaJcwClassesDir)&quot; ." />
216+
</Target>
217+
218+
</Project>

tests/Java.Base-Tests/Java.Base-Tests.csproj

+11
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88
<IsPackable>false</IsPackable>
99
</PropertyGroup>
1010

11+
<Import Project="..\..\build-tools\Java.Interop.Sdk\Sdk\Sdk.props" />
1112
<Import Project="..\..\TargetFrameworkDependentValues.props" />
1213

1314
<PropertyGroup>
1415
<OutputPath>$(TestOutputFullPath)</OutputPath>
16+
<JavaOutputJar>$(OutputPath)java.base-tests.jar</JavaOutputJar>
1517
</PropertyGroup>
1618

1719
<ItemGroup>
@@ -26,6 +28,15 @@
2628
<ProjectReference Include="..\TestJVM\TestJVM.csproj" />
2729
</ItemGroup>
2830

31+
<ItemGroup>
32+
<JavaCompile Include="$(MSBuildThisFileDirectory)java\net\dot\jni\test\HasInterfaceMethodInheritance.java" />
33+
<JavaCompile Include="$(MSBuildThisFileDirectory)java\net\dot\jni\test\InterfaceMethodInheritance.java" />
34+
<JavaCompile Include="$(MSBuildThisFileDirectory)java\net\dot\jni\test\PublicInterface.java" />
35+
<JavaCompile Include="java\**\*.java" Bind="False" />
36+
37+
</ItemGroup>
38+
2939
<Import Project="Java.Base-Tests.targets" />
40+
<Import Project="..\..\build-tools\Java.Interop.Sdk\Sdk\Sdk.targets" />
3041

3142
</Project>
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,2 @@
11
<Project>
2-
3-
<ItemGroup>
4-
<_BuildJavaBaseTestsJarInputs Include="$(TargetPath)" />
5-
<_BuildJavaBaseTestsJarInputs Include="$(MSBuildThisFileFullPath)" />
6-
<_BuildJavaBaseTestsJarInputs Include="$(MSBuildThisFileFullPath)" />
7-
<_BuildJavaBaseTestsJarInputs Include="java\**\*.java" />
8-
</ItemGroup>
9-
10-
<Target Name="_CreateJavaCallableWrappers"
11-
Condition=" '$(TargetPath)' != '' "
12-
AfterTargets="Build"
13-
Inputs="@(_BuildJavaBaseTestsJarInputs)"
14-
Outputs="$(IntermediateOutputPath)java\.stamp">
15-
<RemoveDir Directories="$(IntermediateOutputPath)java" />
16-
<MakeDir Directories="$(IntermediateOutputPath)java" />
17-
<ItemGroup>
18-
<!-- I can't find a good way to trim the trailing `\`, so append with `.` so we can sanely quote for $(_Libpath) -->
19-
<_RefAsmDirs Include="@(ReferencePathWithRefAssemblies->'%(RootDir)%(Directory).'->Distinct())" />
20-
</ItemGroup>
21-
<PropertyGroup>
22-
<_JcwGen>"$(UtilityOutputFullPath)/jcw-gen.dll"</_JcwGen>
23-
<_Target>--codegen-target JavaInterop1</_Target>
24-
<_Output>-o "$(IntermediateOutputPath)/java"</_Output>
25-
<_Libpath>@(_RefAsmDirs->'-L "%(Identity)"', ' ')</_Libpath>
26-
</PropertyGroup>
27-
<Exec Command="$(DotnetToolPath) $(_JcwGen) -v &quot;$(TargetPath)&quot; $(_Target) $(_Output) $(_Libpath)" />
28-
<Touch Files="$(IntermediateOutputPath)java\.stamp" AlwaysCreate="True" />
29-
</Target>
30-
31-
<ItemGroup>
32-
<_JcwSource Include="$(IntermediateOutputPath)java\**\*.java;java\**\*.java" />
33-
</ItemGroup>
34-
35-
<Target Name="_BuildJavaBaseTestsJar"
36-
Condition=" '$(TargetPath)' != '' "
37-
AfterTargets="_CreateJavaCallableWrappers"
38-
Inputs="$(IntermediateOutputPath)java\.stamp;@(_JcwSource)"
39-
Outputs="$(OutputPath)java.base-tests.jar">
40-
<RemoveDir Directories="$(IntermediateOutputPath)classes" />
41-
<MakeDir Directories="$(IntermediateOutputPath)classes" />
42-
<ItemGroup>
43-
<_JcwSourceReal Include="$(IntermediateOutputPath)java\**\*.java;java\**\*.java" />
44-
</ItemGroup>
45-
<Exec Command="&quot;$(JavaCPath)&quot; $(_JavacSourceOptions) -d &quot;$(IntermediateOutputPath)classes&quot; -classpath &quot;$(OutputPath)/java-interop.jar&quot; @(_JcwSourceReal->'%(Identity)', ' ')" />
46-
<Exec Command="&quot;$(JarPath)&quot; cf &quot;$(OutputPath)java.base-tests.jar&quot; -C &quot;$(IntermediateOutputPath)classes&quot; ." />
47-
</Target>
48-
492
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using System;
2+
3+
using Java.Interop;
4+
5+
using NUnit.Framework;
6+
7+
namespace Java.BaseTests {
8+
9+
[TestFixture]
10+
public class InterfaceMethodInheritanceTests : JavaVMFixture {
11+
12+
[Test]
13+
public void InterfaceMethod ()
14+
{
15+
using var iface = global::Net.Dot.Jni.Test.HasInterfaceMethodInheritance.Create ();
16+
var m = iface!.M ();
17+
Assert.AreEqual ("HasInterfaceMethodInheritance.m", m);
18+
var n = iface!.N ();
19+
Assert.AreEqual ("HasInterfaceMethodInheritance.n", n);
20+
var o = iface!.O ();
21+
Assert.AreEqual ("HasInterfaceMethodInheritance.o", o);
22+
var p = iface!.P ();
23+
Assert.AreEqual ("HasInterfaceMethodInheritance.p", p);
24+
}
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package net.dot.jni.test;
2+
3+
public class HasInterfaceMethodInheritance implements InterfaceMethodInheritance {
4+
private HasInterfaceMethodInheritance() {
5+
}
6+
7+
public static InterfaceMethodInheritance create() {
8+
return new HasInterfaceMethodInheritance();
9+
}
10+
11+
public String m() {
12+
return "HasInterfaceMethodInheritance.m";
13+
}
14+
15+
public String n() {
16+
return "HasInterfaceMethodInheritance.n";
17+
}
18+
19+
public String o() {
20+
return "HasInterfaceMethodInheritance.o";
21+
}
22+
23+
public String p() {
24+
return "HasInterfaceMethodInheritance.p";
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package net.dot.jni.test;
2+
3+
/* package */ interface BaseInterface {
4+
String m();
5+
}
6+
7+
public interface InterfaceMethodInheritance extends BaseInterface, PublicInterface {
8+
String n();
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package net.dot.jni.test;
2+
3+
/* package */ interface InternalInterface {
4+
String o();
5+
}
6+
7+
public interface PublicInterface extends InternalInterface {
8+
String p();
9+
}

0 commit comments

Comments
 (0)