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