Transitivity would require dataflow which I think is more than what is being proposed at the moment for error checking, but the general idea, of relaxing constraints on GWT.create() so that you can write methods which delegate to it is on the radar.
On Wed, Mar 10, 2010 at 4:26 PM, Ian Petersen <ispet...@gmail.com> wrote: > If you do as Ray suggests and implement @IsLiteral, please make it > work transitively. ie. make this work: > > public static <T extends IMarker> T foo(@IsLiteral Class<T> clazz) { > return (T)GWT.create(clazz); > } > > The above example is not particularly compelling, but it's the best I > can do right now. It would be really cool if @IsLiteral just meant > that the compiler has to be able to statically trace the value of the > annotated parameter to a literal, possibly through assignment to a > final field along the way. > > Ian > > On Wed, Mar 10, 2010 at 4:08 PM, Scott Blum <sco...@google.com> wrote: >> Generally speaking, this sounds like a good direction. I am becoming more >> fond of things that can be checked locally. >> >> On Wed, Mar 10, 2010 at 7:02 PM, Ray Cromwell <cromwell...@google.com> >> wrote: >>> >>> Can I suggest a middle-ground philosophical approach for the future? >>> In the normal javac world, GWT.create(nonLiteral) or >>> runAsync(nonLiteral) would not cause a compile time error, but an >>> expected run-time error, because the code is syntactically valid and >>> type-correct. Our issue stems from the fact that we have blessed >>> create() and runAsync() with additional adhoc magic, and thus we end >>> up sprinkling the error checking around the magic-processing code. >>> >>> But isn't what we really want an extension to the type system that >>> allows the signatures of these functions to assert the needed >>> constraints, and then have the compiler enforce them in a general way? >>> So why not introduce something like @IsLiteral (ala >>> @Nullable/@NotNull), and either code JDT pass, or a GenJavaAST check >>> to enforce? Then we can dispense with the special purpose checks for >>> these two functions and rely on declarative type checks instead? >>> >>> e.g. >>> public static <T> T create(@IsLiteral Class<?> clazzLiteral) >>> public static void runAsync(@IsLiteral Class<?> name, RunAsyncCallback >>> callback) >>> >>> Granted, this won't solve all needs for error checking, because using >>> annotations for declarative types will have limits in terms of >>> expressible logic and there are some checks that just might depend on >>> other compile state / semantic actions having run. However, for the >>> class of problems that could be statically / locally detectable if you >>> simply had additional type assertions, it seems like a clean >>> philosophical approach. >>> >>> It also has the benefit of making the magical constraints visible to >>> those looking at the method declarations and not relying on ad-hoc >>> documentation. >>> >>> -Ray >>> >>> >>> On Wed, Mar 10, 2010 at 2:43 PM, Scott Blum <sco...@google.com> wrote: >>> > Hi Lex, >>> > Thanks for the very thoughtful write-up. You make many excellent >>> > points, >>> > and I especially agree with you about how much it sucks to work with >>> > Eclipse's internal AST, and the points about how it's less code and >>> > easier >>> > to understand if you mix the checking and transform code together, for >>> > sure. >>> > No need to follow up on those point, since I basically think you're >>> > right. >>> > >>> > On Wed, Mar 10, 2010 at 3:53 PM, Lex Spoon <sp...@google.com> wrote: >>> >> >>> >> Before delving into the design principle, perhaps you can identify the >>> >> more concrete implications of this choice on what a developer would see >>> >> from >>> >> GWT? If there's a user-visible behavior involved, then we should be >>> >> able to >>> >> converge on any changes where we can clearly help developers with a >>> >> small >>> >> amount of our effort. >>> > >>> > There is one user-visible implication, which I had forgotten about until >>> > now. If my brain worked properly, I'd have remembered it up front. I >>> > apologize for having turned the current architecture into a religious >>> > conviction and forgotten the real underlying reason! >>> > The problem is having a "one error at a time" compiler. The most >>> > natural >>> > architecture has the unfortunate property that it halts the compile on >>> > the >>> > first error. If you have multiple errors in your project, you have to >>> > compile multiple times to find out what they all are, and our compiler >>> > isn't >>> > nearly as quick to spin up as we'd like it to be. The Checker >>> > architecture >>> > avoids this problem by queueing up the errors globally and then halting >>> > at a >>> > point where they can be reported en masse. >>> > Thankfully, ReplaceRunAsyncs at least locally queues up all errors >>> > related >>> > specifically to RunAsync. But in the general case, if all our checkers >>> > were >>> > simply integrated into the main compiler, you end up with "one class of >>> > error at a time" behavior. I do think CodeSplitter and findEntryPoints >>> > are >>> > a mild departure from the "report all errors at once" idea. (The latter >>> > is >>> > hopefully such a rare and fundamental problem that it's practically >>> > irrelevant.) >>> > I admit I'm not particularly happy that GenerateJavaAST.precompile() >>> > calls >>> > checkForErrors() 3 different times, but I agree that it would be too >>> > much >>> > work and too brittle to try to e.g. build a GWT AST from a JDT AST that >>> > contains errors. What makes our compiler so bad in this regard is that >>> > this >>> > happens globally. For unit-at-a-time compilers, it's fine if the >>> > syntactic >>> > errors in Foo prevent you from semantically checking Foo, because they >>> > generally won't keep you from semantically checking the >>> > syntactically-valid >>> > Bar. >>> > >>> >> >>> >> Finally, you mentioned sharing code between the compiler and with IDE >>> >> plugins. I'm quite excited by that development, and Miguel and I have >>> >> spoken several times about how the relevant APIs can end up looking. >>> >> It's >>> >> very early days, however. There are no APIs agreed on, and the options >>> >> for >>> >> the AST alone are ranging all over the place, including: APT, JSR 308, >>> >> our >>> >> TypeOracle, our JJS nodes, or maybe a new API. One option clearly >>> >> won't >>> >> work though, and that's the internal JDT trees that the compiler >>> >> currently >>> >> uses. The internal JDT trees are an internal API of the Eclipse >>> >> project, >>> >> and they change it from release to release. They're also just plain >>> >> miserable to work against. So, while it's still too early to do very >>> >> much >>> >> to help that upcoming refactoring, one thing that's already clear is >>> >> that >>> >> the internal JDT trees aren't suitable. We would do well to use them >>> >> as >>> >> little as possible. >>> > >>> > Totally agree. And in fact, I don't think the paper tiger of "integrate >>> > error checking with the Eclipse plugin" is a good reason to do the extra >>> > work right now, since we have no idea what that's really going to look >>> > like. >>> > How about we just put a TODO in for now to mark that we have >>> > user-facing >>> > error checking that we'll eventually want to integrate? >>> > Scott >>> > >> >> -- >> http://groups.google.com/group/Google-Web-Toolkit-Contributors > > -- > http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors