Chromium Code Reviews| 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()); |