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

Side by Side Diff: pkg/compiler/lib/src/closure.dart

Issue 2603263002: Prefix resolution_types with Resolution. (Closed)
Patch Set: Rebased Created 3 years, 11 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
« no previous file with comments | « no previous file | pkg/compiler/lib/src/common/backend_api.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 library closureToClassMapper; 5 library closureToClassMapper;
6 6
7 import 'common/names.dart' show Identifiers; 7 import 'common/names.dart' show Identifiers;
8 import 'common/resolution.dart' show ParsingContext, Resolution; 8 import 'common/resolution.dart' show ParsingContext, Resolution;
9 import 'common/tasks.dart' show CompilerTask; 9 import 'common/tasks.dart' show CompilerTask;
10 import 'common.dart'; 10 import 'common.dart';
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 } 172 }
173 173
174 Expression get initializer { 174 Expression get initializer {
175 throw new SpannableAssertionFailure( 175 throw new SpannableAssertionFailure(
176 local, 'Should not access initializer of ClosureFieldElement.'); 176 local, 'Should not access initializer of ClosureFieldElement.');
177 } 177 }
178 178
179 bool get isInstanceMember => true; 179 bool get isInstanceMember => true;
180 bool get isAssignable => false; 180 bool get isAssignable => false;
181 181
182 DartType computeType(Resolution resolution) => type; 182 ResolutionDartType computeType(Resolution resolution) => type;
183 183
184 DartType get type { 184 ResolutionDartType get type {
185 if (local is LocalElement) { 185 if (local is LocalElement) {
186 LocalElement element = local; 186 LocalElement element = local;
187 return element.type; 187 return element.type;
188 } 188 }
189 return const DynamicType(); 189 return const ResolutionDynamicType();
190 } 190 }
191 191
192 String toString() => "ClosureFieldElement($name)"; 192 String toString() => "ClosureFieldElement($name)";
193 193
194 accept(ElementVisitor visitor, arg) { 194 accept(ElementVisitor visitor, arg) {
195 return visitor.visitClosureFieldElement(this, arg); 195 return visitor.visitClosureFieldElement(this, arg);
196 } 196 }
197 197
198 Element get analyzableElement => closureClass.methodElement.analyzableElement; 198 Element get analyzableElement => closureClass.methodElement.analyzableElement;
199 199
200 @override 200 @override
201 List<FunctionElement> get nestedClosures => const <FunctionElement>[]; 201 List<FunctionElement> get nestedClosures => const <FunctionElement>[];
202 202
203 @override 203 @override
204 bool get hasConstant => false; 204 bool get hasConstant => false;
205 205
206 @override 206 @override
207 ConstantExpression get constant => null; 207 ConstantExpression get constant => null;
208 } 208 }
209 209
210 // TODO(ahe): These classes continuously cause problems. We need to find 210 // TODO(ahe): These classes continuously cause problems. We need to find
211 // a more general solution. 211 // a more general solution.
212 class ClosureClassElement extends ClassElementX { 212 class ClosureClassElement extends ClassElementX {
213 DartType rawType; 213 ResolutionDartType rawType;
214 DartType thisType; 214 ResolutionDartType thisType;
215 FunctionType callType; 215 ResolutionFunctionType callType;
216 216
217 /// Node that corresponds to this closure, used for source position. 217 /// Node that corresponds to this closure, used for source position.
218 final FunctionExpression node; 218 final FunctionExpression node;
219 219
220 /** 220 /**
221 * The element for the declaration of the function expression. 221 * The element for the declaration of the function expression.
222 */ 222 */
223 final LocalFunctionElement methodElement; 223 final LocalFunctionElement methodElement;
224 224
225 final List<ClosureFieldElement> _closureFields = <ClosureFieldElement>[]; 225 final List<ClosureFieldElement> _closureFields = <ClosureFieldElement>[];
226 226
227 ClosureClassElement( 227 ClosureClassElement(
228 this.node, String name, Compiler compiler, LocalFunctionElement closure) 228 this.node, String name, Compiler compiler, LocalFunctionElement closure)
229 : this.methodElement = closure, 229 : this.methodElement = closure,
230 super( 230 super(
231 name, 231 name,
232 closure.compilationUnit, 232 closure.compilationUnit,
233 // By assigning a fresh class-id we make sure that the hashcode 233 // By assigning a fresh class-id we make sure that the hashcode
234 // is unique, but also emit closure classes after all other 234 // is unique, but also emit closure classes after all other
235 // classes (since the emitter sorts classes by their id). 235 // classes (since the emitter sorts classes by their id).
236 compiler.idGenerator.getNextFreeId(), 236 compiler.idGenerator.getNextFreeId(),
237 STATE_DONE) { 237 STATE_DONE) {
238 JavaScriptBackend backend = compiler.backend; 238 JavaScriptBackend backend = compiler.backend;
239 ClassElement superclass = methodElement.isInstanceMember 239 ClassElement superclass = methodElement.isInstanceMember
240 ? backend.helpers.boundClosureClass 240 ? backend.helpers.boundClosureClass
241 : backend.helpers.closureClass; 241 : backend.helpers.closureClass;
242 superclass.ensureResolved(compiler.resolution); 242 superclass.ensureResolved(compiler.resolution);
243 supertype = superclass.thisType; 243 supertype = superclass.thisType;
244 interfaces = const Link<DartType>(); 244 interfaces = const Link<ResolutionDartType>();
245 thisType = rawType = new InterfaceType(this); 245 thisType = rawType = new ResolutionInterfaceType(this);
246 allSupertypesAndSelf = 246 allSupertypesAndSelf =
247 superclass.allSupertypesAndSelf.extendClass(thisType); 247 superclass.allSupertypesAndSelf.extendClass(thisType);
248 callType = methodElement.type; 248 callType = methodElement.type;
249 } 249 }
250 250
251 Iterable<ClosureFieldElement> get closureFields => _closureFields; 251 Iterable<ClosureFieldElement> get closureFields => _closureFields;
252 252
253 void addField(ClosureFieldElement field, DiagnosticReporter listener) { 253 void addField(ClosureFieldElement field, DiagnosticReporter listener) {
254 _closureFields.add(field); 254 _closureFields.add(field);
255 addMember(field, listener); 255 addMember(field, listener);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 TypedElement, 296 TypedElement,
297 CapturedVariable, 297 CapturedVariable,
298 FieldElement, 298 FieldElement,
299 PrivatelyNamedJSEntity { 299 PrivatelyNamedJSEntity {
300 final BoxLocal box; 300 final BoxLocal box;
301 301
302 BoxFieldElement(String name, this.variableElement, BoxLocal box) 302 BoxFieldElement(String name, this.variableElement, BoxLocal box)
303 : this.box = box, 303 : this.box = box,
304 super(name, ElementKind.FIELD, box.executableContext); 304 super(name, ElementKind.FIELD, box.executableContext);
305 305
306 DartType computeType(Resolution resolution) => type; 306 ResolutionDartType computeType(Resolution resolution) => type;
307 307
308 DartType get type => variableElement.type; 308 ResolutionDartType get type => variableElement.type;
309 309
310 @override 310 @override
311 Entity get declaredEntity => variableElement; 311 Entity get declaredEntity => variableElement;
312 @override 312 @override
313 Entity get rootOfScope => box; 313 Entity get rootOfScope => box;
314 314
315 final VariableElement variableElement; 315 final VariableElement variableElement;
316 316
317 accept(ElementVisitor visitor, arg) { 317 accept(ElementVisitor visitor, arg) {
318 return visitor.visitBoxFieldElement(this, arg); 318 return visitor.visitBoxFieldElement(this, arg);
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
745 closureData.variablesUsedInTryOrGenerator.add(variable); 745 closureData.variablesUsedInTryOrGenerator.add(variable);
746 } 746 }
747 } else if (variable is LocalParameterElement && 747 } else if (variable is LocalParameterElement &&
748 variable.functionDeclaration.asyncMarker == AsyncMarker.SYNC_STAR) { 748 variable.functionDeclaration.asyncMarker == AsyncMarker.SYNC_STAR) {
749 // Parameters in a sync* function are shared between each Iterator created 749 // Parameters in a sync* function are shared between each Iterator created
750 // by the Iterable returned by the function, therefore they must be boxed. 750 // by the Iterable returned by the function, therefore they must be boxed.
751 closureData.variablesUsedInTryOrGenerator.add(variable); 751 closureData.variablesUsedInTryOrGenerator.add(variable);
752 } 752 }
753 } 753 }
754 754
755 void useTypeVariableAsLocal(TypeVariableType typeVariable) { 755 void useTypeVariableAsLocal(ResolutionTypeVariableType typeVariable) {
756 useLocal(new TypeVariableLocal(typeVariable, outermostElement)); 756 useLocal(new TypeVariableLocal(typeVariable, outermostElement));
757 } 757 }
758 758
759 void declareLocal(LocalVariableElement element) { 759 void declareLocal(LocalVariableElement element) {
760 scopeVariables.add(element); 760 scopeVariables.add(element);
761 } 761 }
762 762
763 void registerNeedsThis() { 763 void registerNeedsThis() {
764 if (closureData.thisLocal != null) { 764 if (closureData.thisLocal != null) {
765 useLocal(closureData.thisLocal); 765 useLocal(closureData.thisLocal);
(...skipping 27 matching lines...) Expand all
793 visit(arguments); 793 visit(arguments);
794 } 794 }
795 } else { 795 } else {
796 visit(definition); 796 visit(definition);
797 } 797 }
798 } 798 }
799 } 799 }
800 800
801 visitTypeAnnotation(TypeAnnotation node) { 801 visitTypeAnnotation(TypeAnnotation node) {
802 MemberElement member = executableContext.memberContext; 802 MemberElement member = executableContext.memberContext;
803 DartType type = elements.getType(node); 803 ResolutionDartType type = elements.getType(node);
804 // TODO(karlklose,johnniwinther): if the type is null, the annotation is 804 // TODO(karlklose,johnniwinther): if the type is null, the annotation is
805 // from a parameter which has been analyzed before the method has been 805 // from a parameter which has been analyzed before the method has been
806 // resolved and the result has been thrown away. 806 // resolved and the result has been thrown away.
807 if (compiler.options.enableTypeAssertions && 807 if (compiler.options.enableTypeAssertions &&
808 type != null && 808 type != null &&
809 type.containsTypeVariables) { 809 type.containsTypeVariables) {
810 if (insideClosure && member.isFactoryConstructor) { 810 if (insideClosure && member.isFactoryConstructor) {
811 // This is a closure in a factory constructor. Since there is no 811 // This is a closure in a factory constructor. Since there is no
812 // [:this:], we have to mark the type arguments as free variables to 812 // [:this:], we have to mark the type arguments as free variables to
813 // capture them in the closure. 813 // capture them in the closure.
814 type.forEachTypeVariable((TypeVariableType variable) { 814 type.forEachTypeVariable((ResolutionTypeVariableType variable) {
815 useTypeVariableAsLocal(variable); 815 useTypeVariableAsLocal(variable);
816 }); 816 });
817 } 817 }
818 if (member.isInstanceMember && !member.isField) { 818 if (member.isInstanceMember && !member.isField) {
819 // In checked mode, using a type variable in a type annotation may lead 819 // In checked mode, using a type variable in a type annotation may lead
820 // to a runtime type check that needs to access the type argument and 820 // to a runtime type check that needs to access the type argument and
821 // therefore the closure needs a this-element, if it is not in a field 821 // therefore the closure needs a this-element, if it is not in a field
822 // initializer; field initatializers are evaluated in a context where 822 // initializer; field initatializers are evaluated in a context where
823 // the type arguments are available in locals. 823 // the type arguments are available in locals.
824 registerNeedsThis(); 824 registerNeedsThis();
(...skipping 26 matching lines...) Expand all
851 } else if (element != null && element.isTypeVariable) { 851 } else if (element != null && element.isTypeVariable) {
852 TypeVariableElement variable = element; 852 TypeVariableElement variable = element;
853 analyzeType(variable.type); 853 analyzeType(variable.type);
854 } else if (node.receiver == null && 854 } else if (node.receiver == null &&
855 Elements.isInstanceSend(node, elements)) { 855 Elements.isInstanceSend(node, elements)) {
856 registerNeedsThis(); 856 registerNeedsThis();
857 } else if (node.isSuperCall) { 857 } else if (node.isSuperCall) {
858 registerNeedsThis(); 858 registerNeedsThis();
859 } else if (node.isTypeTest || node.isTypeCast) { 859 } else if (node.isTypeTest || node.isTypeCast) {
860 TypeAnnotation annotation = node.typeAnnotationFromIsCheckOrCast; 860 TypeAnnotation annotation = node.typeAnnotationFromIsCheckOrCast;
861 DartType type = elements.getType(annotation); 861 ResolutionDartType type = elements.getType(annotation);
862 analyzeType(type); 862 analyzeType(type);
863 } else if (node.isTypeTest) { 863 } else if (node.isTypeTest) {
864 DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast); 864 ResolutionDartType type =
865 elements.getType(node.typeAnnotationFromIsCheckOrCast);
865 analyzeType(type); 866 analyzeType(type);
866 } else if (node.isTypeCast) { 867 } else if (node.isTypeCast) {
867 DartType type = elements.getType(node.arguments.head); 868 ResolutionDartType type = elements.getType(node.arguments.head);
868 analyzeType(type); 869 analyzeType(type);
869 } 870 }
870 node.visitChildren(this); 871 node.visitChildren(this);
871 } 872 }
872 873
873 visitSendSet(SendSet node) { 874 visitSendSet(SendSet node) {
874 Element element = elements[node]; 875 Element element = elements[node];
875 if (Elements.isLocal(element)) { 876 if (Elements.isLocal(element)) {
876 mutatedVariables.add(element); 877 mutatedVariables.add(element);
877 if (compiler.options.enableTypeAssertions) { 878 if (compiler.options.enableTypeAssertions) {
878 TypedElement typedElement = element; 879 TypedElement typedElement = element;
879 analyzeTypeVariables(typedElement.type); 880 analyzeTypeVariables(typedElement.type);
880 } 881 }
881 } 882 }
882 super.visitSendSet(node); 883 super.visitSendSet(node);
883 } 884 }
884 885
885 visitNewExpression(NewExpression node) { 886 visitNewExpression(NewExpression node) {
886 DartType type = elements.getType(node); 887 ResolutionDartType type = elements.getType(node);
887 analyzeType(type); 888 analyzeType(type);
888 node.visitChildren(this); 889 node.visitChildren(this);
889 } 890 }
890 891
891 visitLiteralList(LiteralList node) { 892 visitLiteralList(LiteralList node) {
892 DartType type = elements.getType(node); 893 ResolutionDartType type = elements.getType(node);
893 analyzeType(type); 894 analyzeType(type);
894 node.visitChildren(this); 895 node.visitChildren(this);
895 } 896 }
896 897
897 visitLiteralMap(LiteralMap node) { 898 visitLiteralMap(LiteralMap node) {
898 DartType type = elements.getType(node); 899 ResolutionDartType type = elements.getType(node);
899 analyzeType(type); 900 analyzeType(type);
900 node.visitChildren(this); 901 node.visitChildren(this);
901 } 902 }
902 903
903 void analyzeTypeVariables(DartType type) { 904 void analyzeTypeVariables(ResolutionDartType type) {
904 type.forEachTypeVariable((TypeVariableType typeVariable) { 905 type.forEachTypeVariable((ResolutionTypeVariableType typeVariable) {
905 // Field initializers are inlined and access the type variable as 906 // Field initializers are inlined and access the type variable as
906 // normal parameters. 907 // normal parameters.
907 if (!outermostElement.isField && !outermostElement.isConstructor) { 908 if (!outermostElement.isField && !outermostElement.isConstructor) {
908 registerNeedsThis(); 909 registerNeedsThis();
909 } else { 910 } else {
910 useTypeVariableAsLocal(typeVariable); 911 useTypeVariableAsLocal(typeVariable);
911 } 912 }
912 }); 913 });
913 } 914 }
914 915
915 void analyzeType(DartType type) { 916 void analyzeType(ResolutionDartType type) {
916 // TODO(johnniwinther): Find out why this can be null. 917 // TODO(johnniwinther): Find out why this can be null.
917 if (type == null) return; 918 if (type == null) return;
918 if (outermostElement.isClassMember && 919 if (outermostElement.isClassMember &&
919 compiler.backend.classNeedsRti(outermostElement.enclosingClass)) { 920 compiler.backend.classNeedsRti(outermostElement.enclosingClass)) {
920 if (outermostElement.isConstructor || outermostElement.isField) { 921 if (outermostElement.isConstructor || outermostElement.isField) {
921 analyzeTypeVariables(type); 922 analyzeTypeVariables(type);
922 } else if (outermostElement.isInstanceMember) { 923 } else if (outermostElement.isInstanceMember) {
923 if (type.containsTypeVariables) { 924 if (type.containsTypeVariables) {
924 registerNeedsThis(); 925 registerNeedsThis();
925 } 926 }
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
1111 thisElement = new ThisLocal(element); 1112 thisElement = new ThisLocal(element);
1112 } 1113 }
1113 closureData = new ClosureClassMap(null, null, null, thisElement); 1114 closureData = new ClosureClassMap(null, null, null, thisElement);
1114 } 1115 }
1115 closureMappingCache[element.declaration] = closureData; 1116 closureMappingCache[element.declaration] = closureData;
1116 if (closureData.callElement != null) { 1117 if (closureData.callElement != null) {
1117 closureMappingCache[closureData.callElement] = closureData; 1118 closureMappingCache[closureData.callElement] = closureData;
1118 } 1119 }
1119 1120
1120 inNewScope(node, () { 1121 inNewScope(node, () {
1121 DartType type = element.type; 1122 ResolutionDartType type = element.type;
1122 // If the method needs RTI, or checked mode is set, we need to 1123 // If the method needs RTI, or checked mode is set, we need to
1123 // escape the potential type variables used in that closure. 1124 // escape the potential type variables used in that closure.
1124 if (element is FunctionElement && 1125 if (element is FunctionElement &&
1125 (compiler.backend.methodNeedsRti(element) || 1126 (compiler.backend.methodNeedsRti(element) ||
1126 compiler.options.enableTypeAssertions)) { 1127 compiler.options.enableTypeAssertions)) {
1127 analyzeTypeVariables(type); 1128 analyzeTypeVariables(type);
1128 } 1129 }
1129 1130
1130 visitChildren(); 1131 visitChildren();
1131 }); 1132 });
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1189 // An `await for` loop is enclosed in an implicit try-finally. 1190 // An `await for` loop is enclosed in an implicit try-finally.
1190 bool oldInTryStatement = inTryStatement; 1191 bool oldInTryStatement = inTryStatement;
1191 inTryStatement = true; 1192 inTryStatement = true;
1192 visitLoop(node); 1193 visitLoop(node);
1193 inTryStatement = oldInTryStatement; 1194 inTryStatement = oldInTryStatement;
1194 } 1195 }
1195 } 1196 }
1196 1197
1197 /// A type variable as a local variable. 1198 /// A type variable as a local variable.
1198 class TypeVariableLocal implements Local { 1199 class TypeVariableLocal implements Local {
1199 final TypeVariableType typeVariable; 1200 final ResolutionTypeVariableType typeVariable;
1200 final ExecutableElement executableContext; 1201 final ExecutableElement executableContext;
1201 1202
1202 TypeVariableLocal(this.typeVariable, this.executableContext); 1203 TypeVariableLocal(this.typeVariable, this.executableContext);
1203 1204
1204 String get name => typeVariable.name; 1205 String get name => typeVariable.name;
1205 1206
1206 int get hashCode => typeVariable.hashCode; 1207 int get hashCode => typeVariable.hashCode;
1207 1208
1208 bool operator ==(other) { 1209 bool operator ==(other) {
1209 if (other is! TypeVariableLocal) return false; 1210 if (other is! TypeVariableLocal) return false;
1210 return typeVariable == other.typeVariable; 1211 return typeVariable == other.typeVariable;
1211 } 1212 }
1212 } 1213 }
1213 1214
1214 /// 1215 ///
1215 /// Move the below classes to a JS model eventually. 1216 /// Move the below classes to a JS model eventually.
1216 /// 1217 ///
1217 abstract class JSEntity implements Entity { 1218 abstract class JSEntity implements Entity {
1218 Entity get declaredEntity; 1219 Entity get declaredEntity;
1219 } 1220 }
1220 1221
1221 abstract class PrivatelyNamedJSEntity implements JSEntity { 1222 abstract class PrivatelyNamedJSEntity implements JSEntity {
1222 Entity get rootOfScope; 1223 Entity get rootOfScope;
1223 } 1224 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/common/backend_api.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698