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 Type getType(TypeAnnotation annotation); | 8 Type getType(TypeAnnotation annotation); |
| 9 } | 9 } |
| 10 | 10 |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 342 } | 342 } |
| 343 | 343 |
| 344 void resolveImplicitSuperConstructorSend(FunctionElement constructor, | 344 void resolveImplicitSuperConstructorSend(FunctionElement constructor, |
| 345 FunctionExpression functionNode) { | 345 FunctionExpression functionNode) { |
| 346 // If the class has a super resolve the implicit super call. | 346 // If the class has a super resolve the implicit super call. |
| 347 ClassElement classElement = constructor.enclosingElement; | 347 ClassElement classElement = constructor.enclosingElement; |
| 348 ClassElement superClass = classElement.superclass; | 348 ClassElement superClass = classElement.superclass; |
| 349 if (classElement != visitor.compiler.objectClass) { | 349 if (classElement != visitor.compiler.objectClass) { |
| 350 assert(superClass !== null); | 350 assert(superClass !== null); |
| 351 assert(superClass.isResolved); | 351 assert(superClass.isResolved); |
| 352 resolveSuperOrThis(constructor, true, true, const SourceString(''), | 352 var element = resolveSuperOrThis(constructor, true, true, |
| 353 Selector.INVOCATION_0, functionNode); | 353 const SourceString(''), |
| 354 Selector.INVOCATION_0, functionNode); | |
| 355 visitor.world.registerStaticUse(element); | |
| 354 } | 356 } |
| 355 } | 357 } |
| 356 | 358 |
| 357 Element resolveSuperOrThis(FunctionElement constructor, | 359 Element resolveSuperOrThis(FunctionElement constructor, |
| 358 bool isSuperCall, | 360 bool isSuperCall, |
| 359 bool isImplicitSuperCall, | 361 bool isImplicitSuperCall, |
| 360 SourceString constructorName, | 362 SourceString constructorName, |
| 361 Selector selector, | 363 Selector selector, |
| 362 Node diagnosticNode) { | 364 Node diagnosticNode) { |
| 363 ClassElement lookupTarget = constructor.enclosingElement; | 365 ClassElement lookupTarget = constructor.enclosingElement; |
| (...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 717 super(compiler) { | 719 super(compiler) { |
| 718 LibraryElement library = element.getLibrary(); | 720 LibraryElement library = element.getLibrary(); |
| 719 element = element.getEnclosingMember(); | 721 element = element.getEnclosingMember(); |
| 720 if (element !== null) { | 722 if (element !== null) { |
| 721 context = new ClassScope(element.enclosingElement, library); | 723 context = new ClassScope(element.enclosingElement, library); |
| 722 } else { | 724 } else { |
| 723 this.context = new TopScope(library); | 725 this.context = new TopScope(library); |
| 724 } | 726 } |
| 725 } | 727 } |
| 726 | 728 |
| 729 Enqueuer get world() => compiler.enqueuer.resolution; | |
| 730 | |
| 727 Element lookup(Node node, SourceString name) { | 731 Element lookup(Node node, SourceString name) { |
| 728 Element result = context.lookup(name); | 732 Element result = context.lookup(name); |
| 729 if (!inInstanceContext && result != null && result.isInstanceMember()) { | 733 if (!inInstanceContext && result != null && result.isInstanceMember()) { |
| 730 error(node, MessageKind.NO_INSTANCE_AVAILABLE, [node]); | 734 error(node, MessageKind.NO_INSTANCE_AVAILABLE, [node]); |
| 731 } | 735 } |
| 732 return result; | 736 return result; |
| 733 } | 737 } |
| 734 | 738 |
| 735 // Create, or reuse an already created, statement element for a statement. | 739 // Create, or reuse an already created, statement element for a statement. |
| 736 TargetElement getOrCreateTargetElement(Node statement) { | 740 TargetElement getOrCreateTargetElement(Node statement) { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 796 Element existing = context.add(element); | 800 Element existing = context.add(element); |
| 797 if (existing != element) { | 801 if (existing != element) { |
| 798 error(node, MessageKind.DUPLICATE_DEFINITION, [node]); | 802 error(node, MessageKind.DUPLICATE_DEFINITION, [node]); |
| 799 } | 803 } |
| 800 } | 804 } |
| 801 return element; | 805 return element; |
| 802 } | 806 } |
| 803 | 807 |
| 804 Element useElement(Node node, Element element) { | 808 Element useElement(Node node, Element element) { |
| 805 if (element === null) return null; | 809 if (element === null) return null; |
| 806 return mapping[node] = element; | 810 mapping[node] = element; |
| 811 if (element.isTopLevel() || element.isMember()) { | |
| 812 if (element.isInstanceMember()) { | |
| 813 var send = node.asSend(); | |
| 814 if (send !== null) { | |
| 815 Selector selector = mapping.getSelector(send); | |
| 816 if (selector !== null) { | |
| 817 world.registerDynamicInvocation(element.name, selector); | |
| 818 } | |
| 819 } | |
| 820 } else { | |
| 821 if (!element.isPrefix() && | |
| 822 !element.isClass() && | |
| 823 !element.isTypedef() && | |
| 824 !element.isTypeVariable()) { | |
| 825 world.registerStaticUse(element); | |
| 826 } | |
| 827 } | |
| 828 } | |
| 829 return element; | |
| 807 } | 830 } |
| 808 | 831 |
| 809 Type useType(TypeAnnotation annotation, Type type) { | 832 Type useType(TypeAnnotation annotation, Type type) { |
| 810 if (type !== null) { | 833 if (type !== null) { |
| 811 mapping.setType(annotation, type); | 834 mapping.setType(annotation, type); |
| 812 useElement(annotation, type.element); | 835 useElement(annotation, type.element); |
| 813 } | 836 } |
| 814 return type; | 837 return type; |
| 815 } | 838 } |
| 816 | 839 |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1057 if (target === compiler.assertMethod && !node.isCall) { | 1080 if (target === compiler.assertMethod && !node.isCall) { |
| 1058 // We can only use assert by calling it. | 1081 // We can only use assert by calling it. |
| 1059 if (!inInstanceContext) { | 1082 if (!inInstanceContext) { |
| 1060 error(node, MessageKind.MISSING_ARGUMENTS_TO_ASSERT, [node]); | 1083 error(node, MessageKind.MISSING_ARGUMENTS_TO_ASSERT, [node]); |
| 1061 } | 1084 } |
| 1062 target = null; | 1085 target = null; |
| 1063 } | 1086 } |
| 1064 // TODO(ngeoffray): Warn if target is null and the send is | 1087 // TODO(ngeoffray): Warn if target is null and the send is |
| 1065 // unqualified. | 1088 // unqualified. |
| 1066 useElement(node, target); | 1089 useElement(node, target); |
| 1090 if (target === null) handleDynamicSend(node); | |
|
ngeoffray
2012/06/12 12:44:14
handleDynamicSend -> registerDynamicSend ?
ahe
2012/06/12 18:47:13
Done.
| |
| 1067 if (node.isPropertyAccess) return target; | 1091 if (node.isPropertyAccess) return target; |
| 1068 } | 1092 } |
| 1069 | 1093 |
| 1070 visitSendSet(SendSet node) { | 1094 visitSendSet(SendSet node) { |
| 1071 Element target = resolveSend(node); | 1095 Element target = resolveSend(node); |
| 1072 Element setter = null; | 1096 Element setter = null; |
| 1073 Element getter = null; | 1097 Element getter = null; |
| 1074 if (target != null && target.kind == ElementKind.ABSTRACT_FIELD) { | 1098 if (target != null && target.kind == ElementKind.ABSTRACT_FIELD) { |
| 1075 AbstractFieldElement field = target; | 1099 AbstractFieldElement field = target; |
| 1076 setter = field.setter; | 1100 setter = field.setter; |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1092 useElement(node.selector, getter); | 1116 useElement(node.selector, getter); |
| 1093 } else if (node.isIndex) { | 1117 } else if (node.isIndex) { |
| 1094 selector = Selector.INDEX_SET; | 1118 selector = Selector.INDEX_SET; |
| 1095 } else { | 1119 } else { |
| 1096 selector = Selector.SETTER; | 1120 selector = Selector.SETTER; |
| 1097 } | 1121 } |
| 1098 visit(node.argumentsNode); | 1122 visit(node.argumentsNode); |
| 1099 mapping.setSelector(node, selector); | 1123 mapping.setSelector(node, selector); |
| 1100 // TODO(ngeoffray): Warn if target is null and the send is | 1124 // TODO(ngeoffray): Warn if target is null and the send is |
| 1101 // unqualified. | 1125 // unqualified. |
| 1126 handleDynamicSend(node); | |
| 1102 return useElement(node, setter); | 1127 return useElement(node, setter); |
| 1103 } | 1128 } |
| 1104 | 1129 |
| 1130 handleDynamicSend(Send node) { | |
| 1131 Identifier id = node.selector.asIdentifier(); | |
| 1132 if (id === null) return; | |
| 1133 SourceString name = node.selector.asIdentifier().source; | |
| 1134 if (node.isIndex && !node.arguments.tail.isEmpty()) { | |
| 1135 name = Elements.constructOperatorName( | |
| 1136 const SourceString('operator'), | |
| 1137 const SourceString('[]=')); | |
| 1138 } else if (node.selector.asOperator() != null) { | |
| 1139 switch (name.stringValue) { | |
| 1140 case '===': | |
| 1141 case '!==': | |
| 1142 case '!': | |
| 1143 case '&&': | |
| 1144 case '||': | |
| 1145 case 'is': | |
| 1146 case '>>>': | |
| 1147 return null; | |
| 1148 } | |
| 1149 name = Elements.constructOperatorName( | |
| 1150 const SourceString('operator'), | |
| 1151 name, | |
| 1152 node.argumentsNode is Prefix); | |
| 1153 } | |
| 1154 Selector selector = mapping.getSelector(node); | |
| 1155 if (Selector.GETTER === selector) { | |
| 1156 world.registerDynamicGetter(name, selector); | |
| 1157 } else if (Selector.SETTER === selector) { | |
| 1158 world.registerDynamicSetter(name, selector); | |
| 1159 // Also register the getter for compound assignments. | |
| 1160 world.registerDynamicGetter(name, Selector.GETTER); | |
| 1161 } else { | |
| 1162 world.registerDynamicInvocation(name, selector); | |
| 1163 } | |
| 1164 var interceptor = new Interceptors(compiler).getStaticInterceptor( | |
| 1165 name, | |
| 1166 node.argumentCount()); | |
| 1167 if (interceptor !== null) { | |
| 1168 world.registerStaticUse(interceptor); | |
| 1169 } | |
| 1170 } | |
| 1171 | |
| 1105 visitLiteralInt(LiteralInt node) { | 1172 visitLiteralInt(LiteralInt node) { |
| 1106 } | 1173 } |
| 1107 | 1174 |
| 1108 visitLiteralDouble(LiteralDouble node) { | 1175 visitLiteralDouble(LiteralDouble node) { |
| 1109 } | 1176 } |
| 1110 | 1177 |
| 1111 visitLiteralBool(LiteralBool node) { | 1178 visitLiteralBool(LiteralBool node) { |
| 1112 } | 1179 } |
| 1113 | 1180 |
| 1114 visitLiteralString(LiteralString node) { | 1181 visitLiteralString(LiteralString node) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1162 FunctionElement constructor = resolveConstructor(node); | 1229 FunctionElement constructor = resolveConstructor(node); |
| 1163 handleArguments(node.send); | 1230 handleArguments(node.send); |
| 1164 if (constructor === null) return null; | 1231 if (constructor === null) return null; |
| 1165 // TODO(karlklose): handle optional arguments. | 1232 // TODO(karlklose): handle optional arguments. |
| 1166 if (node.send.argumentCount() != constructor.parameterCount(compiler)) { | 1233 if (node.send.argumentCount() != constructor.parameterCount(compiler)) { |
| 1167 // TODO(ngeoffray): resolution error with wrong number of | 1234 // TODO(ngeoffray): resolution error with wrong number of |
| 1168 // parameters. We cannot do this rigth now because of the | 1235 // parameters. We cannot do this rigth now because of the |
| 1169 // List constructor. | 1236 // List constructor. |
| 1170 } | 1237 } |
| 1171 useElement(node.send, constructor); | 1238 useElement(node.send, constructor); |
| 1239 compiler.withCurrentElement(constructor, () { | |
| 1240 FunctionExpression tree = constructor.parseNode(compiler); | |
| 1241 compiler.resolver.resolveConstructorImplementation(constructor, tree); | |
| 1242 }); | |
| 1243 world.registerStaticUse(constructor.defaultImplementation); | |
| 1244 ClassElement cls = constructor.defaultImplementation.enclosingElement; | |
| 1245 world.registerInstantiatedClass(cls); | |
| 1246 cls.forEachInstanceField( | |
| 1247 includeBackendMembers: false, | |
| 1248 includeSuperMembers: true, | |
| 1249 f: (ClassElement enclosingClass, Element member) { | |
| 1250 world.addToWorkList(member); | |
| 1251 }); | |
| 1172 return null; | 1252 return null; |
| 1173 } | 1253 } |
| 1174 | 1254 |
| 1175 TypeAnnotation getTypeAnnotationFromSend(Send send) { | 1255 TypeAnnotation getTypeAnnotationFromSend(Send send) { |
| 1176 if (send.selector.asTypeAnnotation() !== null) { | 1256 if (send.selector.asTypeAnnotation() !== null) { |
| 1177 return send.selector; | 1257 return send.selector; |
| 1178 } else if (send.selector.asSend() !== null) { | 1258 } else if (send.selector.asSend() !== null) { |
| 1179 Send selector = send.selector; | 1259 Send selector = send.selector; |
| 1180 if (selector.receiver.asTypeAnnotation() !== null) { | 1260 if (selector.receiver.asTypeAnnotation() !== null) { |
| 1181 return selector.receiver; | 1261 return selector.receiver; |
| (...skipping 831 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2013 | 2093 |
| 2014 TopScope(LibraryElement library) : super(null, library); | 2094 TopScope(LibraryElement library) : super(null, library); |
| 2015 Element lookup(SourceString name) { | 2095 Element lookup(SourceString name) { |
| 2016 return library.find(name); | 2096 return library.find(name); |
| 2017 } | 2097 } |
| 2018 | 2098 |
| 2019 Element add(Element newElement) { | 2099 Element add(Element newElement) { |
| 2020 throw "Cannot add an element in the top scope"; | 2100 throw "Cannot add an element in the top scope"; |
| 2021 } | 2101 } |
| 2022 } | 2102 } |
| OLD | NEW |