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

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: 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 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 ff55a582dcd5b76566158e3d53970fda5ef4a5b9..d64d0e46baa57728cc047140ab2b26177302a902 100644
--- a/dart/frog/leg/resolver.dart
+++ b/dart/frog/leg/resolver.dart
@@ -958,10 +958,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);
@@ -977,41 +973,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;
- }
- Element elt = resolveTypeRequired(selector);
- if (elt === null) {
- error(selector, MessageKind.CANNOT_RESOLVE_TYPE, [selector]);
- return null;
- }
- if (elt.isTypedef()) {
- error(selector, MessageKind.CANNOT_INSTANTIATE_TYPEDEF, [cls.name]);
- return null;
- }
- if (!elt.isClass()) {
- error(selector, MessageKind.NOT_A_TYPE, [cls.name]);
- return null;
- }
- ClassElement cls = elt;
- cls.resolve(compiler);
- if (cls.isInterface() && (cls.defaultClass === null)) {
- error(selector, MessageKind.CANNOT_INSTANTIATE_INTERFACE, [cls.name]);
+ FunctionElement constructor =
+ node.accept(new ConstructorResolver(compiler, this));
+ if (constructor === null) {
+ error(node.send, MessageKind.CANNOT_FIND_CONSTRUCTOR, [node.send]);
}
- 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;
}
Element resolveTypeRequired(Node node) {
@@ -1438,6 +1405,83 @@ 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);
+ 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);
+ 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.TYPEDEF) {
+ error(node, MessageKind.CANNOT_INSTANTIATE_TYPEDEF, [name]);
+ } 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