Regarding the generics issue, I agree that the checker is behaving
correctly: the List<SubFooProxy> would be converted to a List<SubFoo>
when being checked against the domain type.  A List<? extends BaseFoo>
can't be assigned to the type List<SubFoo> since the list might contain
OtherFoo elements.

Since we've mainly be talking about edge-case details of the
implementation and it sounds like the checker mostly works with your
code base, I'm going to go ahead and check the code in with some
error-reporting fixes to make it less spammy when compiling with javac.
The findFoo() error is changed to a warning, although I'm thinking that
it might be better for the novice user if it's an error.  For the
advanced user, an annotation processor option could be used to switch
that from an error to a warning.

I'll be on vacation the early part of next week and will be studiously
avoiding the computer.  Thanks for your feedback, it's been very
helpful.


http://gwt-code-reviews.appspot.com/1467804/diff/6052/user/src/com/google/web/bindery/requestfactory/apt/DomainChecker.java
File
user/src/com/google/web/bindery/requestfactory/apt/DomainChecker.java
(right):

http://gwt-code-reviews.appspot.com/1467804/diff/6052/user/src/com/google/web/bindery/requestfactory/apt/DomainChecker.java#newcode340
user/src/com/google/web/bindery/requestfactory/apt/DomainChecker.java:340:
state.warn(warnTo, "Cannot validate method (%s.%s) because the domain
mapping for the"
On 2011/07/01 09:19:16, tbroyer wrote:
On 2011/06/30 15:16:48, bobv wrote:
> This is more verbose, but it will unambiguously identify the
unchecked method
in
> question.

This doesn't print what one would expect:

Another place where Eclipse and javac differ :-)


I don't mind having the warning on the getId method because of a
previous
warning on EmbeddedProxyId, but there should IMO be only one, not
hundreds of
them! (I actually have 52 such warnings exactly)

The duplicate messages are due to the way client interfaces are checked.
 Each proxy or context type is examined individually as a flattened list
of all methods exposed by that type.  If proxyA and proxyB both inherit
some interface X, the methods in X will be checked multiple times.
Admittedly this is more work than strictly necessary, but de-duplicating
the effort would complicate the checker code.  Instead I've added some
code to the State object to prevent duplicate messages from being
emitted.

http://gwt-code-reviews.appspot.com/1467804/diff/6052/user/src/com/google/web/bindery/requestfactory/apt/TransportableTypeVisitor.java
File
user/src/com/google/web/bindery/requestfactory/apt/TransportableTypeVisitor.java
(right):

http://gwt-code-reviews.appspot.com/1467804/diff/6052/user/src/com/google/web/bindery/requestfactory/apt/TransportableTypeVisitor.java#newcode102
user/src/com/google/web/bindery/requestfactory/apt/TransportableTypeVisitor.java:102:
return state.types.erasure(t).accept(this, state);
On 2011/07/01 09:19:16, tbroyer wrote:
Have you tried with an intersection type? i.e. something like <T
extends
MyInterface & EntityProxy>
I don't have that in my code base, and haven't tried it, but judging
from the
code of Eclipse's TypeVariableImpl#getUpperBound, it might very well
trigger the
bug too, in which case erasure() probably wouldn't be an appropriare
workaround.
I was thinking about looping on the Types#directSupertypes until one
is detected
as a "transportable type":
for (TypeMirror type : state.types.directSupertypes(t)) {
    if (type.accept(this, state)) {
      return true;
    }
}
return false;

that should work, because the expected type of getUpperBound is a
DeclaredType,
so visitDeclared should have been called, and it only uses
isAssignable checks
(so isAssignable(MyInterface&EntityProxy, EntityProxy) would be
equivalent to

isAssignable(MyInterface,EntityProxy)|| isAssignable(EntityProxy,EntityProxy).
In the case of <T extends Enum<T>>, I guess it'd work the same.

I don't think that intersection types make sense in the most-derived
RequestFactory interfaces.  Enums are the only concrete types that you
can specify in a RequestFactory interface.  The implementations of all
other return types (proxies, etc) will necessarily be implemented by the
RequestFactory generator.  The extra mix-in interfaces in the
intersection type probably won't be implemented by whatever generated,
concrete type is being returned.  The only way that would work is if the
concrete type was generated from an interface that already implemented
the mix-in.

http://gwt-code-reviews.appspot.com/1467804/

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

Reply via email to