Fix bug. Integrate precedence API into JSO

This commit is contained in:
Alexey Andreev 2015-10-11 18:03:46 +03:00
parent 6d23626867
commit 7c4b4ebe77
4 changed files with 42 additions and 26 deletions

View File

@ -1603,7 +1603,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
expr.getOperand().acceptVisitor(this); expr.getOperand().acceptVisitor(this);
writer.ws().append("&").ws().append("65535"); writer.ws().append("&").ws().append("65535");
if (outerPrecedence.ordinal() > Precedence.BITWISE_AND.ordinal()) { if (outerPrecedence.ordinal() > Precedence.BITWISE_AND.ordinal()) {
writer.append('('); writer.append(')');
} }
break; break;
case NULL_CHECK: case NULL_CHECK:

View File

@ -44,7 +44,8 @@ class JSBodyAstEmitter implements JSBodyEmitter {
int paramIndex = 0; int paramIndex = 0;
if (!isStatic) { if (!isStatic) {
int index = paramIndex++; int index = paramIndex++;
astWriter.declareNameEmitter("this", prec -> context.writeExpr(context.getArgument(index))); astWriter.declareNameEmitter("this", prec -> context.writeExpr(context.getArgument(index),
convert(prec)));
} }
for (int i = 0; i < parameterNames.length; ++i) { for (int i = 0; i < parameterNames.length; ++i) {
int index = paramIndex++; int index = paramIndex++;

View File

@ -20,6 +20,7 @@ import org.teavm.codegen.SourceWriter;
import org.teavm.dependency.DependencyAgent; import org.teavm.dependency.DependencyAgent;
import org.teavm.dependency.DependencyPlugin; import org.teavm.dependency.DependencyPlugin;
import org.teavm.dependency.MethodDependency; import org.teavm.dependency.MethodDependency;
import org.teavm.javascript.Precedence;
import org.teavm.javascript.Renderer; import org.teavm.javascript.Renderer;
import org.teavm.javascript.ast.ConstantExpr; import org.teavm.javascript.ast.ConstantExpr;
import org.teavm.javascript.ast.Expr; import org.teavm.javascript.ast.Expr;
@ -76,41 +77,45 @@ public class JSNativeGenerator implements Injector, DependencyPlugin, Generator
SourceWriter writer = context.getWriter(); SourceWriter writer = context.getWriter();
switch (methodRef.getName()) { switch (methodRef.getName()) {
case "get": case "get":
context.writeExpr(context.getArgument(0)); context.writeExpr(context.getArgument(0), Precedence.MEMBER_ACCESS);
renderProperty(context.getArgument(1), context); renderProperty(context.getArgument(1), context);
break; break;
case "set": case "set":
writer.append('('); context.writeExpr(context.getArgument(0), Precedence.ASSIGNMENT.next());
context.writeExpr(context.getArgument(0));
renderProperty(context.getArgument(1), context); renderProperty(context.getArgument(1), context);
writer.ws().append('=').ws(); writer.ws().append('=').ws();
context.writeExpr(context.getArgument(2)); context.writeExpr(context.getArgument(2), Precedence.ASSIGNMENT.next());
writer.append(')');
break; break;
case "invoke": case "invoke":
context.writeExpr(context.getArgument(0)); context.writeExpr(context.getArgument(0), Precedence.GROUPING);
renderProperty(context.getArgument(1), context); renderProperty(context.getArgument(1), context);
writer.append('('); writer.append('(');
for (int i = 2; i < context.argumentCount(); ++i) { for (int i = 2; i < context.argumentCount(); ++i) {
if (i > 2) { if (i > 2) {
writer.append(',').ws(); writer.append(',').ws();
} }
context.writeExpr(context.getArgument(i)); context.writeExpr(context.getArgument(i), Precedence.min());
} }
writer.append(')'); writer.append(')');
break; break;
case "instantiate": case "instantiate":
writer.append("(new ("); if (context.getPrecedence().ordinal() >= Precedence.FUNCTION_CALL.ordinal()) {
context.writeExpr(context.getArgument(0)); writer.append("(");
}
writer.append("new ");
context.writeExpr(context.getArgument(0), Precedence.GROUPING);
renderProperty(context.getArgument(1), context); renderProperty(context.getArgument(1), context);
writer.append(")("); writer.append("(");
for (int i = 2; i < context.argumentCount(); ++i) { for (int i = 2; i < context.argumentCount(); ++i) {
if (i > 2) { if (i > 2) {
writer.append(',').ws(); writer.append(',').ws();
} }
context.writeExpr(context.getArgument(i)); context.writeExpr(context.getArgument(i), Precedence.min());
}
writer.append(")");
if (context.getPrecedence().ordinal() >= Precedence.FUNCTION_CALL.ordinal()) {
writer.append(")");
} }
writer.append("))");
break; break;
case "wrap": case "wrap":
if (methodRef.getDescriptor().parameterType(0).isObject("java.lang.String")) { if (methodRef.getDescriptor().parameterType(0).isObject("java.lang.String")) {
@ -122,14 +127,19 @@ public class JSNativeGenerator implements Injector, DependencyPlugin, Generator
} }
} }
writer.append("$rt_ustr("); writer.append("$rt_ustr(");
context.writeExpr(context.getArgument(0)); context.writeExpr(context.getArgument(0), Precedence.min());
writer.append(")"); writer.append(")");
} else if (methodRef.getDescriptor().parameterType(0) == ValueType.BOOLEAN) { } else if (methodRef.getDescriptor().parameterType(0) == ValueType.BOOLEAN) {
writer.append("(!!("); if (context.getPrecedence().ordinal() >= Precedence.UNARY.ordinal()) {
context.writeExpr(context.getArgument(0)); writer.append("(");
writer.append("))"); }
writer.append("!!");
context.writeExpr(context.getArgument(0), Precedence.UNARY);
if (context.getPrecedence().ordinal() >= Precedence.UNARY.ordinal()) {
writer.append(")");
}
} else { } else {
context.writeExpr(context.getArgument(0)); context.writeExpr(context.getArgument(0), context.getPrecedence());
} }
break; break;
case "function": case "function":
@ -137,17 +147,22 @@ public class JSNativeGenerator implements Injector, DependencyPlugin, Generator
break; break;
case "unwrapString": case "unwrapString":
writer.append("$rt_str("); writer.append("$rt_str(");
context.writeExpr(context.getArgument(0)); context.writeExpr(context.getArgument(0), Precedence.min());
writer.append(")"); writer.append(")");
break; break;
case "unwrapBoolean": case "unwrapBoolean":
writer.append("("); if (context.getPrecedence().ordinal() >= Precedence.CONDITIONAL.ordinal()) {
context.writeExpr(context.getArgument(0)); writer.append("(");
writer.ws().append("?").ws().append("1").ws().append(":").ws().append("0").append(")"); }
context.writeExpr(context.getArgument(0), Precedence.CONDITIONAL.next());
writer.ws().append("?").ws().append("1").ws().append(":").ws().append("0");
if (context.getPrecedence().ordinal() >= Precedence.CONDITIONAL.ordinal()) {
writer.append(")");
}
break; break;
default: default:
if (methodRef.getName().startsWith("unwrap")) { if (methodRef.getName().startsWith("unwrap")) {
context.writeExpr(context.getArgument(0)); context.writeExpr(context.getArgument(0), context.getPrecedence());
} }
break; break;
} }
@ -199,7 +214,7 @@ public class JSNativeGenerator implements Injector, DependencyPlugin, Generator
String name = extractPropertyName(property); String name = extractPropertyName(property);
if (name == null) { if (name == null) {
writer.append('['); writer.append('[');
context.writeExpr(property); context.writeExpr(property, Precedence.min());
writer.append(']'); writer.append(']');
} else if (!isIdentifier(name)) { } else if (!isIdentifier(name)) {
writer.append("[\""); writer.append("[\"");

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.teavm.jso; package org.teavm.jso.test;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import org.junit.Test; import org.junit.Test;