[gwt-contrib] Re: Initial support for @GwtCreate (code-gen methods)

2013-08-20 Thread Andrés Testi
Hi James, thanks for your feedback!
 

> Note that the @GwtCreate class parameters aren't replaced by 
>> GwtCreateFactory as was originally suggested by Ray Cromwell. This provides 
>> access to actual parameters.
>>
>>
> It would be possible to do a full replacement if the factory also gave 
> access to the class field, and any code in the method block accessing the 
> class could be re-routed through the factory.
> Though, I see no good reason why to do the extra work this way, I figured 
> I'd mention it in case someone else has a use case for it.
>


I think that having the class field isolated from GwtCreateFactory,  the 
code pruner would have better opportunities to remove the extra parameter. 
 

>
> * Upcoming improvements:
>>
>>   1) Support for explicit generators
>>
>> @GwtCreate(generator = FooGenerator.class)
>>
>>
> Did you see my pull request with some (very) basic support for this?
> https://gwt-review.googlesource.com/#/c/4000/
>


Sure! I studied your patch before implementing this one.

 

>   2) Multiple parameters for GWT.create() by means of @GwtCreate.Param
>>
>>UiBinder createBinder(
>> @GwtCreate(generator = UiBinGen.class) final Class uiType, 
>> @GwtCreate.Param final Class ownerType) {
>>
>
> Is the intention here to just send more classes to the generator,
> or to actually send parameters to the constructor of the rebound object 
> being instantiated?
>

The intention here is to send more than one arguments to the generator by 
means a special annotation as was suggested by Ray.

 

>   Foo createFoo(
> @GwtCreate final Class fooType,
> @GwtCreate.Param final Class arg1,
> @GwtCreate.Param final Class arg2) {  
> return GWT.create(fooType, arg1, arg2);
>   }
>
> Sending classes is no good, because the constructor needs the values.
>
> Personally, I think the best solution is to add the parameters to 
> @GwtCreate;
>
>   Foo createFoo(
> @GwtCreate({String.class, int.class})
> final Class fooType,
> String arg1, int arg2) {  
> return GWT.create(fooType, arg1, arg2);
>   }
>
> Class values in annotations must be class literals, so that makes that 
> easy.
>

My intention was to provide extra parameters as arguments for code-gen 
methods, i.e:

   createUiBinder(Widget.class, Owner.class, "template.ui.xml"); 
 

> It also means we don't care about the order of extra parameters sent to 
> the method,
> nor are we forced to get these values from the method parameters (or even 
> declare GWT.create params as params in method);
> the invocation of GWT.create(cls, params) would simply supply the 
> JExpressions to pass along to constructors.
> (Have to pull out the initializers from the JNewArray made by the 
> generics, but that's simple).
>
> I assume we would be changing GWT.create to be create(Class c, Object 
> ... params);
> the compiler could bail if params.length > 0 anywhere that's not in a 
> method (method w/ parameter) annotated with @GwtCreate.
>
> Then, add a JType[] and JExpression[] to JGwtCreate to be able to find the 
> right constructor and have values to send it 
> (not sure if unboxing would work without a tweak, but that's no biggie).
>
>
> The only hard-ish part would be updating ResolveRebinds to pass along the 
> list of JExpressions correctly.
>
>
> Do you have any work started in this area, cos I'd be glad to give it a 
> shot / send over a pull request.
>

No, I don't have did nothing in this are, you are welcome to join efforts 
and ideas :-)
 

>
> To allow mixed multiple code-gen parameters, we would bind main 
> parameters by name
>
>>
>>   
>>   void mixedMultiple(
>>   @GwtCreate final Class fooType, 
>>   @GwtCreate.Param("fooType") final Class fooArg,
>>   @GwtCreate final Class barType, 
>>   @GwtCreate.Param("barType") final Class barArg)
>>
>
> I really don't like this much typing to wire stuff up.
> Putting the params in the @GwtCreate would make this much cleaner:
>
>  B create(
> @GwtCreate({String.class}) final Class fooType,
> @GwtCreate({Foo.class}) final Class barType) {
> F foo = GWT.create(fooType, "some string");
> return GWT.create(barType, foo); // params can come from anywhere
>   }
>

As I mentioned before, I want to pass "some string" as argument to 
create(fooType, barType, String)
 

>   3) Support for GWT.create(this.getClass()) ? not exactly, but...
>>
>> Explicits generators can eliminate the issue of the unique generator 
>> per class hierarchy. An aditional boolean parameter for @GwtCreate would 
>> mitigate the code size issue
>>
>>   abstract class UiBinderComposite extends UiBinderComposite {
>>
>> public UiBinderComposite() {
>>   UiBinder binder = 
>> createBinder(getClass());
>> }
>>
>> private static UiBinder
>> createBinder(@GwtCreate(
>> /

Re: [gwt-contrib] Initial support for @GwtCreate (code-gen methods)

2013-08-20 Thread Andrés Testi
Hi Brian, thanks for the feedback!
What you proposes is not so hard to add, but I want the API end users to 
not have to deal with GWT.create() at all. 

El lunes, 19 de agosto de 2013 19:18:24 UTC-3, Brian Slesinsky escribió:
>
> Interesting. I like the idea of replacing class parameters with something 
> else. I'm not sure we need to sweep the implementation under the rug. 
> Particularly in fancier scenarios, it might be easier to work with it 
> explicitly.
>
> Suppose we have:
>
> /** Encapsulates a GWT create call. */
> interface Creator {
>   Class getClassLiteral();
>   List getArgs();
>   T get();
> }
>
> public class GWT {
>   ...  
>
>/** Performs a GWT.create() call an encapsulates the result. */
>final  Creator creator(Class classLiteral, Object... args);
> }
>
> Then you can write code that takes a Creator:
>
> MyService s = createService(GWT.creator(MyService.class), arg);
>
> static  S createService(Creator creator, String 
> arg) {
>S s = creator.get();
>// do some initialization involving arg.
>return s;
> }
>
> This is how you write it without any compiler magic. But we would also 
> support using a bare class:
>
> MyService s = createService(MyService.class, arg);
>
> static  S createService(@Creator final Class 
> theClass, String arg) {
>S s = GWT.create(theClass);
>// do some initialization involving arg.
>return s;
> }
>
> The compiler rewrites any Class arg marked as @Creator to actually take a 
> Creator, inserts the GWT.creator() call at the call site, and replaces the 
> GWT.create() call with a creator.get() call in the API. So we have compiler 
> magic to make the API look pretty for simple cases, but it's not strictly 
> necessary since you could write the same thing yourself (at the cost of 
> some verbosity).
>
> (I bundled the arguments along with the class since that seemed like the 
> most conservative approach. I'm not sure what happens if you have 
> compile-time arguments coming from the different places than the class 
> itself.)
>

All the compile-time arguments are required to come from the same place, 
being all literal or all @GwtCreate arguments.

  Foo createFoo(@GwtCreate Class type, @GwtCreate.Param 
String str) {

// This will compile
GWT.create(type, str);

// This will fail
GWT.create(type, "hello");

// This will compile
GWT.create(Foo.class, "hello");
  }


- Andrés
 

-- 
http://groups.google.com/group/Google-Web-Toolkit-Contributors
--- 
You received this message because you are subscribed to the Google Groups "GWT 
Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to google-web-toolkit-contributors+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [gwt-contrib] Re: I'm enhancing GWT to provide Java stack traces for clientside exceptions in production

2013-08-20 Thread Brian Slesinsky
Thanks for looking into how to improve Java stack traces. I agree that we
could do a better job. However, there are some problems with your approach:

First of all, we can't guarantee that we will accept this change. That
doesn't seem very fair to whoever might be donating money.

I would like to make sure we come up with a solution taking the best
features of everyone's ideas, while remaining as simple as possible. See
the discussion about GWT.create() improvements for an example. So the final
result will likely be modified and include ideas from multiple
contributors, though course the person who volunteers to do most of the
work often has the largest influence. And simple patches aren't a solo
effort because someone has to review them and try them out.

With a project as complex and widely used as GWT, the drawbacks to a change
may be unexpected. It's unfortunate, but we often find that after
committing a change to Google's codebase, we discover problems that nobody
thought of in review and we not caught by GWT's own tests. It's much easier
to test a change if it's broken up into smaller patches.

So if possible it's best to split up a larger feature into smaller patches
and consider each of them on their merits. For example, if some things are
just bug fixes, we should review and commit them separately. This is often
a good way to get started in the community - before trying something large,
fix simpler bugs. This gives us a chance to get to know your work through
smaller and less risky changes, and you'll likely learn things along the
way. Resist the urge to add more features since that makes a change riskier
and harder to get agreement on.

- Brian

On Mon, Aug 19, 2013 at 1:06 PM, Alex Epshteyn  wrote:

> Hello folks,
>
> I just wanted to remind everyone that the last day to fund this project is
> this Friday, August 23.
>
> I've been using this framework in production in my app now for 2 months,
> and it works great.  Have logged 70,000 perfect stack traces so far!
>  Already fixed 3 major bugs in my GWT-based UI code that I would NEVER
> found otherwise.
>
> Let's get this capability into GWT by the end of the year.  Please donate!
>
> Thanks,
> Alex
>
>
>
> On Wednesday, July 17, 2013 4:56:40 PM UTC-4, Alex Epshteyn wrote:
>>
>> Dear fellow GWT users,
>>
>> I would like to announce that I have finally solved what I always thought
>> to be GWT's greatest weakness: its lack of debugging information for
>> client-side exceptions in production.
>>
>> With my patch, your deployed app will be able to report stack traces like
>> this:
>>
>> com.google.gwt.core.client.**JavaScriptException: (TypeError) : a is null
>> com.google.gwt.dom.client.**DOMImplMozilla.$**getBodyOffsetLeft(**
>> DOMImplMozilla.java:145)
>> com.google.gwt.user.client.ui.**PopupPanel.$setPopupPosition(**
>> Document.java:1287)
>> com.google.gwt.user.client.ui.**PopupPanel.setPopupPosition(**
>> PopupPanel.java:884)
>> com.google.gwt.user.client.ui.**PopupPanel.PopupPanel(**
>> PopupPanel.java:453)
>> com.typeracer.commons.client.**widgets.EnhancedPopup.**
>> EnhancedPopup(EnhancedPopup.**java:32)
>> com.typeracer.commons.client.**widgets.PopupWithIcon.**PopupWithIcon(**
>> PopupWithFocusableTextBox.**java:28)
>> com.typeracer.main.client.**controller.**TyperacerUncaughtExceptionHand**
>> ler$1.execute(**TyperacerUncaughtExceptionHand**ler.java:55)
>> com.google.gwt.core.client.**impl.SchedulerImpl.**runScheduledTasks(**
>> SchedulerImpl.java:50)
>> etc... :-)
>>
>>
>> instead of the current state of affairs that looks like this:
>>
>> lineNumber: 3190 columnNumber: 15354: a is null; (TypeError) fileName:
>> http://localhost:8088/**9C4DC2D905BEA407601C92C56B43E3**B8.cache.html
>>
>> stack: @http://localhost:8088/**9C4DC2D905BEA407601C92C56B43E3**
>> B8.cache.html:2422
>>
>> Rub@http://localhost:8088/**9C4DC2D905BEA407601C92C56B43E3**
>> B8.cache.html:2423
>>
>> dSb@http://localhost:8088/**9C4DC2D905BEA407601C92C56B43E3**
>> B8.cache.html:3190
>>
>> tA@http://localhost:8088/**9C4DC2D905BEA407601C92C56B43E3**
>> B8.cache.html:2810
>>
>> Xmb@http://localhost:8088/**9C4DC2D905BEA407601C92C56B43E3**
>> B8.cache.html:2289
>>
>> etc... :-(
>>
>>
>> I am asking the community to support me in finishing this effort and
>> integrating my patch into GWT.  Please take a look and what I've done, and
>> consider making a donation:
>>
>> http://igg.me/at/gwt-stack-**traces/x/3494291
>>
>> I am an indie developer and I just need some funding to continue this
>> work.  I'm looking for bot

Re: [gwt-contrib] Possible GWT.create() Improvements (link)

2013-08-20 Thread Andrés Testi
As an alternative to what Goktug proposed about macros, we would have an 
equivalent to Scala macros (sorry for insisting with Scala :-) )

  @Macro(SumGenerator.class)
  Integer sum(Integer arg0, Integer arg1) {
// We will never be here
return null;
  }

  // rebind space
  class SumGenerator {

Expr sum(GeneratorContext ctx, TreeLogger logger, Arg 
arg0, Arg arg1) {

   if(arg0.isLiteral() && arg1.isLiteral()) {

 // If both arguments are literals, we sum they at compile time
 Integer result = arg0.getValue() + arg1.getValue();

 return ctx.compile("return {};", result);
   }

   // We return a runtime sum
   return ctx.compile("return {} + {};", arg0, arg1);
}
  }

- Andrés

-- 
http://groups.google.com/group/Google-Web-Toolkit-Contributors
--- 
You received this message because you are subscribed to the Google Groups "GWT 
Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to google-web-toolkit-contributors+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [gwt-contrib] Re: I'm enhancing GWT to provide Java stack traces for clientside exceptions in production

2013-08-20 Thread Colin Alworth
I got a tweet from you asking for a donation (or rather a 'partner', which
apparently means 'money'), but couldn't frame a useful response in 140
chars, so since this thread is coming back, I thought to do so here
instead.

What license are you offering these code samples under - if it isn't
something open and available, what is the benefit to an advance copy of the
jar if I, an author of a library and several open source tools and
applications, cannot provide it to my customers or other downstream users?

We've found that https://gist.github.com/niloc132/3906501 goes a heck of a
long ways toward offering optional debug info - if not enabled, the user
gets the normal-size application with zero size or performance hit, and by
redirecting to a slightly different url, the full trace info can be pulled
out (with the quirks you mention of course*), which typically goes a long
ways toward identifying the real issue.

* How often have you needed to know which line of Impl.java or DOMImpl.java
a stack trace intersects? To make your case more effectively, you might
consider using code where it is meaningful to see those lines, something
other than the equivelent of
java.lang.reflect.Method.invoke(Method.java:601). Perhaps some real life
JSNI, or an annoying IE6-9 focus() or setAttribute issue?

You touch briefly on the risk of '[exposing] your application’s
implementation details', but unless I am mistaken, the extra metadata
included in the file:line ints should still be enough to take apart an app
and map it to discrete files and reconstruct methods, even un-inlining (as
you mention) to pull out clearer details. My understanding was that the
premise of the sourceMap was to work entirely from the stack to allow the
actual source to be obfuscated, and avoid any other metadata from being
left in the compiled output. Combine this with the fact that many of those
classes are publicly available (GWT itself, etc), and it seems that you
could reverse out a significant portion of the app - the "secret sauce".
Can you comment on using this for public applications and any reverse
engineering attempts you've made?


On Mon, Aug 19, 2013 at 3:06 PM, Alex Epshteyn  wrote:

> Hello folks,
>
> I just wanted to remind everyone that the last day to fund this project is
> this Friday, August 23.
>
> I've been using this framework in production in my app now for 2 months,
> and it works great.  Have logged 70,000 perfect stack traces so far!
>  Already fixed 3 major bugs in my GWT-based UI code that I would NEVER
> found otherwise.
>
> Let's get this capability into GWT by the end of the year.  Please donate!
>
> Thanks,
> Alex
>
>
>
> On Wednesday, July 17, 2013 4:56:40 PM UTC-4, Alex Epshteyn wrote:
>>
>> Dear fellow GWT users,
>>
>> I would like to announce that I have finally solved what I always thought
>> to be GWT's greatest weakness: its lack of debugging information for
>> client-side exceptions in production.
>>
>> With my patch, your deployed app will be able to report stack traces like
>> this:
>>
>> com.google.gwt.core.client.**JavaScriptException: (TypeError) : a is null
>> com.google.gwt.dom.client.**DOMImplMozilla.$**getBodyOffsetLeft(**
>> DOMImplMozilla.java:145)
>> com.google.gwt.user.client.ui.**PopupPanel.$setPopupPosition(**
>> Document.java:1287)
>> com.google.gwt.user.client.ui.**PopupPanel.setPopupPosition(**
>> PopupPanel.java:884)
>> com.google.gwt.user.client.ui.**PopupPanel.PopupPanel(**
>> PopupPanel.java:453)
>> com.typeracer.commons.client.**widgets.EnhancedPopup.**
>> EnhancedPopup(EnhancedPopup.**java:32)
>> com.typeracer.commons.client.**widgets.PopupWithIcon.**PopupWithIcon(**
>> PopupWithFocusableTextBox.**java:28)
>> com.typeracer.main.client.**controller.**TyperacerUncaughtExceptionHand**
>> ler$1.execute(**TyperacerUncaughtExceptionHand**ler.java:55)
>> com.google.gwt.core.client.**impl.SchedulerImpl.**runScheduledTasks(**
>> SchedulerImpl.java:50)
>> etc... :-)
>>
>>
>> instead of the current state of affairs that looks like this:
>>
>> lineNumber: 3190 columnNumber: 15354: a is null; (TypeError) fileName:
>> http://localhost:8088/**9C4DC2D905BEA407601C92C56B43E3**B8.cache.html
>>
>> stack: @http://localhost:8088/**9C4DC2D905BEA407601C92C56B43E3**
>> B8.cache.html:2422
>>
>> Rub@http://localhost:8088/**9C4DC2D905BEA407601C92C56B43E3**
>> B8.cache.html:2423
>>
>> dSb@http://localhost:8088/**9C4DC2D905BEA407601C92C56B43E3**
>> B8.cache.html:3190
>>
>> tA@http://localhost:8088/**9C4DC2D905BEA407601C92C56B43E3**
>> B8.cache.html:2810
>>
>> Xmb@http://localhost:8088/**9C4DC2D905BEA407601C92C56B43E3**
>> B8.cache.html:2289

[gwt-contrib] Re: Initial support for @GwtCreate (code-gen methods)

2013-08-20 Thread James Nelson

>
>
> Thanks! I think this proposal is the most conservative way to enhance 
> GWT.create(). A more radical approach would be to forget GWT.create() and 
> imitate what scala macros do, as was suggested by Gotktug:
>
>   @Macro(SumGenerator.class)
>   int sum(int arg0, int arg1) {
> return 0; // we will never be here
>   }
>
>   // Rebind space
>   class SumGenerator {
>
> public Expr sum(GeneratorContext ctx, TreeLogger logger, 
> Arg arg0, Arg arg1) {
>   if(arg0.isLiteral() && arg1.isLiteral) {
> Integer result = arg0.getValue() + arg1.getValue();
> return ctx.compile("return " + result.toString();
>} 
>return ctx.compile("return %s + %s", arg0, arg1); 
> }
>   }
>
>
I definitely like the API this offers.

I do maintain a hack on UnifyAst that allows manually creating magic 
methods;
https://github.com/WeTheInternet/xapi/tree/master/gwt/gwt-method-inject
It's a little ugly in the xml, since I didn't think it wise to create a new 
gwt.xml property for something that will likely never make it into master.

The example generator API w/ Arg could be extrapolated from the magic 
method injector linked to above, using the literal finder from the other 
code review I posted.

I'm not sure if it could look exactly like the snippet posted (I just 
return JExpression to match GWT.create behavior),
but it does allow defining arbitrary magic methods for experimentation w/ 
extensions to the compiler.

The big problem, of course, is dev mode / jvms, which do not perform magic 
method injection.
Those platforms would require bytecode enhancement, or (as I've been 
doing), specifying a method body which is fully functional in a jvm 
sans-generators.


The only hard part of the scala-esque macros would be ctx.compile("..."); 
I've had to either manually create AST nodes (which then lack valid 
SourceInfo), or generate classes so I can then get compiled jjs ast nodes 
from UnifyAst (make sure you call StandardGeneratorContext.finish() before 
attempting this).
I guess it would be possible to automate all of that behind the scenes,
or maybe it would be easy for someone with deeper knowledge than I about 
CompilationUnitBuilder (or wherever strings would be lexed into ast nodes).

For now, however, I think the scala macro idea is a bit too ambitious.




As for passing multiple class lits to a generator, I definitely see where 
it would be useful to have more than one class in a generator,
although UIBinder already achieves this using generic type parameters (but 
requires manually defining the interface, of course).

This would, unfortunately, likely change the Generator interface contract 
and thus break existing code (maybe fine for GWT 3.0, but definitely no 
sooner).
There is also a problem for dev mode, which I'll get into a few paragraphs 
down.


As for the object-instead-of-class details I posted above,
What do you think about:
 T GWT.construct(Class cls, Object ... params)?

It would look and feel exactly like GWT.create,
except it would support constructors with arguments (and would only be 
usable through an annotated factory method, to provide classlits for param 
types).

This would add a new feature that cannot currently be achieved, plus 
promote immutability (more final, less .setValue()).

As such, I think I'll take a stab at it using the aforelinked 
magic-method-inject module when I get some free time (of which I am in 
unfortunately very short supply).
If the experiment goes well, and I can post a working prototype, I'll be 
sure to tag you in the pull request.

The only gotcha I foresee would be dev mode (which I am not terribly 
familiar with modifying); 
about the only way I can think of the get the annotation with class lits in 
the jvm would be to use reflection to look up the call stack and grab the 
enclosing method (ick,
I really don't like seeing comments like // Do not modify the call order 
because this code depends on stack depth == n).

Speaking of which...  getting multiple class params to work in dev mode 
will face the same problem; how to safely (and preferably quickly) extract 
the method annotations within the jvm.


Anyway, they're both fun ideas to play with, and although I'm not holding 
my breath on getting either of them into master any time soon (or ever),
I still like a good challenge, and I think something like GWT.construct() 
could be a lot of fun to work on.

If you have any ideas or suggestions, do let me know!
 

> This last proposal requires a hard work to be done, and a totally new 
> generator API. Before to start with something like this, I prefer to 
> explore the code-gen compiler plugin for javac 8 mentioned by Ray in the 
> other thread. We should stay standard and portable as possible.
>
>
For posterity's sake, could you drop those links off here (or are you 
referring to the ones Ray posted in the G+ community? The phrase "javac 8" 
doesn't ring any bells for me).

Thanks,
James

-- 
http://groups.google.com

[gwt-contrib] Re: Initial support for @GwtCreate (code-gen methods)

2013-08-20 Thread James Nelson

>
>
> For posterity's sake, could you drop those links off here (or are you 
> referring to the ones Ray posted in the G+ community? The phrase "javac 8" 
> doesn't ring any bells for me).
>
>
Nevermind.  I just browsed the group and saw the thread.  My bad. 

-- 
http://groups.google.com/group/Google-Web-Toolkit-Contributors
--- 
You received this message because you are subscribed to the Google Groups "GWT 
Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to google-web-toolkit-contributors+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.