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

Side by Side Diff: dart/frog/leg/resolver.dart

Issue 9600059: Resolve constructors with type arguments. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 9 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
« no previous file with comments | « dart/frog/leg/elements/elements.dart ('k') | dart/frog/leg/scanner/parser.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 } 8 }
9 9
10 class TreeElementMapping implements TreeElements { 10 class TreeElementMapping implements TreeElements {
(...skipping 937 matching lines...) Expand 10 before | Expand all | Expand 10 after
948 visitParenthesizedExpression(ParenthesizedExpression node) { 948 visitParenthesizedExpression(ParenthesizedExpression node) {
949 visit(node.expression); 949 visit(node.expression);
950 } 950 }
951 951
952 visitNewExpression(NewExpression node) { 952 visitNewExpression(NewExpression node) {
953 if (node.isConst()) { 953 if (node.isConst()) {
954 warning(node, MessageKind.GENERIC, 954 warning(node, MessageKind.GENERIC,
955 ['const expressions are not implemented']); 955 ['const expressions are not implemented']);
956 } 956 }
957 Node selector = node.send.selector; 957 Node selector = node.send.selector;
958 if (selector.asTypeAnnotation() === null) {
959 cancel(
960 node, 'named constructors with type arguments are not implemented');
961 }
962 958
963 FunctionElement constructor = resolveConstructor(node); 959 FunctionElement constructor = resolveConstructor(node);
964 handleArguments(node.send); 960 handleArguments(node.send);
965 if (constructor === null) return null; 961 if (constructor === null) return null;
966 // TODO(karlklose): handle optional arguments. 962 // TODO(karlklose): handle optional arguments.
967 if (node.send.argumentCount() != constructor.parameterCount(compiler)) { 963 if (node.send.argumentCount() != constructor.parameterCount(compiler)) {
968 // TODO(ngeoffray): resolution error with wrong number of 964 // TODO(ngeoffray): resolution error with wrong number of
969 // parameters. We cannot do this rigth now because of the 965 // parameters. We cannot do this rigth now because of the
970 // List constructor. 966 // List constructor.
971 } 967 }
972 useElement(node.send, constructor); 968 useElement(node.send, constructor);
973 return null; 969 return null;
974 } 970 }
975 971
976 FunctionElement resolveConstructor(NewExpression node) { 972 FunctionElement resolveConstructor(NewExpression node) {
977 SourceString constructorName; 973 FunctionElement constructor =
978 Node selector = node.send.selector; 974 node.accept(new ConstructorResolver(compiler, this));
979 Node typeName = selector.asTypeAnnotation().typeName; 975 if (constructor === null) {
980 if (typeName.asSend() !== null) { 976 error(node.send, MessageKind.CANNOT_FIND_CONSTRUCTOR, [node.send]);
981 SourceString className = typeName.asSend().receiver.asIdentifier().source;
982 SourceString name = typeName.asSend().selector.asIdentifier().source;
983 constructorName = Elements.constructConstructorName(className, name);
984 } else {
985 constructorName = typeName.asIdentifier().source;
986 } 977 }
987 ClassElement cls = resolveTypeRequired(selector); 978 return constructor;
988 if (cls === null) {
989 error(selector, MessageKind.CANNOT_RESOLVE_TYPE, [selector]);
990 return null;
991 }
992 cls.resolve(compiler);
993 if (cls.isInterface() && (cls.defaultClass === null)) {
994 error(selector, MessageKind.CANNOT_INSTANTIATE_INTERFACE, [cls.name]);
995 }
996 FunctionElement constructor = cls.lookupConstructor(constructorName);
997 if (constructor !== null) return constructor;
998 if (constructorName == cls.name && node.send.argumentsNode.isEmpty()) {
999 return cls.getSynthesizedConstructor();
1000 }
1001 error(node.send, MessageKind.CANNOT_FIND_CONSTRUCTOR, [node.send]);
1002 return null;
1003 } 979 }
1004 980
1005 ClassElement resolveTypeRequired(Node node) { 981 ClassElement resolveTypeRequired(Node node) {
1006 bool old = typeRequired; 982 bool old = typeRequired;
1007 typeRequired = true; 983 typeRequired = true;
1008 ClassElement cls = visit(node); 984 ClassElement cls = visit(node);
1009 typeRequired = old; 985 typeRequired = old;
1010 return cls; 986 return cls;
1011 } 987 }
1012 988
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
1417 node.accept(new ResolverVisitor(compiler, enclosingElement)); 1393 node.accept(new ResolverVisitor(compiler, enclosingElement));
1418 } 1394 }
1419 1395
1420 // TODO(ahe): This is temporary. 1396 // TODO(ahe): This is temporary.
1421 ClassElement get currentClass() { 1397 ClassElement get currentClass() {
1422 return enclosingElement.isMember() 1398 return enclosingElement.isMember()
1423 ? enclosingElement.enclosingElement : null; 1399 ? enclosingElement.enclosingElement : null;
1424 } 1400 }
1425 } 1401 }
1426 1402
1403 class ConstructorResolver extends CommonResolverVisitor<Element> {
1404 final ResolverVisitor resolver;
1405 ConstructorResolver(Compiler compiler, this.resolver) : super(compiler);
1406
1407 visitNode(Node node) {
1408 throw 'not supported';
1409 }
1410
1411 visitNewExpression(NewExpression node) {
1412 Node selector = node.send.selector;
1413 Element e = visit(selector);
1414 if (e !== null && e.kind === ElementKind.CLASS) {
1415 ClassElement cls = e;
1416 cls.resolve(compiler);
1417 compiler.resolver.toResolve.add(cls);
ngeoffray 2012/03/07 11:32:06 You don't need to add it to the list of classes to
ahe 2012/03/07 11:34:32 I think I do for its supertypes.
ngeoffray 2012/03/07 11:37:41 I see. Initially, toResolve was only for delaying
ahe 2012/03/07 21:04:09 OK. This is somewhat complicated. I have implement
1418 if (cls.isInterface() && (cls.defaultClass === null)) {
1419 error(selector, MessageKind.CANNOT_INSTANTIATE_INTERFACE, [cls.name]);
1420 }
1421 FunctionElement constructor = cls.lookupConstructor(cls.name);
1422 if (constructor === null && node.send.argumentsNode.isEmpty()) {
1423 e = cls.getSynthesizedConstructor();
1424 } else {
1425 e = constructor;
1426 }
1427 }
1428 return e;
1429 }
1430
1431 visitTypeAnnotation(TypeAnnotation node) {
1432 // TODO(ahe): Do not ignore type arguments.
1433 return visit(node.typeName);
1434 }
1435
1436 visitSend(Send node) {
1437 Element e = visit(node.receiver);
1438 if (e === null) return null; // TODO(ahe): Return erroneous element.
1439
1440 if (e.kind === ElementKind.CLASS) {
1441 ClassElement cls = e;
1442 cls.resolve(compiler);
1443 compiler.resolver.toResolve.add(cls);
ngeoffray 2012/03/07 11:32:06 ditto
1444 if (cls.isInterface() && (cls.defaultClass === null)) {
1445 error(node.receiver, MessageKind.CANNOT_INSTANTIATE_INTERFACE,
1446 [cls.name]);
1447 }
1448 Identifier name = node.selector.asIdentifier();
1449 if (name === null) {
1450 internalError(node.selector, 'unexpected node');
1451 }
1452 SourceString constructorName =
1453 Elements.constructConstructorName(cls.name, name.source);
1454 FunctionElement constructor = cls.lookupConstructor(constructorName);
1455 if (constructor === null) {
1456 error(name, MessageKind.CANNOT_FIND_CONSTRUCTOR, [name]);
1457 }
1458 e = constructor;
1459 } else {
1460 internalError(node.resolve, 'unexpected element $e');
1461 }
1462 return e;
1463 }
1464
1465 Element visitIdentifier(Identifier node) {
1466 SourceString name = node.source;
1467 Element e = resolver.lookup(node, name);
1468 if (e === null) {
1469 error(node, MessageKind.CANNOT_RESOLVE, [name]);
1470 // TODO(ahe): Return erroneous element.
1471 } else if (e.kind !== ElementKind.CLASS) {
1472 error(node, MessageKind.NOT_A_TYPE, [name]);
1473 }
1474 return e;
1475 }
1476 }
1477
1427 class Scope { 1478 class Scope {
1428 final Element element; 1479 final Element element;
1429 final Scope parent; 1480 final Scope parent;
1430 1481
1431 Scope(this.parent, this.element); 1482 Scope(this.parent, this.element);
1432 abstract Element add(Element element); 1483 abstract Element add(Element element);
1433 abstract Element lookup(SourceString name); 1484 abstract Element lookup(SourceString name);
1434 } 1485 }
1435 1486
1436 class MethodScope extends Scope { 1487 class MethodScope extends Scope {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1478 class TopScope extends Scope { 1529 class TopScope extends Scope {
1479 LibraryElement get library() => element; 1530 LibraryElement get library() => element;
1480 1531
1481 TopScope(LibraryElement library) : super(null, library); 1532 TopScope(LibraryElement library) : super(null, library);
1482 Element lookup(SourceString name) => library.find(name); 1533 Element lookup(SourceString name) => library.find(name);
1483 1534
1484 Element add(Element element) { 1535 Element add(Element element) {
1485 throw "Cannot add an element in the top scope"; 1536 throw "Cannot add an element in the top scope";
1486 } 1537 }
1487 } 1538 }
OLDNEW
« no previous file with comments | « dart/frog/leg/elements/elements.dart ('k') | dart/frog/leg/scanner/parser.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698