| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of dart2js; | 5 part of dart2js; |
| 6 | 6 |
| 7 class TypeCheckerTask extends CompilerTask { | 7 class TypeCheckerTask extends CompilerTask { |
| 8 TypeCheckerTask(Compiler compiler) : super(compiler); | 8 TypeCheckerTask(Compiler compiler) : super(compiler); |
| 9 String get name => "Type checker"; | 9 String get name => "Type checker"; |
| 10 | 10 |
| (...skipping 1572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1583 | 1583 |
| 1584 // Executing a return statement return e; [...] It is a static type warning | 1584 // Executing a return statement return e; [...] It is a static type warning |
| 1585 // if the type of e may not be assigned to the declared return type of the | 1585 // if the type of e may not be assigned to the declared return type of the |
| 1586 // immediately enclosing function. | 1586 // immediately enclosing function. |
| 1587 if (expression != null) { | 1587 if (expression != null) { |
| 1588 DartType expressionType = analyze(expression); | 1588 DartType expressionType = analyze(expression); |
| 1589 if (executableContext.isGenerativeConstructor) { | 1589 if (executableContext.isGenerativeConstructor) { |
| 1590 // The resolver already emitted an error for this expression. | 1590 // The resolver already emitted an error for this expression. |
| 1591 } else { | 1591 } else { |
| 1592 if (currentAsyncMarker == AsyncMarker.ASYNC) { | 1592 if (currentAsyncMarker == AsyncMarker.ASYNC) { |
| 1593 expressionType = coreTypes.futureType(flatten(expressionType)); | 1593 expressionType = coreTypes.futureType(types.flatten(expressionType)); |
| 1594 } | 1594 } |
| 1595 if (expectedReturnType.isVoid && | 1595 if (expectedReturnType.isVoid && |
| 1596 !types.isAssignable(expressionType, const VoidType())) { | 1596 !types.isAssignable(expressionType, const VoidType())) { |
| 1597 reportTypeWarning(expression, MessageKind.RETURN_VALUE_IN_VOID); | 1597 reportTypeWarning(expression, MessageKind.RETURN_VALUE_IN_VOID); |
| 1598 } else { | 1598 } else { |
| 1599 checkAssignable(expression, expressionType, expectedReturnType); | 1599 checkAssignable(expression, expressionType, expectedReturnType); |
| 1600 } | 1600 } |
| 1601 } | 1601 } |
| 1602 | 1602 |
| 1603 } else if (!types.isAssignable(expectedReturnType, const VoidType())) { | 1603 } else if (!types.isAssignable(expectedReturnType, const VoidType())) { |
| 1604 // Let f be the function immediately enclosing a return statement of the | 1604 // Let f be the function immediately enclosing a return statement of the |
| 1605 // form 'return;' It is a static warning if both of the following | 1605 // form 'return;' It is a static warning if both of the following |
| 1606 // conditions hold: | 1606 // conditions hold: |
| 1607 // - f is not a generative constructor. | 1607 // - f is not a generative constructor. |
| 1608 // - The return type of f may not be assigned to void. | 1608 // - The return type of f may not be assigned to void. |
| 1609 reportTypeWarning(node, MessageKind.RETURN_NOTHING, | 1609 reportTypeWarning(node, MessageKind.RETURN_NOTHING, |
| 1610 {'returnType': expectedReturnType}); | 1610 {'returnType': expectedReturnType}); |
| 1611 } | 1611 } |
| 1612 return const StatementType(); | 1612 return const StatementType(); |
| 1613 } | 1613 } |
| 1614 | 1614 |
| 1615 DartType visitThrow(Throw node) { | 1615 DartType visitThrow(Throw node) { |
| 1616 // TODO(johnniwinther): Handle reachability. | 1616 // TODO(johnniwinther): Handle reachability. |
| 1617 analyze(node.expression); | 1617 analyze(node.expression); |
| 1618 return const DynamicType(); | 1618 return const DynamicType(); |
| 1619 } | 1619 } |
| 1620 | 1620 |
| 1621 /// Flatten [type] by recursively removing enclosing `Future` annotations. | |
| 1622 /// | |
| 1623 /// For instance: | |
| 1624 /// flatten(T) = T | |
| 1625 /// flatten(Future<T>) = T | |
| 1626 /// flatten(Future<Future<T>>) = T | |
| 1627 /// | |
| 1628 /// This method is used in the static typing of await and type checking of | |
| 1629 /// return. | |
| 1630 DartType flatten(DartType type) { | |
| 1631 if (type is InterfaceType) { | |
| 1632 InterfaceType futureType = type.asInstanceOf(compiler.futureClass); | |
| 1633 if (futureType != null) { | |
| 1634 return flatten(futureType.typeArguments.first); | |
| 1635 } | |
| 1636 } | |
| 1637 return type; | |
| 1638 } | |
| 1639 | |
| 1640 DartType visitAwait(Await node) { | 1621 DartType visitAwait(Await node) { |
| 1641 DartType expressionType = analyze(node.expression); | 1622 DartType expressionType = analyze(node.expression); |
| 1642 return flatten(expressionType); | 1623 return types.flatten(expressionType); |
| 1643 } | 1624 } |
| 1644 | 1625 |
| 1645 DartType visitYield(Yield node) { | 1626 DartType visitYield(Yield node) { |
| 1646 DartType resultType = analyze(node.expression); | 1627 DartType resultType = analyze(node.expression); |
| 1647 if (!node.hasStar) { | 1628 if (!node.hasStar) { |
| 1648 if (currentAsyncMarker.isAsync) { | 1629 if (currentAsyncMarker.isAsync) { |
| 1649 resultType = coreTypes.streamType(resultType); | 1630 resultType = coreTypes.streamType(resultType); |
| 1650 } else { | 1631 } else { |
| 1651 resultType = coreTypes.iterableType(resultType); | 1632 resultType = coreTypes.iterableType(resultType); |
| 1652 } | 1633 } |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1860 | 1841 |
| 1861 visitTypedef(Typedef node) { | 1842 visitTypedef(Typedef node) { |
| 1862 // Do not typecheck [Typedef] nodes. | 1843 // Do not typecheck [Typedef] nodes. |
| 1863 } | 1844 } |
| 1864 | 1845 |
| 1865 visitNode(Node node) { | 1846 visitNode(Node node) { |
| 1866 compiler.internalError(node, | 1847 compiler.internalError(node, |
| 1867 'Unexpected node ${node.getObjectDescription()} in the type checker.'); | 1848 'Unexpected node ${node.getObjectDescription()} in the type checker.'); |
| 1868 } | 1849 } |
| 1869 } | 1850 } |
| OLD | NEW |