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

Commit 3343634

Browse files
jonpryoratsushieno
authored andcommitted
[generator] Only skip generic "overloads" of bound types (#178)
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=57828 The #runtime team is attempting to update xamarin-android to use the [mono/2017-06][0] and [mono/2017-08][1] (and...) branches, and when doing so they are seeing a unit test fail in `Xamarin.Android.Build.Tests.BuildTest.GeneratorValidateMultiMethodEventName()`: no `BG850*` warnings are expected but they are produced. After much analysis, the cause of ght `BG850*` warnings is that the mono/2017-06 branch introduces a non-generic "overload" of `System.Collections.Generic.KeyValuePair`: namespace System.Collections.Generic { // New with mono/2017-06 partial class KeyValuePair { public static KeyValuePair<TKey, TValue> Create<TKey, TValue>(TKey key, TValue value); } // Existing since forever partial struct KeyValuePair<TKey, TValue> { } } Specifically, the above "`KeyValuePair` overload" type runs into a FIXME within `CodeGenerator.cs`: // FIXME: at some stage we want to import generic types. // For now generator fails to load generic types that have conflicting type e.g. // AdapterView`1 and AdapterView cannot co-exist. // It is mostly because generator primarily targets jar (no real generics land). The *intent* of the check that is that, given a type `AdapterView<T>`, we only check to see if `AdapterView` exists as well. If it does exist, then we *ignore* the `AdapterView<T>` type, and only use the `AdapterView` type for code generation. In the case of `KeyValuePair`, the same "check" is done, which cause us to *skip* type registration for `KeyValuePair<TKey, TValue>`, which in turn causes us to invalidate e.g. `IDictionary<TKey, TValue>` -- as it implements `ICollection<KeyValuePair<TKey, TValue>>` -- and everything promply falls apart from there: warning BG8C00: For type System.Collections.Generic.IDictionary`2, base interface System.Collections.Generic.ICollection`1<System.Collections.Generic.KeyValuePair`2<TKey,TValue>> is invalid. warning BG8C00: For type System.Collections.Generic.IDictionary`2, base interface System.Collections.Generic.IEnumerable`1<System.Collections.Generic.KeyValuePair`2<TKey,TValue>> is invalid. warning BG8502: Invalidating System.Collections.Generic.IDictionary`2 and all nested types because some of its interfaces were invalid. warning BG8801: Invalid parameter type System.Collections.Generic.IDictionary`2<System.String,System.Collections.Generic.IList`1<System.String>> in method MapEquivalents in managed type Java.Util.Locale.LanguageRange. warning BG8801: Invalid parameter type System.Collections.Generic.IDictionary`2<System.String,System.Collections.Generic.IList`1<System.String>> in method Parse in managed type Java.Util.Locale.LanguageRange. warning BG8801: Invalid parameter type System.Collections.Generic.IDictionary`2<System.String,System.Object> in method NewFileSystem in managed type Java.Nio.FileNio.Spi.FileSystemProvider. warning BG8801: Invalid parameter type System.Collections.Generic.IDictionary`2<System.String,System.Object> in method NewFileSystem in managed type Java.Nio.FileNio.Spi.FileSystemProvider. warning BG8801: Invalid parameter type System.Collections.Generic.IDictionary`2<System.String,System.String> in method .ctor in managed type Java.Security.Provider.Service. warning BG8801: Invalid parameter type System.Collections.Generic.IDictionary`2<System.Object,System.Object> in method PutAll in managed type Java.Security.Provider. I still don't fully understand the scenario that the check was attempting to solve, so in lieu of actually fixing the FIXME, make the check *stricter* so that we only ignore "generically overloaded" types if they bind the *same* Java type. Since `KeyValuePair<TKey, TValue>` binds *no* Java type, it will no longer be skipped, thus removing the BG8502 and related warnings. Additionally, a bit of code cleanup for consistency: some parts of the code use `HAVE_CECIL`, and others use `USE_CECIL`. Standardize on `HAVE_CECIL` for consistency and sanity. [0]: dotnet/android#631 [1]: dotnet/android#723
1 parent 1cd0361 commit 3343634

11 files changed

Lines changed: 38 additions & 25 deletions

File tree

‎src/Java.Interop.Tools.TypeNameMappings/Java.Interop.Tools.TypeNameMappings/JniType.cs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
#if HAVE_CECIL
1010
usingMono.Cecil;
1111
usingJava.Interop.Tools.Cecil;
12-
#if !GENERATOR
1312
usingAndroid.Runtime;
13+
#if !GENERATOR
1414
usingJava.Interop.Tools.JavaCallableWrappers;
1515
#endif // !GENERATOR
1616
#endif // HAVE_CECIL
@@ -252,7 +252,7 @@ static string GetSpecialExportJniType (string typeName, ExportParameterKind expo
252252
returnnull;
253253
}
254254

255-
#if !GEN_JAVA_STUBS&&!GENERATOR&&!JAVADOC_TO_MDOC
255+
#if !GEN_JAVA_STUBS&&!JAVADOC_TO_MDOC
256256
// Keep in sync with ToJniNameFromAttributes(TypeDefinition)
257257
publicstaticstringToJniNameFromAttributes(Typetype)
258258
{
@@ -384,7 +384,7 @@ static string ToJniNameWhichShouldReplaceExistingToJniName (Type type, ExportPar
384384
}
385385
#endif
386386

387-
#if HAVE_CECIL&&!GENERATOR
387+
#if HAVE_CECIL
388388

389389
internalstaticExportParameterKindGetExportKind(Mono.Cecil.ICustomAttributeProviderp)
390390
{

‎tools/generator/ClassGen.cs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
usingSystem.Xml.Linq;
1616

1717
namespaceMonoDroid.Generation{
18-
#if USE_CECIL
18+
#if HAVE_CECIL
1919
staticclassManagedExtensions
2020
{
2121
publicstaticstringFullNameCorrected(thisTypeReferencet)
@@ -69,7 +69,7 @@ public override bool IsFinal {
6969
get{returnt.IsSealed;}
7070
}
7171
}
72-
#endif
72+
#endif// HAVE_CECIL
7373

7474
publicclassXmlClassGen:ClassGen{
7575
boolis_abstract;

‎tools/generator/CodeGenerator.cs‎

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
usingXamarin.Android.Tools.ApiXmlAdjuster;
1515

1616
usingJava.Interop.Tools.Cecil;
17+
usingJava.Interop.Tools.TypeNameMappings;
1718

1819
namespaceXamarin.Android.Binder{
1920

@@ -262,8 +263,10 @@ static void Run (CodeGeneratorOptions options, DirectoryAssemblyResolver resolve
262263
// For now generator fails to load generic types that have conflicting type e.g.
263264
// AdapterView`1 and AdapterView cannot co-exist.
264265
// It is mostly because generator primarily targets jar (no real generics land).
265-
if(td.HasGenericParameters&&
266-
md.GetType(td.FullName.Substring(0,td.FullName.IndexOf('`')))!=null)
266+
varnonGenericOverload=td.HasGenericParameters
267+
?md.GetType(td.FullName.Substring(0,td.FullName.IndexOf('`')))
268+
:null;
269+
if(BindSameType(td,nonGenericOverload))
267270
continue;
268271
ProcessReferencedType(td,opt);
269272
}
@@ -366,6 +369,15 @@ static void AddTypeToTable (GenBase gb)
366369
AddTypeToTable(nt);
367370
}
368371

372+
staticboolBindSameType(TypeDefinitiona,TypeDefinitionb)
373+
{
374+
if(a==null||b==null)
375+
returnfalse;
376+
if(!a.ImplementsInterface("Android.Runtime.IJavaObject")||!b.ImplementsInterface("Android.Runtime.IJavaObject"))
377+
returnfalse;
378+
returnJniType.ToJniName(a)==JniType.ToJniName(b);
379+
}
380+
369381
staticIEnumerable<GenBase>FlattenNestedTypes(IEnumerable<GenBase>gens)
370382
{
371383
foreach(vargingens){
@@ -404,7 +416,7 @@ static void Validate (List<GenBase> gens, CodeGenerationOptions opt)
404416
}while(removed.Count>0);
405417
}
406418

407-
#if USE_CECIL
419+
#if HAVE_CECIL
408420
staticvoidProcessReferencedType(TypeDefinitiontd,CodeGenerationOptionsopt)
409421
{
410422
if(!td.IsPublic&&!td.IsNested)
@@ -434,7 +446,7 @@ static void ProcessReferencedType (TypeDefinition td, CodeGenerationOptions opt)
434446
foreach(varntintd.NestedTypes)
435447
ProcessReferencedType(nt,opt);
436448
}
437-
#endif
449+
#endif// HAVE_CECIL
438450

439451
staticvoidGenerateAnnotationAttributes(List<GenBase>gens,IEnumerable<string>zips)
440452
{

‎tools/generator/Ctor.cs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
usingXamarin.Android.Tools;
99

1010
namespaceMonoDroid.Generation{
11-
#if USE_CECIL
11+
#if HAVE_CECIL
1212
publicclassManagedCtor:Ctor{
1313
MethodDefinitionm;
1414
stringname;
@@ -53,7 +53,7 @@ public override string CustomAttributes {
5353
get{returnnull;}
5454
}
5555
}
56-
#endif
56+
#endif// HAVE_CECIL
5757

5858
publicclassXmlCtor:Ctor{
5959
stringname;

‎tools/generator/Field.cs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
usingSystem.Xml.Linq;
1212

1313
namespaceMonoDroid.Generation{
14-
#if USE_CECIL
14+
#if HAVE_CECIL
1515
publicclassManagedField:Field{
1616
FieldDefinitionf;
1717
stringjava_name;
@@ -83,7 +83,7 @@ protected override Parameter SetterParameter {
8383
}
8484
}
8585
}
86-
#endif
86+
#endif// HAVE_CECIL
8787

8888
publicclassXmlField:Field{
8989

‎tools/generator/GenBaseSupport.cs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public static bool IsPrefixableName (string name)
5050
}
5151
}
5252

53-
#if USE_CECIL
53+
#if HAVE_CECIL
5454
publicclassManagedGenBaseSupport:GenBaseSupport
5555
{
5656
TypeDefinitiont;
@@ -152,7 +152,7 @@ public override string Visibility {
152152
get{returnt.IsPublic||t.IsNestedPublic?"public":"protected internal";}
153153
}
154154
}
155-
#endif
155+
#endif// HAVE_CECIL
156156

157157
publicclassXmlGenBaseSupport:GenBaseSupport
158158
{

‎tools/generator/InterfaceGen.cs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
usingXamarin.Android.Tools;
1212

1313
namespaceMonoDroid.Generation{
14-
#if USE_CECIL
14+
#if HAVE_CECIL
1515
publicclassManagedInterfaceGen:InterfaceGen{
1616
publicManagedInterfaceGen(TypeDefinitiont)
1717
:base(newManagedGenBaseSupport(t))
@@ -34,7 +34,7 @@ public override bool MayHaveManagedGenericArguments {
3434
get{return!this.IsAcw;}
3535
}
3636
}
37-
#endif
37+
#endif// HAVE_CECIL
3838

3939
publicclassXmlInterfaceGen:InterfaceGen{
4040

‎tools/generator/Method.cs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
usingSystem.Xml.Linq;
1313

1414
namespaceMonoDroid.Generation{
15-
#if USE_CECIL
15+
#if HAVE_CECIL
1616
publicclassManagedMethod:Method{
1717
MethodDefinitionm;
1818
stringjava_name;
@@ -121,7 +121,7 @@ public override string CustomAttributes {
121121
get{returnnull;}
122122
}
123123
}
124-
#endif
124+
#endif// HAVE_CECIL
125125

126126
publicclassXmlMethod:Method{
127127

‎tools/generator/MethodBase.cs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public interface IMethodBaseSupport {
2020
stringVisibility{get;}
2121
}
2222

23-
#if USE_CECIL
23+
#if HAVE_CECIL
2424
publicclassManagedMethodBaseSupport:IMethodBaseSupport{
2525
MethodDefinitionm;
2626
publicManagedMethodBaseSupport(MethodDefinitionm)
@@ -79,7 +79,7 @@ public IEnumerable<Parameter> GetParameters (CustomAttribute regatt)
7979
}
8080
}
8181
}
82-
#endif
82+
#endif// HAVE_CECIL
8383

8484
publicclassXmlMethodBaseSupport:IMethodBaseSupport{
8585

‎tools/generator/Parameter.cs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ public static Parameter FromClassElement (XElement elem)
284284
returnnewParameter(name,java_package+"."+java_type,null,false);
285285
}
286286

287-
#if USE_CECIL
287+
#if HAVE_CECIL
288288
publicstaticParameterFromManagedParameter(ParameterDefinitionp,stringjnitype,stringrawtype)
289289
{
290290
// FIXME: safe to use CLR type name? assuming yes as we often use it in metadatamap.
@@ -297,6 +297,6 @@ public static Parameter FromManagedType (TypeDefinition t, string javaType)
297297
{
298298
returnnewParameter("__self",javaType??t.FullName,t.FullName,false);
299299
}
300-
#endif
300+
#endif// HAVE_CECIL
301301
}
302302
}

0 commit comments

Comments
 (0)