Chromium Code Reviews| 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; |