Commit ada479b
[Mono.Android] Define JavaCollection before ICollection (#741)
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=58303
Background: It is possible for a Java type to have
"aliasing bindings": two or more managed types which claim to bind
the same Java type:
// C#
namespace Android.Runtime {
[Register ("java/util/HashMap", DoNotRegisterAcw=true)]
partial class JavaDictionary {
}
}
namespace Java.Util {
[Register ("java/util/HashMap", DoNotRegisterAcw=true)]
partial class HashMap {
}
}
These can't be realistically forbidden.
Enter a new-to-bind Java type:
// Java
public class Bxc58383 extends java.util.HashMap implements java.util.Map {
}
In order to bind the above `Bxc58383` type, `generator` needs to
determine the appropriate binding type to use for `java.util.HashMap`.
`generator`'s approach to supporting aliasing types is (largely) to
ignore the problem (almost) entirely: There Can Be Only One™ mapping
from a Java type to a managed type, so `generator` needs to pick one.
It does so by using the *last* definition encountered in the assembly.
Consequently, for the above set of C# declarations, when `generator`
needs to find the managed type which binds `java.util.HashMap`,
`Java.Util.HashMap` will be chosen, as it is the last declared type.
Unfortunately, "real life" is a bit more complicated:
`Mono.Android.dll` is made up of *thousands* of files, and the order
of types within an assembly is a compiler implementation detail.
As such...the current `Mono.Android.dll` has `JavaDictionary` defined
*after* `HashMap`:
# output truncated for relevance
$ monodis --typedef bin/Debug/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v7.1/Mono.Android.dll | grep 'Dictionary\|HashMap'
1270: Java.Util.Dictionary (flist=12611, mlist=29569, flags=0x100081, extends=0x20b8)
1287: Java.Util.HashMap (flist=12662, mlist=29806, flags=0x100001, extends=0x1388)
3992: Android.Runtime.JavaDictionary (flist=32135, mlist=85344, flags=0x100001, extends=0x20b8)
Because `JavaDictionary` is defined *after* `HashMap`, and both of
those types have `[Register]` attributes which declare that they bind
the *same* Java type, the result is that the binding of `Bxc58383` is
horrifically broken:
// C#
partial class Bxc58383 : global::Android.Runtime.JavaDictionary, global::Java.Util.IMap {
}
Unfortunately, `JavaDictionary` doesn't itself implement `IMap`, so:
error CS0535: 'Bxc58383' does not implement interface member 'IMap.ContainsKey(Object)'
along with 10 other related errors.
Update the `src/Mono.Android` build process so that `JavaDictionary`
and related types will be defined within `Mono.Android.dll` *before*
all the generated types. This allows `HashMap` to be defined last,
allowing `Bxc58383` to be bound without error:
# output truncated
$ monodis --typedef bin/Debug/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v7.1/Mono.Android.dll | grep 'Dictionary\|HashMap'
3703: Android.Runtime.JavaDictionary (flist=34089, mlist=78134, flags=0x100001, extends=0x4e08)
4170: Java.Util.Dictionary (flist=39685, mlist=91737, flags=0x100081, extends=0x4e08)
4187: Java.Util.HashMap (flist=39736, mlist=91974, flags=0x100001, extends=0x40d8)1 parent b070682 commit ada479b
File tree
3 files changed
+22
-14
lines changed- src/Mono.Android
- tests/CodeGen-Binding/Xamarin.Android.McwGen-Tests
- java/com/xamarin/android
3 files changed
+22
-14
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
75 | 75 | | |
76 | 76 | | |
77 | 77 | | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
78 | 92 | | |
79 | 93 | | |
80 | 94 | | |
| |||
311 | 325 | | |
312 | 326 | | |
313 | 327 | | |
314 | | - | |
315 | | - | |
316 | | - | |
317 | | - | |
318 | | - | |
319 | | - | |
320 | | - | |
321 | | - | |
322 | | - | |
323 | | - | |
324 | | - | |
325 | | - | |
326 | | - | |
327 | | - | |
328 | 328 | | |
329 | 329 | | |
330 | 330 | | |
| |||
Lines changed: 1 addition & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
76 | 76 | | |
77 | 77 | | |
78 | 78 | | |
| 79 | + | |
79 | 80 | | |
80 | 81 | | |
81 | 82 | | |
| |||
Lines changed: 7 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
0 commit comments