| 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 resolution; | 5 part of resolution; |
| 6 | 6 |
| 7 abstract class TreeElements { | 7 abstract class TreeElements { |
| 8 Element get currentElement; |
| 9 Set<Node> get superUses; |
| 10 |
| 11 /// A set of additional dependencies. See [registerDependency] below. |
| 12 Set<Element> get otherDependencies; |
| 13 |
| 8 Element operator[](Node node); | 14 Element operator[](Node node); |
| 9 Selector getSelector(Send send); | 15 Selector getSelector(Send send); |
| 10 Selector getGetterSelectorInComplexSendSet(SendSet node); | 16 Selector getGetterSelectorInComplexSendSet(SendSet node); |
| 11 Selector getOperatorSelectorInComplexSendSet(SendSet node); | 17 Selector getOperatorSelectorInComplexSendSet(SendSet node); |
| 12 Selector getIteratorSelector(ForIn node); | 18 Selector getIteratorSelector(ForIn node); |
| 13 Selector getMoveNextSelector(ForIn node); | 19 Selector getMoveNextSelector(ForIn node); |
| 14 Selector getCurrentSelector(ForIn node); | 20 Selector getCurrentSelector(ForIn node); |
| 15 DartType getType(Node node); | 21 DartType getType(Node node); |
| 16 bool isParameterChecked(Element element); | 22 bool isParameterChecked(Element element); |
| 17 Set<Node> get superUses; | 23 |
| 24 /// Register additional dependencies required by [currentElement]. |
| 25 /// For example, elements that are used by a backend. |
| 26 void registerDependency(Element element); |
| 18 } | 27 } |
| 19 | 28 |
| 20 class TreeElementMapping implements TreeElements { | 29 class TreeElementMapping implements TreeElements { |
| 21 final Element currentElement; | 30 final Element currentElement; |
| 22 final Map<Spannable, Selector> selectors = | 31 final Map<Spannable, Selector> selectors = |
| 23 new LinkedHashMap<Spannable, Selector>(); | 32 new LinkedHashMap<Spannable, Selector>(); |
| 24 final Map<Node, DartType> types = new LinkedHashMap<Node, DartType>(); | 33 final Map<Node, DartType> types = new LinkedHashMap<Node, DartType>(); |
| 25 final Set<Element> checkedParameters = new Set<Element>(); | 34 final Set<Element> checkedParameters = new LinkedHashSet<Element>(); |
| 26 final Set<Node> superUses = new Set<Node>(); | 35 final Set<Node> superUses = new LinkedHashSet<Node>(); |
| 36 final Set<Element> otherDependencies = new LinkedHashSet<Element>(); |
| 37 final int hashCode = ++hashCodeCounter; |
| 38 static int hashCodeCounter = 0; |
| 27 | 39 |
| 28 TreeElementMapping(this.currentElement); | 40 TreeElementMapping(this.currentElement); |
| 29 | 41 |
| 30 operator []=(Node node, Element element) { | 42 operator []=(Node node, Element element) { |
| 31 assert(invariant(node, () { | 43 assert(invariant(node, () { |
| 32 if (node is FunctionExpression) { | 44 if (node is FunctionExpression) { |
| 33 return !node.modifiers.isExternal(); | 45 return !node.modifiers.isExternal(); |
| 34 } | 46 } |
| 35 return true; | 47 return true; |
| 36 })); | 48 })); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 selectors[node.inToken] = selector; | 123 selectors[node.inToken] = selector; |
| 112 } | 124 } |
| 113 | 125 |
| 114 Selector getCurrentSelector(ForIn node) { | 126 Selector getCurrentSelector(ForIn node) { |
| 115 return selectors[node.inToken]; | 127 return selectors[node.inToken]; |
| 116 } | 128 } |
| 117 | 129 |
| 118 bool isParameterChecked(Element element) { | 130 bool isParameterChecked(Element element) { |
| 119 return checkedParameters.contains(element); | 131 return checkedParameters.contains(element); |
| 120 } | 132 } |
| 133 |
| 134 void registerDependency(Element element) { |
| 135 otherDependencies.add(element); |
| 136 } |
| 137 |
| 138 String toString() => 'TreeElementMapping($currentElement)'; |
| 121 } | 139 } |
| 122 | 140 |
| 123 class ResolverTask extends CompilerTask { | 141 class ResolverTask extends CompilerTask { |
| 124 ResolverTask(Compiler compiler) : super(compiler); | 142 ResolverTask(Compiler compiler) : super(compiler); |
| 125 | 143 |
| 126 String get name => 'Resolver'; | 144 String get name => 'Resolver'; |
| 127 | 145 |
| 128 TreeElements resolve(Element element) { | 146 TreeElements resolve(Element element) { |
| 129 return measure(() { | 147 return measure(() { |
| 130 if (Elements.isErroneousElement(element)) return null; | 148 if (Elements.isErroneousElement(element)) return null; |
| (...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 437 } | 455 } |
| 438 ResolverVisitor visitor = visitorFor(element); | 456 ResolverVisitor visitor = visitorFor(element); |
| 439 // TODO(johnniwinther): Avoid analyzing initializers if | 457 // TODO(johnniwinther): Avoid analyzing initializers if |
| 440 // [Compiler.analyzeSignaturesOnly] is set. | 458 // [Compiler.analyzeSignaturesOnly] is set. |
| 441 initializerDo(tree, visitor.visit); | 459 initializerDo(tree, visitor.visit); |
| 442 | 460 |
| 443 if (Elements.isStaticOrTopLevelField(element)) { | 461 if (Elements.isStaticOrTopLevelField(element)) { |
| 444 if (tree.asSendSet() != null) { | 462 if (tree.asSendSet() != null) { |
| 445 // TODO(ngeoffray): We could do better here by using the | 463 // TODO(ngeoffray): We could do better here by using the |
| 446 // constant handler to figure out if it's a lazy field or not. | 464 // constant handler to figure out if it's a lazy field or not. |
| 447 compiler.backend.registerLazyField(); | 465 compiler.backend.registerLazyField(visitor.mapping); |
| 448 } | 466 } |
| 449 } | 467 } |
| 450 | 468 |
| 451 // Perform various checks as side effect of "computing" the type. | 469 // Perform various checks as side effect of "computing" the type. |
| 452 element.computeType(compiler); | 470 element.computeType(compiler); |
| 453 | 471 |
| 454 return visitor.mapping; | 472 return visitor.mapping; |
| 455 } | 473 } |
| 456 | 474 |
| 457 TreeElements resolveParameter(Element element) { | 475 TreeElements resolveParameter(Element element) { |
| (...skipping 1077 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1535 new TypedefType.userProvidedBadType(typdef, arguments.toLink())); | 1553 new TypedefType.userProvidedBadType(typdef, arguments.toLink())); |
| 1536 } else { | 1554 } else { |
| 1537 if (arguments.isEmpty) { | 1555 if (arguments.isEmpty) { |
| 1538 type = typdef.rawType; | 1556 type = typdef.rawType; |
| 1539 } else { | 1557 } else { |
| 1540 type = new TypedefType(typdef, arguments.toLink()); | 1558 type = new TypedefType(typdef, arguments.toLink()); |
| 1541 } | 1559 } |
| 1542 } | 1560 } |
| 1543 } else if (element.isTypeVariable()) { | 1561 } else if (element.isTypeVariable()) { |
| 1544 if (enclosingElement.isInStaticMember()) { | 1562 if (enclosingElement.isInStaticMember()) { |
| 1545 compiler.backend.registerThrowRuntimeError(); | 1563 compiler.backend.registerThrowRuntimeError( |
| 1564 // TODO(ahe): Get the TreeElements for the current element. |
| 1565 compiler.globalDependencies); |
| 1546 compiler.reportWarning(node, | 1566 compiler.reportWarning(node, |
| 1547 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER.message( | 1567 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER.message( |
| 1548 {'typeVariableName': node})); | 1568 {'typeVariableName': node})); |
| 1549 type = new MalformedType( | 1569 type = new MalformedType( |
| 1550 new ErroneousElementX( | 1570 new ErroneousElementX( |
| 1551 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, | 1571 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, |
| 1552 {'typeVariableName': node}, | 1572 {'typeVariableName': node}, |
| 1553 typeName.source, enclosingElement), | 1573 typeName.source, enclosingElement), |
| 1554 element.computeType(compiler)); | 1574 element.computeType(compiler)); |
| 1555 } else { | 1575 } else { |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1726 error(node, MessageKind.INVALID_USE_OF_SUPER); | 1746 error(node, MessageKind.INVALID_USE_OF_SUPER); |
| 1727 } | 1747 } |
| 1728 return null; | 1748 return null; |
| 1729 } else { | 1749 } else { |
| 1730 Element element = lookup(node, node.source); | 1750 Element element = lookup(node, node.source); |
| 1731 if (element == null) { | 1751 if (element == null) { |
| 1732 if (!inInstanceContext) { | 1752 if (!inInstanceContext) { |
| 1733 element = warnAndCreateErroneousElement(node, node.source, | 1753 element = warnAndCreateErroneousElement(node, node.source, |
| 1734 MessageKind.CANNOT_RESOLVE, | 1754 MessageKind.CANNOT_RESOLVE, |
| 1735 {'name': node}); | 1755 {'name': node}); |
| 1736 compiler.backend.registerThrowNoSuchMethod(); | 1756 compiler.backend.registerThrowNoSuchMethod(mapping); |
| 1737 } | 1757 } |
| 1738 } else if (element.isErroneous()) { | 1758 } else if (element.isErroneous()) { |
| 1739 // Use the erroneous element. | 1759 // Use the erroneous element. |
| 1740 } else { | 1760 } else { |
| 1741 if ((element.kind.category & allowedCategory) == 0) { | 1761 if ((element.kind.category & allowedCategory) == 0) { |
| 1742 // TODO(ahe): Improve error message. Need UX input. | 1762 // TODO(ahe): Improve error message. Need UX input. |
| 1743 error(node, MessageKind.GENERIC, | 1763 error(node, MessageKind.GENERIC, |
| 1744 {'text': "is not an expression $element"}); | 1764 {'text': "is not an expression $element"}); |
| 1745 } | 1765 } |
| 1746 } | 1766 } |
| 1747 if (!Elements.isUnresolved(element) && element.isClass()) { | 1767 if (!Elements.isUnresolved(element) && element.isClass()) { |
| 1748 ClassElement classElement = element; | 1768 ClassElement classElement = element; |
| 1749 classElement.ensureResolved(compiler); | 1769 classElement.ensureResolved(compiler); |
| 1750 } | 1770 } |
| 1751 return useElement(node, element); | 1771 return useElement(node, element); |
| 1752 } | 1772 } |
| 1753 } | 1773 } |
| 1754 | 1774 |
| 1755 Element visitTypeAnnotation(TypeAnnotation node) { | 1775 Element visitTypeAnnotation(TypeAnnotation node) { |
| 1756 DartType type = resolveTypeAnnotation(node); | 1776 DartType type = resolveTypeAnnotation(node); |
| 1757 if (type != null) { | 1777 if (type != null) { |
| 1758 if (inCheckContext) { | 1778 if (inCheckContext) { |
| 1759 compiler.enqueuer.resolution.registerIsCheck(type); | 1779 compiler.enqueuer.resolution.registerIsCheck(type, mapping); |
| 1760 } | 1780 } |
| 1761 return type.element; | 1781 return type.element; |
| 1762 } | 1782 } |
| 1763 return null; | 1783 return null; |
| 1764 } | 1784 } |
| 1765 | 1785 |
| 1766 Element defineElement(Node node, Element element, | 1786 Element defineElement(Node node, Element element, |
| 1767 {bool doAddToScope: true}) { | 1787 {bool doAddToScope: true}) { |
| 1768 compiler.ensure(element != null); | 1788 compiler.ensure(element != null); |
| 1769 mapping[node] = element; | 1789 mapping[node] = element; |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1935 enclosingElement = function; | 1955 enclosingElement = function; |
| 1936 // Run the body in a fresh statement scope. | 1956 // Run the body in a fresh statement scope. |
| 1937 StatementScope oldStatementScope = statementScope; | 1957 StatementScope oldStatementScope = statementScope; |
| 1938 statementScope = new StatementScope(); | 1958 statementScope = new StatementScope(); |
| 1939 visit(node.body); | 1959 visit(node.body); |
| 1940 statementScope = oldStatementScope; | 1960 statementScope = oldStatementScope; |
| 1941 | 1961 |
| 1942 scope = oldScope; | 1962 scope = oldScope; |
| 1943 enclosingElement = previousEnclosingElement; | 1963 enclosingElement = previousEnclosingElement; |
| 1944 | 1964 |
| 1945 world.registerInstantiatedClass(compiler.functionClass); | 1965 world.registerInstantiatedClass(compiler.functionClass, mapping); |
| 1946 } | 1966 } |
| 1947 | 1967 |
| 1948 visitIf(If node) { | 1968 visitIf(If node) { |
| 1949 visit(node.condition); | 1969 visit(node.condition); |
| 1950 visit(node.thenPart); | 1970 visit(node.thenPart); |
| 1951 visit(node.elsePart); | 1971 visit(node.elsePart); |
| 1952 } | 1972 } |
| 1953 | 1973 |
| 1954 static bool isLogicalOperator(Identifier op) { | 1974 static bool isLogicalOperator(Identifier op) { |
| 1955 String str = op.source.stringValue; | 1975 String str = op.source.stringValue; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2013 // [target] may be null which means invoking noSuchMethod on | 2033 // [target] may be null which means invoking noSuchMethod on |
| 2014 // super. | 2034 // super. |
| 2015 if (target == null) { | 2035 if (target == null) { |
| 2016 target = warnAndCreateErroneousElement( | 2036 target = warnAndCreateErroneousElement( |
| 2017 node, name, MessageKind.NO_SUCH_SUPER_MEMBER, | 2037 node, name, MessageKind.NO_SUCH_SUPER_MEMBER, |
| 2018 {'className': currentClass, 'memberName': name}); | 2038 {'className': currentClass, 'memberName': name}); |
| 2019 // We still need to register the invocation, because we might | 2039 // We still need to register the invocation, because we might |
| 2020 // call [:super.noSuchMethod:] that does a | 2040 // call [:super.noSuchMethod:] that does a |
| 2021 // [:InvocationMirror.invokeOn:]. | 2041 // [:InvocationMirror.invokeOn:]. |
| 2022 world.registerDynamicInvocation(selector.name, selector); | 2042 world.registerDynamicInvocation(selector.name, selector); |
| 2023 compiler.backend.registerSuperNoSuchMethod(); | 2043 compiler.backend.registerSuperNoSuchMethod(mapping); |
| 2024 } | 2044 } |
| 2025 } else if (Elements.isUnresolved(resolvedReceiver)) { | 2045 } else if (Elements.isUnresolved(resolvedReceiver)) { |
| 2026 return null; | 2046 return null; |
| 2027 } else if (resolvedReceiver.isClass()) { | 2047 } else if (resolvedReceiver.isClass()) { |
| 2028 ClassElement receiverClass = resolvedReceiver; | 2048 ClassElement receiverClass = resolvedReceiver; |
| 2029 receiverClass.ensureResolved(compiler); | 2049 receiverClass.ensureResolved(compiler); |
| 2030 if (node.isOperator) { | 2050 if (node.isOperator) { |
| 2031 // When the resolved receiver is a class, we can have two cases: | 2051 // When the resolved receiver is a class, we can have two cases: |
| 2032 // 1) a static send: C.foo, or | 2052 // 1) a static send: C.foo, or |
| 2033 // 2) an operator send, where the receiver is a class literal: 'C + 1'. | 2053 // 2) an operator send, where the receiver is a class literal: 'C + 1'. |
| 2034 // The following code that looks up the selector on the resolved | 2054 // The following code that looks up the selector on the resolved |
| 2035 // receiver will treat the second as the invocation of a static operator | 2055 // receiver will treat the second as the invocation of a static operator |
| 2036 // if the resolved receiver is not null. | 2056 // if the resolved receiver is not null. |
| 2037 return null; | 2057 return null; |
| 2038 } | 2058 } |
| 2039 target = receiverClass.lookupLocalMember(name); | 2059 target = receiverClass.lookupLocalMember(name); |
| 2040 if (target == null || target.isInstanceMember()) { | 2060 if (target == null || target.isInstanceMember()) { |
| 2041 compiler.backend.registerThrowNoSuchMethod(); | 2061 compiler.backend.registerThrowNoSuchMethod(mapping); |
| 2042 // TODO(johnniwinther): With the simplified [TreeElements] invariant, | 2062 // TODO(johnniwinther): With the simplified [TreeElements] invariant, |
| 2043 // try to resolve injected elements if [currentClass] is in the patch | 2063 // try to resolve injected elements if [currentClass] is in the patch |
| 2044 // library of [receiverClass]. | 2064 // library of [receiverClass]. |
| 2045 | 2065 |
| 2046 // TODO(karlklose): this should be reported by the caller of | 2066 // TODO(karlklose): this should be reported by the caller of |
| 2047 // [resolveSend] to select better warning messages for getters and | 2067 // [resolveSend] to select better warning messages for getters and |
| 2048 // setters. | 2068 // setters. |
| 2049 MessageKind kind = (target == null) | 2069 MessageKind kind = (target == null) |
| 2050 ? MessageKind.METHOD_NOT_FOUND | 2070 ? MessageKind.METHOD_NOT_FOUND |
| 2051 : MessageKind.MEMBER_NOT_STATIC; | 2071 : MessageKind.MEMBER_NOT_STATIC; |
| 2052 return warnAndCreateErroneousElement(node, name, kind, | 2072 return warnAndCreateErroneousElement(node, name, kind, |
| 2053 {'className': receiverClass.name, | 2073 {'className': receiverClass.name, |
| 2054 'memberName': name}); | 2074 'memberName': name}); |
| 2055 } | 2075 } |
| 2056 } else if (identical(resolvedReceiver.kind, ElementKind.PREFIX)) { | 2076 } else if (identical(resolvedReceiver.kind, ElementKind.PREFIX)) { |
| 2057 PrefixElement prefix = resolvedReceiver; | 2077 PrefixElement prefix = resolvedReceiver; |
| 2058 target = prefix.lookupLocalMember(name); | 2078 target = prefix.lookupLocalMember(name); |
| 2059 if (Elements.isUnresolved(target)) { | 2079 if (Elements.isUnresolved(target)) { |
| 2060 compiler.backend.registerThrowNoSuchMethod(); | 2080 compiler.backend.registerThrowNoSuchMethod(mapping); |
| 2061 return warnAndCreateErroneousElement( | 2081 return warnAndCreateErroneousElement( |
| 2062 node, name, MessageKind.NO_SUCH_LIBRARY_MEMBER, | 2082 node, name, MessageKind.NO_SUCH_LIBRARY_MEMBER, |
| 2063 {'libraryName': prefix.name, 'memberName': name}); | 2083 {'libraryName': prefix.name, 'memberName': name}); |
| 2064 } else if (target.kind == ElementKind.CLASS) { | 2084 } else if (target.kind == ElementKind.CLASS) { |
| 2065 ClassElement classElement = target; | 2085 ClassElement classElement = target; |
| 2066 classElement.ensureResolved(compiler); | 2086 classElement.ensureResolved(compiler); |
| 2067 } | 2087 } |
| 2068 } | 2088 } |
| 2069 return target; | 2089 return target; |
| 2070 } | 2090 } |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2165 bool oldSendIsMemberAccess = sendIsMemberAccess; | 2185 bool oldSendIsMemberAccess = sendIsMemberAccess; |
| 2166 sendIsMemberAccess = node.isPropertyAccess || node.isCall; | 2186 sendIsMemberAccess = node.isPropertyAccess || node.isCall; |
| 2167 Element target = resolveSend(node); | 2187 Element target = resolveSend(node); |
| 2168 sendIsMemberAccess = oldSendIsMemberAccess; | 2188 sendIsMemberAccess = oldSendIsMemberAccess; |
| 2169 | 2189 |
| 2170 if (!Elements.isUnresolved(target)) { | 2190 if (!Elements.isUnresolved(target)) { |
| 2171 if (target.isAbstractField()) { | 2191 if (target.isAbstractField()) { |
| 2172 AbstractFieldElement field = target; | 2192 AbstractFieldElement field = target; |
| 2173 target = field.getter; | 2193 target = field.getter; |
| 2174 if (target == null && !inInstanceContext) { | 2194 if (target == null && !inInstanceContext) { |
| 2175 compiler.backend.registerThrowNoSuchMethod(); | 2195 compiler.backend.registerThrowNoSuchMethod(mapping); |
| 2176 target = | 2196 target = |
| 2177 warnAndCreateErroneousElement(node.selector, field.name, | 2197 warnAndCreateErroneousElement(node.selector, field.name, |
| 2178 MessageKind.CANNOT_RESOLVE_GETTER); | 2198 MessageKind.CANNOT_RESOLVE_GETTER); |
| 2179 } | 2199 } |
| 2180 } else if (target.impliesType() && !sendIsMemberAccess) { | 2200 } else if (target.impliesType() && !sendIsMemberAccess) { |
| 2181 compiler.backend.registerTypeLiteral(); | 2201 compiler.backend.registerTypeLiteral(mapping); |
| 2182 } | 2202 } |
| 2183 } | 2203 } |
| 2184 | 2204 |
| 2185 bool resolvedArguments = false; | 2205 bool resolvedArguments = false; |
| 2186 if (node.isOperator) { | 2206 if (node.isOperator) { |
| 2187 String operatorString = node.selector.asOperator().source.stringValue; | 2207 String operatorString = node.selector.asOperator().source.stringValue; |
| 2188 if (operatorString == 'is' || operatorString == 'as') { | 2208 if (operatorString == 'is' || operatorString == 'as') { |
| 2189 assert(node.arguments.tail.isEmpty); | 2209 assert(node.arguments.tail.isEmpty); |
| 2190 DartType type = resolveTypeTest(node.arguments.head); | 2210 DartType type = resolveTypeTest(node.arguments.head); |
| 2191 if (type != null) { | 2211 if (type != null) { |
| 2192 if (operatorString == 'as') { | 2212 if (operatorString == 'as') { |
| 2193 compiler.enqueuer.resolution.registerAsCheck(type); | 2213 compiler.enqueuer.resolution.registerAsCheck(type, mapping); |
| 2194 } else { | 2214 } else { |
| 2195 compiler.enqueuer.resolution.registerIsCheck(type); | 2215 compiler.enqueuer.resolution.registerIsCheck(type, mapping); |
| 2196 } | 2216 } |
| 2197 } | 2217 } |
| 2198 resolvedArguments = true; | 2218 resolvedArguments = true; |
| 2199 } else if (identical(operatorString, '?')) { | 2219 } else if (identical(operatorString, '?')) { |
| 2200 Element parameter = mapping[node.receiver]; | 2220 Element parameter = mapping[node.receiver]; |
| 2201 if (parameter == null | 2221 if (parameter == null |
| 2202 || !identical(parameter.kind, ElementKind.PARAMETER)) { | 2222 || !identical(parameter.kind, ElementKind.PARAMETER)) { |
| 2203 error(node.receiver, MessageKind.PARAMETER_NAME_EXPECTED); | 2223 error(node.receiver, MessageKind.PARAMETER_NAME_EXPECTED); |
| 2204 } else { | 2224 } else { |
| 2205 mapping.checkedParameters.add(parameter); | 2225 mapping.checkedParameters.add(parameter); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2239 world.registerJsCall(node, this); | 2259 world.registerJsCall(node, this); |
| 2240 } | 2260 } |
| 2241 } | 2261 } |
| 2242 | 2262 |
| 2243 // TODO(ngeoffray): Warn if target is null and the send is | 2263 // TODO(ngeoffray): Warn if target is null and the send is |
| 2244 // unqualified. | 2264 // unqualified. |
| 2245 useElement(node, target); | 2265 useElement(node, target); |
| 2246 registerSend(selector, target); | 2266 registerSend(selector, target); |
| 2247 if (node.isPropertyAccess) { | 2267 if (node.isPropertyAccess) { |
| 2248 // It might be the closurization of a method. | 2268 // It might be the closurization of a method. |
| 2249 world.registerInstantiatedClass(compiler.functionClass); | 2269 world.registerInstantiatedClass(compiler.functionClass, mapping); |
| 2250 } | 2270 } |
| 2251 return node.isPropertyAccess ? target : null; | 2271 return node.isPropertyAccess ? target : null; |
| 2252 } | 2272 } |
| 2253 | 2273 |
| 2254 void warnArgumentMismatch(Send node, Element target) { | 2274 void warnArgumentMismatch(Send node, Element target) { |
| 2255 compiler.backend.registerThrowNoSuchMethod(); | 2275 compiler.backend.registerThrowNoSuchMethod(mapping); |
| 2256 // TODO(karlklose): we can be more precise about the reason of the | 2276 // TODO(karlklose): we can be more precise about the reason of the |
| 2257 // mismatch. | 2277 // mismatch. |
| 2258 warning(node.argumentsNode, MessageKind.INVALID_ARGUMENTS, | 2278 warning(node.argumentsNode, MessageKind.INVALID_ARGUMENTS, |
| 2259 {'methodName': target.name}); | 2279 {'methodName': target.name}); |
| 2260 } | 2280 } |
| 2261 | 2281 |
| 2262 /// Callback for native enqueuer to parse a type. Returns [:null:] on error. | 2282 /// Callback for native enqueuer to parse a type. Returns [:null:] on error. |
| 2263 DartType resolveTypeFromString(String typeName) { | 2283 DartType resolveTypeFromString(String typeName) { |
| 2264 Element element = scope.lookup(new SourceString(typeName)); | 2284 Element element = scope.lookup(new SourceString(typeName)); |
| 2265 if (element == null) return null; | 2285 if (element == null) return null; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2276 String source = operatorName.stringValue; | 2296 String source = operatorName.stringValue; |
| 2277 bool isComplex = !identical(source, '='); | 2297 bool isComplex = !identical(source, '='); |
| 2278 if (!Elements.isUnresolved(target)) { | 2298 if (!Elements.isUnresolved(target)) { |
| 2279 if (target.isAbstractField()) { | 2299 if (target.isAbstractField()) { |
| 2280 AbstractFieldElement field = target; | 2300 AbstractFieldElement field = target; |
| 2281 setter = field.setter; | 2301 setter = field.setter; |
| 2282 getter = field.getter; | 2302 getter = field.getter; |
| 2283 if (setter == null && !inInstanceContext) { | 2303 if (setter == null && !inInstanceContext) { |
| 2284 setter = warnAndCreateErroneousElement( | 2304 setter = warnAndCreateErroneousElement( |
| 2285 node.selector, field.name, MessageKind.CANNOT_RESOLVE_SETTER); | 2305 node.selector, field.name, MessageKind.CANNOT_RESOLVE_SETTER); |
| 2286 compiler.backend.registerThrowNoSuchMethod(); | 2306 compiler.backend.registerThrowNoSuchMethod(mapping); |
| 2287 } | 2307 } |
| 2288 if (isComplex && getter == null && !inInstanceContext) { | 2308 if (isComplex && getter == null && !inInstanceContext) { |
| 2289 getter = warnAndCreateErroneousElement( | 2309 getter = warnAndCreateErroneousElement( |
| 2290 node.selector, field.name, MessageKind.CANNOT_RESOLVE_GETTER); | 2310 node.selector, field.name, MessageKind.CANNOT_RESOLVE_GETTER); |
| 2291 compiler.backend.registerThrowNoSuchMethod(); | 2311 compiler.backend.registerThrowNoSuchMethod(mapping); |
| 2292 } | 2312 } |
| 2293 } else if (target.impliesType()) { | 2313 } else if (target.impliesType()) { |
| 2294 compiler.backend.registerThrowNoSuchMethod(); | 2314 compiler.backend.registerThrowNoSuchMethod(mapping); |
| 2295 } else if (target.modifiers.isFinal() || target.modifiers.isConst()) { | 2315 } else if (target.modifiers.isFinal() || target.modifiers.isConst()) { |
| 2296 setter = warnAndCreateErroneousElement( | 2316 setter = warnAndCreateErroneousElement( |
| 2297 node.selector, target.name, MessageKind.CANNOT_RESOLVE_SETTER); | 2317 node.selector, target.name, MessageKind.CANNOT_RESOLVE_SETTER); |
| 2298 compiler.backend.registerThrowNoSuchMethod(); | 2318 compiler.backend.registerThrowNoSuchMethod(mapping); |
| 2299 } | 2319 } |
| 2300 } | 2320 } |
| 2301 | 2321 |
| 2302 visit(node.argumentsNode); | 2322 visit(node.argumentsNode); |
| 2303 | 2323 |
| 2304 // TODO(ngeoffray): Check if the target can be assigned. | 2324 // TODO(ngeoffray): Check if the target can be assigned. |
| 2305 // TODO(ngeoffray): Warn if target is null and the send is | 2325 // TODO(ngeoffray): Warn if target is null and the send is |
| 2306 // unqualified. | 2326 // unqualified. |
| 2307 | 2327 |
| 2308 Selector selector = mapping.getSelector(node); | 2328 Selector selector = mapping.getSelector(node); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2361 // the use of classes. Wouldn't it be simpler if we just did? | 2381 // the use of classes. Wouldn't it be simpler if we just did? |
| 2362 if (!target.isClass()) { | 2382 if (!target.isClass()) { |
| 2363 // [target] might be the implementation element and only declaration | 2383 // [target] might be the implementation element and only declaration |
| 2364 // elements may be registered. | 2384 // elements may be registered. |
| 2365 world.registerStaticUse(target.declaration); | 2385 world.registerStaticUse(target.declaration); |
| 2366 } | 2386 } |
| 2367 } | 2387 } |
| 2368 } | 2388 } |
| 2369 | 2389 |
| 2370 visitLiteralInt(LiteralInt node) { | 2390 visitLiteralInt(LiteralInt node) { |
| 2371 world.registerInstantiatedClass(compiler.intClass); | 2391 world.registerInstantiatedClass(compiler.intClass, mapping); |
| 2372 } | 2392 } |
| 2373 | 2393 |
| 2374 visitLiteralDouble(LiteralDouble node) { | 2394 visitLiteralDouble(LiteralDouble node) { |
| 2375 world.registerInstantiatedClass(compiler.doubleClass); | 2395 world.registerInstantiatedClass(compiler.doubleClass, mapping); |
| 2376 } | 2396 } |
| 2377 | 2397 |
| 2378 visitLiteralBool(LiteralBool node) { | 2398 visitLiteralBool(LiteralBool node) { |
| 2379 world.registerInstantiatedClass(compiler.boolClass); | 2399 world.registerInstantiatedClass(compiler.boolClass, mapping); |
| 2380 } | 2400 } |
| 2381 | 2401 |
| 2382 visitLiteralString(LiteralString node) { | 2402 visitLiteralString(LiteralString node) { |
| 2383 world.registerInstantiatedClass(compiler.stringClass); | 2403 world.registerInstantiatedClass(compiler.stringClass, mapping); |
| 2384 } | 2404 } |
| 2385 | 2405 |
| 2386 visitLiteralNull(LiteralNull node) { | 2406 visitLiteralNull(LiteralNull node) { |
| 2387 world.registerInstantiatedClass(compiler.nullClass); | 2407 world.registerInstantiatedClass(compiler.nullClass, mapping); |
| 2388 } | 2408 } |
| 2389 | 2409 |
| 2390 visitStringJuxtaposition(StringJuxtaposition node) { | 2410 visitStringJuxtaposition(StringJuxtaposition node) { |
| 2391 world.registerInstantiatedClass(compiler.stringClass); | 2411 world.registerInstantiatedClass(compiler.stringClass, mapping); |
| 2392 node.visitChildren(this); | 2412 node.visitChildren(this); |
| 2393 } | 2413 } |
| 2394 | 2414 |
| 2395 visitNodeList(NodeList node) { | 2415 visitNodeList(NodeList node) { |
| 2396 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { | 2416 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { |
| 2397 visit(link.head); | 2417 visit(link.head); |
| 2398 } | 2418 } |
| 2399 } | 2419 } |
| 2400 | 2420 |
| 2401 visitOperator(Operator node) { | 2421 visitOperator(Operator node) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2437 { // This entire block is temporary code per the above TODO. | 2457 { // This entire block is temporary code per the above TODO. |
| 2438 FunctionElement targetImplementation = redirectionTarget.implementation; | 2458 FunctionElement targetImplementation = redirectionTarget.implementation; |
| 2439 FunctionExpression function = targetImplementation.parseNode(compiler); | 2459 FunctionExpression function = targetImplementation.parseNode(compiler); |
| 2440 if (function.body != null && function.body.asReturn() != null | 2460 if (function.body != null && function.body.asReturn() != null |
| 2441 && function.body.asReturn().isRedirectingFactoryBody) { | 2461 && function.body.asReturn().isRedirectingFactoryBody) { |
| 2442 unimplemented(node.expression, 'redirecing to redirecting factory'); | 2462 unimplemented(node.expression, 'redirecing to redirecting factory'); |
| 2443 } | 2463 } |
| 2444 } | 2464 } |
| 2445 world.registerStaticUse(redirectionTarget); | 2465 world.registerStaticUse(redirectionTarget); |
| 2446 world.registerInstantiatedClass( | 2466 world.registerInstantiatedClass( |
| 2447 redirectionTarget.enclosingElement.declaration); | 2467 redirectionTarget.enclosingElement.declaration, mapping); |
| 2448 } | 2468 } |
| 2449 | 2469 |
| 2450 visitThrow(Throw node) { | 2470 visitThrow(Throw node) { |
| 2451 if (!inCatchBlock && node.expression == null) { | 2471 if (!inCatchBlock && node.expression == null) { |
| 2452 error(node, MessageKind.THROW_WITHOUT_EXPRESSION); | 2472 error(node, MessageKind.THROW_WITHOUT_EXPRESSION); |
| 2453 } | 2473 } |
| 2454 compiler.backend.registerThrow(); | 2474 compiler.backend.registerThrow(mapping); |
| 2455 visit(node.expression); | 2475 visit(node.expression); |
| 2456 } | 2476 } |
| 2457 | 2477 |
| 2458 visitVariableDefinitions(VariableDefinitions node) { | 2478 visitVariableDefinitions(VariableDefinitions node) { |
| 2459 VariableDefinitionsVisitor visitor = | 2479 VariableDefinitionsVisitor visitor = |
| 2460 new VariableDefinitionsVisitor(compiler, node, this, | 2480 new VariableDefinitionsVisitor(compiler, node, this, |
| 2461 ElementKind.VARIABLE); | 2481 ElementKind.VARIABLE); |
| 2462 // Ensure that we set the type of the [VariableListElement] since it depends | 2482 // Ensure that we set the type of the [VariableListElement] since it depends |
| 2463 // on the current scope. If the current scope is a [MethodScope] or | 2483 // on the current scope. If the current scope is a [MethodScope] or |
| 2464 // [BlockScope] it will not be available for the | 2484 // [BlockScope] it will not be available for the |
| (...skipping 21 matching lines...) Expand all Loading... |
| 2486 visitNewExpression(NewExpression node) { | 2506 visitNewExpression(NewExpression node) { |
| 2487 Node selector = node.send.selector; | 2507 Node selector = node.send.selector; |
| 2488 FunctionElement constructor = resolveConstructor(node); | 2508 FunctionElement constructor = resolveConstructor(node); |
| 2489 resolveSelector(node.send); | 2509 resolveSelector(node.send); |
| 2490 resolveArguments(node.send.argumentsNode); | 2510 resolveArguments(node.send.argumentsNode); |
| 2491 useElement(node.send, constructor); | 2511 useElement(node.send, constructor); |
| 2492 if (Elements.isUnresolved(constructor)) return constructor; | 2512 if (Elements.isUnresolved(constructor)) return constructor; |
| 2493 Selector callSelector = mapping.getSelector(node.send); | 2513 Selector callSelector = mapping.getSelector(node.send); |
| 2494 if (!callSelector.applies(constructor, compiler)) { | 2514 if (!callSelector.applies(constructor, compiler)) { |
| 2495 warnArgumentMismatch(node.send, constructor); | 2515 warnArgumentMismatch(node.send, constructor); |
| 2496 compiler.backend.registerThrowNoSuchMethod(); | 2516 compiler.backend.registerThrowNoSuchMethod(mapping); |
| 2497 } | 2517 } |
| 2498 compiler.withCurrentElement(constructor, () { | 2518 compiler.withCurrentElement(constructor, () { |
| 2499 FunctionExpression tree = constructor.parseNode(compiler); | 2519 FunctionExpression tree = constructor.parseNode(compiler); |
| 2500 compiler.resolver.resolveConstructorImplementation(constructor, tree); | 2520 compiler.resolver.resolveConstructorImplementation(constructor, tree); |
| 2501 }); | 2521 }); |
| 2502 | 2522 |
| 2503 if (constructor.defaultImplementation != constructor) { | 2523 if (constructor.defaultImplementation != constructor) { |
| 2504 // Support for deprecated interface support. | 2524 // Support for deprecated interface support. |
| 2505 // TODO(ngeoffray): Remove once we remove such support. | 2525 // TODO(ngeoffray): Remove once we remove such support. |
| 2506 world.registerStaticUse(constructor.declaration); | 2526 world.registerStaticUse(constructor.declaration); |
| 2507 world.registerInstantiatedClass( | 2527 world.registerInstantiatedClass( |
| 2508 constructor.getEnclosingClass().declaration); | 2528 constructor.getEnclosingClass().declaration, mapping); |
| 2509 constructor = constructor.defaultImplementation; | 2529 constructor = constructor.defaultImplementation; |
| 2510 } | 2530 } |
| 2511 // [constructor.defaultImplementation] might be the implementation element | 2531 // [constructor.defaultImplementation] might be the implementation element |
| 2512 // and only declaration elements may be registered. | 2532 // and only declaration elements may be registered. |
| 2513 world.registerStaticUse(constructor.declaration); | 2533 world.registerStaticUse(constructor.declaration); |
| 2514 ClassElement cls = constructor.getEnclosingClass(); | 2534 ClassElement cls = constructor.getEnclosingClass(); |
| 2515 // [cls] might be the implementation element and only declaration elements | 2535 // [cls] might be the implementation element and only declaration elements |
| 2516 // may be registered. | 2536 // may be registered. |
| 2517 world.registerInstantiatedType(mapping.getType(node)); | 2537 world.registerInstantiatedType(mapping.getType(node), mapping); |
| 2518 if (cls.isAbstract(compiler)) { | 2538 if (cls.isAbstract(compiler)) { |
| 2519 compiler.backend.registerAbstractClassInstantiation(); | 2539 compiler.backend.registerAbstractClassInstantiation(mapping); |
| 2520 } | 2540 } |
| 2521 // [cls] might be the declaration element and we want to include injected | 2541 // [cls] might be the declaration element and we want to include injected |
| 2522 // members. | 2542 // members. |
| 2523 cls.implementation.forEachInstanceField( | 2543 cls.implementation.forEachInstanceField( |
| 2524 (ClassElement enclosingClass, Element member) { | 2544 (ClassElement enclosingClass, Element member) { |
| 2525 world.addToWorkList(member); | 2545 world.addToWorkList(member); |
| 2526 }, | 2546 }, |
| 2527 includeBackendMembers: false, | 2547 includeBackendMembers: false, |
| 2528 includeSuperMembers: true); | 2548 includeSuperMembers: true); |
| 2529 return null; | 2549 return null; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2568 } | 2588 } |
| 2569 } | 2589 } |
| 2570 | 2590 |
| 2571 DartType resolveTypeAnnotation(TypeAnnotation node) { | 2591 DartType resolveTypeAnnotation(TypeAnnotation node) { |
| 2572 Function report = typeRequired ? error : warning; | 2592 Function report = typeRequired ? error : warning; |
| 2573 DartType type = typeResolver.resolveTypeAnnotation( | 2593 DartType type = typeResolver.resolveTypeAnnotation( |
| 2574 node, scope, enclosingElement, | 2594 node, scope, enclosingElement, |
| 2575 onFailure: report, whenResolved: useType); | 2595 onFailure: report, whenResolved: useType); |
| 2576 if (type == null) return null; | 2596 if (type == null) return null; |
| 2577 if (inCheckContext) { | 2597 if (inCheckContext) { |
| 2578 compiler.enqueuer.resolution.registerIsCheck(type); | 2598 compiler.enqueuer.resolution.registerIsCheck(type, mapping); |
| 2579 } | 2599 } |
| 2580 if (typeRequired || inCheckContext) { | 2600 if (typeRequired || inCheckContext) { |
| 2581 if (type is InterfaceType) { | 2601 if (type is InterfaceType) { |
| 2582 InterfaceType itf = type; | 2602 InterfaceType itf = type; |
| 2583 itf.typeArguments.forEach((DartType argument) { | 2603 itf.typeArguments.forEach((DartType argument) { |
| 2584 analyzeTypeArgument(type, argument); | 2604 analyzeTypeArgument(type, argument); |
| 2585 }); | 2605 }); |
| 2586 } | 2606 } |
| 2587 // TODO(ngeoffray): Also handle T a (in checked mode). | 2607 // TODO(ngeoffray): Also handle T a (in checked mode). |
| 2588 } | 2608 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2609 } | 2629 } |
| 2610 } | 2630 } |
| 2611 } | 2631 } |
| 2612 DartType listType; | 2632 DartType listType; |
| 2613 if (typeArgument != null) { | 2633 if (typeArgument != null) { |
| 2614 listType = new InterfaceType(compiler.listClass, | 2634 listType = new InterfaceType(compiler.listClass, |
| 2615 new Link<DartType>.fromList([typeArgument])); | 2635 new Link<DartType>.fromList([typeArgument])); |
| 2616 } else { | 2636 } else { |
| 2617 listType = compiler.listClass.rawType; | 2637 listType = compiler.listClass.rawType; |
| 2618 } | 2638 } |
| 2619 world.registerInstantiatedType(listType); | 2639 world.registerInstantiatedType(listType, mapping); |
| 2620 visit(node.elements); | 2640 visit(node.elements); |
| 2621 } | 2641 } |
| 2622 | 2642 |
| 2623 visitConditional(Conditional node) { | 2643 visitConditional(Conditional node) { |
| 2624 node.visitChildren(this); | 2644 node.visitChildren(this); |
| 2625 } | 2645 } |
| 2626 | 2646 |
| 2627 visitStringInterpolation(StringInterpolation node) { | 2647 visitStringInterpolation(StringInterpolation node) { |
| 2628 world.registerInstantiatedClass(compiler.stringClass); | 2648 world.registerInstantiatedClass(compiler.stringClass, mapping); |
| 2629 compiler.backend.registerStringInterpolation(); | 2649 compiler.backend.registerStringInterpolation(mapping); |
| 2630 node.visitChildren(this); | 2650 node.visitChildren(this); |
| 2631 } | 2651 } |
| 2632 | 2652 |
| 2633 visitStringInterpolationPart(StringInterpolationPart node) { | 2653 visitStringInterpolationPart(StringInterpolationPart node) { |
| 2634 registerImplicitInvocation(const SourceString('toString'), 0); | 2654 registerImplicitInvocation(const SourceString('toString'), 0); |
| 2635 node.visitChildren(this); | 2655 node.visitChildren(this); |
| 2636 } | 2656 } |
| 2637 | 2657 |
| 2638 visitBreakStatement(BreakStatement node) { | 2658 visitBreakStatement(BreakStatement node) { |
| 2639 TargetElement target; | 2659 TargetElement target; |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2764 } | 2784 } |
| 2765 }); | 2785 }); |
| 2766 if (!targetElement.isTarget && identical(mapping[body], targetElement)) { | 2786 if (!targetElement.isTarget && identical(mapping[body], targetElement)) { |
| 2767 // If the body is itself a break or continue for another target, it | 2787 // If the body is itself a break or continue for another target, it |
| 2768 // might have updated its mapping to the target it actually does target. | 2788 // might have updated its mapping to the target it actually does target. |
| 2769 mapping.remove(body); | 2789 mapping.remove(body); |
| 2770 } | 2790 } |
| 2771 } | 2791 } |
| 2772 | 2792 |
| 2773 visitLiteralMap(LiteralMap node) { | 2793 visitLiteralMap(LiteralMap node) { |
| 2774 world.registerInstantiatedClass(compiler.mapClass); | 2794 world.registerInstantiatedClass(compiler.mapClass, mapping); |
| 2775 if (node.isConst()) { | 2795 if (node.isConst()) { |
| 2776 compiler.backend.registerConstantMap(); | 2796 compiler.backend.registerConstantMap(mapping); |
| 2777 } | 2797 } |
| 2778 node.visitChildren(this); | 2798 node.visitChildren(this); |
| 2779 } | 2799 } |
| 2780 | 2800 |
| 2781 visitLiteralMapEntry(LiteralMapEntry node) { | 2801 visitLiteralMapEntry(LiteralMapEntry node) { |
| 2782 node.visitChildren(this); | 2802 node.visitChildren(this); |
| 2783 } | 2803 } |
| 2784 | 2804 |
| 2785 visitNamedArgument(NamedArgument node) { | 2805 visitNamedArgument(NamedArgument node) { |
| 2786 visit(node.expression); | 2806 visit(node.expression); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2847 continueLabels.forEach((String key, LabelElement label) { | 2867 continueLabels.forEach((String key, LabelElement label) { |
| 2848 if (!label.isContinueTarget) { | 2868 if (!label.isContinueTarget) { |
| 2849 TargetElement targetElement = label.target; | 2869 TargetElement targetElement = label.target; |
| 2850 SwitchCase switchCase = targetElement.statement; | 2870 SwitchCase switchCase = targetElement.statement; |
| 2851 mapping.remove(switchCase); | 2871 mapping.remove(switchCase); |
| 2852 mapping.remove(label.label); | 2872 mapping.remove(label.label); |
| 2853 } | 2873 } |
| 2854 }); | 2874 }); |
| 2855 // TODO(ngeoffray): We should check here instead of the SSA backend if | 2875 // TODO(ngeoffray): We should check here instead of the SSA backend if |
| 2856 // there might be an error. | 2876 // there might be an error. |
| 2857 compiler.backend.registerFallThroughError(); | 2877 compiler.backend.registerFallThroughError(mapping); |
| 2858 } | 2878 } |
| 2859 | 2879 |
| 2860 visitSwitchCase(SwitchCase node) { | 2880 visitSwitchCase(SwitchCase node) { |
| 2861 node.labelsAndCases.accept(this); | 2881 node.labelsAndCases.accept(this); |
| 2862 visitIn(node.statements, new BlockScope(scope)); | 2882 visitIn(node.statements, new BlockScope(scope)); |
| 2863 } | 2883 } |
| 2864 | 2884 |
| 2865 visitCaseMatch(CaseMatch node) { | 2885 visitCaseMatch(CaseMatch node) { |
| 2866 visit(node.expression); | 2886 visit(node.expression); |
| 2867 } | 2887 } |
| 2868 | 2888 |
| 2869 visitTryStatement(TryStatement node) { | 2889 visitTryStatement(TryStatement node) { |
| 2870 visit(node.tryBlock); | 2890 visit(node.tryBlock); |
| 2871 if (node.catchBlocks.isEmpty && node.finallyBlock == null) { | 2891 if (node.catchBlocks.isEmpty && node.finallyBlock == null) { |
| 2872 // TODO(ngeoffray): The precise location is | 2892 // TODO(ngeoffray): The precise location is |
| 2873 // node.getEndtoken.next. Adjust when issue #1581 is fixed. | 2893 // node.getEndtoken.next. Adjust when issue #1581 is fixed. |
| 2874 error(node, MessageKind.NO_CATCH_NOR_FINALLY); | 2894 error(node, MessageKind.NO_CATCH_NOR_FINALLY); |
| 2875 } | 2895 } |
| 2876 visit(node.catchBlocks); | 2896 visit(node.catchBlocks); |
| 2877 visit(node.finallyBlock); | 2897 visit(node.finallyBlock); |
| 2878 } | 2898 } |
| 2879 | 2899 |
| 2880 visitCatchBlock(CatchBlock node) { | 2900 visitCatchBlock(CatchBlock node) { |
| 2881 compiler.backend.registerCatchStatement(); | 2901 compiler.backend.registerCatchStatement(mapping); |
| 2882 // Check that if catch part is present, then | 2902 // Check that if catch part is present, then |
| 2883 // it has one or two formal parameters. | 2903 // it has one or two formal parameters. |
| 2884 if (node.formals != null) { | 2904 if (node.formals != null) { |
| 2885 if (node.formals.isEmpty) { | 2905 if (node.formals.isEmpty) { |
| 2886 error(node, MessageKind.EMPTY_CATCH_DECLARATION); | 2906 error(node, MessageKind.EMPTY_CATCH_DECLARATION); |
| 2887 } | 2907 } |
| 2888 if (!node.formals.nodes.tail.isEmpty) { | 2908 if (!node.formals.nodes.tail.isEmpty) { |
| 2889 if (!node.formals.nodes.tail.tail.isEmpty) { | 2909 if (!node.formals.nodes.tail.tail.isEmpty) { |
| 2890 for (Node extra in node.formals.nodes.tail.tail) { | 2910 for (Node extra in node.formals.nodes.tail.tail) { |
| 2891 error(extra, MessageKind.EXTRA_CATCH_DECLARATION); | 2911 error(extra, MessageKind.EXTRA_CATCH_DECLARATION); |
| 2892 } | 2912 } |
| 2893 } | 2913 } |
| 2894 compiler.backend.registerStackTraceInCatch(); | 2914 compiler.backend.registerStackTraceInCatch(mapping); |
| 2895 } | 2915 } |
| 2896 | 2916 |
| 2897 // Check that the formals aren't optional and that they have no | 2917 // Check that the formals aren't optional and that they have no |
| 2898 // modifiers or type. | 2918 // modifiers or type. |
| 2899 for (Link<Node> link = node.formals.nodes; | 2919 for (Link<Node> link = node.formals.nodes; |
| 2900 !link.isEmpty; | 2920 !link.isEmpty; |
| 2901 link = link.tail) { | 2921 link = link.tail) { |
| 2902 // If the formal parameter is a node list, it means that it is a | 2922 // If the formal parameter is a node list, it means that it is a |
| 2903 // sequence of optional parameters. | 2923 // sequence of optional parameters. |
| 2904 NodeList nodeList = link.head.asNodeList(); | 2924 NodeList nodeList = link.head.asNodeList(); |
| (...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3429 } | 3449 } |
| 3430 | 3450 |
| 3431 SourceString visitSendSet(SendSet node) { | 3451 SourceString visitSendSet(SendSet node) { |
| 3432 assert(node.arguments.tail.isEmpty); // Sanity check | 3452 assert(node.arguments.tail.isEmpty); // Sanity check |
| 3433 resolver.visit(node.arguments.head); | 3453 resolver.visit(node.arguments.head); |
| 3434 return visit(node.selector); | 3454 return visit(node.selector); |
| 3435 } | 3455 } |
| 3436 | 3456 |
| 3437 SourceString visitIdentifier(Identifier node) { | 3457 SourceString visitIdentifier(Identifier node) { |
| 3438 // The variable is initialized to null. | 3458 // The variable is initialized to null. |
| 3439 resolver.world.registerInstantiatedClass(compiler.nullClass); | 3459 resolver.world.registerInstantiatedClass(compiler.nullClass, |
| 3460 resolver.mapping); |
| 3440 return node.source; | 3461 return node.source; |
| 3441 } | 3462 } |
| 3442 | 3463 |
| 3443 visitNodeList(NodeList node) { | 3464 visitNodeList(NodeList node) { |
| 3444 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { | 3465 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { |
| 3445 SourceString name = visit(link.head); | 3466 SourceString name = visit(link.head); |
| 3446 VariableElement element = | 3467 VariableElement element = |
| 3447 new VariableElementX(name, variables, kind, link.head); | 3468 new VariableElementX(name, variables, kind, link.head); |
| 3448 resolver.defineElement(link.head, element); | 3469 resolver.defineElement(link.head, element); |
| 3449 } | 3470 } |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3668 ConstructorResolver(Compiler compiler, this.resolver) : super(compiler); | 3689 ConstructorResolver(Compiler compiler, this.resolver) : super(compiler); |
| 3669 | 3690 |
| 3670 visitNode(Node node) { | 3691 visitNode(Node node) { |
| 3671 throw 'not supported'; | 3692 throw 'not supported'; |
| 3672 } | 3693 } |
| 3673 | 3694 |
| 3674 failOrReturnErroneousElement(Element enclosing, Node diagnosticNode, | 3695 failOrReturnErroneousElement(Element enclosing, Node diagnosticNode, |
| 3675 SourceString targetName, MessageKind kind, | 3696 SourceString targetName, MessageKind kind, |
| 3676 Map arguments) { | 3697 Map arguments) { |
| 3677 if (kind == MessageKind.CANNOT_FIND_CONSTRUCTOR) { | 3698 if (kind == MessageKind.CANNOT_FIND_CONSTRUCTOR) { |
| 3678 compiler.backend.registerThrowNoSuchMethod(); | 3699 compiler.backend.registerThrowNoSuchMethod(resolver.mapping); |
| 3679 } else { | 3700 } else { |
| 3680 compiler.backend.registerThrowRuntimeError(); | 3701 compiler.backend.registerThrowRuntimeError(resolver.mapping); |
| 3681 } | 3702 } |
| 3682 if (inConstContext) { | 3703 if (inConstContext) { |
| 3683 error(diagnosticNode, kind, arguments); | 3704 error(diagnosticNode, kind, arguments); |
| 3684 } else { | 3705 } else { |
| 3685 ResolutionWarning warning = new ResolutionWarning(kind, arguments); | 3706 ResolutionWarning warning = new ResolutionWarning(kind, arguments); |
| 3686 compiler.reportWarning(diagnosticNode, warning); | 3707 compiler.reportWarning(diagnosticNode, warning); |
| 3687 return new ErroneousElementX(kind, arguments, targetName, enclosing); | 3708 return new ErroneousElementX(kind, arguments, targetName, enclosing); |
| 3688 } | 3709 } |
| 3689 } | 3710 } |
| 3690 | 3711 |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3820 return e; | 3841 return e; |
| 3821 } | 3842 } |
| 3822 | 3843 |
| 3823 /// Assumed to be called by [resolveRedirectingFactory]. | 3844 /// Assumed to be called by [resolveRedirectingFactory]. |
| 3824 Element visitReturn(Return node) { | 3845 Element visitReturn(Return node) { |
| 3825 Node expression = node.expression; | 3846 Node expression = node.expression; |
| 3826 return finishConstructorReference(visit(expression), | 3847 return finishConstructorReference(visit(expression), |
| 3827 expression, expression); | 3848 expression, expression); |
| 3828 } | 3849 } |
| 3829 } | 3850 } |
| OLD | NEW |