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

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: rebased 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 940 matching lines...) Expand 10 before | Expand all | Expand 10 after
951 visitParenthesizedExpression(ParenthesizedExpression node) { 951 visitParenthesizedExpression(ParenthesizedExpression node) {
952 visit(node.expression); 952 visit(node.expression);
953 } 953 }
954 954
955 visitNewExpression(NewExpression node) { 955 visitNewExpression(NewExpression node) {
956 if (node.isConst()) { 956 if (node.isConst()) {
957 warning(node, MessageKind.GENERIC, 957 warning(node, MessageKind.GENERIC,
958 ['const expressions are not implemented']); 958 ['const expressions are not implemented']);
959 } 959 }
960 Node selector = node.send.selector; 960 Node selector = node.send.selector;
961 if (selector.asTypeAnnotation() === null) {
962 cancel(
963 node, 'named constructors with type arguments are not implemented');
964 }
965 961
966 FunctionElement constructor = resolveConstructor(node); 962 FunctionElement constructor = resolveConstructor(node);
967 handleArguments(node.send); 963 handleArguments(node.send);
968 if (constructor === null) return null; 964 if (constructor === null) return null;
969 // TODO(karlklose): handle optional arguments. 965 // TODO(karlklose): handle optional arguments.
970 if (node.send.argumentCount() != constructor.parameterCount(compiler)) { 966 if (node.send.argumentCount() != constructor.parameterCount(compiler)) {
971 // TODO(ngeoffray): resolution error with wrong number of 967 // TODO(ngeoffray): resolution error with wrong number of
972 // parameters. We cannot do this rigth now because of the 968 // parameters. We cannot do this rigth now because of the
973 // List constructor. 969 // List constructor.
974 } 970 }
975 useElement(node.send, constructor); 971 useElement(node.send, constructor);
976 return null; 972 return null;
977 } 973 }
978 974
979 FunctionElement resolveConstructor(NewExpression node) { 975 FunctionElement resolveConstructor(NewExpression node) {
980 SourceString constructorName; 976 FunctionElement constructor =
981 Node selector = node.send.selector; 977 node.accept(new ConstructorResolver(compiler, this));
982 Node typeName = selector.asTypeAnnotation().typeName; 978 if (constructor === null) {
983 if (typeName.asSend() !== null) { 979 error(node.send, MessageKind.CANNOT_FIND_CONSTRUCTOR, [node.send]);
984 SourceString className = typeName.asSend().receiver.asIdentifier().source;
985 SourceString name = typeName.asSend().selector.asIdentifier().source;
986 constructorName = Elements.constructConstructorName(className, name);
987 } else {
988 constructorName = typeName.asIdentifier().source;
989 } 980 }
990 Element elt = resolveTypeRequired(selector); 981 return constructor;
991 if (elt === null) {
992 error(selector, MessageKind.CANNOT_RESOLVE_TYPE, [selector]);
993 return null;
994 }
995 if (elt.isTypedef()) {
996 error(selector, MessageKind.CANNOT_INSTANTIATE_TYPEDEF, [cls.name]);
997 return null;
998 }
999 if (!elt.isClass()) {
1000 error(selector, MessageKind.NOT_A_TYPE, [cls.name]);
1001 return null;
1002 }
1003 ClassElement cls = elt;
1004 cls.resolve(compiler);
1005 if (cls.isInterface() && (cls.defaultClass === null)) {
1006 error(selector, MessageKind.CANNOT_INSTANTIATE_INTERFACE, [cls.name]);
1007 }
1008 FunctionElement constructor = cls.lookupConstructor(constructorName);
1009 if (constructor !== null) return constructor;
1010 if (constructorName == cls.name && node.send.argumentsNode.isEmpty()) {
1011 return cls.getSynthesizedConstructor();
1012 }
1013 error(node.send, MessageKind.CANNOT_FIND_CONSTRUCTOR, [node.send]);
1014 return null;
1015 } 982 }
1016 983
1017 Element resolveTypeRequired(Node node) { 984 Element resolveTypeRequired(Node node) {
1018 bool old = typeRequired; 985 bool old = typeRequired;
1019 typeRequired = true; 986 typeRequired = true;
1020 Element element = visit(node); 987 Element element = visit(node);
1021 typeRequired = old; 988 typeRequired = old;
1022 return element; 989 return element;
1023 } 990 }
1024 991
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
1431 node.accept(new ResolverVisitor(compiler, enclosingElement)); 1398 node.accept(new ResolverVisitor(compiler, enclosingElement));
1432 } 1399 }
1433 1400
1434 // TODO(ahe): This is temporary. 1401 // TODO(ahe): This is temporary.
1435 ClassElement get currentClass() { 1402 ClassElement get currentClass() {
1436 return enclosingElement.isMember() 1403 return enclosingElement.isMember()
1437 ? enclosingElement.enclosingElement : null; 1404 ? enclosingElement.enclosingElement : null;
1438 } 1405 }
1439 } 1406 }
1440 1407
1408 class ConstructorResolver extends CommonResolverVisitor<Element> {
1409 final ResolverVisitor resolver;
1410 ConstructorResolver(Compiler compiler, this.resolver) : super(compiler);
1411
1412 visitNode(Node node) {
1413 throw 'not supported';
1414 }
1415
1416 visitNewExpression(NewExpression node) {
1417 Node selector = node.send.selector;
1418 Element e = visit(selector);
1419 if (e !== null && e.kind === ElementKind.CLASS) {
1420 ClassElement cls = e;
1421 cls.resolve(compiler);
1422 compiler.resolver.toResolve.add(cls);
1423 if (cls.isInterface() && (cls.defaultClass === null)) {
1424 error(selector, MessageKind.CANNOT_INSTANTIATE_INTERFACE, [cls.name]);
1425 }
1426 FunctionElement constructor = cls.lookupConstructor(cls.name);
1427 if (constructor === null && node.send.argumentsNode.isEmpty()) {
1428 e = cls.getSynthesizedConstructor();
1429 } else {
1430 e = constructor;
1431 }
1432 }
1433 return e;
1434 }
1435
1436 visitTypeAnnotation(TypeAnnotation node) {
1437 // TODO(ahe): Do not ignore type arguments.
1438 return visit(node.typeName);
1439 }
1440
1441 visitSend(Send node) {
1442 Element e = visit(node.receiver);
1443 if (e === null) return null; // TODO(ahe): Return erroneous element.
1444
1445 if (e.kind === ElementKind.CLASS) {
1446 ClassElement cls = e;
1447 cls.resolve(compiler);
1448 compiler.resolver.toResolve.add(cls);
1449 if (cls.isInterface() && (cls.defaultClass === null)) {
1450 error(node.receiver, MessageKind.CANNOT_INSTANTIATE_INTERFACE,
1451 [cls.name]);
1452 }
1453 Identifier name = node.selector.asIdentifier();
1454 if (name === null) {
1455 internalError(node.selector, 'unexpected node');
1456 }
1457 SourceString constructorName =
1458 Elements.constructConstructorName(cls.name, name.source);
1459 FunctionElement constructor = cls.lookupConstructor(constructorName);
1460 if (constructor === null) {
1461 error(name, MessageKind.CANNOT_FIND_CONSTRUCTOR, [name]);
1462 }
1463 e = constructor;
1464 } else {
1465 internalError(node.resolve, 'unexpected element $e');
1466 }
1467 return e;
1468 }
1469
1470 Element visitIdentifier(Identifier node) {
1471 SourceString name = node.source;
1472 Element e = resolver.lookup(node, name);
1473 if (e === null) {
1474 error(node, MessageKind.CANNOT_RESOLVE, [name]);
1475 // TODO(ahe): Return erroneous element.
1476 } else if (e.kind === ElementKind.TYPEDEF) {
1477 error(node, MessageKind.CANNOT_INSTANTIATE_TYPEDEF, [name]);
1478 } else if (e.kind !== ElementKind.CLASS) {
1479 error(node, MessageKind.NOT_A_TYPE, [name]);
1480 }
1481 return e;
1482 }
1483 }
1484
1441 class Scope { 1485 class Scope {
1442 final Element element; 1486 final Element element;
1443 final Scope parent; 1487 final Scope parent;
1444 1488
1445 Scope(this.parent, this.element); 1489 Scope(this.parent, this.element);
1446 abstract Element add(Element element); 1490 abstract Element add(Element element);
1447 abstract Element lookup(SourceString name); 1491 abstract Element lookup(SourceString name);
1448 } 1492 }
1449 1493
1450 class MethodScope extends Scope { 1494 class MethodScope extends Scope {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1492 class TopScope extends Scope { 1536 class TopScope extends Scope {
1493 LibraryElement get library() => element; 1537 LibraryElement get library() => element;
1494 1538
1495 TopScope(LibraryElement library) : super(null, library); 1539 TopScope(LibraryElement library) : super(null, library);
1496 Element lookup(SourceString name) => library.find(name); 1540 Element lookup(SourceString name) => library.find(name);
1497 1541
1498 Element add(Element element) { 1542 Element add(Element element) {
1499 throw "Cannot add an element in the top scope"; 1543 throw "Cannot add an element in the top scope";
1500 } 1544 }
1501 } 1545 }
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