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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « dart/frog/leg/elements/elements.dart ('k') | dart/frog/leg/scanner/parser.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: dart/frog/leg/resolver.dart
diff --git a/dart/frog/leg/resolver.dart b/dart/frog/leg/resolver.dart
index 947d7bc7f1364f74bb070052c449700895e8ee72..df3f7e1206dacd038134b7d96ef80370d39ef534 100644
--- a/dart/frog/leg/resolver.dart
+++ b/dart/frog/leg/resolver.dart
@@ -955,10 +955,6 @@ class ResolverVisitor extends CommonResolverVisitor<Element> {
['const expressions are not implemented']);
}
Node selector = node.send.selector;
- if (selector.asTypeAnnotation() === null) {
- cancel(
- node, 'named constructors with type arguments are not implemented');
- }
FunctionElement constructor = resolveConstructor(node);
handleArguments(node.send);
@@ -974,32 +970,12 @@ class ResolverVisitor extends CommonResolverVisitor<Element> {
}
FunctionElement resolveConstructor(NewExpression node) {
- SourceString constructorName;
- Node selector = node.send.selector;
- Node typeName = selector.asTypeAnnotation().typeName;
- if (typeName.asSend() !== null) {
- SourceString className = typeName.asSend().receiver.asIdentifier().source;
- SourceString name = typeName.asSend().selector.asIdentifier().source;
- constructorName = Elements.constructConstructorName(className, name);
- } else {
- constructorName = typeName.asIdentifier().source;
- }
- ClassElement cls = resolveTypeRequired(selector);
- if (cls === null) {
- error(selector, MessageKind.CANNOT_RESOLVE_TYPE, [selector]);
- return null;
+ FunctionElement constructor =
+ node.accept(new ConstructorResolver(compiler, this));
+ if (constructor === null) {
+ error(node.send, MessageKind.CANNOT_FIND_CONSTRUCTOR, [node.send]);
}
- cls.resolve(compiler);
- if (cls.isInterface() && (cls.defaultClass === null)) {
- error(selector, MessageKind.CANNOT_INSTANTIATE_INTERFACE, [cls.name]);
- }
- FunctionElement constructor = cls.lookupConstructor(constructorName);
- if (constructor !== null) return constructor;
- if (constructorName == cls.name && node.send.argumentsNode.isEmpty()) {
- return cls.getSynthesizedConstructor();
- }
- error(node.send, MessageKind.CANNOT_FIND_CONSTRUCTOR, [node.send]);
- return null;
+ return constructor;
}
ClassElement resolveTypeRequired(Node node) {
@@ -1424,6 +1400,81 @@ class SignatureResolver extends CommonResolverVisitor<Element> {
}
}
+class ConstructorResolver extends CommonResolverVisitor<Element> {
+ final ResolverVisitor resolver;
+ ConstructorResolver(Compiler compiler, this.resolver) : super(compiler);
+
+ visitNode(Node node) {
+ throw 'not supported';
+ }
+
+ visitNewExpression(NewExpression node) {
+ Node selector = node.send.selector;
+ Element e = visit(selector);
+ if (e !== null && e.kind === ElementKind.CLASS) {
+ ClassElement cls = e;
+ cls.resolve(compiler);
+ 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
+ if (cls.isInterface() && (cls.defaultClass === null)) {
+ error(selector, MessageKind.CANNOT_INSTANTIATE_INTERFACE, [cls.name]);
+ }
+ FunctionElement constructor = cls.lookupConstructor(cls.name);
+ if (constructor === null && node.send.argumentsNode.isEmpty()) {
+ e = cls.getSynthesizedConstructor();
+ } else {
+ e = constructor;
+ }
+ }
+ return e;
+ }
+
+ visitTypeAnnotation(TypeAnnotation node) {
+ // TODO(ahe): Do not ignore type arguments.
+ return visit(node.typeName);
+ }
+
+ visitSend(Send node) {
+ Element e = visit(node.receiver);
+ if (e === null) return null; // TODO(ahe): Return erroneous element.
+
+ if (e.kind === ElementKind.CLASS) {
+ ClassElement cls = e;
+ cls.resolve(compiler);
+ compiler.resolver.toResolve.add(cls);
ngeoffray 2012/03/07 11:32:06 ditto
+ if (cls.isInterface() && (cls.defaultClass === null)) {
+ error(node.receiver, MessageKind.CANNOT_INSTANTIATE_INTERFACE,
+ [cls.name]);
+ }
+ Identifier name = node.selector.asIdentifier();
+ if (name === null) {
+ internalError(node.selector, 'unexpected node');
+ }
+ SourceString constructorName =
+ Elements.constructConstructorName(cls.name, name.source);
+ FunctionElement constructor = cls.lookupConstructor(constructorName);
+ if (constructor === null) {
+ error(name, MessageKind.CANNOT_FIND_CONSTRUCTOR, [name]);
+ }
+ e = constructor;
+ } else {
+ internalError(node.resolve, 'unexpected element $e');
+ }
+ return e;
+ }
+
+ Element visitIdentifier(Identifier node) {
+ SourceString name = node.source;
+ Element e = resolver.lookup(node, name);
+ if (e === null) {
+ error(node, MessageKind.CANNOT_RESOLVE, [name]);
+ // TODO(ahe): Return erroneous element.
+ } else if (e.kind !== ElementKind.CLASS) {
+ error(node, MessageKind.NOT_A_TYPE, [name]);
+ }
+ return e;
+ }
+}
+
class Scope {
final Element element;
final Scope parent;
« 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