Index: compiler/java/com/google/dart/compiler/backend/js/GenerateJavascriptAST.java |
=================================================================== |
--- compiler/java/com/google/dart/compiler/backend/js/GenerateJavascriptAST.java (revision 650) |
+++ compiler/java/com/google/dart/compiler/backend/js/GenerateJavascriptAST.java (working copy) |
@@ -1669,8 +1669,9 @@ |
int numParams = params.size(); |
for (int i = 0; i < numParams; ++i) { |
JsNameRef jsParam = jsParams.get(i).getName().makeRef(); |
- JsExpression expr = rtt.addTypeCheck(getCurrentClass(), jsParam, |
- typeOf(params.get(i).getTypeNode()), null, params.get(i)); |
+ DartParameter param = params.get(i); |
+ Type paramType = param.getSymbol().getType(); |
+ JsExpression expr = rtt.addTypeCheck(getCurrentClass(), jsParam, paramType, null, param); |
fabiomfv
2011/10/26 14:43:25
assuming this change is basically refactoring?
jat
2011/10/31 20:16:14
No, this is what actually fixes issue 6. The prob
|
if (expr != jsParam) { |
// if the expression was returned unchanged, omit the check |
checks.add(new JsExprStmt(expr)); |
@@ -1843,6 +1844,8 @@ |
@Override |
public JsNode visitIfStatement(DartIfStatement x) { |
JsExpression jsCondition = (JsExpression) generate(x.getCondition()); |
+ jsCondition = rtt.addTypeCheck(getCurrentClass(), jsCondition, typeProvider.getBoolType(), |
+ x.getCondition().getType(), x); |
JsStatement jsThenStmt = (JsStatement) generate(x.getThenStatement()); |
JsStatement jsElseStmt = null; |
if (x.getElseStatement() != null) { |
@@ -1877,6 +1880,8 @@ |
@Override |
public JsNode visitWhileStatement(DartWhileStatement x) { |
JsExpression condition = (JsExpression) generate(x.getCondition()); |
+ condition = rtt.addTypeCheck(getCurrentClass(), condition, typeProvider.getBoolType(), |
+ x.getCondition().getType(), x); |
JsBlock body = (JsBlock) generate(x.getBody()); |
return new JsWhile(condition, body).setSourceRef(x); |
} |
@@ -1884,6 +1889,8 @@ |
@Override |
public JsNode visitDoWhileStatement(DartDoWhileStatement x) { |
JsExpression condition = (JsExpression) generate(x.getCondition()); |
+ condition = rtt.addTypeCheck(getCurrentClass(), condition, typeProvider.getBoolType(), |
+ x.getCondition().getType(), x); |
JsBlock body = (JsBlock) generate(x.getBody()); |
return new JsDoWhile(condition, body).setSourceRef(x); |
} |
@@ -1895,7 +1902,10 @@ |
JsFor jsFor = new JsFor().setSourceRef(x); |
if (x.getCondition() != null) { |
- jsFor.setCondition((JsExpression) generate(x.getCondition())); |
+ JsExpression condExpr = (JsExpression) generate(x.getCondition()); |
+ condExpr = rtt.addTypeCheck(getCurrentClass(), condExpr, typeProvider.getBoolType(), |
+ x.getCondition().getType(), x); |
+ jsFor.setCondition(condExpr); |
} |
if (x.getIncrement() != null) { |
jsFor.setIncrExpr((JsExpression) generate(x.getIncrement())); |
@@ -1944,15 +1954,33 @@ |
DartFunction function = functionStack.peek(); |
if (function != null) { |
// NOTE: FunctionExpressionInliner might be leaving return statements around |
- DartTypeNode returnType = function.getReturnTypeNode(); |
- expr = rtt.addTypeCheck(getCurrentClass(), expr, typeOf(returnType), |
- returnValue.getType(), x); |
+ DartTypeNode returnTypeNode = function.getReturnTypeNode(); |
+ Type returnType = null; |
+ if (returnTypeNode == null) { |
+ // check for factory methods, which return the type of their name |
+ returnType = getFactoryReturnType(function); |
+ } |
+ if (returnType == null) { |
+ returnType = typeOf(returnTypeNode); |
+ } |
+ expr = rtt.addTypeCheck(getCurrentClass(), expr, returnType, returnValue.getType(), x); |
} |
jsRet.setExpr(expr); |
} |
return jsRet.setSourceRef(x); |
} |
+ /** |
+ * Get the return type of a factory method. |
+ * |
+ * @param function |
+ * @return {@link Type} instance or null if not a factory method or otherwise unavailable |
+ */ |
+ private Type getFactoryReturnType(DartFunction function) { |
+ // TODO: implement |
+ return null; |
+ } |
+ |
@Override |
public JsNode visitTryStatement(DartTryStatement x) { |
JsTry jsTry = new JsTry(); |
@@ -2177,6 +2205,8 @@ |
@Override |
public JsNode visitConditional(DartConditional x) { |
JsExpression testExpr = (JsExpression) generate(x.getCondition()); |
+ testExpr = rtt.addTypeCheck(getCurrentClass(), testExpr, typeProvider.getBoolType(), |
+ x.getCondition().getType(), x); |
JsExpression thenExpr = (JsExpression) generate(x.getThenExpression()); |
JsExpression elseExpr = (JsExpression) generate(x.getElseExpression()); |
return new JsConditional(testExpr, thenExpr, elseExpr).setSourceRef(x); |
@@ -2192,10 +2222,11 @@ |
return generateInstanceOfComparison(x); |
} |
+ DartExpression arg1 = x.getArg1(); |
DartExpression arg2 = x.getArg2(); |
JsExpression rhs = (JsExpression) generate(arg2); |
if (operator == Token.ASSIGN) { |
- return x.getArg1().accept(new Assignment(x, rhs, arg2.getType())); |
+ return arg1.accept(new Assignment(x, rhs, arg2.getType())); |
} |
assert !operator.isUserDefinableOperator() || !operator.isAssignmentOperator() : x; |
@@ -2208,8 +2239,12 @@ |
skipShim = optStrategy.canSkipOperatorShim(x); |
} |
- JsExpression lhs = (JsExpression) generate(x.getArg1()); |
+ JsExpression lhs = (JsExpression) generate(arg1); |
Token op = x.getOperator(); |
+ |
+ lhs = rtt.addTypeCheck(getCurrentClass(), lhs, getRequiredType(op), arg1.getType(), arg1); |
+ rhs = rtt.addTypeCheck(getCurrentClass(), rhs, getRequiredType(op), arg2.getType(), arg2); |
+ |
if (skipShim) { |
if (op.isEqualityOperator()) { |
op = mapToStrictEquals(op); |
@@ -2220,7 +2255,7 @@ |
op = mapToNonStrictEquals(op); |
rhs = nulle(); |
} |
- if (x.getArg1() instanceof DartNullLiteral) { |
+ if (arg1 instanceof DartNullLiteral) { |
JsExpression tmp = lhs; |
lhs = rhs; |
rhs = tmp; |
@@ -2237,6 +2272,25 @@ |
} |
} |
+ /** |
+ * Return a type which an operator requires for its operands. |
+ * |
+ * @param op operator |
+ * @return a {@link Type} instance, which will be {@code null} if there are |
+ * no restrictions |
+ */ |
+ private Type getRequiredType(Token op) { |
+ switch (op) { |
+ case NOT: |
fabiomfv
2011/10/26 14:43:25
we probably dont need NOT since we dont call getRe
jat
2011/10/31 20:16:14
Done.
|
+ case OR: |
+ case AND: |
+ return typeProvider.getBoolType(); |
+ // TODO: other operators? |
+ default: |
+ return null; |
+ } |
+ } |
+ |
private Type getTypeOfIdentifier(DartIdentifier ident) { |
Element element = ident.getReferencedElement(); |
DartTypeNode typeNode = null; |
@@ -2374,6 +2428,8 @@ |
break; |
case NOT: |
jsUnaryOperator = JsUnaryOperator.NOT; |
+ arg = rtt.addTypeCheck(getCurrentClass(), arg, typeProvider.getBoolType(), |
+ x.getArg().getType(), x.getArg()); |
break; |
default: |
throw new AssertionError("Unexpected unary operator " + operator.name()); |