Have JsInliner refuse to interpose a new expression before a substituted argument. Review at http://gwt-code-reviews.appspot.com/344801 Review by: scottb@google.com git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@7913 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/js/JsInliner.java b/dev/core/src/com/google/gwt/dev/js/JsInliner.java index 2c15ef1..1cef6f4 100644 --- a/dev/core/src/com/google/gwt/dev/js/JsInliner.java +++ b/dev/core/src/com/google/gwt/dev/js/JsInliner.java
@@ -673,13 +673,30 @@ maintainsOrder = false; } } - + @Override public void endVisit(JsNameRef x, JsContext<JsExpression> ctx) { checkName(x.getName()); } @Override + public void endVisit(JsNew x, JsContext<JsExpression> ctx) { + /* + * Unless all arguments have already been evaluated, assume + * that invoking the new expression might interfere with + * the evaluation of the argument. + * + * It would be possible to allow this if the invoked function + * either does nothing or does nothing that affects the + * remaining arguments. However, currently there is no + * analysis of the invoked function. + */ + if (unevaluated.size() > 0) { + maintainsOrder = false; + } + } + + @Override public void endVisit(JsThisRef x, JsContext<JsExpression> ctx) { checkName(THIS_NAME); }
diff --git a/dev/core/test/com/google/gwt/dev/js/JsInlinerTest.java b/dev/core/test/com/google/gwt/dev/js/JsInlinerTest.java index 4debe87..cb1f37b 100644 --- a/dev/core/test/com/google/gwt/dev/js/JsInlinerTest.java +++ b/dev/core/test/com/google/gwt/dev/js/JsInlinerTest.java
@@ -80,6 +80,29 @@ compare(expected, input); } + /** + * Test that a new expression breaks argument ordering. + */ + public void testOrderingNew() throws Exception { + StringBuffer code = new StringBuffer(); + // A static variable x + code.append("var x;"); + + // foo() uses x + code.append("function foo() { alert('x = ' + x); }"); + + // callee does "new foo" before evaluating its argument + code.append("function callee(arg) { new foo(); return arg; }"); + + // caller invokes callee with a multi that initializes x + code.append("function caller() { callee((x=1,2)); }"); + + // bootstrap the program + code.append("caller();"); + + compare(code.toString(), code.toString()); + } + public void testSelfRecursion() throws Exception { String input = "function a1() { return blah && b1() }" + "function b1() { return bar && a1()}" + "function c() { a1() } c()"; @@ -94,7 +117,6 @@ input = optimize(input, JsSymbolResolver.class, FixStaticRefsVisitor.class, JsInliner.class, JsUnusedFunctionRemover.class); expected = optimize(expected); - System.err.println("Input vs "); assertEquals(expected, input); } }