Chromium Code Reviews| Index: dart/frog/leg/resolver.dart |
| diff --git a/dart/frog/leg/resolver.dart b/dart/frog/leg/resolver.dart |
| index aaf42427d81ab3d84b03ab21d97f2bd0aef7b3ce..1e378adb9e42588d5a4ea29c922695106edd0b5e 100644 |
| --- a/dart/frog/leg/resolver.dart |
| +++ b/dart/frog/leg/resolver.dart |
| @@ -58,34 +58,80 @@ class ResolverTask extends CompilerTask { |
| } |
| TreeElements resolveMethodElement(FunctionElement element) { |
| - if (element.kind === ElementKind.GENERATIVE_CONSTRUCTOR && |
| - constructorElements[element] !== null) { |
| - return constructorElements[element]; |
| - } |
| - FunctionExpression tree = element.parseNode(compiler); |
| - ResolverVisitor visitor = new ResolverVisitor(compiler, element); |
| - visitor.useElement(tree, element); |
| - visitor.setupFunction(tree, element); |
| + return compiler.withCurrentElement(element, () { |
| + bool isConstructor = element.kind === ElementKind.GENERATIVE_CONSTRUCTOR; |
| + if (isConstructor) { |
| + TreeElements elements = constructorElements[element]; |
| + if (elements !== null) return elements; |
| + } |
| + FunctionExpression tree = element.parseNode(compiler); |
| + if (isConstructor) { |
| + resolveConstructorImplementation(element, tree); |
| + } |
| + ResolverVisitor visitor = new ResolverVisitor(compiler, element); |
| + visitor.useElement(tree, element); |
| + visitor.setupFunction(tree, element); |
| - if (tree.initializers != null) { |
| - new InitializerResolver(visitor, element).resolveInitializers(tree); |
| + if (tree.initializers != null) { |
| + new InitializerResolver(visitor, element).resolveInitializers(tree); |
| + } |
| + visitor.visit(tree.body); |
| + |
| + // Resolve the type annotations encountered in the method. |
| + Link<ClassElement> newResolvedClasses = const EmptyLink<ClassElement>(); |
| + while (!toResolve.isEmpty()) { |
| + ClassElement classElement = toResolve.removeFirst(); |
| + if (!classElement.isResolved) { |
| + classElement.resolve(compiler); |
| + } |
| + newResolvedClasses = newResolvedClasses.prepend(classElement); |
| + } |
| + checkClassHierarchy(newResolvedClasses); |
| + if (isConstructor) { |
| + constructorElements[element] = visitor.mapping; |
| + } |
| + return visitor.mapping; |
| + }); |
| + } |
| + |
| + void resolveConstructorImplementation(FunctionElement constructor, |
| + FunctionExpression node) { |
| + assert(constructor.implementation === constructor); |
| + ClassElement cls = constructor.enclosingElement; |
| + if (!cls.isInterface()) return; |
| + Type defaultType = cls.defaultClass; |
| + if (defaultType === null) { |
| + error(node, MessageKind.NO_DEFAULT_CLASS, [cls.name]); |
| + } |
| + ClassElement defaultClass = defaultType.element; |
| + defaultClass.resolve(compiler); |
| + if (defaultClass.isInterface()) { |
| + error(node, MessageKind.CANNOT_INSTANTIATE_INTERFACE, |
| + [defaultClass.name]); |
| } |
| - visitor.visit(tree.body); |
| - |
| - // Resolve the type annotations encountered in the method. |
| - Link<ClassElement> newResolvedClasses = const EmptyLink<ClassElement>(); |
| - while (!toResolve.isEmpty()) { |
| - ClassElement classElement = toResolve.removeFirst(); |
| - if (!classElement.isResolved) { |
| - classElement.resolve(compiler); |
| + constructor.implementation = |
| + defaultClass.lookupConstructor(constructor.name); |
| + if (constructor.implementation === null) { |
|
ngeoffray
2012/02/17 09:45:21
Maybe add a comment here that you're looking for t
ahe
2012/02/17 15:43:11
Done.
|
| + String name = constructor.name.toString(); |
| + name = name.replaceFirst(cls.name.toString(), |
| + defaultClass.name.toString()); |
| + constructor.implementation = |
| + defaultClass.lookupConstructor(new SourceString(name)); |
| + |
| + if (constructor.implementation === null |
| + && new SourceString(name) == defaultClass.name |
|
ngeoffray
2012/02/17 09:45:21
You could share new SourceString(name) with line 1
ahe
2012/02/17 15:43:11
Done.
|
| + && constructor.functionParameters.parameterCount === 0) { |
|
ngeoffray
2012/02/17 09:45:21
constructor.computeParameters(compiler).parameterC
ahe
2012/02/17 15:43:11
Done.
|
| + constructor.implementation = defaultClass.getSynthesizedConstructor(); |
| } |
| - newResolvedClasses = newResolvedClasses.prepend(classElement); |
| } |
| - checkClassHierarchy(newResolvedClasses); |
| - if (element.kind === ElementKind.GENERATIVE_CONSTRUCTOR) { |
| - constructorElements[element] = visitor.mapping; |
| + if (constructor === null) { |
|
ngeoffray
2012/02/17 09:45:21
This case cannot happen.
ahe
2012/02/17 15:43:11
Done.
|
| + error(node.send, MessageKind.CANNOT_FIND_CONSTRUCTOR, [node.send]); |
| + return null; |
| + } |
| + |
| + if (constructor.implementation === null) { |
| + error(node, MessageKind.CANNOT_FIND_CONSTRUCTOR, [name]); |
| } |
| - return visitor.mapping; |
| } |
| TreeElements resolveVariableElement(Element element) { |
| @@ -817,34 +863,32 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
| } else { |
| constructorName = typeName.asIdentifier().source; |
| } |
| + handleArguments(node.send); |
|
ngeoffray
2012/02/17 09:45:21
This should still be done at the end, otherwise yo
ahe
2012/02/17 15:43:11
Done.
|
| ClassElement cls = resolveTypeRequired(selector); |
| - Element constructor = null; |
| - if (cls !== null) { |
| - cls.resolve(compiler); |
| - if (cls.isInterface() && (cls.defaultClass === null)) { |
| - error(selector, MessageKind.CANNOT_INSTANTIATE_INTERFACE, [cls.name]); |
| - } |
| - constructor = cls.lookupConstructor(constructorName); |
| - if (constructorName == cls.name |
| - && constructor === null |
| - && node.send.argumentsNode.isEmpty()) { |
| - constructor = cls.getSynthesizedConstructor(); |
| - } |
| - if (constructor === null) { |
| - error(node.send, MessageKind.CANNOT_FIND_CONSTRUCTOR, [node.send]); |
| - } else { |
| - FunctionElement function = constructor; |
| - // TODO(karlklose): handle optional arguments. |
| - if (node.send.argumentCount() != function.parameterCount(compiler)) { |
| - // TODO(ngeoffray): reslution error with wrong number of |
| - // parameters. We cannot do this rigth now because of the |
| - // List constructor. |
| - } |
| - } |
| - } else { |
| + if (cls === null) { |
| error(selector, MessageKind.CANNOT_RESOLVE_TYPE, [selector]); |
| + return null; |
| + } |
| + cls.resolve(compiler); |
| + if (cls.isInterface() && (cls.defaultClass === null)) { |
| + error(selector, MessageKind.CANNOT_INSTANTIATE_INTERFACE, [cls.name]); |
| + } |
| + FunctionElement constructor = cls.lookupConstructor(constructorName); |
| + if (constructorName == cls.name |
| + && constructor === null |
| + && node.send.argumentsNode.isEmpty()) { |
| + constructor = cls.getSynthesizedConstructor(); |
| + } |
| + if (constructor === null) { |
| + error(node.send, MessageKind.CANNOT_FIND_CONSTRUCTOR, [node.send]); |
| + return null; |
| + } |
| + // TODO(karlklose): handle optional arguments. |
| + if (node.send.argumentCount() != constructor.parameterCount(compiler)) { |
| + // TODO(ngeoffray): resolution error with wrong number of |
| + // parameters. We cannot do this rigth now because of the |
| + // List constructor. |
| } |
| - handleArguments(node.send); |
| useElement(node.send, constructor); |
| return null; |
| } |