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

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: Address comments and rebase. 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 1433 matching lines...) Expand 10 before | Expand all | Expand 10 after
1444 visit(node.condition); 1444 visit(node.condition);
1445 visitLoopBodyIn(node, node.body, new BlockScope(scope)); 1445 visitLoopBodyIn(node, node.body, new BlockScope(scope));
1446 } 1446 }
1447 1447
1448 visitParenthesizedExpression(ParenthesizedExpression node) { 1448 visitParenthesizedExpression(ParenthesizedExpression node) {
1449 visit(node.expression); 1449 visit(node.expression);
1450 } 1450 }
1451 1451
1452 visitNewExpression(NewExpression node) { 1452 visitNewExpression(NewExpression node) {
1453 Node selector = node.send.selector; 1453 Node selector = node.send.selector;
1454
1455 FunctionElement constructor = resolveConstructor(node); 1454 FunctionElement constructor = resolveConstructor(node);
1456 resolveSelector(node.send); 1455 resolveSelector(node.send);
1457 resolveArguments(node.send.argumentsNode); 1456 resolveArguments(node.send.argumentsNode);
1458 if (constructor === null) return null; 1457 useElement(node.send, constructor);
1458 if (Element.isInvalid(constructor)) return constructor;
1459 // TODO(karlklose): handle optional arguments. 1459 // TODO(karlklose): handle optional arguments.
1460 if (node.send.argumentCount() != constructor.parameterCount(compiler)) { 1460 if (node.send.argumentCount() != constructor.parameterCount(compiler)) {
1461 // TODO(ngeoffray): resolution error with wrong number of 1461 // TODO(ngeoffray): resolution error with wrong number of
1462 // parameters. We cannot do this rigth now because of the 1462 // parameters. We cannot do this rigth now because of the
1463 // List constructor. 1463 // List constructor.
1464 } 1464 }
1465 useElement(node.send, constructor);
1466 world.registerStaticUse(constructor); 1465 world.registerStaticUse(constructor);
1467 compiler.withCurrentElement(constructor, () { 1466 compiler.withCurrentElement(constructor, () {
1468 FunctionExpression tree = constructor.parseNode(compiler); 1467 FunctionExpression tree = constructor.parseNode(compiler);
1469 compiler.resolver.resolveConstructorImplementation(constructor, tree); 1468 compiler.resolver.resolveConstructorImplementation(constructor, tree);
1470 }); 1469 });
1471 world.registerStaticUse(constructor.defaultImplementation); 1470 world.registerStaticUse(constructor.defaultImplementation);
1472 ClassElement cls = constructor.defaultImplementation.getEnclosingClass(); 1471 ClassElement cls = constructor.defaultImplementation.getEnclosingClass();
1473 world.registerInstantiatedClass(cls); 1472 world.registerInstantiatedClass(cls);
1474 cls.forEachInstanceField( 1473 cls.forEachInstanceField(
1475 includeBackendMembers: false, 1474 includeBackendMembers: false,
(...skipping 10 matching lines...) Expand all
1486 } else if (send.selector.asSend() !== null) { 1485 } else if (send.selector.asSend() !== null) {
1487 Send selector = send.selector; 1486 Send selector = send.selector;
1488 if (selector.receiver.asTypeAnnotation() !== null) { 1487 if (selector.receiver.asTypeAnnotation() !== null) {
1489 return selector.receiver; 1488 return selector.receiver;
1490 } 1489 }
1491 } else { 1490 } else {
1492 compiler.internalError("malformed send in new expression"); 1491 compiler.internalError("malformed send in new expression");
1493 } 1492 }
1494 } 1493 }
1495 1494
1495 /**
1496 * Try to resolve the constructor that is referred to by [node].
1497 * Note: this function may return an ErroneousFunctionElement instead of
1498 * [null], if there is no corresponding constructor, class or library.
1499 */
1496 FunctionElement resolveConstructor(NewExpression node) { 1500 FunctionElement resolveConstructor(NewExpression node) {
1497 FunctionElement constructor = 1501 FunctionElement constructor =
1498 node.accept(new ConstructorResolver(compiler, this)); 1502 node.accept(new ConstructorResolver(compiler, this));
1499 TypeAnnotation annotation = getTypeAnnotationFromSend(node.send); 1503 TypeAnnotation annotation = getTypeAnnotationFromSend(node.send);
1500 Type type = resolveTypeRequired(annotation); 1504 // TODO(karlklose): clean up: the type should be resolved in the
1501 if (constructor === null) { 1505 // constructor resolver visitor to avoid visiting the node twice.
1502 Element resolved = (type != null) ? type.element : null; 1506 resolveTypeRequired(annotation);
1503 if (resolved !== null && resolved.kind === ElementKind.TYPE_VARIABLE) {
1504 error(node, MessageKind.TYPE_VARIABLE_AS_CONSTRUCTOR);
1505 return null;
1506 } else {
1507 error(node.send, MessageKind.CANNOT_FIND_CONSTRUCTOR, [node.send]);
1508 return null;
1509 }
1510 }
1511 return constructor; 1507 return constructor;
1512 } 1508 }
1513 1509
1514 Type resolveTypeRequired(TypeAnnotation node) { 1510 Type resolveTypeRequired(TypeAnnotation node) {
1515 bool old = typeRequired; 1511 bool old = typeRequired;
1516 typeRequired = true; 1512 typeRequired = true;
1517 Type result = resolveTypeAnnotation(node); 1513 Type result = resolveTypeAnnotation(node);
1518 typeRequired = old; 1514 typeRequired = old;
1519 return result; 1515 return result;
1520 } 1516 }
(...skipping 796 matching lines...) Expand 10 before | Expand all | Expand 10 after
2317 2313
2318 // TODO(ahe): This is temporary. 2314 // TODO(ahe): This is temporary.
2319 ClassElement get currentClass() { 2315 ClassElement get currentClass() {
2320 return enclosingElement.isMember() 2316 return enclosingElement.isMember()
2321 ? enclosingElement.getEnclosingClass() : null; 2317 ? enclosingElement.getEnclosingClass() : null;
2322 } 2318 }
2323 } 2319 }
2324 2320
2325 class ConstructorResolver extends CommonResolverVisitor<Element> { 2321 class ConstructorResolver extends CommonResolverVisitor<Element> {
2326 final ResolverVisitor resolver; 2322 final ResolverVisitor resolver;
2323
2327 ConstructorResolver(Compiler compiler, this.resolver) : super(compiler); 2324 ConstructorResolver(Compiler compiler, this.resolver) : super(compiler);
2328 2325
2329 visitNode(Node node) { 2326 visitNode(Node node) {
2330 throw 'not supported'; 2327 throw 'not supported';
2331 } 2328 }
2332 2329
2330 FunctionElement lookupConstructor(ClassElement cls,
2331 Node diagnosticNode,
2332 SourceString constructorName) {
2333 cls.ensureResolved(compiler);
2334 Element result = cls.lookupConstructor(cls.name, constructorName);
2335 if (result === null) {
2336 String fullConstructorName = cls.name.slowToString();
2337 if (constructorName !== const SourceString('')) {
2338 fullConstructorName = '$fullConstructorName'
2339 '.${constructorName.slowToString()}';
2340 }
2341 ResolutionWarning message =
2342 new ResolutionWarning(MessageKind.CANNOT_FIND_CONSTRUCTOR,
2343 [fullConstructorName]);
2344 compiler.reportWarning(diagnosticNode, message);
2345 return new ErroneousFunctionElement(message, cls);
2346 }
2347 return result;
2348 }
2349
2333 visitNewExpression(NewExpression node) { 2350 visitNewExpression(NewExpression node) {
2334 Node selector = node.send.selector; 2351 Node selector = node.send.selector;
2335 Element e = visit(selector); 2352 Element e = visit(selector);
2336 if (e !== null && e.kind === ElementKind.CLASS) { 2353 if (!Element.isInvalid(e) && e.kind === ElementKind.CLASS) {
2337 ClassElement cls = e; 2354 ClassElement cls = e;
2338 cls.ensureResolved(compiler); 2355 cls.ensureResolved(compiler);
2339 if (cls.isInterface() && (cls.defaultClass === null)) { 2356 if (cls.isInterface() && (cls.defaultClass === null)) {
2340 error(selector, MessageKind.CANNOT_INSTANTIATE_INTERFACE, [cls.name]); 2357 error(selector, MessageKind.CANNOT_INSTANTIATE_INTERFACE, [cls.name]);
2341 } 2358 }
2342 e = cls.lookupConstructor(cls.name); 2359 e = lookupConstructor(cls, selector, const SourceString(''));
2343 } 2360 }
2344 return e; 2361 return e;
2345 } 2362 }
2346 2363
2347 visitTypeAnnotation(TypeAnnotation node) { 2364 visitTypeAnnotation(TypeAnnotation node) {
2348 // TODO(ahe): Do not ignore type arguments. 2365 // TODO(ahe): Do not ignore type arguments.
2349 return visit(node.typeName); 2366 return visit(node.typeName);
2350 } 2367 }
2351 2368
2352 visitSend(Send node) { 2369 visitSend(Send node) {
2353 Element e = visit(node.receiver); 2370 Element e = visit(node.receiver);
2354 if (e === null) return null; // TODO(ahe): Return erroneous element. 2371 if (e === null) return null; // TODO(ahe): Return erroneous element.
2355 2372
2356 Identifier name = node.selector.asIdentifier(); 2373 Identifier name = node.selector.asIdentifier();
2357 if (name === null) internalError(node.selector, 'unexpected node'); 2374 if (name === null) internalError(node.selector, 'unexpected node');
2358 2375
2359 if (e.kind === ElementKind.CLASS) { 2376 if (e.kind === ElementKind.CLASS) {
2360 ClassElement cls = e; 2377 ClassElement cls = e;
2361 cls.ensureResolved(compiler); 2378 cls.ensureResolved(compiler);
2362 if (cls.isInterface() && (cls.defaultClass === null)) { 2379 if (cls.isInterface() && (cls.defaultClass === null)) {
2363 error(node.receiver, MessageKind.CANNOT_INSTANTIATE_INTERFACE, 2380 error(node.receiver, MessageKind.CANNOT_INSTANTIATE_INTERFACE,
2364 [cls.name]); 2381 [cls.name]);
2365 } 2382 }
2366 SourceString constructorName = 2383 return lookupConstructor(cls, name, name.source);
2367 Elements.constructConstructorName(cls.name, name.source);
2368 FunctionElement constructor = cls.lookupConstructor(constructorName);
2369 if (constructor === null) {
2370 error(name, MessageKind.CANNOT_FIND_CONSTRUCTOR, [name]);
2371 }
2372 e = constructor;
2373 } else if (e.kind === ElementKind.PREFIX) { 2384 } else if (e.kind === ElementKind.PREFIX) {
2374 PrefixElement prefix = e; 2385 PrefixElement prefix = e;
2375 e = prefix.lookupLocalMember(name.source); 2386 e = prefix.lookupLocalMember(name.source);
2376 if (e === null) { 2387 if (e === null) {
2377 error(name, MessageKind.CANNOT_RESOLVE, [name]); 2388 error(name, MessageKind.CANNOT_RESOLVE, [name]);
2378 // TODO(ahe): Return erroneous element. 2389 // TODO(ahe): Return erroneous element.
2379 } else if (e.kind !== ElementKind.CLASS) { 2390 } else if (e.kind !== ElementKind.CLASS) {
2380 error(node, MessageKind.NOT_A_TYPE, [name]); 2391 error(node, MessageKind.NOT_A_TYPE, [name]);
2381 } 2392 }
2382 } else { 2393 } else {
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
2515 TopScope(LibraryElement library) : super(null, library); 2526 TopScope(LibraryElement library) : super(null, library);
2516 Element lookup(SourceString name) { 2527 Element lookup(SourceString name) {
2517 return library.find(name); 2528 return library.find(name);
2518 } 2529 }
2519 2530
2520 Element add(Element newElement) { 2531 Element add(Element newElement) {
2521 throw "Cannot add an element in the top scope"; 2532 throw "Cannot add an element in the top scope";
2522 } 2533 }
2523 String toString() => '$element'; 2534 String toString() => '$element';
2524 } 2535 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698