It took me some time, and I haven't thoroughly reviewed all the code,
neither did I tried it yet against my own code base.

I really like the move to APT, but to replace the RFIV, there would need
to be a DomainToClientMapper, probably generated in a similar way as the
TypeTokenResolver.Builder.

In the small tests I did, the interfaces validated with RfValidator but
later failed in RFIV (I did something similar to issue 5926
http://code.google.com/p/google-web-toolkit/issues/detail?id=5926 i.e.
with bridge methods; in my case, using generics because that's the issue
we're facing in our app, which shouldn't require a
@SkipInterfaceValidation).

I did the review in several short periods, jumping from one class to the
other, so maybe the comments don't line up very well.


http://gwt-code-reviews.appspot.com/1467804/diff/1/user/build.xml
File user/build.xml (right):

http://gwt-code-reviews.appspot.com/1467804/diff/1/user/build.xml#newcode155
user/build.xml:155: <exclude
name="com/google/web/bindery/requestfactory/apt/**"/>
Why is this needed? I can understand that it makes iterating on the APT
code easier (changes you make to it aren't taken into account when
determining whether to precompile modules –which is slow and resource
consuming–, when launching, e.g., unit tests) but you probably meant to
only have it a s a temporary measure?
(I mean, same would be true of many **/server/** classes)

http://gwt-code-reviews.appspot.com/1467804/diff/1/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/1/user/src/com/google/web/bindery/requestfactory/apt/DomainChecker.java#newcode50
user/src/com/google/web/bindery/requestfactory/apt/DomainChecker.java:50:
private ExecutableElement found;
shouldn't they all be 'final' ?

http://gwt-code-reviews.appspot.com/1467804/diff/1/user/src/com/google/web/bindery/requestfactory/apt/DomainChecker.java#newcode83
user/src/com/google/web/bindery/requestfactory/apt/DomainChecker.java:83:
TypeMirror paramType = maybeBox(paramElement.asType(), state);
Correct me if I'm wrong, but this is a change from RFIV, where argument
types weren't "boxed" before being compared. If this is a willful
change, then ReflectiveServiceLayer would have to be updated as well
when looking up methods.

Similarly, return type is only boxed in RFIV for service methods, not
properties.

http://gwt-code-reviews.appspot.com/1467804/diff/1/user/src/com/google/web/bindery/requestfactory/apt/DomainChecker.java#newcode96
user/src/com/google/web/bindery/requestfactory/apt/DomainChecker.java:96:
|| state.types.isSubsignature((ExecutableType) x.asType(),
(ExecutableType) found
That's great, as it seems to fix issue 5926. (unfortunately, because
RFIV is still used, an interface that validates with RfValidator at
compile-time can fail with RFIV at runtime)

http://code.google.com/p/google-web-toolkit/issues/detail?id=5926

http://gwt-code-reviews.appspot.com/1467804/diff/1/user/src/com/google/web/bindery/requestfactory/apt/DomainChecker.java#newcode111
user/src/com/google/web/bindery/requestfactory/apt/DomainChecker.java:111:
returnType = maybeBox(returnType, state);
Why isn't this done in the constructor?

http://gwt-code-reviews.appspot.com/1467804/diff/1/user/src/com/google/web/bindery/requestfactory/apt/DomainChecker.java#newcode115
user/src/com/google/web/bindery/requestfactory/apt/DomainChecker.java:115:
return scanAllInheritedMethods(x, state);
Isn't that more or less the default behavior? (default behavior would
visit fields and nested types too)

http://gwt-code-reviews.appspot.com/1467804/diff/1/user/src/com/google/web/bindery/requestfactory/apt/DomainChecker.java#newcode149
user/src/com/google/web/bindery/requestfactory/apt/DomainChecker.java:149:
TypeMirror returnType = x.getReturnType().accept(new
ClientToDomainMapper(), state);
x should probably be turned into an ExecutableType using
state.types.asMemberOf(domainType.asType(), x) to make sure we preserve
"actual type variables" in the hierarchy (and similarly in
MethodFinder).

I mean, if we have:
interface BaseFooProxy<T> {
  T getT();
  void setT(T);
}
and
interface FooProxy extends BaseFooProxy<BarProxy> { }

the ExecutableElement will have a "formal type variable" T and we only
know about its bounds. What we'd like to check here is that the domain
object has "BarProxy getT()" and "void setT(BarProxy)" methods, and only
ExecutableType would give us the information.
There might be other places where that'd be beneficial.

...and that'd help fix issue 5926 in an elegant way:
http://code.google.com/p/google-web-toolkit/issues/detail?id=5926

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

http://gwt-code-reviews.appspot.com/1467804/diff/1/user/src/com/google/web/bindery/requestfactory/apt/Finder.java#newcode34
user/src/com/google/web/bindery/requestfactory/apt/Finder.java:34: *
Make this externally-configurable?
That'd be easy, using ProcessingEnvironment#getOptions.

http://gwt-code-reviews.appspot.com/1467804/diff/1/user/src/com/google/web/bindery/requestfactory/apt/Finder.java#newcode46
user/src/com/google/web/bindery/requestfactory/apt/Finder.java:46: //
Ignore anything other than interfaces
Shouldn't that comment be *above* the 'if' rather than within?

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

http://gwt-code-reviews.appspot.com/1467804/diff/1/user/src/com/google/web/bindery/requestfactory/apt/ProxyScanner.java#newcode40
user/src/com/google/web/bindery/requestfactory/apt/ProxyScanner.java:40:
if (x.getSimpleName().contentEquals("stableId") &&
x.getParameters().isEmpty()) {
How about overriding shouldIgnore and put this check in there?

http://gwt-code-reviews.appspot.com/1467804/diff/1/user/src/com/google/web/bindery/requestfactory/apt/ProxyScanner.java#newcode51
user/src/com/google/web/bindery/requestfactory/apt/ProxyScanner.java:51:
// Parameters checked by visitVariable
Should that comment be outside the 'if' ?

http://gwt-code-reviews.appspot.com/1467804/diff/1/user/src/com/google/web/bindery/requestfactory/apt/ProxyScanner.java#newcode62
user/src/com/google/web/bindery/requestfactory/apt/ProxyScanner.java:62:
state.poison(x, "A proxy must be annotated with %s, %s, or %s",
ProxyFor.class
Isn't it a breaking change? That is, in 2.3 (and 2.4) I can declare a
"BaseFooProxy extends EntityProxy" without ProxyFor/etc. annotation, and
then define sub-interfaces with the annotation. With this check, I have
to move the "extends EntityProxy" to the sub-interfaces (as you did in
the unit test).

I don't really mind, but it'll probably break a few people's code
(starting with mine)

Otherwise, maybe the check could be moved to places referencing proxy
types, i.e. places where ProxyScanner is called except RfValidator (and
similarly for request context's @Service/ServiceName vs.
RequestContextScanner).

http://gwt-code-reviews.appspot.com/1467804/diff/1/user/src/com/google/web/bindery/requestfactory/apt/ProxyScanner.java#newcode68
user/src/com/google/web/bindery/requestfactory/apt/ProxyScanner.java:68:
// See javadoc on Element.getAnnotation() for why it works this way
Just wondering, why isn't State#checkExtraTypes using this method? or
why isn't this code using the same algorithm as State#checkExtraTypes?
(in other words: why two ways of doing the same thing, in the same
codebase?)

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

http://gwt-code-reviews.appspot.com/1467804/diff/1/user/src/com/google/web/bindery/requestfactory/apt/RequestContextScanner.java#newcode71
user/src/com/google/web/bindery/requestfactory/apt/RequestContextScanner.java:71:
} else if (isSetter(x, state)) {
Setters in a RequestContext? Did I miss some earlier change?

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

http://gwt-code-reviews.appspot.com/1467804/diff/1/user/src/com/google/web/bindery/requestfactory/apt/RfApt.java#newcode149
user/src/com/google/web/bindery/requestfactory/apt/RfApt.java:149: +
BinaryName.toSourceName(entry.getValue()) + ".class.getName());");
Now there's another issue when applied to the gwt-user unit tests: many
test cases declare non-public inner interfaces (generally
package-protected) and the generated build cannot compile due to type
visibility issues.
Looks like Class.forName is the only real fix. Maybe that should be done
in TypeTokenResolver.Builder#addTypeToken (so it'll also be applied to
tokens loaded from properties files), and this code simply generate
string literals?

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

http://gwt-code-reviews.appspot.com/1467804/diff/1/user/src/com/google/web/bindery/requestfactory/apt/ScannerBase.java#newcode116
user/src/com/google/web/bindery/requestfactory/apt/ScannerBase.java:116:
protected void poisonIfRedundant(State state, TypeElement x,
Annotation... annotations) {
That method deserves a javadoc! I thought it was misnamed as it wasn't
checking much things, but reading ProxyScanner I found that one
annotation has already be "asserted" and the passed annotations are
other possible annotations on the same element (a type, generally), that
have been "resolved" and should then be 'null' (otherwise, it means
they're present, thus redundant).

The javadoc may be just some sample code showing how it's supposed to be
used.

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

http://gwt-code-reviews.appspot.com/1467804/diff/1/user/src/com/google/web/bindery/requestfactory/apt/State.java#newcode161
user/src/com/google/web/bindery/requestfactory/apt/State.java:161:
return clientToDomainMain;
Collections.unmodifiableMap() ? (as a safeguard)

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

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

Reply via email to