+1 from me; I did a similar thing in STOB with regard to non-serializable types. I also think---though I don't have data to prove---that we often get spam from classes that happen to be on the classpath, but could be provably *not* reachable (even by things like RPC polymorphism), for example from server-only classes. I was hoping to get around to doing something like my STOB work, such that problems during speculative scanning would result in a "tombstone" class definition, and an actual error message only if that tombstone were later referenced.
That's a provably correct, and less spammy than we are now. If you wanted to be very fancy, you could add a verbosity or warnings-control flag to choose that and your may-give-false-positives case... I think we've rejected warning-suppression flags a while ago, but I'm not sure it's the right call. On Mon, Jun 15, 2009 at 11:11 PM, Bruce Johnson <[email protected]> wrote: > We've known for a while that the GWT compiler is spammy, even at default > log levels. There is a reason for this behavior, believe it or not: > TypeOracle's JClassType#getSubtypes() call. Because generators can ask for > the subtypes of any type, the compiler has to parse essentially everything, > not just those types that are statically reachable from a module's entry > point(s). We sometimes refer to it as "speculative parsing." Overall, the > behavior is vitally useful for code generators, especially RPC and I18n, and > it's generally useful anytime you need to do something factory-like, where > you might have used Class.forName() if it were available. So, I'm not > proposing that we change that behavior. The problem is that in the process > of speculatively parsing everything on the client source path, inevitably we > end up encountering source files that can't actually be meaninfully compiled > given the current client source path and other various reasons for > mismatches. It can happen when you have more than one <module>.gwt.xml in > the same location with different sets of inherited modules. > We ought to find a way to keep quieter about problems we find during that > speculative parse. We want to *not* spam the log when the source file was > found "speculatively" but definitely still report errors when they really > are relevant to getting a clean compile. > > This isn't as simple as it might sound. It isn't just a "how do we code it" > question. Imagine you have a GWT module that needs RPC. Because RPC can use > polymorphism, you might have an RPC method whose return type is "Shape" (vs. > concrete subtypes Circle, Square, Triangle). This is handled magically in > the GWT RPC generator because it can see those subtypes of Shape and quietly > generate deserializers in the generated RPC proxy. The tricky bit is when > Circle.java has a syntax error, say. The type "Circle" won't be found as a > subtype of Shape in the type oracle, so the GWT RPC generator won't know to > emit a deserializer for it. (To be precise, it won't even know that it > *ought* to try to do so.) We have a choice: either we emit a string of > non-fatal errors regarding the failure to parse Circle.java or we don't. If > we do, we get the spam we hate today, but at least we've informed the > developer that something fishy may happen, since it wasn't a perfectly clean > compile. If we don't emit such errors, then a module will quietly appear to > compile, even when there are compilation problems that might affect the > intended behavior (in this case, when a server responds to the client with a > Circle object, the client won't know how to deserialize it). > > All that said, I don't think it will be big a problem in practice if we log > less and risk the kind of surprise failure I described with something like > RPC. After all, javac (or your IDE) would complain about Cirlce.java not > compiling anyway, so the only real failure mode happens if you *only* > compile with the GWT compiler -- and that seems pretty unlikely, especially > if you're working in an IDE. > > Here's a proposal for the new behavior. When the GWT compile invokes JDT to > do the front-end compile, capture the errors in an in-memory data structure > (keyed by type name?) but do not log them right away. After the JDT > front-end compile settles, create a set of "known statically reachable" > types from the entry point classes (the entry point classes are reachable > from themselves by definition). Only log errors on compilation unit in that > set of dependencies, and do not log errors in an other case. > > Anybody see any problems with this idea? I think this would omit log > messages that make you say, "What on earth does NumberFormat_fr_Test.java > have to do with my compiling Hello.java?" > > -- Bruce > > > > > > --~--~---------~--~----~------------~-------~--~----~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~----------~----~----~----~------~----~------~--~---
