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 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
423 } else { | 423 } else { |
424 lastSeenNode = node; | 424 lastSeenNode = node; |
425 } | 425 } |
426 bool previouslyInitializer = analyzingInitializer; | 426 bool previouslyInitializer = analyzingInitializer; |
427 analyzingInitializer = inInitializer; | 427 analyzingInitializer = inInitializer; |
428 DartType result = node.accept(this); | 428 DartType result = node.accept(this); |
429 analyzingInitializer = previouslyInitializer; | 429 analyzingInitializer = previouslyInitializer; |
430 if (result == null) { | 430 if (result == null) { |
431 compiler.internalError(node, 'Type is null.'); | 431 compiler.internalError(node, 'Type is null.'); |
432 } | 432 } |
433 return result; | 433 return _record(node, result); |
434 } | 434 } |
435 | 435 |
436 void checkTypePromotion(Node node, TypePromotion typePromotion, | 436 void checkTypePromotion(Node node, TypePromotion typePromotion, |
437 {bool checkAccesses: false}) { | 437 {bool checkAccesses: false}) { |
438 VariableElement variable = typePromotion.variable; | 438 VariableElement variable = typePromotion.variable; |
439 String variableName = variable.name; | 439 String variableName = variable.name; |
440 List<Node> potentialMutationsIn = | 440 List<Node> potentialMutationsIn = |
441 elements.getPotentialMutationsIn(node, variable); | 441 elements.getPotentialMutationsIn(node, variable); |
442 if (!potentialMutationsIn.isEmpty) { | 442 if (!potentialMutationsIn.isEmpty) { |
443 typePromotion.addHint(typePromotion.node, | 443 typePromotion.addHint(typePromotion.node, |
(...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1108 types.isMoreSpecific(shownTypeGeneric, knownType)) { | 1108 types.isMoreSpecific(shownTypeGeneric, knownType)) { |
1109 // This should be the case but we double-check. | 1109 // This should be the case but we double-check. |
1110 // TODO(johnniwinther): Ensure that we don't suggest malbounded types. | 1110 // TODO(johnniwinther): Ensure that we don't suggest malbounded types. |
1111 return shownTypeGeneric; | 1111 return shownTypeGeneric; |
1112 } | 1112 } |
1113 } | 1113 } |
1114 return null; | 1114 return null; |
1115 | 1115 |
1116 } | 1116 } |
1117 | 1117 |
| 1118 static bool _fyiShown = false; |
| 1119 DartType _record(Node node, DartType type) { |
| 1120 if (node is! Expression) return type; |
| 1121 if (compiler.computeAnalysisStats && |
| 1122 executableContext != null && |
| 1123 // TODO(sigmund): enable also in core libs. |
| 1124 !executableContext.library.isPlatformLibrary && !type.isDynamic) { |
| 1125 if (!_fyiShown) { |
| 1126 print('FYI computeAnalysisStats is on: caching types of expressions'); |
| 1127 _fyiShown = true; |
| 1128 } |
| 1129 elements.typesCache[node] = type; |
| 1130 } |
| 1131 return type; |
| 1132 } |
| 1133 |
1118 DartType visitSend(Send node) { | 1134 DartType visitSend(Send node) { |
1119 if (elements.isAssert(node)) { | 1135 if (elements.isAssert(node)) { |
1120 return analyzeInvocation(node, const AssertAccess()); | 1136 return analyzeInvocation(node, const AssertAccess()); |
1121 } | 1137 } |
1122 | 1138 |
1123 Element element = elements[node]; | 1139 Element element = elements[node]; |
1124 | 1140 |
1125 if (element != null && element.isConstructor) { | 1141 if (element != null && element.isConstructor) { |
1126 DartType receiverType; | 1142 DartType receiverType; |
1127 if (node.receiver != null) { | 1143 if (node.receiver != null) { |
(...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1682 } | 1698 } |
1683 for (Link<Node> link = node.definitions.nodes; !link.isEmpty; | 1699 for (Link<Node> link = node.definitions.nodes; !link.isEmpty; |
1684 link = link.tail) { | 1700 link = link.tail) { |
1685 Node definition = link.head; | 1701 Node definition = link.head; |
1686 invariant(definition, definition is Identifier || definition is SendSet, | 1702 invariant(definition, definition is Identifier || definition is SendSet, |
1687 message: 'expected identifier or initialization'); | 1703 message: 'expected identifier or initialization'); |
1688 if (definition is SendSet) { | 1704 if (definition is SendSet) { |
1689 SendSet initialization = definition; | 1705 SendSet initialization = definition; |
1690 DartType initializer = analyzeNonVoid(initialization.arguments.head); | 1706 DartType initializer = analyzeNonVoid(initialization.arguments.head); |
1691 checkAssignable(initialization.assignmentOperator, initializer, type); | 1707 checkAssignable(initialization.assignmentOperator, initializer, type); |
| 1708 // TODO(sigmund): explore inferring a type for `var` using the RHS (like |
| 1709 // DDC does), for example: |
| 1710 // if (node.type == null && node.modifiers.isVar && |
| 1711 // !initializer.isDynamic) { |
| 1712 // var variable = elements[definition]; |
| 1713 // if (variable != null) { |
| 1714 // var typePromotion = new TypePromotion( |
| 1715 // node, variable, initializer); |
| 1716 // registerKnownTypePromotion(typePromotion); |
| 1717 // } |
| 1718 // } |
1692 } | 1719 } |
1693 } | 1720 } |
1694 return const StatementType(); | 1721 return const StatementType(); |
1695 } | 1722 } |
1696 | 1723 |
1697 DartType visitWhile(While node) { | 1724 DartType visitWhile(While node) { |
1698 checkCondition(node.condition); | 1725 checkCondition(node.condition); |
1699 analyze(node.body); | 1726 analyze(node.body); |
1700 return const StatementType(); | 1727 return const StatementType(); |
1701 } | 1728 } |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1872 | 1899 |
1873 visitTypedef(Typedef node) { | 1900 visitTypedef(Typedef node) { |
1874 // Do not typecheck [Typedef] nodes. | 1901 // Do not typecheck [Typedef] nodes. |
1875 } | 1902 } |
1876 | 1903 |
1877 visitNode(Node node) { | 1904 visitNode(Node node) { |
1878 compiler.internalError(node, | 1905 compiler.internalError(node, |
1879 'Unexpected node ${node.getObjectDescription()} in the type checker.'); | 1906 'Unexpected node ${node.getObjectDescription()} in the type checker.'); |
1880 } | 1907 } |
1881 } | 1908 } |
OLD | NEW |