Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of resolution; | 5 part of resolution; |
| 6 | 6 |
| 7 abstract class TreeElements { | 7 abstract class TreeElements { |
| 8 Element operator[](Node node); | 8 Element operator[](Node node); |
| 9 Selector getSelector(Send send); | 9 Selector getSelector(Send send); |
| 10 DartType getType(Node node); | 10 DartType getType(Node node); |
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 377 | 377 |
| 378 TreeElements resolveField(VariableElement element) { | 378 TreeElements resolveField(VariableElement element) { |
| 379 Node tree = element.parseNode(compiler); | 379 Node tree = element.parseNode(compiler); |
| 380 if(element.modifiers.isStatic() && element.variables.isTopLevel()) { | 380 if(element.modifiers.isStatic() && element.variables.isTopLevel()) { |
| 381 error(element.modifiers.getStatic(), | 381 error(element.modifiers.getStatic(), |
| 382 MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC); | 382 MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC); |
| 383 } | 383 } |
| 384 ResolverVisitor visitor = visitorFor(element); | 384 ResolverVisitor visitor = visitorFor(element); |
| 385 initializerDo(tree, visitor.visit); | 385 initializerDo(tree, visitor.visit); |
| 386 | 386 |
| 387 if (Elements.isStaticOrTopLevelField(element)) { | |
| 388 if (tree.asSendSet() != null) { | |
| 389 // TODO(ngeoffray): We could do better here by using the | |
| 390 // constant handler to figure out if it's a lazy field or not. | |
| 391 compiler.backend.registerLazyField(); | |
| 392 } | |
| 393 } | |
| 394 | |
| 387 // Perform various checks as side effect of "computing" the type. | 395 // Perform various checks as side effect of "computing" the type. |
| 388 element.computeType(compiler); | 396 element.computeType(compiler); |
| 389 | 397 |
| 390 return visitor.mapping; | 398 return visitor.mapping; |
| 391 } | 399 } |
| 392 | 400 |
| 393 TreeElements resolveParameter(Element element) { | 401 TreeElements resolveParameter(Element element) { |
| 394 Node tree = element.parseNode(compiler); | 402 Node tree = element.parseNode(compiler); |
| 395 ResolverVisitor visitor = visitorFor(element.enclosingElement); | 403 ResolverVisitor visitor = visitorFor(element.enclosingElement); |
| 396 initializerDo(tree, visitor.visit); | 404 initializerDo(tree, visitor.visit); |
| (...skipping 1054 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1451 new TypedefType(typdef, arguments.toLink())); | 1459 new TypedefType(typdef, arguments.toLink())); |
| 1452 } else { | 1460 } else { |
| 1453 if (arguments.isEmpty) { | 1461 if (arguments.isEmpty) { |
| 1454 type = typdef.rawType; | 1462 type = typdef.rawType; |
| 1455 } else { | 1463 } else { |
| 1456 type = new TypedefType(typdef, arguments.toLink()); | 1464 type = new TypedefType(typdef, arguments.toLink()); |
| 1457 } | 1465 } |
| 1458 } | 1466 } |
| 1459 } else if (element.isTypeVariable()) { | 1467 } else if (element.isTypeVariable()) { |
| 1460 if (enclosingElement.isInStaticMember()) { | 1468 if (enclosingElement.isInStaticMember()) { |
| 1469 compiler.backend.registerThrowRuntimeError(); | |
| 1461 compiler.reportWarning(node, | 1470 compiler.reportWarning(node, |
| 1462 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER.message( | 1471 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER.message( |
| 1463 {'typeVariableName': node})); | 1472 {'typeVariableName': node})); |
| 1464 type = new MalformedType( | 1473 type = new MalformedType( |
| 1465 new ErroneousElementX( | 1474 new ErroneousElementX( |
| 1466 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, | 1475 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, |
| 1467 {'typeVariableName': node}, | 1476 {'typeVariableName': node}, |
| 1468 typeName.source, enclosingElement), | 1477 typeName.source, enclosingElement), |
| 1469 element.computeType(compiler)); | 1478 element.computeType(compiler)); |
| 1470 } else { | 1479 } else { |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1635 error(node, MessageKind.INVALID_USE_OF_SUPER); | 1644 error(node, MessageKind.INVALID_USE_OF_SUPER); |
| 1636 } | 1645 } |
| 1637 return null; | 1646 return null; |
| 1638 } else { | 1647 } else { |
| 1639 Element element = lookup(node, node.source); | 1648 Element element = lookup(node, node.source); |
| 1640 if (element == null) { | 1649 if (element == null) { |
| 1641 if (!inInstanceContext) { | 1650 if (!inInstanceContext) { |
| 1642 element = warnAndCreateErroneousElement(node, node.source, | 1651 element = warnAndCreateErroneousElement(node, node.source, |
| 1643 MessageKind.CANNOT_RESOLVE, | 1652 MessageKind.CANNOT_RESOLVE, |
| 1644 {'name': node}); | 1653 {'name': node}); |
| 1654 compiler.backend.registerThrowNoSuchMethod(); | |
| 1645 } | 1655 } |
| 1646 } else if (element.isErroneous()) { | 1656 } else if (element.isErroneous()) { |
| 1647 // Use the erroneous element. | 1657 // Use the erroneous element. |
| 1648 } else { | 1658 } else { |
| 1649 if ((element.kind.category & allowedCategory) == 0) { | 1659 if ((element.kind.category & allowedCategory) == 0) { |
| 1650 // TODO(ahe): Improve error message. Need UX input. | 1660 // TODO(ahe): Improve error message. Need UX input. |
| 1651 error(node, MessageKind.GENERIC, | 1661 error(node, MessageKind.GENERIC, |
| 1652 {'text': "is not an expression $element"}); | 1662 {'text': "is not an expression $element"}); |
| 1653 } | 1663 } |
| 1654 } | 1664 } |
| 1655 if (!Elements.isUnresolved(element) | 1665 if (!Elements.isUnresolved(element) && element.isClass()) { |
| 1656 && element.kind == ElementKind.CLASS) { | |
| 1657 ClassElement classElement = element; | 1666 ClassElement classElement = element; |
| 1658 classElement.ensureResolved(compiler); | 1667 classElement.ensureResolved(compiler); |
| 1668 compiler.backend.registerTypeLiteral(); | |
| 1659 } | 1669 } |
| 1660 return useElement(node, element); | 1670 return useElement(node, element); |
| 1661 } | 1671 } |
| 1662 } | 1672 } |
| 1663 | 1673 |
| 1664 Element visitTypeAnnotation(TypeAnnotation node) { | 1674 Element visitTypeAnnotation(TypeAnnotation node) { |
| 1665 DartType type = resolveTypeAnnotation(node); | 1675 DartType type = resolveTypeAnnotation(node); |
| 1666 if (type != null) { | 1676 if (type != null) { |
| 1667 if (inCheckContext) { | 1677 if (inCheckContext) { |
| 1668 compiler.enqueuer.resolution.registerIsCheck(type); | 1678 compiler.enqueuer.resolution.registerIsCheck(type); |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1826 } | 1836 } |
| 1827 | 1837 |
| 1828 visitFunctionExpression(FunctionExpression node) { | 1838 visitFunctionExpression(FunctionExpression node) { |
| 1829 visit(node.returnType); | 1839 visit(node.returnType); |
| 1830 SourceString name; | 1840 SourceString name; |
| 1831 if (node.name == null) { | 1841 if (node.name == null) { |
| 1832 name = const SourceString(""); | 1842 name = const SourceString(""); |
| 1833 } else { | 1843 } else { |
| 1834 name = node.name.asIdentifier().source; | 1844 name = node.name.asIdentifier().source; |
| 1835 } | 1845 } |
| 1836 | |
| 1837 FunctionElement function = new FunctionElementX.node( | 1846 FunctionElement function = new FunctionElementX.node( |
| 1838 name, node, ElementKind.FUNCTION, Modifiers.EMPTY, | 1847 name, node, ElementKind.FUNCTION, Modifiers.EMPTY, |
| 1839 enclosingElement); | 1848 enclosingElement); |
| 1840 // [function] and its enclosing method share the same | 1849 // [function] and its enclosing method share the same |
| 1841 // [TreeElementMapping]. | 1850 // [TreeElementMapping]. |
| 1842 compiler.enqueuer.resolution.resolvedElements[function] = mapping; | 1851 compiler.enqueuer.resolution.resolvedElements[function] = mapping; |
| 1843 Scope oldScope = scope; // The scope is modified by [setupFunction]. | 1852 Scope oldScope = scope; // The scope is modified by [setupFunction]. |
| 1844 setupFunction(node, function); | 1853 setupFunction(node, function); |
| 1845 defineElement(node, function, doAddToScope: node.name != null); | 1854 defineElement(node, function, doAddToScope: node.name != null); |
| 1846 | 1855 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1918 // This is just to guard against internal errors, so no need | 1927 // This is just to guard against internal errors, so no need |
| 1919 // for a real error message. | 1928 // for a real error message. |
| 1920 error(node.receiver, MessageKind.GENERIC, | 1929 error(node.receiver, MessageKind.GENERIC, |
| 1921 {'text': "Object has no superclass"}); | 1930 {'text': "Object has no superclass"}); |
| 1922 } | 1931 } |
| 1923 // TODO(johnniwinther): Ensure correct behavior if currentClass is a | 1932 // TODO(johnniwinther): Ensure correct behavior if currentClass is a |
| 1924 // patch. | 1933 // patch. |
| 1925 target = currentClass.lookupSuperMember(name); | 1934 target = currentClass.lookupSuperMember(name); |
| 1926 // [target] may be null which means invoking noSuchMethod on | 1935 // [target] may be null which means invoking noSuchMethod on |
| 1927 // super. | 1936 // super. |
| 1937 if (target == null) { | |
| 1938 compiler.backend.registerSuperNoSuchMethod(); | |
| 1939 } | |
| 1928 } else if (Elements.isUnresolved(resolvedReceiver)) { | 1940 } else if (Elements.isUnresolved(resolvedReceiver)) { |
| 1929 return null; | 1941 return null; |
| 1930 } else if (identical(resolvedReceiver.kind, ElementKind.CLASS)) { | 1942 } else if (resolvedReceiver.isClass()) { |
| 1931 ClassElement receiverClass = resolvedReceiver; | 1943 ClassElement receiverClass = resolvedReceiver; |
| 1932 receiverClass.ensureResolved(compiler); | 1944 receiverClass.ensureResolved(compiler); |
| 1933 if (node.isOperator) { | 1945 if (node.isOperator) { |
| 1934 // When the resolved receiver is a class, we can have two cases: | 1946 // When the resolved receiver is a class, we can have two cases: |
| 1935 // 1) a static send: C.foo, or | 1947 // 1) a static send: C.foo, or |
| 1936 // 2) an operator send, where the receiver is a class literal: 'C + 1'. | 1948 // 2) an operator send, where the receiver is a class literal: 'C + 1'. |
| 1937 // The following code that looks up the selector on the resolved | 1949 // The following code that looks up the selector on the resolved |
| 1938 // receiver will treat the second as the invocation of a static operator | 1950 // receiver will treat the second as the invocation of a static operator |
| 1939 // if the resolved receiver is not null. | 1951 // if the resolved receiver is not null. |
| 1940 return null; | 1952 return null; |
| 1941 } | 1953 } |
| 1942 target = receiverClass.lookupLocalMember(name); | 1954 target = receiverClass.lookupLocalMember(name); |
| 1943 if (target == null) { | 1955 if (target == null) { |
| 1956 compiler.backend.registerThrowNoSuchMethod(); | |
| 1944 // TODO(johnniwinther): With the simplified [TreeElements] invariant, | 1957 // TODO(johnniwinther): With the simplified [TreeElements] invariant, |
| 1945 // try to resolve injected elements if [currentClass] is in the patch | 1958 // try to resolve injected elements if [currentClass] is in the patch |
| 1946 // library of [receiverClass]. | 1959 // library of [receiverClass]. |
| 1947 | 1960 |
| 1948 // TODO(karlklose): this should be reported by the caller of | 1961 // TODO(karlklose): this should be reported by the caller of |
| 1949 // [resolveSend] to select better warning messages for getters and | 1962 // [resolveSend] to select better warning messages for getters and |
| 1950 // setters. | 1963 // setters. |
| 1951 return warnAndCreateErroneousElement(node, name, | 1964 return warnAndCreateErroneousElement(node, name, |
| 1952 MessageKind.METHOD_NOT_FOUND, | 1965 MessageKind.METHOD_NOT_FOUND, |
| 1953 {'className': receiverClass.name, | 1966 {'className': receiverClass.name, |
| 1954 'methodName': name}); | 1967 'methodName': name}); |
| 1955 } else if (target.isInstanceMember()) { | 1968 } else if (target.isInstanceMember()) { |
| 1956 error(node, MessageKind.MEMBER_NOT_STATIC, | 1969 error(node, MessageKind.MEMBER_NOT_STATIC, |
| 1957 {'className': receiverClass.name, | 1970 {'className': receiverClass.name, |
| 1958 'memberName': name}); | 1971 'memberName': name}); |
| 1959 } | 1972 } |
| 1960 } else if (identical(resolvedReceiver.kind, ElementKind.PREFIX)) { | 1973 } else if (identical(resolvedReceiver.kind, ElementKind.PREFIX)) { |
| 1961 PrefixElement prefix = resolvedReceiver; | 1974 PrefixElement prefix = resolvedReceiver; |
| 1962 target = prefix.lookupLocalMember(name); | 1975 target = prefix.lookupLocalMember(name); |
| 1963 if (Elements.isUnresolved(target)) { | 1976 if (Elements.isUnresolved(target)) { |
| 1977 compiler.backend.registerThrowNoSuchMethod(); | |
| 1964 return warnAndCreateErroneousElement( | 1978 return warnAndCreateErroneousElement( |
| 1965 node, name, MessageKind.NO_SUCH_LIBRARY_MEMBER, | 1979 node, name, MessageKind.NO_SUCH_LIBRARY_MEMBER, |
| 1966 {'libraryName': prefix.name, 'memberName': name}); | 1980 {'libraryName': prefix.name, 'memberName': name}); |
| 1967 } else if (target.kind == ElementKind.CLASS) { | 1981 } else if (target.kind == ElementKind.CLASS) { |
| 1968 ClassElement classElement = target; | 1982 ClassElement classElement = target; |
| 1969 classElement.ensureResolved(compiler); | 1983 classElement.ensureResolved(compiler); |
| 1970 } | 1984 } |
| 1971 } | 1985 } |
| 1972 return target; | 1986 return target; |
| 1973 } | 1987 } |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2064 } | 2078 } |
| 2065 } | 2079 } |
| 2066 | 2080 |
| 2067 visitSend(Send node) { | 2081 visitSend(Send node) { |
| 2068 Element target = resolveSend(node); | 2082 Element target = resolveSend(node); |
| 2069 if (!Elements.isUnresolved(target) | 2083 if (!Elements.isUnresolved(target) |
| 2070 && target.kind == ElementKind.ABSTRACT_FIELD) { | 2084 && target.kind == ElementKind.ABSTRACT_FIELD) { |
| 2071 AbstractFieldElement field = target; | 2085 AbstractFieldElement field = target; |
| 2072 target = field.getter; | 2086 target = field.getter; |
| 2073 if (target == null && !inInstanceContext) { | 2087 if (target == null && !inInstanceContext) { |
| 2088 compiler.backend.registerThrowNoSuchMethod(); | |
| 2074 target = | 2089 target = |
| 2075 warnAndCreateErroneousElement(node.selector, field.name, | 2090 warnAndCreateErroneousElement(node.selector, field.name, |
| 2076 MessageKind.CANNOT_RESOLVE_GETTER); | 2091 MessageKind.CANNOT_RESOLVE_GETTER); |
| 2077 } | 2092 } |
| 2078 } | 2093 } |
| 2079 | 2094 |
| 2080 bool resolvedArguments = false; | 2095 bool resolvedArguments = false; |
| 2081 if (node.isOperator) { | 2096 if (node.isOperator) { |
| 2082 String operatorString = node.selector.asOperator().source.stringValue; | 2097 String operatorString = node.selector.asOperator().source.stringValue; |
| 2083 if (identical(operatorString, 'is') || identical(operatorString, 'as')) { | 2098 if (operatorString == 'is' || operatorString == 'as') { |
|
ahe
2013/02/18 12:38:04
This has to be identical.
| |
| 2084 assert(node.arguments.tail.isEmpty); | 2099 assert(node.arguments.tail.isEmpty); |
| 2085 DartType type = resolveTypeTest(node.arguments.head); | 2100 DartType type = resolveTypeTest(node.arguments.head); |
| 2086 if (type != null) { | 2101 if (type != null) { |
| 2087 compiler.enqueuer.resolution.registerIsCheck(type); | 2102 if (operatorString == 'as') { |
|
ahe
2013/02/18 12:38:04
Identical.
| |
| 2103 compiler.enqueuer.resolution.registerAsCheck(type); | |
| 2104 } else { | |
| 2105 compiler.enqueuer.resolution.registerIsCheck(type); | |
| 2106 } | |
| 2088 } | 2107 } |
| 2089 resolvedArguments = true; | 2108 resolvedArguments = true; |
| 2090 } else if (identical(operatorString, '?')) { | 2109 } else if (identical(operatorString, '?')) { |
| 2091 Element parameter = mapping[node.receiver]; | 2110 Element parameter = mapping[node.receiver]; |
| 2092 if (parameter == null | 2111 if (parameter == null |
| 2093 || !identical(parameter.kind, ElementKind.PARAMETER)) { | 2112 || !identical(parameter.kind, ElementKind.PARAMETER)) { |
| 2094 error(node.receiver, MessageKind.PARAMETER_NAME_EXPECTED); | 2113 error(node.receiver, MessageKind.PARAMETER_NAME_EXPECTED); |
| 2095 } else { | 2114 } else { |
| 2096 mapping.checkedParameters.add(parameter); | 2115 mapping.checkedParameters.add(parameter); |
| 2097 } | 2116 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2136 useElement(node, target); | 2155 useElement(node, target); |
| 2137 registerSend(selector, target); | 2156 registerSend(selector, target); |
| 2138 if (node.isPropertyAccess) { | 2157 if (node.isPropertyAccess) { |
| 2139 // It might be the closurization of a method. | 2158 // It might be the closurization of a method. |
| 2140 world.registerInstantiatedClass(compiler.functionClass); | 2159 world.registerInstantiatedClass(compiler.functionClass); |
| 2141 } | 2160 } |
| 2142 return node.isPropertyAccess ? target : null; | 2161 return node.isPropertyAccess ? target : null; |
| 2143 } | 2162 } |
| 2144 | 2163 |
| 2145 void warnArgumentMismatch(Send node, Element target) { | 2164 void warnArgumentMismatch(Send node, Element target) { |
| 2165 compiler.backend.registerThrowNoSuchMethod(); | |
| 2146 // TODO(karlklose): we can be more precise about the reason of the | 2166 // TODO(karlklose): we can be more precise about the reason of the |
| 2147 // mismatch. | 2167 // mismatch. |
| 2148 warning(node.argumentsNode, MessageKind.INVALID_ARGUMENTS, | 2168 warning(node.argumentsNode, MessageKind.INVALID_ARGUMENTS, |
| 2149 {'methodName': target.name}); | 2169 {'methodName': target.name}); |
| 2150 } | 2170 } |
| 2151 | 2171 |
| 2152 /// Callback for native enqueuer to parse a type. Returns [:null:] on error. | 2172 /// Callback for native enqueuer to parse a type. Returns [:null:] on error. |
| 2153 DartType resolveTypeFromString(String typeName) { | 2173 DartType resolveTypeFromString(String typeName) { |
| 2154 Element element = scope.lookup(new SourceString(typeName)); | 2174 Element element = scope.lookup(new SourceString(typeName)); |
| 2155 if (element == null) return null; | 2175 if (element == null) return null; |
| 2156 if (element is! ClassElement) return null; | 2176 if (element is! ClassElement) return null; |
| 2157 element.ensureResolved(compiler); | 2177 element.ensureResolved(compiler); |
| 2158 return element.computeType(compiler); | 2178 return element.computeType(compiler); |
| 2159 } | 2179 } |
| 2160 | 2180 |
| 2161 visitSendSet(SendSet node) { | 2181 visitSendSet(SendSet node) { |
| 2162 Element target = resolveSend(node); | 2182 Element target = resolveSend(node); |
| 2163 Element setter = target; | 2183 Element setter = target; |
| 2164 Element getter = target; | 2184 Element getter = target; |
| 2165 SourceString operatorName = node.assignmentOperator.source; | 2185 SourceString operatorName = node.assignmentOperator.source; |
| 2166 String source = operatorName.stringValue; | 2186 String source = operatorName.stringValue; |
| 2167 bool isComplex = !identical(source, '='); | 2187 bool isComplex = !identical(source, '='); |
| 2168 if (!Elements.isUnresolved(target) | 2188 if (!Elements.isUnresolved(target)) { |
| 2169 && target.kind == ElementKind.ABSTRACT_FIELD) { | 2189 if (target.isAbstractField()) { |
| 2170 AbstractFieldElement field = target; | 2190 AbstractFieldElement field = target; |
| 2171 setter = field.setter; | 2191 setter = field.setter; |
| 2172 getter = field.getter; | 2192 getter = field.getter; |
| 2173 if (setter == null && !inInstanceContext) { | 2193 if (setter == null && !inInstanceContext) { |
| 2174 setter = | 2194 setter = |
| 2175 warnAndCreateErroneousElement(node.selector, field.name, | 2195 warnAndCreateErroneousElement(node.selector, field.name, |
| 2176 MessageKind.CANNOT_RESOLVE_SETTER); | 2196 MessageKind.CANNOT_RESOLVE_SETTER); |
| 2177 } | 2197 compiler.backend.registerThrowNoSuchMethod(); |
| 2178 if (isComplex && getter == null && !inInstanceContext) { | 2198 } |
| 2179 getter = | 2199 if (isComplex && getter == null && !inInstanceContext) { |
| 2180 warnAndCreateErroneousElement(node.selector, field.name, | 2200 getter = |
| 2181 MessageKind.CANNOT_RESOLVE_GETTER); | 2201 warnAndCreateErroneousElement(node.selector, field.name, |
| 2202 MessageKind.CANNOT_RESOLVE_GETTER); | |
| 2203 compiler.backend.registerThrowNoSuchMethod(); | |
| 2204 } | |
| 2205 } else if (target.impliesType()) { | |
| 2206 compiler.backend.registerThrowNoSuchMethod(); | |
| 2182 } | 2207 } |
| 2183 } | 2208 } |
| 2184 | 2209 |
| 2185 visit(node.argumentsNode); | 2210 visit(node.argumentsNode); |
| 2186 | 2211 |
| 2187 // TODO(ngeoffray): Check if the target can be assigned. | 2212 // TODO(ngeoffray): Check if the target can be assigned. |
| 2188 // TODO(ngeoffray): Warn if target is null and the send is | 2213 // TODO(ngeoffray): Warn if target is null and the send is |
| 2189 // unqualified. | 2214 // unqualified. |
| 2190 | 2215 |
| 2191 Selector selector = mapping.getSelector(node); | 2216 Selector selector = mapping.getSelector(node); |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2323 } | 2348 } |
| 2324 world.registerStaticUse(redirectionTarget); | 2349 world.registerStaticUse(redirectionTarget); |
| 2325 world.registerInstantiatedClass( | 2350 world.registerInstantiatedClass( |
| 2326 redirectionTarget.enclosingElement.declaration); | 2351 redirectionTarget.enclosingElement.declaration); |
| 2327 } | 2352 } |
| 2328 | 2353 |
| 2329 visitThrow(Throw node) { | 2354 visitThrow(Throw node) { |
| 2330 if (!inCatchBlock && node.expression == null) { | 2355 if (!inCatchBlock && node.expression == null) { |
| 2331 error(node, MessageKind.THROW_WITHOUT_EXPRESSION); | 2356 error(node, MessageKind.THROW_WITHOUT_EXPRESSION); |
| 2332 } | 2357 } |
| 2358 compiler.backend.registerThrow(); | |
| 2333 visit(node.expression); | 2359 visit(node.expression); |
| 2334 } | 2360 } |
| 2335 | 2361 |
| 2336 visitVariableDefinitions(VariableDefinitions node) { | 2362 visitVariableDefinitions(VariableDefinitions node) { |
| 2337 VariableDefinitionsVisitor visitor = | 2363 VariableDefinitionsVisitor visitor = |
| 2338 new VariableDefinitionsVisitor(compiler, node, this, | 2364 new VariableDefinitionsVisitor(compiler, node, this, |
| 2339 ElementKind.VARIABLE); | 2365 ElementKind.VARIABLE); |
| 2340 // Ensure that we set the type of the [VariableListElement] since it depends | 2366 // Ensure that we set the type of the [VariableListElement] since it depends |
| 2341 // on the current scope. If the current scope is a [MethodScope] or | 2367 // on the current scope. If the current scope is a [MethodScope] or |
| 2342 // [BlockScope] it will not be available for the | 2368 // [BlockScope] it will not be available for the |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 2358 visit(node.expression); | 2384 visit(node.expression); |
| 2359 } | 2385 } |
| 2360 | 2386 |
| 2361 visitNewExpression(NewExpression node) { | 2387 visitNewExpression(NewExpression node) { |
| 2362 Node selector = node.send.selector; | 2388 Node selector = node.send.selector; |
| 2363 FunctionElement constructor = resolveConstructor(node); | 2389 FunctionElement constructor = resolveConstructor(node); |
| 2364 resolveSelector(node.send); | 2390 resolveSelector(node.send); |
| 2365 resolveArguments(node.send.argumentsNode); | 2391 resolveArguments(node.send.argumentsNode); |
| 2366 useElement(node.send, constructor); | 2392 useElement(node.send, constructor); |
| 2367 if (Elements.isUnresolved(constructor)) return constructor; | 2393 if (Elements.isUnresolved(constructor)) return constructor; |
| 2368 // TODO(karlklose): handle optional arguments. | 2394 Selector callSelector = mapping.getSelector(node.send); |
| 2369 if (node.send.argumentCount() != constructor.parameterCount(compiler)) { | 2395 if (!callSelector.applies(constructor, compiler)) { |
| 2370 // TODO(ngeoffray): resolution error with wrong number of | 2396 warnArgumentMismatch(node.send, constructor); |
|
ahe
2013/02/18 12:38:04
I would prefer if you did this change separately a
| |
| 2371 // parameters. We cannot do this rigth now because of the | 2397 compiler.backend.registerThrowNoSuchMethod(); |
| 2372 // List constructor. | |
| 2373 } | 2398 } |
| 2374 // [constructor] might be the implementation element and only declaration | 2399 // [constructor] might be the implementation element and only declaration |
| 2375 // elements may be registered. | 2400 // elements may be registered. |
| 2376 world.registerStaticUse(constructor.declaration); | 2401 world.registerStaticUse(constructor.declaration); |
| 2377 compiler.withCurrentElement(constructor, () { | 2402 compiler.withCurrentElement(constructor, () { |
| 2378 FunctionExpression tree = constructor.parseNode(compiler); | 2403 FunctionExpression tree = constructor.parseNode(compiler); |
| 2379 compiler.resolver.resolveConstructorImplementation(constructor, tree); | 2404 compiler.resolver.resolveConstructorImplementation(constructor, tree); |
| 2380 }); | 2405 }); |
| 2381 // [constructor.defaultImplementation] might be the implementation element | 2406 // [constructor.defaultImplementation] might be the implementation element |
| 2382 // and only declaration elements may be registered. | 2407 // and only declaration elements may be registered. |
| 2383 world.registerStaticUse(constructor.defaultImplementation.declaration); | 2408 world.registerStaticUse(constructor.defaultImplementation.declaration); |
| 2384 ClassElement cls = constructor.defaultImplementation.getEnclosingClass(); | 2409 ClassElement cls = constructor.defaultImplementation.getEnclosingClass(); |
| 2385 // [cls] might be the implementation element and only declaration elements | 2410 // [cls] might be the implementation element and only declaration elements |
| 2386 // may be registered. | 2411 // may be registered. |
| 2387 world.registerInstantiatedClass(cls.declaration); | 2412 world.registerInstantiatedClass(cls.declaration); |
| 2413 if (cls.isAbstract(compiler)) { | |
| 2414 compiler.backend.registerAbstractClassInstantiation(); | |
| 2415 } | |
| 2388 // [cls] might be the declaration element and we want to include injected | 2416 // [cls] might be the declaration element and we want to include injected |
| 2389 // members. | 2417 // members. |
| 2390 cls.implementation.forEachInstanceField( | 2418 cls.implementation.forEachInstanceField( |
| 2391 (ClassElement enclosingClass, Element member) { | 2419 (ClassElement enclosingClass, Element member) { |
| 2392 world.addToWorkList(member); | 2420 world.addToWorkList(member); |
| 2393 }, | 2421 }, |
| 2394 includeBackendMembers: false, | 2422 includeBackendMembers: false, |
| 2395 includeSuperMembers: true); | 2423 includeSuperMembers: true); |
| 2396 return null; | 2424 return null; |
| 2397 } | 2425 } |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2480 } | 2508 } |
| 2481 visit(node.elements); | 2509 visit(node.elements); |
| 2482 } | 2510 } |
| 2483 | 2511 |
| 2484 visitConditional(Conditional node) { | 2512 visitConditional(Conditional node) { |
| 2485 node.visitChildren(this); | 2513 node.visitChildren(this); |
| 2486 } | 2514 } |
| 2487 | 2515 |
| 2488 visitStringInterpolation(StringInterpolation node) { | 2516 visitStringInterpolation(StringInterpolation node) { |
| 2489 world.registerInstantiatedClass(compiler.stringClass); | 2517 world.registerInstantiatedClass(compiler.stringClass); |
| 2518 compiler.backend.registerStringInterpolation(); | |
| 2490 node.visitChildren(this); | 2519 node.visitChildren(this); |
| 2491 } | 2520 } |
| 2492 | 2521 |
| 2493 visitStringInterpolationPart(StringInterpolationPart node) { | 2522 visitStringInterpolationPart(StringInterpolationPart node) { |
| 2494 registerImplicitInvocation(const SourceString('toString'), 0); | 2523 registerImplicitInvocation(const SourceString('toString'), 0); |
| 2495 node.visitChildren(this); | 2524 node.visitChildren(this); |
| 2496 } | 2525 } |
| 2497 | 2526 |
| 2498 visitBreakStatement(BreakStatement node) { | 2527 visitBreakStatement(BreakStatement node) { |
| 2499 TargetElement target; | 2528 TargetElement target; |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2620 }); | 2649 }); |
| 2621 if (!targetElement.isTarget && identical(mapping[body], targetElement)) { | 2650 if (!targetElement.isTarget && identical(mapping[body], targetElement)) { |
| 2622 // If the body is itself a break or continue for another target, it | 2651 // If the body is itself a break or continue for another target, it |
| 2623 // might have updated its mapping to the target it actually does target. | 2652 // might have updated its mapping to the target it actually does target. |
| 2624 mapping.remove(body); | 2653 mapping.remove(body); |
| 2625 } | 2654 } |
| 2626 } | 2655 } |
| 2627 | 2656 |
| 2628 visitLiteralMap(LiteralMap node) { | 2657 visitLiteralMap(LiteralMap node) { |
| 2629 world.registerInstantiatedClass(compiler.mapClass); | 2658 world.registerInstantiatedClass(compiler.mapClass); |
| 2659 if (node.isConst()) { | |
| 2660 compiler.backend.registerConstantMap(); | |
| 2661 } | |
| 2630 node.visitChildren(this); | 2662 node.visitChildren(this); |
| 2631 } | 2663 } |
| 2632 | 2664 |
| 2633 visitLiteralMapEntry(LiteralMapEntry node) { | 2665 visitLiteralMapEntry(LiteralMapEntry node) { |
| 2634 node.visitChildren(this); | 2666 node.visitChildren(this); |
| 2635 } | 2667 } |
| 2636 | 2668 |
| 2637 visitNamedArgument(NamedArgument node) { | 2669 visitNamedArgument(NamedArgument node) { |
| 2638 visit(node.expression); | 2670 visit(node.expression); |
| 2639 } | 2671 } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2697 | 2729 |
| 2698 // Clean-up unused labels. | 2730 // Clean-up unused labels. |
| 2699 continueLabels.forEach((String key, LabelElement label) { | 2731 continueLabels.forEach((String key, LabelElement label) { |
| 2700 if (!label.isContinueTarget) { | 2732 if (!label.isContinueTarget) { |
| 2701 TargetElement targetElement = label.target; | 2733 TargetElement targetElement = label.target; |
| 2702 SwitchCase switchCase = targetElement.statement; | 2734 SwitchCase switchCase = targetElement.statement; |
| 2703 mapping.remove(switchCase); | 2735 mapping.remove(switchCase); |
| 2704 mapping.remove(label.label); | 2736 mapping.remove(label.label); |
| 2705 } | 2737 } |
| 2706 }); | 2738 }); |
| 2739 // TODO(ngeoffray): We should check here instead of the SSA backend if | |
| 2740 // there might be an error. | |
| 2741 compiler.backend.registerFallThroughError(); | |
| 2707 } | 2742 } |
| 2708 | 2743 |
| 2709 visitSwitchCase(SwitchCase node) { | 2744 visitSwitchCase(SwitchCase node) { |
| 2710 node.labelsAndCases.accept(this); | 2745 node.labelsAndCases.accept(this); |
| 2711 visitIn(node.statements, new BlockScope(scope)); | 2746 visitIn(node.statements, new BlockScope(scope)); |
| 2712 } | 2747 } |
| 2713 | 2748 |
| 2714 visitCaseMatch(CaseMatch node) { | 2749 visitCaseMatch(CaseMatch node) { |
| 2715 visit(node.expression); | 2750 visit(node.expression); |
| 2716 } | 2751 } |
| 2717 | 2752 |
| 2718 visitTryStatement(TryStatement node) { | 2753 visitTryStatement(TryStatement node) { |
| 2719 visit(node.tryBlock); | 2754 visit(node.tryBlock); |
| 2720 if (node.catchBlocks.isEmpty && node.finallyBlock == null) { | 2755 if (node.catchBlocks.isEmpty && node.finallyBlock == null) { |
| 2721 // TODO(ngeoffray): The precise location is | 2756 // TODO(ngeoffray): The precise location is |
| 2722 // node.getEndtoken.next. Adjust when issue #1581 is fixed. | 2757 // node.getEndtoken.next. Adjust when issue #1581 is fixed. |
| 2723 error(node, MessageKind.NO_CATCH_NOR_FINALLY); | 2758 error(node, MessageKind.NO_CATCH_NOR_FINALLY); |
| 2724 } | 2759 } |
| 2725 visit(node.catchBlocks); | 2760 visit(node.catchBlocks); |
| 2726 visit(node.finallyBlock); | 2761 visit(node.finallyBlock); |
| 2727 } | 2762 } |
| 2728 | 2763 |
| 2729 visitCatchBlock(CatchBlock node) { | 2764 visitCatchBlock(CatchBlock node) { |
| 2765 compiler.backend.registerCatchStatement(); | |
| 2730 // Check that if catch part is present, then | 2766 // Check that if catch part is present, then |
| 2731 // it has one or two formal parameters. | 2767 // it has one or two formal parameters. |
| 2732 if (node.formals != null) { | 2768 if (node.formals != null) { |
| 2733 if (node.formals.isEmpty) { | 2769 if (node.formals.isEmpty) { |
| 2734 error(node, MessageKind.EMPTY_CATCH_DECLARATION); | 2770 error(node, MessageKind.EMPTY_CATCH_DECLARATION); |
| 2735 } | 2771 } |
| 2736 if (!node.formals.nodes.tail.isEmpty && | 2772 if (!node.formals.nodes.tail.isEmpty) { |
| 2737 !node.formals.nodes.tail.tail.isEmpty) { | 2773 if (!node.formals.nodes.tail.tail.isEmpty) { |
|
ahe
2013/02/18 12:38:04
Generally, I really like going from && to nested i
| |
| 2738 for (Node extra in node.formals.nodes.tail.tail) { | 2774 for (Node extra in node.formals.nodes.tail.tail) { |
| 2739 error(extra, MessageKind.EXTRA_CATCH_DECLARATION); | 2775 error(extra, MessageKind.EXTRA_CATCH_DECLARATION); |
| 2776 } | |
| 2740 } | 2777 } |
| 2778 compiler.backend.registerStackTraceInCatch(); | |
| 2741 } | 2779 } |
| 2742 | 2780 |
| 2743 // Check that the formals aren't optional and that they have no | 2781 // Check that the formals aren't optional and that they have no |
| 2744 // modifiers or type. | 2782 // modifiers or type. |
| 2745 for (Link<Node> link = node.formals.nodes; | 2783 for (Link<Node> link = node.formals.nodes; |
| 2746 !link.isEmpty; | 2784 !link.isEmpty; |
| 2747 link = link.tail) { | 2785 link = link.tail) { |
| 2748 // If the formal parameter is a node list, it means that it is a | 2786 // If the formal parameter is a node list, it means that it is a |
| 2749 // sequence of optional parameters. | 2787 // sequence of optional parameters. |
| 2750 NodeList nodeList = link.head.asNodeList(); | 2788 NodeList nodeList = link.head.asNodeList(); |
| 2751 if (nodeList != null) { | 2789 if (nodeList != null) { |
| 2752 error(nodeList, MessageKind.OPTIONAL_PARAMETER_IN_CATCH); | 2790 error(nodeList, MessageKind.OPTIONAL_PARAMETER_IN_CATCH); |
| 2753 } else { | 2791 } else { |
| 2754 VariableDefinitions declaration = link.head; | 2792 VariableDefinitions declaration = link.head; |
| 2755 for (Node modifier in declaration.modifiers.nodes) { | 2793 for (Node modifier in declaration.modifiers.nodes) { |
| 2756 error(modifier, MessageKind.PARAMETER_WITH_MODIFIER_IN_CATCH); | 2794 error(modifier, MessageKind.PARAMETER_WITH_MODIFIER_IN_CATCH); |
| 2757 } | 2795 } |
| 2758 TypeAnnotation type = declaration.type; | 2796 TypeAnnotation type = declaration.type; |
| 2759 if (type != null) { | 2797 if (type != null) { |
| 2760 error(type, MessageKind.PARAMETER_WITH_TYPE_IN_CATCH); | 2798 error(type, MessageKind.PARAMETER_WITH_TYPE_IN_CATCH); |
| 2761 } | 2799 } |
| 2762 } | 2800 } |
| 2763 } | 2801 } |
| 2764 } | 2802 } |
| (...skipping 744 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3509 | 3547 |
| 3510 ConstructorResolver(Compiler compiler, this.resolver) : super(compiler); | 3548 ConstructorResolver(Compiler compiler, this.resolver) : super(compiler); |
| 3511 | 3549 |
| 3512 visitNode(Node node) { | 3550 visitNode(Node node) { |
| 3513 throw 'not supported'; | 3551 throw 'not supported'; |
| 3514 } | 3552 } |
| 3515 | 3553 |
| 3516 failOrReturnErroneousElement(Element enclosing, Node diagnosticNode, | 3554 failOrReturnErroneousElement(Element enclosing, Node diagnosticNode, |
| 3517 SourceString targetName, MessageKind kind, | 3555 SourceString targetName, MessageKind kind, |
| 3518 Map arguments) { | 3556 Map arguments) { |
| 3557 if (kind == MessageKind.CANNOT_FIND_CONSTRUCTOR) { | |
| 3558 compiler.backend.registerThrowNoSuchMethod(); | |
| 3559 } else { | |
| 3560 compiler.backend.registerThrowRuntimeError(); | |
| 3561 } | |
| 3519 if (inConstContext) { | 3562 if (inConstContext) { |
| 3520 error(diagnosticNode, kind, arguments); | 3563 error(diagnosticNode, kind, arguments); |
| 3521 } else { | 3564 } else { |
| 3522 ResolutionWarning warning = new ResolutionWarning(kind, arguments); | 3565 ResolutionWarning warning = new ResolutionWarning(kind, arguments); |
| 3523 compiler.reportWarning(diagnosticNode, warning); | 3566 compiler.reportWarning(diagnosticNode, warning); |
| 3524 return new ErroneousElementX(kind, arguments, targetName, enclosing); | 3567 return new ErroneousElementX(kind, arguments, targetName, enclosing); |
| 3525 } | 3568 } |
| 3526 } | 3569 } |
| 3527 | 3570 |
| 3528 Selector createConstructorSelector(SourceString constructorName) { | 3571 Selector createConstructorSelector(SourceString constructorName) { |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3657 return e; | 3700 return e; |
| 3658 } | 3701 } |
| 3659 | 3702 |
| 3660 /// Assumed to be called by [resolveRedirectingFactory]. | 3703 /// Assumed to be called by [resolveRedirectingFactory]. |
| 3661 Element visitReturn(Return node) { | 3704 Element visitReturn(Return node) { |
| 3662 Node expression = node.expression; | 3705 Node expression = node.expression; |
| 3663 return finishConstructorReference(visit(expression), | 3706 return finishConstructorReference(visit(expression), |
| 3664 expression, expression); | 3707 expression, expression); |
| 3665 } | 3708 } |
| 3666 } | 3709 } |
| OLD | NEW |