Chromium Code Reviews| 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 interface TreeElements { | 5 interface TreeElements { |
| 6 Element operator[](Node node); | 6 Element operator[](Node node); |
| 7 Selector getSelector(Send send); | 7 Selector getSelector(Send send); |
| 8 DartType getType(TypeAnnotation annotation); | 8 DartType getType(TypeAnnotation annotation); |
| 9 bool isParameterChecked(Element element); | 9 bool isParameterChecked(Element element); |
| 10 } | 10 } |
| (...skipping 934 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 945 } | 945 } |
| 946 return arguments.toLink(); | 946 return arguments.toLink(); |
| 947 } | 947 } |
| 948 } | 948 } |
| 949 | 949 |
| 950 class ResolverVisitor extends CommonResolverVisitor<Element> { | 950 class ResolverVisitor extends CommonResolverVisitor<Element> { |
| 951 final TreeElementMapping mapping; | 951 final TreeElementMapping mapping; |
| 952 final Element enclosingElement; | 952 final Element enclosingElement; |
| 953 final TypeResolver typeResolver; | 953 final TypeResolver typeResolver; |
| 954 bool inInstanceContext; | 954 bool inInstanceContext; |
| 955 bool inCheckContext; | |
| 955 Scope scope; | 956 Scope scope; |
| 956 ClassElement currentClass; | 957 ClassElement currentClass; |
| 957 bool typeRequired = false; | 958 bool typeRequired = false; |
| 958 StatementScope statementScope; | 959 StatementScope statementScope; |
| 959 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION; | 960 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION; |
| 960 | 961 |
| 961 ResolverVisitor(Compiler compiler, Element element) | 962 ResolverVisitor(Compiler compiler, Element element) |
| 962 : this.mapping = new TreeElementMapping(), | 963 : this.mapping = new TreeElementMapping(), |
| 963 this.enclosingElement = element, | 964 this.enclosingElement = element, |
| 964 // When the element is a field, we are actually resolving its | 965 // When the element is a field, we are actually resolving its |
| 965 // initial value, which should not have access to instance | 966 // initial value, which should not have access to instance |
| 966 // fields. | 967 // fields. |
| 967 inInstanceContext = (element.isInstanceMember() && !element.isField()) | 968 inInstanceContext = (element.isInstanceMember() && !element.isField()) |
| 968 || element.isGenerativeConstructor(), | 969 || element.isGenerativeConstructor(), |
| 969 this.currentClass = element.isMember() ? | 970 this.currentClass = element.isMember() ? element.getEnclosingClass() |
| 970 element.getEnclosingClass() : | 971 : null, |
| 971 null, | |
| 972 this.statementScope = new StatementScope(), | 972 this.statementScope = new StatementScope(), |
| 973 typeResolver = new TypeResolver(compiler), | 973 typeResolver = new TypeResolver(compiler), |
| 974 scope = element.buildEnclosingScope(), | 974 scope = element.buildEnclosingScope(), |
| 975 inCheckContext = compiler.enableTypeAssertions, | |
| 975 super(compiler) { | 976 super(compiler) { |
| 976 } | 977 } |
| 977 | 978 |
| 978 Enqueuer get world => compiler.enqueuer.resolution; | 979 Enqueuer get world => compiler.enqueuer.resolution; |
| 979 | 980 |
| 980 Element lookup(Node node, SourceString name) { | 981 Element lookup(Node node, SourceString name) { |
| 981 Element result = scope.lookup(name); | 982 Element result = scope.lookup(name); |
| 982 if (!inInstanceContext && result != null && result.isInstanceMember()) { | 983 if (!inInstanceContext && result != null && result.isInstanceMember()) { |
| 983 error(node, MessageKind.NO_INSTANCE_AVAILABLE, [node]); | 984 error(node, MessageKind.NO_INSTANCE_AVAILABLE, [node]); |
| 984 } | 985 } |
| 985 return result; | 986 return result; |
| 986 } | 987 } |
| 987 | 988 |
| 988 // Create, or reuse an already created, statement element for a statement. | 989 // Create, or reuse an already created, statement element for a statement. |
| 989 TargetElement getOrCreateTargetElement(Node statement) { | 990 TargetElement getOrCreateTargetElement(Node statement) { |
| 990 TargetElement element = mapping[statement]; | 991 TargetElement element = mapping[statement]; |
| 991 if (element === null) { | 992 if (element === null) { |
| 992 element = new TargetElement(statement, | 993 element = new TargetElement(statement, |
| 993 statementScope.nestingLevel, | 994 statementScope.nestingLevel, |
| 994 enclosingElement); | 995 enclosingElement); |
| 995 mapping[statement] = element; | 996 mapping[statement] = element; |
| 996 } | 997 } |
| 997 return element; | 998 return element; |
| 998 } | 999 } |
| 999 | 1000 |
| 1001 doInCheckContext(action()) { | |
| 1002 bool wasInCheckContext = inCheckContext; | |
| 1003 inCheckContext = true; | |
| 1004 var result = action(); | |
| 1005 inCheckContext = wasInCheckContext; | |
| 1006 return result; | |
| 1007 } | |
| 1008 | |
| 1000 inStaticContext(action()) { | 1009 inStaticContext(action()) { |
| 1001 bool wasInstanceContext = inInstanceContext; | 1010 bool wasInstanceContext = inInstanceContext; |
| 1002 inInstanceContext = false; | 1011 inInstanceContext = false; |
| 1003 var result = action(); | 1012 var result = action(); |
| 1004 inInstanceContext = wasInstanceContext; | 1013 inInstanceContext = wasInstanceContext; |
| 1005 return result; | 1014 return result; |
| 1006 } | 1015 } |
| 1007 | 1016 |
| 1008 visitInStaticContext(Node node) { | 1017 visitInStaticContext(Node node) { |
| 1009 inStaticContext(() => visit(node)); | 1018 inStaticContext(() => visit(node)); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1030 // TODO(ahe): Improve error message. Need UX input. | 1039 // TODO(ahe): Improve error message. Need UX input. |
| 1031 error(node, MessageKind.GENERIC, ["is not an expression $element"]); | 1040 error(node, MessageKind.GENERIC, ["is not an expression $element"]); |
| 1032 } | 1041 } |
| 1033 } | 1042 } |
| 1034 return useElement(node, element); | 1043 return useElement(node, element); |
| 1035 } | 1044 } |
| 1036 } | 1045 } |
| 1037 | 1046 |
| 1038 Element visitTypeAnnotation(TypeAnnotation node) { | 1047 Element visitTypeAnnotation(TypeAnnotation node) { |
| 1039 DartType type = resolveTypeAnnotation(node); | 1048 DartType type = resolveTypeAnnotation(node); |
| 1040 if (type !== null) return type.element; | 1049 if (type !== null) { |
| 1050 if (inCheckContext) { | |
| 1051 compiler.enqueuer.resolution.registerIsCheck(type); | |
| 1052 } | |
| 1053 return type.element; | |
| 1054 } | |
| 1041 return null; | 1055 return null; |
| 1042 } | 1056 } |
| 1043 | 1057 |
| 1044 Element defineElement(Node node, Element element, | 1058 Element defineElement(Node node, Element element, |
| 1045 [bool doAddToScope = true]) { | 1059 [bool doAddToScope = true]) { |
| 1046 compiler.ensure(element !== null); | 1060 compiler.ensure(element !== null); |
| 1047 mapping[node] = element; | 1061 mapping[node] = element; |
| 1048 if (doAddToScope) { | 1062 if (doAddToScope) { |
| 1049 Element existing = scope.add(element); | 1063 Element existing = scope.add(element); |
| 1050 if (existing != element) { | 1064 if (existing != element) { |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1340 // TODO(karlklose): make this a runtime error. | 1354 // TODO(karlklose): make this a runtime error. |
| 1341 error(node.selector, MessageKind.CANNOT_RESOLVE_GETTER); | 1355 error(node.selector, MessageKind.CANNOT_RESOLVE_GETTER); |
| 1342 } | 1356 } |
| 1343 } | 1357 } |
| 1344 | 1358 |
| 1345 bool resolvedArguments = false; | 1359 bool resolvedArguments = false; |
| 1346 if (node.isOperator) { | 1360 if (node.isOperator) { |
| 1347 String operatorString = node.selector.asOperator().source.stringValue; | 1361 String operatorString = node.selector.asOperator().source.stringValue; |
| 1348 if (operatorString === 'is' || operatorString === 'as') { | 1362 if (operatorString === 'is' || operatorString === 'as') { |
| 1349 assert(node.arguments.tail.isEmpty()); | 1363 assert(node.arguments.tail.isEmpty()); |
| 1350 resolveTypeTest(node.arguments.head); | 1364 DartType type = resolveTypeTest(node.arguments.head); |
| 1365 if (type != null) { | |
| 1366 compiler.enqueuer.resolution.registerIsCheck(type); | |
| 1367 } | |
| 1351 resolvedArguments = true; | 1368 resolvedArguments = true; |
| 1352 } else if (operatorString === '?') { | 1369 } else if (operatorString === '?') { |
| 1353 Element parameter = mapping[node.receiver]; | 1370 Element parameter = mapping[node.receiver]; |
| 1354 if (parameter === null || parameter.kind !== ElementKind.PARAMETER) { | 1371 if (parameter === null || parameter.kind !== ElementKind.PARAMETER) { |
| 1355 error(node.receiver, MessageKind.PARAMETER_NAME_EXPECTED); | 1372 error(node.receiver, MessageKind.PARAMETER_NAME_EXPECTED); |
| 1356 } else { | 1373 } else { |
| 1357 mapping.checkedParameters.add(parameter); | 1374 mapping.checkedParameters.add(parameter); |
| 1358 } | 1375 } |
| 1359 } | 1376 } |
| 1360 } | 1377 } |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1601 DartType resolveTypeRequired(TypeAnnotation node) { | 1618 DartType resolveTypeRequired(TypeAnnotation node) { |
| 1602 bool old = typeRequired; | 1619 bool old = typeRequired; |
| 1603 typeRequired = true; | 1620 typeRequired = true; |
| 1604 DartType result = resolveTypeAnnotation(node); | 1621 DartType result = resolveTypeAnnotation(node); |
| 1605 typeRequired = old; | 1622 typeRequired = old; |
| 1606 return result; | 1623 return result; |
| 1607 } | 1624 } |
| 1608 | 1625 |
| 1609 DartType resolveTypeAnnotation(TypeAnnotation node) { | 1626 DartType resolveTypeAnnotation(TypeAnnotation node) { |
| 1610 Function report = typeRequired ? error : warning; | 1627 Function report = typeRequired ? error : warning; |
| 1611 return typeResolver.resolveTypeAnnotation(node, inScope: scope, | 1628 DartType type = typeResolver.resolveTypeAnnotation(node, inScope: scope, |
| 1612 onFailure: report, | 1629 onFailure: report, |
| 1613 whenResolved: useType); | 1630 whenResolved: useType); |
| 1631 if (compiler.enableTypeAssertions && type != null) { | |
|
ngeoffray
2012/09/05 12:50:40
use inCheckContext
karlklose
2012/09/06 11:04:02
Done.
| |
| 1632 compiler.enqueuer.resolution.registerIsCheck(type); | |
| 1633 } | |
| 1634 return type; | |
| 1614 } | 1635 } |
| 1615 | 1636 |
| 1616 visitModifiers(Modifiers node) { | 1637 visitModifiers(Modifiers node) { |
| 1617 // TODO(ngeoffray): Implement this. | 1638 // TODO(ngeoffray): Implement this. |
| 1618 unimplemented(node, 'modifiers'); | 1639 unimplemented(node, 'modifiers'); |
| 1619 } | 1640 } |
| 1620 | 1641 |
| 1621 visitLiteralList(LiteralList node) { | 1642 visitLiteralList(LiteralList node) { |
| 1622 NodeList arguments = node.typeArguments; | 1643 NodeList arguments = node.typeArguments; |
| 1623 if (arguments !== null) { | 1644 if (arguments !== null) { |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1878 error(modifier, MessageKind.PARAMETER_WITH_MODIFIER_IN_CATCH); | 1899 error(modifier, MessageKind.PARAMETER_WITH_MODIFIER_IN_CATCH); |
| 1879 } | 1900 } |
| 1880 TypeAnnotation type = declaration.type; | 1901 TypeAnnotation type = declaration.type; |
| 1881 if (type !== null) { | 1902 if (type !== null) { |
| 1882 error(type, MessageKind.PARAMETER_WITH_TYPE_IN_CATCH); | 1903 error(type, MessageKind.PARAMETER_WITH_TYPE_IN_CATCH); |
| 1883 } | 1904 } |
| 1884 } | 1905 } |
| 1885 } | 1906 } |
| 1886 | 1907 |
| 1887 Scope blockScope = new BlockScope(scope); | 1908 Scope blockScope = new BlockScope(scope); |
| 1888 visitIn(node.type, blockScope); | 1909 doInCheckContext(() => visitIn(node.type, blockScope)); |
| 1889 visitIn(node.formals, blockScope); | 1910 visitIn(node.formals, blockScope); |
| 1890 visitIn(node.block, blockScope); | 1911 visitIn(node.block, blockScope); |
| 1891 } | 1912 } |
| 1892 | 1913 |
| 1893 visitTypedef(Typedef node) { | 1914 visitTypedef(Typedef node) { |
| 1894 unimplemented(node, 'typedef'); | 1915 unimplemented(node, 'typedef'); |
| 1895 } | 1916 } |
| 1896 } | 1917 } |
| 1897 | 1918 |
| 1898 class TypeDefinitionVisitor extends CommonResolverVisitor<DartType> { | 1919 class TypeDefinitionVisitor extends CommonResolverVisitor<DartType> { |
| (...skipping 767 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2666 TopScope(LibraryElement library) : super(null, library); | 2687 TopScope(LibraryElement library) : super(null, library); |
| 2667 Element lookup(SourceString name) { | 2688 Element lookup(SourceString name) { |
| 2668 return library.find(name); | 2689 return library.find(name); |
| 2669 } | 2690 } |
| 2670 | 2691 |
| 2671 Element add(Element newElement) { | 2692 Element add(Element newElement) { |
| 2672 throw "Cannot add an element in the top scope"; | 2693 throw "Cannot add an element in the top scope"; |
| 2673 } | 2694 } |
| 2674 String toString() => '$element'; | 2695 String toString() => '$element'; |
| 2675 } | 2696 } |
| OLD | NEW |