-
Notifications
You must be signed in to change notification settings - Fork 58
[generator] Fix issue where generic types couldn't be found in SymbolTable (#543) #552
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
I'm not sure how to interpret this. The BG8800 warning isn't within the Should that BG8800 warning continue to be emitted? What's the context for that warning? I'm not sure I understand the last two paragraphs. |
Yeah, it isn't when building Presumably this could matter in situations where you are referencing another one of your own bound libraries that has had generics added to it. In the right situations it would make it impossible to bind some types/methods because it cannot resolve the type. For example, something like this would probably fail: LibraryA:
LibraryB references LibraryA
|
table.AddType (dict); | ||
|
||
Assert.NotNull (table.Lookup ("System.Collections.Generic.IList<Java.Util.Locale.LanguageRange>")); | ||
Assert.NotNull (table.Lookup ("System.Collections.Generic.IList<List<Java.Util.Locale.LanguageRange>>")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To ensure that the nested <...>
logic works, we should also add:
Assert.NotNull (table.Lookup ("System.Collections.Generic.IList<Dictionary<string, Java.Util.Locale.LanguageRange>>"));
We might also want to assert that not only is the table.Lookup()
not null, but also what the resulting value is.
Fixes: #543 In commit 262743b we began stripping the arity from Cecil imported types so that we wouldn't write invalid types like ``System.Collections.Generic.IList`1<string>``, in order to correctly emit `System.Collections.Generic.IList<string>`. However when we try to resolve these types in the `SymbolTable` we only look at the type name, ignoring the generic type parameters. In this case we are looking for `System.Collections.Generic.IList` but the type is stored in the symbol table with the arity to disambiguate types like ``Action`1`` and ``Action`2``. Therefore our lookup fails because the table key is ``System.Collections.Generic.IList`1``. For example, if we have `LibraryA.dll` with: public class Foo : Java.Lang.Object { public virtual void Bar (IList<string> p0) {…} } And we attempt to bind a `LibraryB.jar` which references `LibraryA.dll`, overriding `Foo.Bar()`: public class Foo2 : Foo { public override void Bar (IList<string> p0) {…} } Then `Foo2.Bar()` would elicit a BG8800 warning: warning BG8800: Unknown parameter type System.Collections.Generic.IList<System.String> in method Bar in managed type Foo2. Fix type lookup so that if the type is not found in the `SymbolTable` and there are generic type parameters, calculate the arity from the generic type parameters and look in the table again. That is, `System.Collections.Generic.IList<string>` is rechecked as ``System.Collections.Generic.IList`1``, which allows the type to be found.
Context: #543
In #450 we began stripping the arity from Cecil imported types so that we wouldn't write invalid types like
System.Collections.Generic.IList'1<string>
, resulting in the correctly formedSystem.Collections.Generic.IList<string>
.However when we try to resolve these types in the SymbolTable we only look at the type name, ignoring the generic types. In this case we are looking for
System.Collections.Generic.IList
but the type is stored in the symbol table with the arity to disambiguate types likeAction'1
andAction'2
. Therefore our lookup fails because the table key isSystem.Collections.Generic.IList'1
.With this PR, if the type is not found in the table and there are generic type parameters, calculate the arity from the generic type parameters and look in the table again.
That is,
System.Collections.Generic.IList<string>
is rechecked asSystem.Collections.Generic.IList'1
, which allows the type to be found.This is a relatively rare case because it comes from reference assemblies read in via Cecil, and there aren't many generics used in binding libraries. The only case in
Mono.Android.dll
is: