On Mon, Jan 4, 2010 at 1:26 PM, <[email protected]> wrote:

> http://gwt-code-reviews.appspot.com/126817/diff/2006/2007
> File dev/core/test/com/google/gwt/dev/jjs/impl/JsniRefLookupTest.java
> (right):
>
> http://gwt-code-reviews.appspot.com/126817/diff/2006/2007#newcode234
> Line 234: JMethod res = (JMethod) lookup("test.Bar::foo(*)", errors);
> It seems weird that this should work. If Bar didn't declare foo() (and
> the lookup went up to the supertype Foo), this would fail to compile.
> It breaks the otherwise-Java style of name lookups used by JSNI to care
> about where the method is declared.  It also rewards the unnecessary
> (and ugly) practice of re-defining a method overload just to make it the
> "default".


> It's simplest to explain to users that the @class::method(*) wildcard
> syntax selects the one method out of the entire supertype/superinterface
> hierarchy whose name is "method" without having to get into discussions
> about which type a method is declared on.
>

As would be expected, the trickiest part of this patch has to do with
overloading and inheritance.  These are dark corners that good code will not
rely on, but our tools have to do something with them.

I'm not in love with the current algorithm, but what precisely shall we do?
 It's certainly important, but let's be careful not to bike shed the corner
cases.

For this particular test case, I thought that if someone defines Bar and Bar
has exactly one foo method, then Bar::foo(*) should be allowed, regardless
of what Bar inherits.  It's easy enough to disallow such a reference, but
should we?  We have a choice here between supporting good code and
eliminating bad code.  I fear that if we try to eliminate all the bad code
programmers could write, we will never be able to accept any code at all.
 It's just a design guideline, though.  Does anyone else have an opinion
about this question?

If we want to rule that case out, then my next suggestion would be to count
overloads exactly as a Java compiler would.  That would mean that methods
overriding each other would not count as extra overloads.  The main
trickiness would be dealing with inheritance that includes bridge methods.
 That wouldn't be insurmountable, but it's more complicated than the current
solution.

FWIW, the current algorithm is as follows.  I think it's pretty easy to work
with.  If the user asks for Foo::bar(*), then start in class Foo and look
for methods named bar.  If you see exactly one, then that's the one they
mean.  If you see more than one, then the reference is ambiguous.  If you
see zero, then recurse into inherited superclasses and methods.


Also, on that vein, add test code for looking up wildcards on
> interfaces.


Good idea, I will.

Lex

-- 
http://groups.google.com/group/Google-Web-Toolkit-Contributors

Reply via email to