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

Side by Side Diff: lib/compiler/implementation/resolver.dart

Issue 10829379: Add erroneous elements for function types and use them to allow unresolvable constructors to be han… (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 4 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 interface TreeElements { 5 interface TreeElements {
6 Element operator[](Node node); 6 Element operator[](Node node);
7 Selector getSelector(Send send); 7 Selector getSelector(Send send);
8 Type getType(TypeAnnotation annotation); 8 Type getType(TypeAnnotation annotation);
9 } 9 }
10 10
(...skipping 1400 matching lines...) Expand 10 before | Expand all | Expand 10 after
1411 visit(node.condition); 1411 visit(node.condition);
1412 visitLoopBodyIn(node, node.body, new BlockScope(scope)); 1412 visitLoopBodyIn(node, node.body, new BlockScope(scope));
1413 } 1413 }
1414 1414
1415 visitParenthesizedExpression(ParenthesizedExpression node) { 1415 visitParenthesizedExpression(ParenthesizedExpression node) {
1416 visit(node.expression); 1416 visit(node.expression);
1417 } 1417 }
1418 1418
1419 visitNewExpression(NewExpression node) { 1419 visitNewExpression(NewExpression node) {
1420 Node selector = node.send.selector; 1420 Node selector = node.send.selector;
1421
1422 FunctionElement constructor = resolveConstructor(node); 1421 FunctionElement constructor = resolveConstructor(node);
1423 resolveSelector(node.send); 1422 resolveSelector(node.send);
1424 resolveArguments(node.send.argumentsNode); 1423 resolveArguments(node.send.argumentsNode);
1425 if (constructor === null) return null; 1424 useElement(node.send, constructor);
1425 if (Element.isInvalid(constructor)) return constructor;
1426 // TODO(karlklose): handle optional arguments. 1426 // TODO(karlklose): handle optional arguments.
1427 if (node.send.argumentCount() != constructor.parameterCount(compiler)) { 1427 if (node.send.argumentCount() != constructor.parameterCount(compiler)) {
1428 // TODO(ngeoffray): resolution error with wrong number of 1428 // TODO(ngeoffray): resolution error with wrong number of
1429 // parameters. We cannot do this rigth now because of the 1429 // parameters. We cannot do this rigth now because of the
1430 // List constructor. 1430 // List constructor.
1431 } 1431 }
1432 useElement(node.send, constructor);
1433 world.registerStaticUse(constructor); 1432 world.registerStaticUse(constructor);
1434 compiler.withCurrentElement(constructor, () { 1433 compiler.withCurrentElement(constructor, () {
1435 FunctionExpression tree = constructor.parseNode(compiler); 1434 FunctionExpression tree = constructor.parseNode(compiler);
1436 compiler.resolver.resolveConstructorImplementation(constructor, tree); 1435 compiler.resolver.resolveConstructorImplementation(constructor, tree);
1437 }); 1436 });
1438 world.registerStaticUse(constructor.defaultImplementation); 1437 world.registerStaticUse(constructor.defaultImplementation);
1439 ClassElement cls = constructor.defaultImplementation.getEnclosingClass(); 1438 ClassElement cls = constructor.defaultImplementation.getEnclosingClass();
1440 world.registerInstantiatedClass(cls); 1439 world.registerInstantiatedClass(cls);
1441 cls.forEachInstanceField( 1440 cls.forEachInstanceField(
1442 includeBackendMembers: false, 1441 includeBackendMembers: false,
(...skipping 10 matching lines...) Expand all
1453 } else if (send.selector.asSend() !== null) { 1452 } else if (send.selector.asSend() !== null) {
1454 Send selector = send.selector; 1453 Send selector = send.selector;
1455 if (selector.receiver.asTypeAnnotation() !== null) { 1454 if (selector.receiver.asTypeAnnotation() !== null) {
1456 return selector.receiver; 1455 return selector.receiver;
1457 } 1456 }
1458 } else { 1457 } else {
1459 compiler.internalError("malformed send in new expression"); 1458 compiler.internalError("malformed send in new expression");
1460 } 1459 }
1461 } 1460 }
1462 1461
1462 /**
1463 * Try to resolve the constructor that is referred to by this
ahe 2012/08/20 15:06:47 "this" is not NewExpression, [node] is. So: Try t
karlklose 2012/08/21 11:44:10 Done.
1464 * [NewExpression].
1465 * Note: this function may return an ErroneousFunctionElement instead of
1466 * [null], if there is no corresponding constructor, class or library.
1467 */
1463 FunctionElement resolveConstructor(NewExpression node) { 1468 FunctionElement resolveConstructor(NewExpression node) {
1464 FunctionElement constructor = 1469 FunctionElement constructor =
1465 node.accept(new ConstructorResolver(compiler, this)); 1470 node.accept(new ConstructorResolver(compiler, this));
1466 TypeAnnotation annotation = getTypeAnnotationFromSend(node.send); 1471 TypeAnnotation annotation = getTypeAnnotationFromSend(node.send);
1467 Type type = resolveTypeRequired(annotation); 1472 Type type = resolveTypeRequired(annotation);
ahe 2012/08/20 15:06:47 This looks bogus to me.
karlklose 2012/08/21 11:44:10 I added a TODO to clean this up.
1468 if (constructor === null) { 1473 if (constructor === null) {
1469 Element resolved = (type != null) ? type.element : null; 1474 Element resolved = (type != null) ? type.element : null;
1470 if (resolved !== null && resolved.kind === ElementKind.TYPE_VARIABLE) { 1475 if (resolved !== null && resolved.kind === ElementKind.TYPE_VARIABLE) {
1471 error(node, MessageKind.TYPE_VARIABLE_AS_CONSTRUCTOR); 1476 error(node, MessageKind.TYPE_VARIABLE_AS_CONSTRUCTOR);
1472 return null; 1477 return null;
1473 } else {
1474 error(node.send, MessageKind.CANNOT_FIND_CONSTRUCTOR, [node.send]);
1475 return null;
1476 } 1478 }
1477 } 1479 }
1478 return constructor; 1480 return constructor;
1479 } 1481 }
1480 1482
1481 Type resolveTypeRequired(TypeAnnotation node) { 1483 Type resolveTypeRequired(TypeAnnotation node) {
1482 bool old = typeRequired; 1484 bool old = typeRequired;
1483 typeRequired = true; 1485 typeRequired = true;
1484 Type result = resolveTypeAnnotation(node); 1486 Type result = resolveTypeAnnotation(node);
1485 typeRequired = old; 1487 typeRequired = old;
(...skipping 755 matching lines...) Expand 10 before | Expand all | Expand 10 after
2241 2243
2242 // TODO(ahe): This is temporary. 2244 // TODO(ahe): This is temporary.
2243 ClassElement get currentClass() { 2245 ClassElement get currentClass() {
2244 return enclosingElement.isMember() 2246 return enclosingElement.isMember()
2245 ? enclosingElement.getEnclosingClass() : null; 2247 ? enclosingElement.getEnclosingClass() : null;
2246 } 2248 }
2247 } 2249 }
2248 2250
2249 class ConstructorResolver extends CommonResolverVisitor<Element> { 2251 class ConstructorResolver extends CommonResolverVisitor<Element> {
2250 final ResolverVisitor resolver; 2252 final ResolverVisitor resolver;
2253
2251 ConstructorResolver(Compiler compiler, this.resolver) : super(compiler); 2254 ConstructorResolver(Compiler compiler, this.resolver) : super(compiler);
2252 2255
2253 visitNode(Node node) { 2256 visitNode(Node node) {
2254 throw 'not supported'; 2257 throw 'not supported';
2255 } 2258 }
2256 2259
2260 FunctionElement lookupConstructor(ClassElement cls,
2261 Node diagnosticNode,
2262 SourceString constructorName) {
2263 cls.ensureResolved(compiler);
2264 Element result = cls.lookupConstructor(cls.name, constructorName);
2265 if (result === null) {
2266 String fullConstructorName = cls.name.slowToString();
2267 if (constructorName !== const SourceString('')) {
2268 fullConstructorName = '$fullConstructorName'
2269 '.${constructorName.slowToString()}';
2270 }
2271 ResolutionWarning message =
2272 new ResolutionWarning(MessageKind.CANNOT_FIND_CONSTRUCTOR,
2273 [fullConstructorName]);
2274 compiler.reportWarning(diagnosticNode, message);
2275 return new ErroneousFunctionElement(message, cls);
2276 }
2277 return result;
2278 }
2279
2257 visitNewExpression(NewExpression node) { 2280 visitNewExpression(NewExpression node) {
2258 Node selector = node.send.selector; 2281 Node selector = node.send.selector;
2259 Element e = visit(selector); 2282 Element e = visit(selector);
2260 if (e !== null && e.kind === ElementKind.CLASS) { 2283 if (e !== null && e.isValid() && e.kind === ElementKind.CLASS) {
ahe 2012/08/20 15:06:47 I don't like having to check for null and valid.
karlklose 2012/08/21 11:44:10 Done, forgot to change that after introducing the
2261 ClassElement cls = e; 2284 ClassElement cls = e;
2262 cls.ensureResolved(compiler); 2285 cls.ensureResolved(compiler);
2263 if (cls.isInterface() && (cls.defaultClass === null)) { 2286 if (cls.isInterface() && (cls.defaultClass === null)) {
2264 error(selector, MessageKind.CANNOT_INSTANTIATE_INTERFACE, [cls.name]); 2287 error(selector, MessageKind.CANNOT_INSTANTIATE_INTERFACE, [cls.name]);
2265 } 2288 }
2266 e = cls.lookupConstructor(cls.name); 2289 e = lookupConstructor(cls, selector, const SourceString(''));
2267 } 2290 }
2268 return e; 2291 return e;
2269 } 2292 }
2270 2293
2271 visitTypeAnnotation(TypeAnnotation node) { 2294 visitTypeAnnotation(TypeAnnotation node) {
2272 // TODO(ahe): Do not ignore type arguments. 2295 // TODO(ahe): Do not ignore type arguments.
2273 return visit(node.typeName); 2296 return visit(node.typeName);
2274 } 2297 }
2275 2298
2276 visitSend(Send node) { 2299 visitSend(Send node) {
2277 Element e = visit(node.receiver); 2300 Element e = visit(node.receiver);
2278 if (e === null) return null; // TODO(ahe): Return erroneous element. 2301 if (e === null) return null; // TODO(ahe): Return erroneous element.
2279 2302
2280 Identifier name = node.selector.asIdentifier(); 2303 Identifier name = node.selector.asIdentifier();
2281 if (name === null) internalError(node.selector, 'unexpected node'); 2304 if (name === null) internalError(node.selector, 'unexpected node');
2282 2305
2283 if (e.kind === ElementKind.CLASS) { 2306 if (e.kind === ElementKind.CLASS) {
2284 ClassElement cls = e; 2307 ClassElement cls = e;
2285 cls.ensureResolved(compiler); 2308 cls.ensureResolved(compiler);
2286 if (cls.isInterface() && (cls.defaultClass === null)) { 2309 if (cls.isInterface() && (cls.defaultClass === null)) {
2287 error(node.receiver, MessageKind.CANNOT_INSTANTIATE_INTERFACE, 2310 error(node.receiver, MessageKind.CANNOT_INSTANTIATE_INTERFACE,
2288 [cls.name]); 2311 [cls.name]);
2289 } 2312 }
2290 SourceString constructorName = 2313 return lookupConstructor(cls, name, name.source);
2291 Elements.constructConstructorName(cls.name, name.source);
2292 FunctionElement constructor = cls.lookupConstructor(constructorName);
2293 if (constructor === null) {
2294 error(name, MessageKind.CANNOT_FIND_CONSTRUCTOR, [name]);
2295 }
2296 e = constructor;
2297 } else if (e.kind === ElementKind.PREFIX) { 2314 } else if (e.kind === ElementKind.PREFIX) {
2298 PrefixElement prefix = e; 2315 PrefixElement prefix = e;
2299 e = prefix.lookupLocalMember(name.source); 2316 e = prefix.lookupLocalMember(name.source);
2300 if (e === null) { 2317 if (e === null) {
2301 error(name, MessageKind.CANNOT_RESOLVE, [name]); 2318 error(name, MessageKind.CANNOT_RESOLVE, [name]);
2302 // TODO(ahe): Return erroneous element. 2319 // TODO(ahe): Return erroneous element.
2303 } else if (e.kind !== ElementKind.CLASS) { 2320 } else if (e.kind !== ElementKind.CLASS) {
2304 error(node, MessageKind.NOT_A_TYPE, [name]); 2321 error(node, MessageKind.NOT_A_TYPE, [name]);
2305 } 2322 }
2306 } else { 2323 } else {
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
2439 TopScope(LibraryElement library) : super(null, library); 2456 TopScope(LibraryElement library) : super(null, library);
2440 Element lookup(SourceString name) { 2457 Element lookup(SourceString name) {
2441 return library.find(name); 2458 return library.find(name);
2442 } 2459 }
2443 2460
2444 Element add(Element newElement) { 2461 Element add(Element newElement) {
2445 throw "Cannot add an element in the top scope"; 2462 throw "Cannot add an element in the top scope";
2446 } 2463 }
2447 String toString() => '$element'; 2464 String toString() => '$element';
2448 } 2465 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698