I want to note that GWT Generators follow exactly (or almost) the same
pattern - properties defined for permutation dictate what code to
compile. For example, in one of my applications (patch to GWT :) in
progress) I use property provider, which check application URL for
presence of special query attribute, and generate either debug or
production version of my classes. It works but inconvinient.
What I would love to be able to write is
if ( GWT.getBooleanProperty("debug",false) )
{
// debug code
}
Formal definition for GWT.getBooleanProperty is
public static boolean getBooleanProperty (String propertyName, boolean
defaultValue)
Of course, I expect compiler to be smart enough to replace this call
either by true or false depending on property value and default value.
After that regular dead code elimination process will do the work.
Obviously, we can imagine also GWT.getStringProperty,
GWT.getIntegerProperty etc. This functionality can become extremely
powerful if compiler is able to simplify expressions like <literal>
<binary operation> <literal> to <new literal> and especially if it is
able to evaluate methods like Sting.equals, Sting.equalsIgnoreCase,
Sting.indexOf etc. with parameters known at runtime.
Does such API extension make any sense?
On Feb 12, 2:32 pm, "Emily Crutcher" <e...@google.com> wrote:
> This seems like a great feature to have, though I'd still love to see the
> assert mechanism as well...
>
> On 2/11/07, Scott Blum <sco...@google.com> wrote:
>
>
>
>
>
> > Perhaps so, especially as our compiler becomes better (and better at
> > optimizing). Before such an API wouldn't have helped much due to lack
> > of good dead code elimination, but now (thanks, Sandy!) I could see
> > some real value here.
>
> --
> "There are only 10 types of people in the world: Those who understand
> binary, and those who don't"
There are many well-know cases when conditional compilation may be
really useful. Debug vs. Production is probably most popular example.
[...]
What I would love to be able to write is
if ( GWT.getBooleanProperty ("debug",false) )
{
// debug code
}
When I first read Alex's proposal I first though this is really
another for of GWT's I18N but instead of Local based it's based on
some other parameter. Alex's proposal introduces more magic methods
beyond GWT.create which I don't like.
I think I'd rather see a means to plug in your own JJS optimizers
which can look for higher level things like like Alex wants and
optimize them. But that would make the AST a public interface and that
is undesirable. IntelliJ IDEA has a structural search and replace
feature which understands the code in an abstract way. Maybe something
like that could be the public API so the AST can remain a private API.
I would have to think on it more.
--
Sandy McArthur
"He who dares not offend cannot be honest."
- Thomas Paine
On 2/12/07, Fred Sauer <fr...@allen-sauer.com> wrote:
>
Main difference with mine proposal is ability to compile several
versions of the same code and make them available for end user.
Open question: what happens if the property is not defined? Is that a
compile time error, or is a default value supplied? I could imagine
writing some reusable code that would take advantage of a "debug"
property if it was defined and true, but not require the user to
define it.
On 2/12/07, Fred Sauer <fr...@allen-sauer.com> wrote:
What I would love to be able to write is
if ( GWT.getBooleanProperty("debug",false) )
{
// debug code
}
So, this is just like the existing functionality but you don't have to
declare a class and use replace-with. That saves a little developer
effort but not much.
> Open question: what happens if the property is not defined? Is that a
> compile time error, or is a default value supplied? I could imagine
> writing some reusable code that would take advantage of a "debug"
> property if it was defined and true, but not require the user to
> define it.
Personally, I think of hosted mode as my debug mode and web mode as
non-debug mode. In that situation I've found GWT.isScript() to be a
sufficient answer to whether or not my code is running in "debug"
mode.
Also, all the examples are about a "debug" property. What other
properties would anyone want?
The only property I can think of that isn't a one-off is for the
current browser. I think this feature would encourage the use of messy
code like:
if ("ie6".equals(GWT.getProperty("user.agent"))) {
// IE widget logic
} else if ("gecko".equals(GWT.getProperty("user.agent"))) {
// Gecko widget logic
} else if ....
Seems to me adding support for enabling assert in web mode is a better
course of action without a compelling list of frequently used
properties beyond "debug".
I think that's a good summary.
> Also, all the examples are about a "debug" property. What other
> properties would anyone want?
Good question. I could see logging as a separate thing from debug. I
know there's GWT.log, but you might want to do custom loggin in web
mode. We could also use it to toggle certain runtime checks -- should
iterators check for concurrent modification? Should ArrayList range
check indices?
> The only property I can think of that isn't a one-off is for the
> current browser. I think this feature would encourage the use of messy
> code like:
>
> if ("ie6".equals(GWT.getProperty("user.agent"))) {
> // IE widget logic
> } else if ("gecko".equals(GWT.getProperty("user.agent"))) {
> // Gecko widget logic
> } else if ....
Granted. (Although the compiler wouldn't actually optimize this out today.)
> Seems to me adding support for enabling assert in web mode is a better
> course of action without a compelling list of frequently used
> properties beyond "debug".
Oh, I absolutely agree that enabling assertions in web mode is
something that needs to happen regardless of this. Wonder if there's
time to sneak it into 1.4.... :)
Scott
"gecko".equals(GWT.getProperty("user.agent"))
I also have working code for asserts, which hope to provide today
(maybe even together with stack traces)
On Feb 13, 9:55 am, "Scott Blum" <sco...@google.com> wrote:
Good question. I could see logging as a separate thing from debug. I
know there's GWT.log, but you might want to do custom loggin in web
mode. We could also use it to toggle certain runtime checks -- should
iterators check for concurrent modification? Should ArrayList range
check indices?
1) WebMode stack traces
2) Asserts
3) Conditional compilation
4) Dead code elimination (or better say compile-time calculation) for
constant calls to methods of String class.
Probably only last one can be separated to another patch but I use
conditional compilation for implementation of asserts and stacktraces
and conditional compilation itself requires String-precalculation.
I would really appreciate if somebody familiar with GWT compiler
provide feedback and critique.
Alex
It depends. In general, you can't use deferred binding with a class
that's supposed to be directly instantiated (like ArrayList directly);
you'd have to instantiate a private impl class via deferred binding;
but then you get into performance issues. You'd think that the
iterator class could be defbound because it's instantiated by the
outer class; however the problem here is that you can't use deferred
binding to produce a non-static inner class, because how are you going
to hook up the outer ref? (Tangent: wonder if it'd be possible to
have a GWT.create(Class, Object outer) to allow just that?)
Scott
So... the thing is that we're trying to push for a 1.4 RC1 next
Wednesday, and I have more things on my plate for this RC than I
actually have time for. :) All of which means that, I probably won't
have time to do an in-depth look at things that aren't slated for 1.4.
I don't think conditional compilation is a candidate, because it's an
API change that would need to be vetted by a wider set of people.
Asserts would be a consideration, except that being implemented in
terrms of cond-comp kind of rules it out. That leaves stack traces
and dead code on Strings, which I hope to have time to look at.
The other big things on my plate are:
- Optionally output JS files directly (rather than HTML); waiting on
jgw's startup optimizations
- Refactor JS naming strategy (inspired by half of issue #610, the
name-allocation patch which proves how much low-hanging fruit there
is)
- The other half of issue #610, merging string constants
- Get patch for issue #622 reviewed & submitted
Scott
I've read your patch in a text editor but haven't applied it and built
it. Below are my thoughts as I cruised down the file.
* There is a lot of reformatting noise. Changes that just introduce
white space make it harder to read.
* Your mixing too many changes in one patch. I know some of the parts
build on the others but things like the string literal method call
optimization have a chance of being accepted more easily if it was
split out. Right now the chance of a GWT dev taking the time to
extract it from your patch is low. I don't know about the GWT project,
but at Apache we won't accept an overloaded patch. Considering GWT
borrows a lot of policies from Apache and they try to keep discussions
to one topic per thread I suspect they feel the same way.
* Is the string literal method call optimization a really a dead code
elimination or a type of inlining?
* Scott has stated in the past he prefers the StackTrace method that
fills in the stack trace as an exception bubbles out. This means stack
traces will be incomplete and only contain the top few frames but it
will have very low performance overhead in the non-exceptional case.
Also, I'm not sure if the bubble up stack fill method will be a
compile time option or an always there feature once added. Probably
depends on how it affects generated code size and performance.
* removing a blank line and then adding another blank line should be
avoided. If your IDE keeps putting those in the patch, I'll manually
delete them from the patch.
* You widen the scope of the JStringLiteral class when you don't need
to. JProgram has a getLiteralString(char[]) method to create
JStringLiterals and if you look at it's source you'll it's part of
future plans for string literal interning. If you don't like that it
takes a char[] param you should add a getLiteralString(String)
variant.
* again with the unneeded formating changes.
* I suspect the addition of setElseStmt and setThenStmt to
JIfStatement aren't gonna fly. I think you either need to use the
Context to mutate them or create a new JIfStatement instance to
replace an existing one with Context. Same for setBody in
JForStatement and JWhileStatement.
> * Scott has stated in the past he prefers the StackTrace method that
> fills in the stack trace as an exception bubbles out. This means stack
> traces will be incomplete and only contain the top few frames but it
> will have very low performance overhead in the non-exceptional case.
> Also, I'm not sure if the bubble up stack fill method will be a
> compile time option or an always there feature once added. Probably
> depends on how it affects generated code size and performance.
Just want to be clear that I'm not committed to an approach. I
*think* I'm leaning towards what you describe, but I really have to
look into it in a lot more detail. It may be that some way of
preserving the whole trace is not out of the question. Either way, I
feel quite confident that stack traces will be a toggle option that
will be off by default.
Scott
I also got your point about huge amount of tasks before 1.4RC But let
me do last try. My problem is I expect to be extremely busy several
weeks after this one and will not be able to participate here
actively.
I cut huge patch to several smaller ones. They cover asserts, stack
traces and compile time calculation of calls to methods of String
class with literal parameters. Conditional compilation is out of scope
before we agreed on API. I believe such cut significantly simplifies
review. And of course I think functionality itself (at least asserts
and stack traces) is important enough to try to include it in to 1.4.
See attached files.
3) Asserts
I really want to do this, but we can't do it without settling on how to turn debugging on and off, so it won't be able to go into 1.4.
Technical critique:
- I think we have some correctness issues-- you always call Exceptions.doAssert() which takes a String as the second argument, but what you are passing in might not be a String. We should be calling the correctly-typed constructor.
- Instead of allowing the arg to be null, it would be better to synthesize the String literal during GenerateJavaAST. This would also allow us to grab the real source text directly from JDT's AST.
Thank you for taking time looking on that. I seems like you checked
not the last version, which attached to comment in issue 692. Here is
a link for this comment posted 6 days ago
http://code.google.com/p/google-web-toolkit/issues/detail?id=692&can=2&q=alex.tkachman#c5
BTW, I completely agree with Dan Morrill, who marked this issue this
Priority-High for 1.4RC. And let me repeat my arguments from another
post on the same issue "it is absolutely unbelievable feeling to catch
in your IDE an exception raised by assert statement in some test
running in web mode... For me it is exactly one of the things, which
is all GWT about"
Let me try to comment point by point now.
> 1) Making Java AST statements mutable
>
> We actually just got this out of the system, and I'd rather not put it back
> in. The change you really want is actually far more fundamental-- you want
> normalization of the Java AST tree. Every type of statement has a
> JStatement as a child today should probably have a JBlock instead; this
> would allow much nicer optimizing and avoid the weird cases of having to
> either remove yourself or replace yourself with an empty block. We would
> have to optimize either going from Java->JS or generating the JS itself to
> suppress unnecessary extra braces, but we should be doing this anyway if
> we're not. I think this merits its own discussion, because it would totally
> solve what you want.
>
> 2) Debug info infrastructure.
>
> I think we want to do something like this, just not for 1.4. I also think
> we need a larger discussion of whether gwt.debug is how we want to do it,
> and the specific formulation. The way it is presently, we'd end up doubling
> the number of permutations by default, for every compile. I think we'd
> rather have debug off by default unless someone specifically turns it on.
> Again, this seems like its own design discussion.
>
In my last patch I've removed doubling of permutation number. All you
need to do is put <set-property name="gwt.debug" value="true"/> in one
of your modules. But I would suggest even better solution - compiler
swtith "-debug", which will force this property on.
> 3) Asserts
> Technical critique:
> - I think we have some correctness issues-- you always call
> Exceptions.doAssert() which takes a String as the second argument, but what
> you are passing in might not be a String. We should be calling the
> correctly-typed constructor.
Good point.
> - Instead of allowing the arg to be null, it would be better to synthesize
> the String literal during GenerateJavaAST. This would also allow us to grab
> the real source text directly from JDT's AST.
>
My last patch does it already.And it is really very convenient.
> 4) Stack trace
>
> Some critiques, even given this approach:
> - We definitely don't want to be doing an array.push() / array.pop() at
> every level. It's much faster to just keep an index handy and don't bother
> cleaning up. The memory is insignificant, and some browsers (IE) take
> O(n^2) to push/pop, as we learned the hard way in RPC.
God, I never new about that. The only reason for me to use some many
native code was wrong hope that array.push/pop are extremely fast.
> - Alternatively, since we're creating our own list of stack trace elements
> that are totally an implementation detail, why not just add an extra field
> and link-list them?
> - Either way, the current "top" element should be readily available to make
> line number updates fast.
Of course, we should do that. It is easy and I will be happy to do
that. Fortunately I have tests :)
> - It doesn't handle JSNI code. Granted, this is an extremely minor point
> (since hosted mode won't do that either), but we could actually make stack
> traces work for JSNI methods.
>
My last patch does that already. File JavaScript_source_info.patch
contains necessary modification for work with JSNI code.
> If I were to take these ideas to the logical extreme, I would probably want
> to do this at the JS level (after some additional infrastructure work to get
> good source info into the JS AST). I would reserve a single well-known
> global identifier for the stack trace, which would be a linked list. A
> method might look like this (sans obfuscation) :
>
> function foo() {
> try {
> $globalException =
> {file:"Blah.java",line:27,className:"com.example.Blah",methodName:"foo",next:$globalException};
> // stmt 1
> $globalException.line = 29;
> // stmt 2
> ++$globalException.line; // :)
> } catch (e) {
> fillInStackTrace(e);
> } finally {
> $globalException = $globalException.next;
> }
> }
>
Scott, I agree that it would be great. But it requires some
infrastructural changes in compiler.
Let us look on that from customer (oh, sorry user :) ) point of view -
we are either able to provide really great functionality, which
dramatically change development experience immediately, or wait for
at least couple of months before we are ready to implement it most
elegant way. Probably I am staying here on businessman position not on
engineer one but my choice (well, suggestion) is to improve the patch
deliver in 1.4.
I don't doubt the coolness of the feature, but I think Dan's making
this part of 1.4 must have been an accident.
We must freeze new features for 1.4 ASAP. I am planning to remove the
1.4 Milestone label for this issue, but it sounds like you guys are
getting so close to a working solution that it should be pretty easy
to slip into the subsequent release.
I've mostly been just lurking on this thread, but I'll chime in just
to say that the reason it seems like the absence of web-mode stack
traces is not urgently important is that if GWT works the way it's
supposed to, it should never be useful in practice. In other words,
any problem that you would find in web mode should already have been
found in hosted mode, where you have an arsenal of good tools. If GWT
users are having problems that can only be diagnosed in web mode, then
something more fundamental needs to be addressed first.
-- Bruce
On 2/22/07, Alex Tkachman <alex.t...@gmail.com> wrote:
> BTW, I completely agree with Dan Morrill, who marked this issue this
> Priority-High for 1.4RC .
I don't doubt the coolness of the feature, but I think Dan's making
this part of 1.4 must have been an accident.
On 2/22/07, Bruce Johnson <br...@google.com> wrote:Dan said he was marking things Critical and High to ensure that someone in the area looked at it at made a decision on it, with Critical including either showstopper bugs or trivial fixes, and anything below High wasn't likely to go in unless it was picked up as part of something else or we had time left over.
I understand your reasons about the schedule. Let us postpone till
next releases.
But I don't agree with you about importance of web mode stack traces.
Hosted mode is great solution for developer, who usually works on one
platform, but tests should be run on all possible combination of
platforms and browsers and stacktraces could be absolutely unique tool
here. And it is especially criticalfor external javascript.
Fortunately sooner or later we plan (as I understand) to involve it in
to our compilation process.
Regarding testing iteself I believe we have to think again about
better infrastructure for remote run of tests.
Alex
On 2/22/07, Bruce Johnson <br...@google.com> wrote:
>
I'm with mostly Alex on this one. It's unreasonable for hosted mode to
support every combination of browser extensions or popup blockers and
simulate various firewalls or unreliable internet connections. A
method for users to be able to send in partial stack traces would help
a lot when trying to nail a user's problem and you cannot travel to
their home and experience the problem yourself.
I'll agree they aren't urgent, I'm surviving without them today. I
just think hosted mode isn't a substitute for them.
Thank you for taking time looking on that. I seems like you checked
not the last version, which attached to comment in issue 692. Here is
a link for this comment posted 6 days ago
http://code.google.com/p/google-web-toolkit/issues/detail?id=692&can=2&q=alex.tkachman#c5
In my last patch I've removed doubling of permutation number. All you
need to do is put <set-property name=" gwt.debug" value="true"/> in one
of your modules. But I would suggest even better solution - compiler
swtith "-debug", which will force this property on.
> - Instead of allowing the arg to be null, it would be better to synthesize
> the String literal during GenerateJavaAST. This would also allow us to grab
> the real source text directly from JDT's AST.
>
My last patch does it already.And it is really very convenient.
> - It doesn't handle JSNI code. Granted, this is an extremely minor point
> (since hosted mode won't do that either), but we could actually make stack
> traces work for JSNI methods.
My last patch does that already. File JavaScript_source_info.patch
contains necessary modification for work with JSNI code.
Where is this debate? I'd like to throw my $0.02 towards everything
being a property so that if I wanted every permutation of -style, -ea,
debug, user.agent, etc generated and selectable at load time I could
have them.