Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 51 return resolveVariableElement(element); | 51 return resolveVariableElement(element); |
| 52 | 52 |
| 53 default: | 53 default: |
| 54 compiler.unimplemented( | 54 compiler.unimplemented( |
| 55 "resolver", node: element.parseNode(compiler)); | 55 "resolver", node: element.parseNode(compiler)); |
| 56 } | 56 } |
| 57 }); | 57 }); |
| 58 } | 58 } |
| 59 | 59 |
| 60 TreeElements resolveMethodElement(FunctionElement element) { | 60 TreeElements resolveMethodElement(FunctionElement element) { |
| 61 if (element.kind === ElementKind.GENERATIVE_CONSTRUCTOR && | 61 return compiler.withCurrentElement(element, () { |
| 62 constructorElements[element] !== null) { | 62 bool isConstructor = element.kind === ElementKind.GENERATIVE_CONSTRUCTOR; |
| 63 return constructorElements[element]; | 63 if (isConstructor) { |
| 64 TreeElements elements = constructorElements[element]; | |
| 65 if (elements !== null) return elements; | |
| 66 } | |
| 67 FunctionExpression tree = element.parseNode(compiler); | |
| 68 if (isConstructor) { | |
| 69 resolveConstructorImplementation(element, tree); | |
| 70 } | |
| 71 ResolverVisitor visitor = new ResolverVisitor(compiler, element); | |
| 72 visitor.useElement(tree, element); | |
| 73 visitor.setupFunction(tree, element); | |
| 74 | |
| 75 if (tree.initializers != null) { | |
| 76 new InitializerResolver(visitor, element).resolveInitializers(tree); | |
| 77 } | |
| 78 visitor.visit(tree.body); | |
| 79 | |
| 80 // Resolve the type annotations encountered in the method. | |
| 81 Link<ClassElement> newResolvedClasses = const EmptyLink<ClassElement>(); | |
| 82 while (!toResolve.isEmpty()) { | |
| 83 ClassElement classElement = toResolve.removeFirst(); | |
| 84 if (!classElement.isResolved) { | |
| 85 classElement.resolve(compiler); | |
| 86 } | |
| 87 newResolvedClasses = newResolvedClasses.prepend(classElement); | |
| 88 } | |
| 89 checkClassHierarchy(newResolvedClasses); | |
| 90 if (isConstructor) { | |
| 91 constructorElements[element] = visitor.mapping; | |
| 92 } | |
| 93 return visitor.mapping; | |
| 94 }); | |
| 95 } | |
| 96 | |
| 97 void resolveConstructorImplementation(FunctionElement constructor, | |
| 98 FunctionExpression node) { | |
| 99 assert(constructor.implementation === constructor); | |
| 100 ClassElement cls = constructor.enclosingElement; | |
| 101 if (!cls.isInterface()) return; | |
| 102 Type defaultType = cls.defaultClass; | |
| 103 if (defaultType === null) { | |
| 104 error(node, MessageKind.NO_DEFAULT_CLASS, [cls.name]); | |
| 64 } | 105 } |
| 65 FunctionExpression tree = element.parseNode(compiler); | 106 ClassElement defaultClass = defaultType.element; |
| 66 ResolverVisitor visitor = new ResolverVisitor(compiler, element); | 107 defaultClass.resolve(compiler); |
| 67 visitor.useElement(tree, element); | 108 if (defaultClass.isInterface()) { |
| 68 visitor.setupFunction(tree, element); | 109 error(node, MessageKind.CANNOT_INSTANTIATE_INTERFACE, |
| 110 [defaultClass.name]); | |
| 111 } | |
| 112 constructor.implementation = | |
| 113 defaultClass.lookupConstructor(constructor.name); | |
| 114 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.
| |
| 115 String name = constructor.name.toString(); | |
| 116 name = name.replaceFirst(cls.name.toString(), | |
| 117 defaultClass.name.toString()); | |
| 118 constructor.implementation = | |
| 119 defaultClass.lookupConstructor(new SourceString(name)); | |
| 69 | 120 |
| 70 if (tree.initializers != null) { | 121 if (constructor.implementation === null |
| 71 new InitializerResolver(visitor, element).resolveInitializers(tree); | 122 && 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.
| |
| 123 && constructor.functionParameters.parameterCount === 0) { | |
|
ngeoffray
2012/02/17 09:45:21
constructor.computeParameters(compiler).parameterC
ahe
2012/02/17 15:43:11
Done.
| |
| 124 constructor.implementation = defaultClass.getSynthesizedConstructor(); | |
| 125 } | |
| 72 } | 126 } |
| 73 visitor.visit(tree.body); | 127 if (constructor === null) { |
|
ngeoffray
2012/02/17 09:45:21
This case cannot happen.
ahe
2012/02/17 15:43:11
Done.
| |
| 128 error(node.send, MessageKind.CANNOT_FIND_CONSTRUCTOR, [node.send]); | |
| 129 return null; | |
| 130 } | |
| 74 | 131 |
| 75 // Resolve the type annotations encountered in the method. | 132 if (constructor.implementation === null) { |
| 76 Link<ClassElement> newResolvedClasses = const EmptyLink<ClassElement>(); | 133 error(node, MessageKind.CANNOT_FIND_CONSTRUCTOR, [name]); |
| 77 while (!toResolve.isEmpty()) { | |
| 78 ClassElement classElement = toResolve.removeFirst(); | |
| 79 if (!classElement.isResolved) { | |
| 80 classElement.resolve(compiler); | |
| 81 } | |
| 82 newResolvedClasses = newResolvedClasses.prepend(classElement); | |
| 83 } | 134 } |
| 84 checkClassHierarchy(newResolvedClasses); | |
| 85 if (element.kind === ElementKind.GENERATIVE_CONSTRUCTOR) { | |
| 86 constructorElements[element] = visitor.mapping; | |
| 87 } | |
| 88 return visitor.mapping; | |
| 89 } | 135 } |
| 90 | 136 |
| 91 TreeElements resolveVariableElement(Element element) { | 137 TreeElements resolveVariableElement(Element element) { |
| 92 Node tree = element.parseNode(compiler); | 138 Node tree = element.parseNode(compiler); |
| 93 ResolverVisitor visitor = new ResolverVisitor(compiler, element); | 139 ResolverVisitor visitor = new ResolverVisitor(compiler, element); |
| 94 if (tree is SendSet) { | 140 if (tree is SendSet) { |
| 95 SendSet send = tree; | 141 SendSet send = tree; |
| 96 visitor.visit(send.arguments.head); | 142 visitor.visit(send.arguments.head); |
| 97 } | 143 } |
| 98 return visitor.mapping; | 144 return visitor.mapping; |
| (...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 810 Node typeName = selector.asTypeAnnotation().typeName; | 856 Node typeName = selector.asTypeAnnotation().typeName; |
| 811 if (typeName.asSend() !== null) { | 857 if (typeName.asSend() !== null) { |
| 812 Identifier receiver = typeName.asSend().receiver.asIdentifier(); | 858 Identifier receiver = typeName.asSend().receiver.asIdentifier(); |
| 813 Identifier selector = typeName.asSend().selector.asIdentifier(); | 859 Identifier selector = typeName.asSend().selector.asIdentifier(); |
| 814 SourceString className = receiver.source; | 860 SourceString className = receiver.source; |
| 815 SourceString name = selector.source; | 861 SourceString name = selector.source; |
| 816 constructorName = Elements.constructConstructorName(className, name); | 862 constructorName = Elements.constructConstructorName(className, name); |
| 817 } else { | 863 } else { |
| 818 constructorName = typeName.asIdentifier().source; | 864 constructorName = typeName.asIdentifier().source; |
| 819 } | 865 } |
| 866 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.
| |
| 820 ClassElement cls = resolveTypeRequired(selector); | 867 ClassElement cls = resolveTypeRequired(selector); |
| 821 Element constructor = null; | 868 if (cls === null) { |
| 822 if (cls !== null) { | |
| 823 cls.resolve(compiler); | |
| 824 if (cls.isInterface() && (cls.defaultClass === null)) { | |
| 825 error(selector, MessageKind.CANNOT_INSTANTIATE_INTERFACE, [cls.name]); | |
| 826 } | |
| 827 constructor = cls.lookupConstructor(constructorName); | |
| 828 if (constructorName == cls.name | |
| 829 && constructor === null | |
| 830 && node.send.argumentsNode.isEmpty()) { | |
| 831 constructor = cls.getSynthesizedConstructor(); | |
| 832 } | |
| 833 if (constructor === null) { | |
| 834 error(node.send, MessageKind.CANNOT_FIND_CONSTRUCTOR, [node.send]); | |
| 835 } else { | |
| 836 FunctionElement function = constructor; | |
| 837 // TODO(karlklose): handle optional arguments. | |
| 838 if (node.send.argumentCount() != function.parameterCount(compiler)) { | |
| 839 // TODO(ngeoffray): reslution error with wrong number of | |
| 840 // parameters. We cannot do this rigth now because of the | |
| 841 // List constructor. | |
| 842 } | |
| 843 } | |
| 844 } else { | |
| 845 error(selector, MessageKind.CANNOT_RESOLVE_TYPE, [selector]); | 869 error(selector, MessageKind.CANNOT_RESOLVE_TYPE, [selector]); |
| 870 return null; | |
| 846 } | 871 } |
| 847 handleArguments(node.send); | 872 cls.resolve(compiler); |
| 873 if (cls.isInterface() && (cls.defaultClass === null)) { | |
| 874 error(selector, MessageKind.CANNOT_INSTANTIATE_INTERFACE, [cls.name]); | |
| 875 } | |
| 876 FunctionElement constructor = cls.lookupConstructor(constructorName); | |
| 877 if (constructorName == cls.name | |
| 878 && constructor === null | |
| 879 && node.send.argumentsNode.isEmpty()) { | |
| 880 constructor = cls.getSynthesizedConstructor(); | |
| 881 } | |
| 882 if (constructor === null) { | |
| 883 error(node.send, MessageKind.CANNOT_FIND_CONSTRUCTOR, [node.send]); | |
| 884 return null; | |
| 885 } | |
| 886 // TODO(karlklose): handle optional arguments. | |
| 887 if (node.send.argumentCount() != constructor.parameterCount(compiler)) { | |
| 888 // TODO(ngeoffray): resolution error with wrong number of | |
| 889 // parameters. We cannot do this rigth now because of the | |
| 890 // List constructor. | |
| 891 } | |
| 848 useElement(node.send, constructor); | 892 useElement(node.send, constructor); |
| 849 return null; | 893 return null; |
| 850 } | 894 } |
| 851 | 895 |
| 852 ClassElement resolveTypeRequired(Node node) { | 896 ClassElement resolveTypeRequired(Node node) { |
| 853 bool old = typeRequired; | 897 bool old = typeRequired; |
| 854 typeRequired = true; | 898 typeRequired = true; |
| 855 ClassElement cls = visit(node); | 899 ClassElement cls = visit(node); |
| 856 typeRequired = old; | 900 typeRequired = old; |
| 857 return cls; | 901 return cls; |
| (...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1292 class TopScope extends Scope { | 1336 class TopScope extends Scope { |
| 1293 LibraryElement get library() => element; | 1337 LibraryElement get library() => element; |
| 1294 | 1338 |
| 1295 TopScope(LibraryElement library) : super(null, library); | 1339 TopScope(LibraryElement library) : super(null, library); |
| 1296 Element lookup(SourceString name) => library.find(name); | 1340 Element lookup(SourceString name) => library.find(name); |
| 1297 | 1341 |
| 1298 Element add(Element element) { | 1342 Element add(Element element) { |
| 1299 throw "Cannot add an element in the top scope"; | 1343 throw "Cannot add an element in the top scope"; |
| 1300 } | 1344 } |
| 1301 } | 1345 } |
| OLD | NEW |