Commit 001a03e
authored
[generator] [Register] interface alternatives into a dummy package (#1242)
Fixes: #802
Context: #798 (comment)
Context: a3b7456
C# and Java are (famously) different languages, and have (had?)
different opinions about e.g. what could be within an `interface`
declaration. Consider `java.lang.reflect.Member`:
// Java
public interface Member {
public static final int PUBLIC = 0;
public static final int DECLARED = 1;
public Class<?> getDeclaringClass();
public String getName();
public int getModifiers();
public boolean isSynthetic();
}
How do we bind this in C#?
Before C# 8 introduced default interface members, we would bind it
as *two* types: the interface binding, and an "interface alternative":
// C# 7
[Register ("java/lang/reflect/Member", "", "Java.Lang.Reflect.IMemberInvoker")]
public interface IMember : IJavaPeerable {
Java.Lang.Class DeclaringClass {get;}
bool IsSynthetic {get;}
int Modifiers {get;}
string Name {get;}
}
// interface alternative
[Register ("java/lang/reflect/Member", DoNotGenerateAcw=true)]
public abstract class Member : Java.Lang.Object {
internal Member(); /* prevent subclassing */
public const int Declared = 1;
public const int Public = 0;
}
An "interface alternative" is a class with the same name as the Java
class, containing all the interface members which couldn't be placed
within the interface declaration: static fields, static methods, ….
C# 8 allowed `interface`s to contain non-instance members, and with
commit a3b7456 this could instead be bound as:
// C# 8
[Register ("java/lang/reflect/Member", "", "Java.Lang.Reflect.IMemberInvoker")]
public partial interface IMember : Java.Interop.IJavaPeerable {
public const int Declared = 1;
public const int Public = 0;
Java.Lang.Class DeclaringClass {get;}
bool IsSynthetic {get;}
int Modifiers {get;}
string Name {get;}
}
// No interface alternative
However, while this was *possible*, removing the
"interface alternative" would be an API break, and thus was retained
for existing types (bd7c60a).
There is one issue with the interface alternative, as previously
declared: the `[Register]` attribute was present, and declared the
same Java name as the interface binding:
[Register ("java/lang/reflect/Member", "", "Java.Lang.Reflect.IMemberInvoker")]
public partial interface IMember {}
[Register ("java/lang/reflect/Member", DoNotGenerateAcw=true)]
public partial class Member {}
which in turn means that often there isn't a 1:1 mapping between
Java types and C# types, but instead a 1:2 mapping, an ambiguity.
This in turn can creep into [binding projects][0] and cause the
generation of invalid code:
public partial class JSONArray
: global::Com.Alibaba.Fastjson.JSON
, global::Java.IO.ISerializable
, global::Java.Lang.ICloneable
, global::Java.Util.List
, global::Java.Util.IRandomAccess
{}
`Java.Util.List` is the interface alternative for the `java.util.List`
interface type, which is a class. The above thus fails to compile
with a CS1721 ("Class 'JSONArray' cannot have multiple base classes:
'JSON' and 'List'"). `JSONArray` should instead have implemented
the `Java.Util.IList` *interface*, but didn't because of this
ambiguity.
Remove this ambiguity by instead registering a "fake" class for
interface alternatives, using a `mono/internal/` prefix:
// interface declaration is unchanged
[Register ("java/lang/reflect/Member", "", "Java.Lang.Reflect.IMemberInvoker")]
public partial interface IMember {}
// interface alternative registers a non-existent type
[Register ("mono/internal/java/lang/reflect/Member", DoNotGenerateAcw=true)]
public partial class Member {}
*Note*: `[Register]` must still be used, because if we remove
`[Register]` entirely, then `jcw-gen` will attempt to create a new
Java Callable Wrapper for it, as interface alternatives are still
`Java.Lang.Object` subclasses.
[0]: dotnet/android#9188 (comment)1 parent d30d554 commit 001a03e
File tree
8 files changed
+17
-14
lines changed- tests/generator-Tests
- Unit-Tests/CodeGeneratorExpectedResults
- XAJavaInterop1-NRT
- XAJavaInterop1
- expected.xaji/TestInterface
- tools/generator/SourceWriters
8 files changed
+17
-14
lines changedLines changed: 2 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| |||
19 | 19 | | |
20 | 20 | | |
21 | 21 | | |
22 | | - | |
| 22 | + | |
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
| |||
Lines changed: 1 addition & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| |||
Lines changed: 1 addition & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| |||
Lines changed: 2 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| |||
19 | 19 | | |
20 | 20 | | |
21 | 21 | | |
22 | | - | |
| 22 | + | |
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
| |||
Lines changed: 2 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| |||
32 | 32 | | |
33 | 33 | | |
34 | 34 | | |
35 | | - | |
| 35 | + | |
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
| |||
Lines changed: 2 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| |||
19 | 19 | | |
20 | 20 | | |
21 | 21 | | |
22 | | - | |
| 22 | + | |
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
| |||
Lines changed: 2 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | | - | |
| 8 | + | |
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| |||
31 | 31 | | |
32 | 32 | | |
33 | 33 | | |
34 | | - | |
| 34 | + | |
35 | 35 | | |
36 | 36 | | |
37 | 37 | | |
| |||
Lines changed: 5 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
39 | 39 | | |
40 | 40 | | |
41 | 41 | | |
42 | | - | |
| 42 | + | |
| 43 | + | |
43 | 44 | | |
44 | 45 | | |
45 | 46 | | |
| |||
179 | 180 | | |
180 | 181 | | |
181 | 182 | | |
182 | | - | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
183 | 186 | | |
184 | 187 | | |
185 | 188 | | |
| |||
0 commit comments