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

Side by Side Diff: dart/lib/compiler/implementation/resolver.dart

Issue 10542073: RFC: Resolution based tree-shaking. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Minor tweaks for the unit tests Created 8 years, 6 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698