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