| 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 Type getType(TypeAnnotation annotation); | 8 Type getType(TypeAnnotation annotation); |
| 9 } | 9 } |
| 10 | 10 |
| (...skipping 927 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 938 } | 938 } |
| 939 return arguments.toLink(); | 939 return arguments.toLink(); |
| 940 } | 940 } |
| 941 } | 941 } |
| 942 | 942 |
| 943 class ResolverVisitor extends CommonResolverVisitor<Element> { | 943 class ResolverVisitor extends CommonResolverVisitor<Element> { |
| 944 final TreeElementMapping mapping; | 944 final TreeElementMapping mapping; |
| 945 final Element enclosingElement; | 945 final Element enclosingElement; |
| 946 final TypeResolver typeResolver; | 946 final TypeResolver typeResolver; |
| 947 bool inInstanceContext; | 947 bool inInstanceContext; |
| 948 bool inCheckContext; |
| 948 Scope scope; | 949 Scope scope; |
| 949 ClassElement currentClass; | 950 ClassElement currentClass; |
| 950 bool typeRequired = false; | 951 bool typeRequired = false; |
| 951 StatementScope statementScope; | 952 StatementScope statementScope; |
| 952 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION; | 953 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION; |
| 953 | 954 |
| 954 ResolverVisitor(Compiler compiler, Element element) | 955 ResolverVisitor(Compiler compiler, Element element) |
| 955 : this.mapping = new TreeElementMapping(), | 956 : this.mapping = new TreeElementMapping(), |
| 956 this.enclosingElement = element, | 957 this.enclosingElement = element, |
| 957 // When the element is a field, we are actually resolving its | 958 // When the element is a field, we are actually resolving its |
| 958 // initial value, which should not have access to instance | 959 // initial value, which should not have access to instance |
| 959 // fields. | 960 // fields. |
| 960 inInstanceContext = (element.isInstanceMember() && !element.isField()) | 961 inInstanceContext = (element.isInstanceMember() && !element.isField()) |
| 961 || element.isGenerativeConstructor(), | 962 || element.isGenerativeConstructor(), |
| 962 this.currentClass = element.isMember() ? | 963 this.currentClass = element.isMember() ? element.getEnclosingClass() |
| 963 element.getEnclosingClass() : | 964 : null, |
| 964 null, | |
| 965 this.statementScope = new StatementScope(), | 965 this.statementScope = new StatementScope(), |
| 966 typeResolver = new TypeResolver(compiler), | 966 typeResolver = new TypeResolver(compiler), |
| 967 scope = element.buildEnclosingScope(), | 967 scope = element.buildEnclosingScope(), |
| 968 inCheckContext = compiler.enableTypeAssertions, |
| 968 super(compiler) { | 969 super(compiler) { |
| 969 } | 970 } |
| 970 | 971 |
| 971 Enqueuer get world => compiler.enqueuer.resolution; | 972 Enqueuer get world => compiler.enqueuer.resolution; |
| 972 | 973 |
| 973 Element lookup(Node node, SourceString name) { | 974 Element lookup(Node node, SourceString name) { |
| 974 Element result = scope.lookup(name); | 975 Element result = scope.lookup(name); |
| 975 if (!inInstanceContext && result != null && result.isInstanceMember()) { | 976 if (!inInstanceContext && result != null && result.isInstanceMember()) { |
| 976 error(node, MessageKind.NO_INSTANCE_AVAILABLE, [node]); | 977 error(node, MessageKind.NO_INSTANCE_AVAILABLE, [node]); |
| 977 } | 978 } |
| 978 return result; | 979 return result; |
| 979 } | 980 } |
| 980 | 981 |
| 981 // Create, or reuse an already created, statement element for a statement. | 982 // Create, or reuse an already created, statement element for a statement. |
| 982 TargetElement getOrCreateTargetElement(Node statement) { | 983 TargetElement getOrCreateTargetElement(Node statement) { |
| 983 TargetElement element = mapping[statement]; | 984 TargetElement element = mapping[statement]; |
| 984 if (element === null) { | 985 if (element === null) { |
| 985 element = new TargetElement(statement, | 986 element = new TargetElement(statement, |
| 986 statementScope.nestingLevel, | 987 statementScope.nestingLevel, |
| 987 enclosingElement); | 988 enclosingElement); |
| 988 mapping[statement] = element; | 989 mapping[statement] = element; |
| 989 } | 990 } |
| 990 return element; | 991 return element; |
| 991 } | 992 } |
| 992 | 993 |
| 994 doInCheckContext(action()) { |
| 995 bool wasInCheckContext = inCheckContext; |
| 996 inCheckContext = true; |
| 997 var result = action(); |
| 998 inCheckContext = wasInCheckContext; |
| 999 return result; |
| 1000 } |
| 1001 |
| 993 inStaticContext(action()) { | 1002 inStaticContext(action()) { |
| 994 bool wasInstanceContext = inInstanceContext; | 1003 bool wasInstanceContext = inInstanceContext; |
| 995 inInstanceContext = false; | 1004 inInstanceContext = false; |
| 996 var result = action(); | 1005 var result = action(); |
| 997 inInstanceContext = wasInstanceContext; | 1006 inInstanceContext = wasInstanceContext; |
| 998 return result; | 1007 return result; |
| 999 } | 1008 } |
| 1000 | 1009 |
| 1001 visitInStaticContext(Node node) { | 1010 visitInStaticContext(Node node) { |
| 1002 inStaticContext(() => visit(node)); | 1011 inStaticContext(() => visit(node)); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1023 // TODO(ahe): Improve error message. Need UX input. | 1032 // TODO(ahe): Improve error message. Need UX input. |
| 1024 error(node, MessageKind.GENERIC, ["is not an expression $element"]); | 1033 error(node, MessageKind.GENERIC, ["is not an expression $element"]); |
| 1025 } | 1034 } |
| 1026 } | 1035 } |
| 1027 return useElement(node, element); | 1036 return useElement(node, element); |
| 1028 } | 1037 } |
| 1029 } | 1038 } |
| 1030 | 1039 |
| 1031 Element visitTypeAnnotation(TypeAnnotation node) { | 1040 Element visitTypeAnnotation(TypeAnnotation node) { |
| 1032 Type type = resolveTypeAnnotation(node); | 1041 Type type = resolveTypeAnnotation(node); |
| 1033 if (type !== null) return type.element; | 1042 if (type !== null) { |
| 1043 if (inCheckContext) { |
| 1044 compiler.enqueuer.resolution.registerIsCheck(type); |
| 1045 } |
| 1046 return type.element; |
| 1047 } |
| 1034 return null; | 1048 return null; |
| 1035 } | 1049 } |
| 1036 | 1050 |
| 1037 Element defineElement(Node node, Element element, | 1051 Element defineElement(Node node, Element element, |
| 1038 [bool doAddToScope = true]) { | 1052 [bool doAddToScope = true]) { |
| 1039 compiler.ensure(element !== null); | 1053 compiler.ensure(element !== null); |
| 1040 mapping[node] = element; | 1054 mapping[node] = element; |
| 1041 if (doAddToScope) { | 1055 if (doAddToScope) { |
| 1042 Element existing = scope.add(element); | 1056 Element existing = scope.add(element); |
| 1043 if (existing != element) { | 1057 if (existing != element) { |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1329 && target.kind == ElementKind.ABSTRACT_FIELD) { | 1343 && target.kind == ElementKind.ABSTRACT_FIELD) { |
| 1330 AbstractFieldElement field = target; | 1344 AbstractFieldElement field = target; |
| 1331 target = field.getter; | 1345 target = field.getter; |
| 1332 } | 1346 } |
| 1333 | 1347 |
| 1334 bool resolvedArguments = false; | 1348 bool resolvedArguments = false; |
| 1335 if (node.isOperator) { | 1349 if (node.isOperator) { |
| 1336 String operatorString = node.selector.asOperator().source.stringValue; | 1350 String operatorString = node.selector.asOperator().source.stringValue; |
| 1337 if (operatorString === 'is' || operatorString === 'as') { | 1351 if (operatorString === 'is' || operatorString === 'as') { |
| 1338 assert(node.arguments.tail.isEmpty()); | 1352 assert(node.arguments.tail.isEmpty()); |
| 1339 resolveTypeTest(node.arguments.head); | 1353 Type type = resolveTypeTest(node.arguments.head); |
| 1354 if (type != null) { |
| 1355 compiler.enqueuer.resolution.registerIsCheck(type); |
| 1356 } |
| 1340 resolvedArguments = true; | 1357 resolvedArguments = true; |
| 1341 } | 1358 } |
| 1342 } | 1359 } |
| 1343 | 1360 |
| 1344 if (!resolvedArguments) { | 1361 if (!resolvedArguments) { |
| 1345 resolveArguments(node.argumentsNode); | 1362 resolveArguments(node.argumentsNode); |
| 1346 } | 1363 } |
| 1347 | 1364 |
| 1348 // If the selector is null, it means that we will not be generating | 1365 // If the selector is null, it means that we will not be generating |
| 1349 // code for this as a send. | 1366 // code for this as a send. |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1588 Type resolveTypeRequired(TypeAnnotation node) { | 1605 Type resolveTypeRequired(TypeAnnotation node) { |
| 1589 bool old = typeRequired; | 1606 bool old = typeRequired; |
| 1590 typeRequired = true; | 1607 typeRequired = true; |
| 1591 Type result = resolveTypeAnnotation(node); | 1608 Type result = resolveTypeAnnotation(node); |
| 1592 typeRequired = old; | 1609 typeRequired = old; |
| 1593 return result; | 1610 return result; |
| 1594 } | 1611 } |
| 1595 | 1612 |
| 1596 Type resolveTypeAnnotation(TypeAnnotation node) { | 1613 Type resolveTypeAnnotation(TypeAnnotation node) { |
| 1597 Function report = typeRequired ? error : warning; | 1614 Function report = typeRequired ? error : warning; |
| 1598 return typeResolver.resolveTypeAnnotation(node, inScope: scope, | 1615 Type type = typeResolver.resolveTypeAnnotation(node, inScope: scope, |
| 1599 onFailure: report, | 1616 onFailure: report, |
| 1600 whenResolved: useType); | 1617 whenResolved: useType); |
| 1618 if (compiler.enableTypeAssertions) { |
| 1619 compiler.enqueuer.resolution.registerIsCheck(type); |
| 1620 } |
| 1621 return type; |
| 1601 } | 1622 } |
| 1602 | 1623 |
| 1603 visitModifiers(Modifiers node) { | 1624 visitModifiers(Modifiers node) { |
| 1604 // TODO(ngeoffray): Implement this. | 1625 // TODO(ngeoffray): Implement this. |
| 1605 unimplemented(node, 'modifiers'); | 1626 unimplemented(node, 'modifiers'); |
| 1606 } | 1627 } |
| 1607 | 1628 |
| 1608 visitLiteralList(LiteralList node) { | 1629 visitLiteralList(LiteralList node) { |
| 1609 NodeList arguments = node.typeArguments; | 1630 NodeList arguments = node.typeArguments; |
| 1610 if (arguments !== null) { | 1631 if (arguments !== null) { |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1841 visitCatchBlock(CatchBlock node) { | 1862 visitCatchBlock(CatchBlock node) { |
| 1842 Scope blockScope = new BlockScope(scope); | 1863 Scope blockScope = new BlockScope(scope); |
| 1843 if (node.formals.isEmpty()) { | 1864 if (node.formals.isEmpty()) { |
| 1844 error(node, MessageKind.EMPTY_CATCH_DECLARATION); | 1865 error(node, MessageKind.EMPTY_CATCH_DECLARATION); |
| 1845 } else if (!node.formals.nodes.tail.isEmpty() | 1866 } else if (!node.formals.nodes.tail.isEmpty() |
| 1846 && !node.formals.nodes.tail.tail.isEmpty()) { | 1867 && !node.formals.nodes.tail.tail.isEmpty()) { |
| 1847 for (Node extra in node.formals.nodes.tail.tail) { | 1868 for (Node extra in node.formals.nodes.tail.tail) { |
| 1848 error(extra, MessageKind.EXTRA_CATCH_DECLARATION); | 1869 error(extra, MessageKind.EXTRA_CATCH_DECLARATION); |
| 1849 } | 1870 } |
| 1850 } | 1871 } |
| 1851 visitIn(node.type, blockScope); | 1872 if (node.type != null) { |
| 1852 visitIn(node.formals, blockScope); | 1873 doInCheckContext(() => visitIn(node.type, blockScope)); |
| 1874 visitIn(node.formals, blockScope); |
| 1875 } else { |
| 1876 // The type annotation for the exception type is on the first formal. |
| 1877 doInCheckContext(() => visitIn(node.formals.nodes.head, blockScope)); |
| 1878 if (!node.formals.nodes.tail.isEmpty()) { |
| 1879 visitIn(node.formals.nodes.tail.head, blockScope); |
| 1880 } |
| 1881 } |
| 1853 visitIn(node.block, blockScope); | 1882 visitIn(node.block, blockScope); |
| 1854 } | 1883 } |
| 1855 | 1884 |
| 1856 visitTypedef(Typedef node) { | 1885 visitTypedef(Typedef node) { |
| 1857 unimplemented(node, 'typedef'); | 1886 unimplemented(node, 'typedef'); |
| 1858 } | 1887 } |
| 1859 } | 1888 } |
| 1860 | 1889 |
| 1861 class TypeDefinitionVisitor extends CommonResolverVisitor<Type> { | 1890 class TypeDefinitionVisitor extends CommonResolverVisitor<Type> { |
| 1862 Scope scope; | 1891 Scope scope; |
| (...skipping 765 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2628 TopScope(LibraryElement library) : super(null, library); | 2657 TopScope(LibraryElement library) : super(null, library); |
| 2629 Element lookup(SourceString name) { | 2658 Element lookup(SourceString name) { |
| 2630 return library.find(name); | 2659 return library.find(name); |
| 2631 } | 2660 } |
| 2632 | 2661 |
| 2633 Element add(Element newElement) { | 2662 Element add(Element newElement) { |
| 2634 throw "Cannot add an element in the top scope"; | 2663 throw "Cannot add an element in the top scope"; |
| 2635 } | 2664 } |
| 2636 String toString() => '$element'; | 2665 String toString() => '$element'; |
| 2637 } | 2666 } |
| OLD | NEW |