Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/resolution/members.dart

Issue 12299008: Stop resolving all of js_helper unconditionally. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698