[gwt-contrib] About GWT opinion in thoughtworks technology radar july 2011
I posted this in the gwt group, but I think this is a better place. http://www.thoughtworks.com/articles/technology-radar-july-2011#Platforms thoughtworks technology radar july 2011, talk negatively about gwt, these are the 3 reasons: First, in many ways, JavaScript is more powerful and expressive than Java, so we suspect that the generation is going in the wrong direction. more powerfull for that? Secondly, it is impossible to hide a complex abstraction difference like that from event-driven desktop to stateless-web without leaky abstraction headaches eventually popping up I can't comment, I do not know the compilation process. Third, it suffers from the same shortcomings of many elaborate frameworks, where building simple, aligned applications is quick and easy, building more sophisticated but not supported functionality is possible but difficult, and building the level of sophistication required by any non-trivial application becomes either impossible or so difficult it isn’t reasonable. What is meant by functionality not supported?. Program non-trivial applications with GWT is easier than directly in javascript. What do you think? -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] About GWT opinion in thoughtworks technology radar july 2011
When you read opinions like this, you have to interpret the author's perspective relative to his/her incentives. Thus, GWT consultants will observe the reasons GWT is really good. Consultants skilled in things other than GWT will find reasons that their solutions are better. There isn't a right answer. More inline below. On Wed, Aug 3, 2011 at 2:53 AM, Emilio Bravo emilio@gmail.com wrote: First, in many ways, JavaScript is more powerful and expressive than Java, so we suspect that the generation is going in the wrong direction. It paints a picture, but there are no facts or evidence in the above statement. Words like powerful and expressive are popular when discussing these sorts of topics precisely because they're vague enough that it's hard to argue with them. You can pick literally any topic and find people eager to take all sides. The question is how seriously you should take the assertion made by the author. Do you trust the author? Why? If so, take the judgment seriously. If you don't have any particular reason to trust the author relative to others who have a different conclusion, then ignore the article and judge for yourself or listen to those with more direct experience using the technology in question. Someone's willingness to write down their assertion doesn't make it more correct. And no tool is right or wrong for every project. Secondly, it is impossible to hide a complex abstraction difference like that from event-driven desktop to stateless-web without leaky abstraction headaches eventually popping up Of course abstractions leak. We knew that when we designed GWT and the design accounts for that. GWT generally doesn't depend on isolating you from JS or the DOM except in cases where memory leaks are the inevitable by-product of not adding widget-like machinery. To put that another way: the absence of GWT's abstractions that leak is UI code that very likely has memory leaks. That there are many GWT libraries that interop with handwritten JS is among the evidence that the above statement seems under-informed and dismissively definitive (e.g. impossible). Third, it suffers from the same shortcomings of many elaborate frameworks, where building simple, aligned applications is quick and easy, building more sophisticated but not supported functionality is possible but difficult, and building the level of sophistication required by any non-trivial application becomes either impossible or so difficult it isn’t reasonable. This one is almost funny. GWT usually gets beat up for the precise opposite: it's good for big apps but not easy enough for small ones. Among the tens of thousands of apps that overcame the above-asserted abstraction headaches and managed to do something sophisticated include Angry Birds, AdWords (with hundreds of thousands of lines of browser code), Lombardi Blueprint (acquired by IBM), DimDim (acquired by Salesforce.com), and, in the last couple of weeks, Google Offers, Hotel Finder, and Web Fonts. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Replace RequestFactoryInterfaceValidator with an annotation-processor-based approach. (issue1503804)
http://gwt-code-reviews.appspot.com/1503804/diff/1/samples/dynatablerf/build.xml File samples/dynatablerf/build.xml (right): http://gwt-code-reviews.appspot.com/1503804/diff/1/samples/dynatablerf/build.xml#newcode8 samples/dynatablerf/build.xml:8: !-- Run the annotation processor -- On 2011/08/02 17:43:26, rjrjr wrote: This is a sample, can you be a bit more verbose? Annotation processor is an implementation detail. So really people only need to include this jar if they want compile time notification of RF errors. Which seems like a pretty big deal, especially if the rf server will no longer do such validation by default. The server code won't accept the RequestFactory interface if it hasn't been validated. A runtime error will occur, telling the user to run the ValidationTool. Should we do something to force people to include this jar, like remove RF from gwt-user? I suppose that's a pretty drastic thing to do to existing users, although frankly it's tempting. Will they see any kind of warning if they don't include it ? I'm actually tempted to be drastic. I've been thinking about pulling the requestfactory server and vm code from gwt-[user|servlet].jar since that encourages deployment bloat. I could go either way on pulling the client code from gwt-user.jar. Would it be better to not include the annotation processor in requestfactory-client.jar and instead require the user to add requestfactory-apt.jar to their build path? It would slightly reduce the amount of code in requestfactory-client.jar and would avoid any confusion with adding requestfactory-client.jar to a server build process. http://gwt-code-reviews.appspot.com/1503804/diff/1/user/src/com/google/web/bindery/requestfactory/apt/DeobfuscatorBuilder.java File user/src/com/google/web/bindery/requestfactory/apt/DeobfuscatorBuilder.java (right): http://gwt-code-reviews.appspot.com/1503804/diff/1/user/src/com/google/web/bindery/requestfactory/apt/DeobfuscatorBuilder.java#newcode38 user/src/com/google/web/bindery/requestfactory/apt/DeobfuscatorBuilder.java:38: * Visits a RequestFactory to create its associated DeobfuscatorBuilder type. On 2011/08/02 17:43:26, rjrjr wrote: Visits an RF to create itself? ...its associated {@link Deobfuscator}... yes? Done. http://gwt-code-reviews.appspot.com/1503804/diff/1/user/src/com/google/web/bindery/requestfactory/apt/DescriptorBuilder.java File user/src/com/google/web/bindery/requestfactory/apt/DescriptorBuilder.java (right): http://gwt-code-reviews.appspot.com/1503804/diff/1/user/src/com/google/web/bindery/requestfactory/apt/DescriptorBuilder.java#newcode34 user/src/com/google/web/bindery/requestfactory/apt/DescriptorBuilder.java:34: * Builds descriptors from TypeMirrors for both simple types and methods. On 2011/08/02 17:43:26, rjrjr wrote: These descriptors are used by {@link ...} Done. http://gwt-code-reviews.appspot.com/1503804/diff/1/user/src/com/google/web/bindery/requestfactory/apt/ValidationTool.java File user/src/com/google/web/bindery/requestfactory/apt/ValidationTool.java (right): http://gwt-code-reviews.appspot.com/1503804/diff/1/user/src/com/google/web/bindery/requestfactory/apt/ValidationTool.java#newcode50 user/src/com/google/web/bindery/requestfactory/apt/ValidationTool.java:50: * output jar and the binary names of RequestFactory interfaces that should be On 2011/07/29 00:53:51, tbroyer wrote: Out of curiosity: why an output *jar* and not an output folder? (or giving the user the choice). Using a folder would allow outputting to a WAR's WEB-INF/classes (before packaging the WAR of course) or, when building using Maven, outputting to target/classes or target/generated-classes (whatever is best for Maven) so the generated classes can be used by tests (which are run before the code is packaged into a JAR, and adding a JAR to the classpath that is not a dependency might not be practical, if at all possible; it's late here, so I haven't checked how it could work). Updated so that if the first argument is a directory, the classes will be emitted as individual files. http://gwt-code-reviews.appspot.com/1503804/diff/1/user/src/com/google/web/bindery/requestfactory/vm/impl/Deobfuscator.java File user/src/com/google/web/bindery/requestfactory/vm/impl/Deobfuscator.java (right): http://gwt-code-reviews.appspot.com/1503804/diff/1/user/src/com/google/web/bindery/requestfactory/vm/impl/Deobfuscator.java#newcode27 user/src/com/google/web/bindery/requestfactory/vm/impl/Deobfuscator.java:27: * Provides access to payload deobfuscation services. On 2011/08/02 17:43:26, rjrjr wrote: ...for both servers and clients. Is this the place to mention what GWT clients do instead? Done. http://gwt-code-reviews.appspot.com/1503804/diff/1/user/src/com/google/web/bindery/requestfactory/vm/impl/Deobfuscator.java#newcode37 user/src/com/google/web/bindery/requestfactory/vm/impl/Deobfuscator.java:37: * processor as part of the build process. On 2011/08/02 17:43:26,
[gwt-contrib] Re: Make generator result caching framework api available publically. (issue1468804)
Still reviewing, but here's a recap of offline initial reaction: I think the thing to do is • give generateIncrementally() a RebindMode return value • unify the rest of the RebindResult class with CachedGeneratorResult • rename CachedGeneratorResult IncrementalGeneratorContext and give it all the new methods from GeneratorContext • include an IncrementalGeneratorContext object as an argument to generateIncrementally() http://gwt-code-reviews.appspot.com/1468804/ -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Replace RequestFactoryInterfaceValidator with an annotation-processor-based approach. (issue1503804)
Per offline conversation, I've removed the annotation processor from requestfactory-client.jar. This means that the server code must be built with requestfactory-apt.jar, but doesn't need to be deployed with it. http://gwt-code-reviews.appspot.com/1503804/ -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] GWT Code Review planned outage Thursday 4 Aug 2011 5pm ET
We will be putting the Rietveld server at http://gwt-code-reviews.appspot.com/ into read-only mode for a few hours at about 5pm Eastern Time tomorrow, Thursday August 4th, to deal with some maintenance. rjrjr -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Make generator result caching framework api available publically. (issue1468804)
Some responses. I did consider most of your suggestions, and in fact for a while I did have things as you suggest, so great minds think alike :). I'll outline my reasoning: First, IncrementalGenerators have to live in the same ecosystem as all the currently extent non-incremental Generator implementations. Having a uniform rebind process whereby the StandardRebindOracle is agnostic to this greatly simplified things. If we were starting from scratch, I think it would probably look quite a bit different. Standard Generators only return a type-name (which can possibly be null). The RebindResult allows legacy generators to be cleanly wrapped and presented to the rebind oracle in a uniform way. A RebindResult is not the same as a CachedRebindResult. The StandardRebindOracle uses the info in the RebindResult to decide how to proceed. It may or may not choose to construct a cache entry, and that cached entry might contain a partial subset of newly generated types and types from a previous cache entry. Since a generator itself shouldn't need to know how to integrate cached types and artifacts, this logic is better left up to the StandardRebindOracle. The RebindResult also contains a target type name, and client data, so it's just a container to wrap a generators results. In the case that an IncrementalGenerator decides it can return quickly and request that all previously cached output can be reused, it doesn't need to do anything, including not re-committing cached compilation units and artifacts to the context, etc. That's all magic handled by the rebind oracle. A CachedRebindResult is specifically input to an IncrementalGenerator, but it's cumbersome to pass it in as a separate arg to generateIncrementally. Having it live in the GeneratorContext makes one less thing a generator implementation needs to pass around to it's internal methods (since GeneratorContext at the least is commonly needed all over the place for a generator anyway). Remember too, that much of the time, an IncrementalGenerator will run when generatorResultCaching is not enabled, such as currently for all web-mode compiles, so it's more of a contextual thing anyway, which makes it more intuitive for it to live in the GeneratorContext. I did have a separate GeneratContextExt interface, which extended the base GeneratorContext interface, but ultimately this became unnecessary, and it greatly simplified the framework by unifying things. I think you had a couple other comments offline (but not summarized above), I'll wait for your further comments to respond to those. http://gwt-code-reviews.appspot.com/1468804/ -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Make generator result caching framework api available publically. (issue1468804)
Nothing else important to add. This is nice! http://gwt-code-reviews.appspot.com/1468804/diff/7001/dev/core/src/com/google/gwt/core/ext/RebindMode.java File dev/core/src/com/google/gwt/core/ext/RebindMode.java (right): http://gwt-code-reviews.appspot.com/1468804/diff/7001/dev/core/src/com/google/gwt/core/ext/RebindMode.java#newcode52 dev/core/src/com/google/gwt/core/ext/RebindMode.java:52: USE_ALL_NEW_WITH_NO_CACHING, It's unlikely that a generator would ever return this, right? Can you say so? http://gwt-code-reviews.appspot.com/1468804/diff/7001/dev/core/src/com/google/gwt/core/ext/RebindResult.java File dev/core/src/com/google/gwt/core/ext/RebindResult.java (right): http://gwt-code-reviews.appspot.com/1468804/diff/7001/dev/core/src/com/google/gwt/core/ext/RebindResult.java#newcode48 dev/core/src/com/google/gwt/core/ext/RebindResult.java:48: * cache reuse decisions. Could you point out explicitly that this data is cached per generated type? http://gwt-code-reviews.appspot.com/1468804/ -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Make generator result caching framework api available publically. (issue1468804)
I'm still not crazy about having addClientData() and getClientData() on separate objects. It seems to me that you've violated your own principal that the GeneratorContext should be the only object that has to get passed to the generator's helpers. Can addClientData() move to the context? That would require getClientData() to be able to retrieve both cached and freshly added data. Is that practical? Sounds like it would be hugely convenient. On Wed, Aug 3, 2011 at 12:43 PM, jbrosenb...@google.com wrote: Some responses. I did consider most of your suggestions, and in fact for a while I did have things as you suggest, so great minds think alike :). I'll outline my reasoning: First, IncrementalGenerators have to live in the same ecosystem as all the currently extent non-incremental Generator implementations. Having a uniform rebind process whereby the StandardRebindOracle is agnostic to this greatly simplified things. If we were starting from scratch, I think it would probably look quite a bit different. Standard Generators only return a type-name (which can possibly be null). The RebindResult allows legacy generators to be cleanly wrapped and presented to the rebind oracle in a uniform way. A RebindResult is not the same as a CachedRebindResult. The StandardRebindOracle uses the info in the RebindResult to decide how to proceed. It may or may not choose to construct a cache entry, and that cached entry might contain a partial subset of newly generated types and types from a previous cache entry. Since a generator itself shouldn't need to know how to integrate cached types and artifacts, this logic is better left up to the StandardRebindOracle. The RebindResult also contains a target type name, and client data, so it's just a container to wrap a generators results. In the case that an IncrementalGenerator decides it can return quickly and request that all previously cached output can be reused, it doesn't need to do anything, including not re-committing cached compilation units and artifacts to the context, etc. That's all magic handled by the rebind oracle. A CachedRebindResult is specifically input to an IncrementalGenerator, but it's cumbersome to pass it in as a separate arg to generateIncrementally. Having it live in the GeneratorContext makes one less thing a generator implementation needs to pass around to it's internal methods (since GeneratorContext at the least is commonly needed all over the place for a generator anyway). Remember too, that much of the time, an IncrementalGenerator will run when generatorResultCaching is not enabled, such as currently for all web-mode compiles, so it's more of a contextual thing anyway, which makes it more intuitive for it to live in the GeneratorContext. I did have a separate GeneratContextExt interface, which extended the base GeneratorContext interface, but ultimately this became unnecessary, and it greatly simplified the framework by unifying things. I think you had a couple other comments offline (but not summarized above), I'll wait for your further comments to respond to those. http://gwt-code-reviews.**appspot.com/1468804/http://gwt-code-reviews.appspot.com/1468804/ -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Make generator result caching framework api available publically. (issue1468804)
Oh, and putClientData seems like a better name. On Wed, Aug 3, 2011 at 1:02 PM, Ray Ryan rj...@google.com wrote: I'm still not crazy about having addClientData() and getClientData() on separate objects. It seems to me that you've violated your own principal that the GeneratorContext should be the only object that has to get passed to the generator's helpers. Can addClientData() move to the context? That would require getClientData() to be able to retrieve both cached and freshly added data. Is that practical? Sounds like it would be hugely convenient. On Wed, Aug 3, 2011 at 12:43 PM, jbrosenb...@google.com wrote: Some responses. I did consider most of your suggestions, and in fact for a while I did have things as you suggest, so great minds think alike :). I'll outline my reasoning: First, IncrementalGenerators have to live in the same ecosystem as all the currently extent non-incremental Generator implementations. Having a uniform rebind process whereby the StandardRebindOracle is agnostic to this greatly simplified things. If we were starting from scratch, I think it would probably look quite a bit different. Standard Generators only return a type-name (which can possibly be null). The RebindResult allows legacy generators to be cleanly wrapped and presented to the rebind oracle in a uniform way. A RebindResult is not the same as a CachedRebindResult. The StandardRebindOracle uses the info in the RebindResult to decide how to proceed. It may or may not choose to construct a cache entry, and that cached entry might contain a partial subset of newly generated types and types from a previous cache entry. Since a generator itself shouldn't need to know how to integrate cached types and artifacts, this logic is better left up to the StandardRebindOracle. The RebindResult also contains a target type name, and client data, so it's just a container to wrap a generators results. In the case that an IncrementalGenerator decides it can return quickly and request that all previously cached output can be reused, it doesn't need to do anything, including not re-committing cached compilation units and artifacts to the context, etc. That's all magic handled by the rebind oracle. A CachedRebindResult is specifically input to an IncrementalGenerator, but it's cumbersome to pass it in as a separate arg to generateIncrementally. Having it live in the GeneratorContext makes one less thing a generator implementation needs to pass around to it's internal methods (since GeneratorContext at the least is commonly needed all over the place for a generator anyway). Remember too, that much of the time, an IncrementalGenerator will run when generatorResultCaching is not enabled, such as currently for all web-mode compiles, so it's more of a contextual thing anyway, which makes it more intuitive for it to live in the GeneratorContext. I did have a separate GeneratContextExt interface, which extended the base GeneratorContext interface, but ultimately this became unnecessary, and it greatly simplified the framework by unifying things. I think you had a couple other comments offline (but not summarized above), I'll wait for your further comments to respond to those. http://gwt-code-reviews.**appspot.com/1468804/http://gwt-code-reviews.appspot.com/1468804/ -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Replace RequestFactoryInterfaceValidator with an annotation-processor-based approach. (issue1503804)
Does this mean something similar to RequestFactoryInterfaceValidator will still need to be present? I ask because of http://code.google.com/p/google-web-toolkit/issues/detail?id=6640 where RequestFactoryInterfaceValidator seems to be getting in my way. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Replace RequestFactoryInterfaceValidator with an annotation-processor-based approach. (issue1503804)
oops, I missed your first reply. The server code won't accept the RequestFactory interface if it hasn't been validated. A runtime error will occur, telling the user to run the ValidationTool. answers my question. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Make generator result caching framework api available publically. (issue1468804)
http://gwt-code-reviews.appspot.com/1468804/ -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Make generator result caching framework api available publically. (issue1468804)
On 2011/08/03 20:03:28, rjrjr wrote: Oh, and putClientData seems like a better name. Done On Wed, Aug 3, 2011 at 1:02 PM, Ray Ryan mailto:rj...@google.com wrote: I'm still not crazy about having addClientData() and getClientData() on separate objects. It seems to me that you've violated your own principal that the GeneratorContext should be the only object that has to get passed to the generator's helpers. Can addClientData() move to the context? That would require getClientData() to be able to retrieve both cached and freshly added data. Is that practical? Sounds like it would be hugely convenient. I'm not sure I see why it makes sense for it not to be part of the cached result. It is indeed closely associated specifically with that previously generated result. By keeping it as part of the cachedResult, it makes one less thing that needs to be passed around internally to the generator (only the context needs to be passed around). The context is specific to the currently running generator environment, and generally gets reset for each generator invocation. Adding more data to the context requires more api and more things for the context to keep track of (currently it just keeps track of a CachedRebindResult object, which it would still need to do). Maybe there's a better name than clientData here, suggestions? It's specific to a generator run invoked that was invoked with the same rebind rule and requested type name as are currently in effect. But it's historical data, and in fact is not essential at all to the generator (if it's not there, the generator will run to completion). http://gwt-code-reviews.appspot.com/1468804/ -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Make generator result caching framework api available publically. (issue1468804)
http://gwt-code-reviews.appspot.com/1468804/diff/7001/dev/core/src/com/google/gwt/core/ext/RebindMode.java File dev/core/src/com/google/gwt/core/ext/RebindMode.java (right): http://gwt-code-reviews.appspot.com/1468804/diff/7001/dev/core/src/com/google/gwt/core/ext/RebindMode.java#newcode52 dev/core/src/com/google/gwt/core/ext/RebindMode.java:52: USE_ALL_NEW_WITH_NO_CACHING, Well no, it is useful in a couple of contexts. This mode allows the framework to not bother creating a cache entry, and avoid incurring the overhead of doing so, if the cache entry can't be made use of anyway. First, in the code that wraps legacy Generators, this RebindMode is always used. Second, even for generators which implement IncrementalGenerator, there are certain conditions whereby the generator can determine positively that its result should not be cached, since it can't possibly make use of any cached information subsequently. Examples of this exist for both the RPC and ClientBundle. In the case of RPC, see ProxyCreator.java, line 875 (which gets returned to line 380). This is basically saying that if a particular RPC implementation is using deRPC, don't attempt caching, since support for deRPC wasn't added. In the case of AbstractClientBundleGenerator, see line 715 (which gets returned to line 394). In this case, it indicates that if a ClientBundle calls for a ResourceGenerator implementation that doesn't implement the SupportsGeneratorResultCaching interface, then this client bundle should never attempt to make use of caching. Since developers can sub-class ResourceGenerator, or other GWT developers can add new ResourceGenerators, this makes sure that they've considered incremental caching in how they've implemented things, and if not, AbstractClientBundleGenerator won't trust it as being cacheable. http://gwt-code-reviews.appspot.com/1468804/diff/7001/dev/core/src/com/google/gwt/core/ext/RebindResult.java File dev/core/src/com/google/gwt/core/ext/RebindResult.java (right): http://gwt-code-reviews.appspot.com/1468804/diff/7001/dev/core/src/com/google/gwt/core/ext/RebindResult.java#newcode48 dev/core/src/com/google/gwt/core/ext/RebindResult.java:48: * cache reuse decisions. On 2011/08/03 19:50:55, rjrjr wrote: Could you point out explicitly that this data is cached per generated type? Done. http://gwt-code-reviews.appspot.com/1468804/ -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Make generator result caching framework api available publically. (issue1468804)
On Wed, Aug 3, 2011 at 2:36 PM, jbrosenb...@google.com wrote: On 2011/08/03 20:03:28, rjrjr wrote: Oh, and putClientData seems like a better name. Done On Wed, Aug 3, 2011 at 1:02 PM, Ray Ryan mailto:rj...@google.com wrote: I'm still not crazy about having addClientData() and getClientData() on separate objects. It seems to me that you've violated your own principal that the GeneratorContext should be the only object that has to get passed to the generator's helpers. Can addClientData() move to the context? That would require getClientData() to be able to retrieve both cached and freshly added data. Is that practical? Sounds like it would be hugely convenient. I'm not sure I see why it makes sense for it not to be part of the cached result. It is indeed closely associated specifically with that previously generated result. By keeping it as part of the cachedResult, it makes one less thing that needs to be passed around internally to the generator (only the context needs to be passed around). No, I have two things to pass around. I have to pass around generatorContext to allow helpers to fetch cached data, and I also have to pass around something to allow helpers to post new cached data. That is, in the current scheme I have to write something like: generateIncrementally(TreeLogger logger, GeneratorContext context, String typeName) { MapString, Serializable helperCachedData; new HelperOne(context, helperCachedData).run(); new HelperTwo(context, helperCachedData).run(); RebindResult result = new RebindResult(USE_WHATEVER, typeName + Impl); for (Map.EntryString, Serializable entry : helperCachedData) { result.putClientData(entry.key, entry.value); } return result; } instead of generateIncrementally(TreeLogger logger, GeneratorContext context, String typeName) { new HelperOne(context).run(); new HelperTwo(context).run(); return new RebindResult(USE_WHATEVER, typeName + Impl); } Further, my helpers have to look in two places for cacheable data generated by an upstream helper. The context is specific to the currently running generator environment, and generally gets reset for each generator invocation. Adding more data to the context requires more api and more things for the context to keep track of (currently it just keeps track of a CachedRebindResult object, which it would still need to do). Maybe there's a better name than clientData here, suggestions? It's specific to a generator run invoked that was invoked with the same rebind rule and requested type name as are currently in effect. But it's historical data, and in fact is not essential at all to the generator (if it's not there, the generator will run to completion). http://gwt-code-reviews.**appspot.com/1468804/http://gwt-code-reviews.appspot.com/1468804/ -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] [google-web-toolkit] r10491 committed - Include enclosing class in generated class name...
Revision: 10491 Author: ncha...@google.com Date: Wed Aug 3 12:02:05 2011 Log: Include enclosing class in generated class name Review at http://gwt-code-reviews.appspot.com/1499804 Review by: rchan...@google.com http://code.google.com/p/google-web-toolkit/source/detail?r=10491 Modified: /trunk/user/src/com/google/gwt/validation/rebind/AbstractCreator.java /trunk/user/src/com/google/gwt/validation/rebind/ValidatorCreator.java === --- /trunk/user/src/com/google/gwt/validation/rebind/AbstractCreator.java Fri May 6 07:35:25 2011 +++ /trunk/user/src/com/google/gwt/validation/rebind/AbstractCreator.java Wed Aug 3 12:02:05 2011 @@ -1,12 +1,12 @@ /* * Copyright 2010 Google Inc. - * + * * Licensed under the Apache License, Version 2.0 (the License); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -59,7 +59,8 @@ return getQualifiedName(); } - protected void addImports(ClassSourceFileComposerFactory composerFactory, Class?... imports) { + protected void addImports(ClassSourceFileComposerFactory composerFactory, + Class?... imports) { for (Class? imp : imports) { composerFactory.addImport(imp.getCanonicalName()); } @@ -82,37 +83,39 @@ String packageName = serviceIntfPkg == null ? : serviceIntfPkg.getName(); return packageName; } + + protected String getSimpleName() { + final int length = getPackage().length(); + final String rawName = validatorType.getQualifiedSourceName().substring( + length == 0 ? 0 : length + 1); + return rawName.replace('.', '_') + Impl; +} protected abstract void writeClassBody(SourceWriter sourceWriter) throws UnableToCompleteException; protected void writeValidatorInstance(SourceWriter sw, BeanHelper bean) { -BeanHelper.writeInterface(context, logger, bean); -// private final MyBeanValidator myBeanValidator = -sw.print(private final + bean.getFullyQualifiedValidatorName() + ); -sw.print(bean.getValidatorInstanceName()); -sw.println( = ); -sw.indent(); -sw.indent(); - -// MyBeanValidator.INSTANCE; -sw.print(bean.getFullyQualifiedValidatorName()); -sw.println(.INSTANCE;); -sw.outdent(); -sw.outdent(); - } + BeanHelper.writeInterface(context, logger, bean); + // private final MyBeanValidator myBeanValidator = + sw.print(private final + bean.getFullyQualifiedValidatorName() + ); + sw.print(bean.getValidatorInstanceName()); + sw.println( = ); + sw.indent(); + sw.indent(); + + // MyBeanValidator.INSTANCE; + sw.print(bean.getFullyQualifiedValidatorName()); + sw.println(.INSTANCE;); + sw.outdent(); + sw.outdent(); +} private String getQualifiedName() { String packageName = getPackage(); return (packageName == ? : packageName + .) + getSimpleName(); } - private String getSimpleName() { -return validatorType.getSimpleSourceName() + Impl; - } - - private SourceWriter getSourceWriter(TreeLogger logger, - GeneratorContext ctx) { + private SourceWriter getSourceWriter(TreeLogger logger, GeneratorContext ctx) { String packageName = getPackage(); String simpleName = getSimpleName(); PrintWriter printWriter = ctx.tryCreate(logger, packageName, simpleName); === --- /trunk/user/src/com/google/gwt/validation/rebind/ValidatorCreator.java Mon Jun 13 07:06:54 2011 +++ /trunk/user/src/com/google/gwt/validation/rebind/ValidatorCreator.java Wed Aug 3 12:02:05 2011 @@ -93,10 +93,6 @@ sourceWriter.println(); writeGwtValidate(sourceWriter); } - - private String getSimpleName() { -return validatorType.getSimpleSourceName() + Impl; - } private void writeConstructor(SourceWriter sw) { // public MyValidator() { -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Make generator result caching framework api available publically. (issue1468804)
Well, a generator has to keep it's own state anyway, in practice. In the case of AbstractClientBundleGenerator, it actually creates a ResourceContext and passes that around, along with the GeneratorContext (this was before any IncrementalGenerator enhancements). In the case of RPC, there are 2 SerializableTypeOracleBuilders and the GeneratorContext that get passed around. I'm not sure, it sounds like you are asking to have a generic functionality for the GeneratorContext, so generators can park data there as needed (not really specific to IncrementalGenerators). What would the semantics be, would it always get added to the cache in entirety, or is there a separate api for saving data for current state and another for specifically placing data that needs to be cached? Is it cleared when each new generator invocation occurs? Since this change is not attempting to modify how the framework behaves with respect to legacy generators, I'd rather not invent api in this patch that's not related to the task at hand. Using your example, before any IncrementalGenerator work, both ClientBundle and RPC look similar to your first example (e.g. there's both a GeneratorContext and helperCachedData passed around everywhere). The only change I've done is to add a way (without modifying current generators), to prepare extra data for subsequent cache reuse checking. In fact, the client data stored for cache reuse checking is generally newly prepared data, not really needed unless caching is enabled. So, the way things work now, are very similar to the current state, but with cache use support added at the beginning (to check reusability) and at the end (to prepare and remember data for future checking). Like so: generateIncrementally(TreeLogger logger, GeneratorContext context, String typeName) { if (checkCacheReusability(context)) return new RebindResult(RebindMode.USE_CACHE,...) // this part is no different for non-incremental generators MyGeneratorStateClass generatorState; new HelperOne(context, generatorState).run(); new HelperTwo(context, generatorState).run(); if (canBeCacheable(context)) { // possibly expensive task PreparedClientData pcd = prepareClientData(context, helperData); RebindResult result = new RebindResult(USE_WHATEVER, typeName + Impl); result.putClientData(pcd, pcd); return result; } else { // no need to prepare any client data return new RebindResult(RebindMode.USE_ALL_NEW_WITH_NO_CACHING,...); } } http://gwt-code-reviews.appspot.com/1468804/ -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
[gwt-contrib] Re: Make generator result caching framework api available publically. (issue1468804)
LGTM On Wed, Aug 3, 2011 at 4:17 PM, jbrosenb...@google.com wrote: Well, a generator has to keep it's own state anyway, in practice. In the case of AbstractClientBundleGenerator, it actually creates a ResourceContext and passes that around, along with the GeneratorContext (this was before any IncrementalGenerator enhancements). In the case of RPC, there are 2 SerializableTypeOracleBuilders and the GeneratorContext that get passed around. I'm not sure, it sounds like you are asking to have a generic functionality for the GeneratorContext, so generators can park data there as needed (not really specific to IncrementalGenerators). What would the semantics be, would it always get added to the cache in entirety, or is there a separate api for saving data for current state and another for specifically placing data that needs to be cached? Is it cleared when each new generator invocation occurs? Since this change is not attempting to modify how the framework behaves with respect to legacy generators, I'd rather not invent api in this patch that's not related to the task at hand. Using your example, before any IncrementalGenerator work, both ClientBundle and RPC look similar to your first example (e.g. there's both a GeneratorContext and helperCachedData passed around everywhere). The only change I've done is to add a way (without modifying current generators), to prepare extra data for subsequent cache reuse checking. In fact, the client data stored for cache reuse checking is generally newly prepared data, not really needed unless caching is enabled. So, the way things work now, are very similar to the current state, but with cache use support added at the beginning (to check reusability) and at the end (to prepare and remember data for future checking). Like so: generateIncrementally(**TreeLogger logger, GeneratorContext context, String typeName) { if (checkCacheReusability(**context)) return new RebindResult(RebindMode.USE_**CACHE,...) // this part is no different for non-incremental generators MyGeneratorStateClass generatorState; new HelperOne(context, generatorState).run(); new HelperTwo(context, generatorState).run(); if (canBeCacheable(context)) { // possibly expensive task PreparedClientData pcd = prepareClientData(context, helperData); RebindResult result = new RebindResult(USE_WHATEVER, typeName + Impl); result.putClientData(pcd, pcd); return result; } else { // no need to prepare any client data return new RebindResult(RebindMode.USE_**ALL_NEW_WITH_NO_CACHING,...); } } http://gwt-code-reviews.**appspot.com/1468804/http://gwt-code-reviews.appspot.com/1468804/ -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] About GWT opinion in thoughtworks technology radar july 2011
The article is a poor source if one attempts to make a meaningful techincal assesment on any opinion. Sure theres a lot of buzzwords but almiost no technically minded examples to back any of the assumptions. Does it show you why X is better than Y at attempting Z. No, so what your basically left is the bias of the authors. Given the share number of technologies covered it is by definition impossible that the authors have really spent sufficient time with each in order to get confortable, become knowledgable and effective with each. On the other hand, it shows that they probably did try many or all for an afternoon and first impressions show in the lack of detail given. This article is perfect for managers while someone who really wants to get something done will after reading the article have gained little benefit from the experience. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors