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

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: All tests pass 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.compiler.enqueuer.resolution.registerStaticUse(element);
kasperl 2012/06/12 05:50:12 Would visitor.world work?
ahe 2012/06/12 06:22:49 visitor.world.
ahe 2012/06/12 10:56:11 Done.
ahe 2012/06/12 10:56:11 Done.
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 Selector selector = mapping.getSelector(node);
814 if (selector !== null) {
815 world.registerDynamicInvocation(element.name, selector);
816 }
817 } else {
818 if (!element.isPrefix() &&
819 !element.isClass() &&
820 !element.isTypedef() &&
821 !element.isTypeVariable()) {
822 world.registerStaticUse(element);
823 }
824 }
825 } else {
826 assert(enclosingElement ===
827 element.getOutermostEnclosingMemberOrTopLevel());
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);
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 "===":
kasperl 2012/06/12 05:50:12 Use ' for string literals for consistency?
ahe 2012/06/12 10:56:11 Done.
1141 case "!==":
1142 case "!":
1143 case "&&":
1144 case "||":
1145 case "is":
1146 case ">>>":
1147 return null;
1148 }
1149 if (name === null) return;
kasperl 2012/06/12 05:50:12 Check for name === null before switching on name.s
ahe 2012/06/12 10:56:11 Removed.
1150 name = Elements.constructOperatorName(
1151 const SourceString('operator'),
1152 name,
1153 node.argumentsNode is Prefix);
1154 }
1155 Selector selector = mapping.getSelector(node);
1156 if (Selector.GETTER === selector) {
1157 world.registerDynamicGetter(name, selector);
1158 } else if (Selector.SETTER === selector) {
1159 world.registerDynamicSetter(name, selector);
1160 // Also register the getter for compound assignments.
1161 world.registerDynamicGetter(name, Selector.GETTER);
1162 } else {
1163 world.registerDynamicInvocation(name, selector);
1164 }
1165 var interceptor = new Interceptors(compiler).getStaticInterceptor(
1166 name,
1167 node.argumentCount());
1168 if (interceptor !== null) {
1169 world.registerStaticUse(interceptor);
1170 }
1171 }
1172
1105 visitLiteralInt(LiteralInt node) { 1173 visitLiteralInt(LiteralInt node) {
1106 } 1174 }
1107 1175
1108 visitLiteralDouble(LiteralDouble node) { 1176 visitLiteralDouble(LiteralDouble node) {
1109 } 1177 }
1110 1178
1111 visitLiteralBool(LiteralBool node) { 1179 visitLiteralBool(LiteralBool node) {
1112 } 1180 }
1113 1181
1114 visitLiteralString(LiteralString node) { 1182 visitLiteralString(LiteralString node) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1162 FunctionElement constructor = resolveConstructor(node); 1230 FunctionElement constructor = resolveConstructor(node);
1163 handleArguments(node.send); 1231 handleArguments(node.send);
1164 if (constructor === null) return null; 1232 if (constructor === null) return null;
1165 // TODO(karlklose): handle optional arguments. 1233 // TODO(karlklose): handle optional arguments.
1166 if (node.send.argumentCount() != constructor.parameterCount(compiler)) { 1234 if (node.send.argumentCount() != constructor.parameterCount(compiler)) {
1167 // TODO(ngeoffray): resolution error with wrong number of 1235 // TODO(ngeoffray): resolution error with wrong number of
1168 // parameters. We cannot do this rigth now because of the 1236 // parameters. We cannot do this rigth now because of the
1169 // List constructor. 1237 // List constructor.
1170 } 1238 }
1171 useElement(node.send, constructor); 1239 useElement(node.send, constructor);
1240 compiler.withCurrentElement(constructor, () {
1241 FunctionExpression tree = constructor.parseNode(compiler);
1242 compiler.resolver.resolveConstructorImplementation(constructor, tree);
1243 });
1244 world.registerStaticUse(constructor.defaultImplementation);
1245 world.registerInstantiatedClass(
1246 constructor.defaultImplementation.enclosingElement);
1247 constructor.defaultImplementation.enclosingElement.forEachInstanceField(
1248 includeBackendMembers: false,
1249 includeSuperMembers: true,
1250 f: (ClassElement enclosingClass, Element member) {
1251 world.addToWorkList(member);
1252 });
1172 return null; 1253 return null;
1173 } 1254 }
1174 1255
1175 TypeAnnotation getTypeAnnotationFromSend(Send send) { 1256 TypeAnnotation getTypeAnnotationFromSend(Send send) {
1176 if (send.selector.asTypeAnnotation() !== null) { 1257 if (send.selector.asTypeAnnotation() !== null) {
1177 return send.selector; 1258 return send.selector;
1178 } else if (send.selector.asSend() !== null) { 1259 } else if (send.selector.asSend() !== null) {
1179 Send selector = send.selector; 1260 Send selector = send.selector;
1180 if (selector.receiver.asTypeAnnotation() !== null) { 1261 if (selector.receiver.asTypeAnnotation() !== null) {
1181 return selector.receiver; 1262 return selector.receiver;
(...skipping 831 matching lines...) Expand 10 before | Expand all | Expand 10 after
2013 2094
2014 TopScope(LibraryElement library) : super(null, library); 2095 TopScope(LibraryElement library) : super(null, library);
2015 Element lookup(SourceString name) { 2096 Element lookup(SourceString name) {
2016 return library.find(name); 2097 return library.find(name);
2017 } 2098 }
2018 2099
2019 Element add(Element newElement) { 2100 Element add(Element newElement) {
2020 throw "Cannot add an element in the top scope"; 2101 throw "Cannot add an element in the top scope";
2021 } 2102 }
2022 } 2103 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698