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 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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 !element.isInstanceMember && | 74 !element.isInstanceMember && |
75 resolvedAst.body == null) { | 75 resolvedAst.body == null) { |
76 // Skip top-level/static fields without an initializer. | 76 // Skip top-level/static fields without an initializer. |
77 return; | 77 return; |
78 } | 78 } |
79 computeClosureToClassMapping(element, closedWorldRefiner); | 79 computeClosureToClassMapping(element, closedWorldRefiner); |
80 }); | 80 }); |
81 } | 81 } |
82 | 82 |
83 ClosureClassMap computeClosureToClassMapping( | 83 ClosureClassMap computeClosureToClassMapping( |
84 AstElement element, ClosedWorldRefiner closedWorldRefiner) { | 84 MemberElement element, ClosedWorldRefiner closedWorldRefiner) { |
85 return measure(() { | 85 return measure(() { |
86 ClosureClassMap cached = _closureMappingCache[element]; | 86 ClosureClassMap cached = _closureMappingCache[element]; |
87 if (cached != null) return cached; | 87 if (cached != null) return cached; |
88 if (element.resolvedAst.kind != ResolvedAstKind.PARSED) { | 88 if (element.resolvedAst.kind != ResolvedAstKind.PARSED) { |
89 return _closureMappingCache[element] = | 89 return _closureMappingCache[element] = |
90 new ClosureClassMap(null, null, null, new ThisLocal(element)); | 90 new ClosureClassMap(null, null, null, new ThisLocal(element)); |
91 } | 91 } |
92 return reporter.withCurrentElement(element.implementation, () { | 92 return reporter.withCurrentElement(element.implementation, () { |
93 Node node = element.resolvedAst.node; | 93 Node node = element.resolvedAst.node; |
94 TreeElements elements = element.resolvedAst.elements; | 94 TreeElements elements = element.resolvedAst.elements; |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 | 343 |
344 @override | 344 @override |
345 bool get hasConstant => false; | 345 bool get hasConstant => false; |
346 | 346 |
347 @override | 347 @override |
348 ConstantExpression get constant => null; | 348 ConstantExpression get constant => null; |
349 } | 349 } |
350 | 350 |
351 /// A local variable used encode the direct (uncaptured) references to [this]. | 351 /// A local variable used encode the direct (uncaptured) references to [this]. |
352 class ThisLocal extends Local { | 352 class ThisLocal extends Local { |
353 final ExecutableElement executableContext; | 353 final MemberEntity memberContext; |
354 final hashCode = ElementX.newHashCode(); | 354 final hashCode = ElementX.newHashCode(); |
355 | 355 |
356 ThisLocal(this.executableContext); | 356 ThisLocal(this.memberContext); |
357 | 357 |
358 @override | 358 Entity get executableContext => memberContext; |
359 MemberElement get memberContext => executableContext.memberContext; | |
360 | 359 |
361 String get name => 'this'; | 360 String get name => 'this'; |
362 | 361 |
363 ClassElement get enclosingClass => executableContext.enclosingClass; | 362 ClassEntity get enclosingClass => memberContext.enclosingClass; |
364 } | 363 } |
365 | 364 |
366 /// Call method of a closure class. | 365 /// Call method of a closure class. |
367 class SynthesizedCallMethodElementX extends BaseFunctionElementX | 366 class SynthesizedCallMethodElementX extends BaseFunctionElementX |
368 implements MethodElement { | 367 implements MethodElement { |
369 final LocalFunctionElement expression; | 368 final LocalFunctionElement expression; |
370 final FunctionExpression node; | 369 final FunctionExpression node; |
371 final TreeElements treeElements; | 370 final TreeElements treeElements; |
372 | 371 |
373 SynthesizedCallMethodElementX(String name, LocalFunctionElement other, | 372 SynthesizedCallMethodElementX(String name, LocalFunctionElement other, |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
645 // The [:elements[node]:] always points to the generative-constructor | 644 // The [:elements[node]:] always points to the generative-constructor |
646 // element, whereas the [element] might be the constructor-body element. | 645 // element, whereas the [element] might be the constructor-body element. |
647 visit(node); // [visitFunctionExpression] will call [visitInvokable]. | 646 visit(node); // [visitFunctionExpression] will call [visitInvokable]. |
648 // When variables need to be boxed their [_capturedVariableMapping] is | 647 // When variables need to be boxed their [_capturedVariableMapping] is |
649 // updated, but we delay updating the similar freeVariableMapping in the | 648 // updated, but we delay updating the similar freeVariableMapping in the |
650 // closure datas that capture these variables. | 649 // closure datas that capture these variables. |
651 // The closures don't have their fields (in the closure class) set, either. | 650 // The closures don't have their fields (in the closure class) set, either. |
652 updateClosures(); | 651 updateClosures(); |
653 } | 652 } |
654 | 653 |
655 void translateLazyInitializer(VariableElement element, | 654 void translateLazyInitializer( |
656 VariableDefinitions node, Expression initializer) { | 655 FieldElement element, VariableDefinitions node, Expression initializer) { |
657 visitInvokable(element, node, () { | 656 visitInvokable(element, node, () { |
658 visit(initializer); | 657 visit(initializer); |
659 }); | 658 }); |
660 updateClosures(); | 659 updateClosures(); |
661 } | 660 } |
662 | 661 |
663 // This function runs through all of the existing closures and updates their | 662 // This function runs through all of the existing closures and updates their |
664 // free variables to the boxed value. It also adds the field-elements to the | 663 // free variables to the boxed value. It also adds the field-elements to the |
665 // class representing the closure. | 664 // class representing the closure. |
666 void updateClosures() { | 665 void updateClosures() { |
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1113 if (insideClosure) { | 1112 if (insideClosure) { |
1114 closure = element; | 1113 closure = element; |
1115 closures.add(closure); | 1114 closures.add(closure); |
1116 closureData = globalizeClosure(node, closure); | 1115 closureData = globalizeClosure(node, closure); |
1117 needsRti = compiler.options.enableTypeAssertions || | 1116 needsRti = compiler.options.enableTypeAssertions || |
1118 compiler.backend.rtiNeed.localFunctionNeedsRti(closure); | 1117 compiler.backend.rtiNeed.localFunctionNeedsRti(closure); |
1119 } else { | 1118 } else { |
1120 outermostElement = element; | 1119 outermostElement = element; |
1121 ThisLocal thisElement = null; | 1120 ThisLocal thisElement = null; |
1122 if (element.isInstanceMember || element.isGenerativeConstructor) { | 1121 if (element.isInstanceMember || element.isGenerativeConstructor) { |
1123 thisElement = new ThisLocal(element); | 1122 MemberElement member = element; |
| 1123 thisElement = new ThisLocal(member); |
1124 } | 1124 } |
1125 closureData = new ClosureClassMap(null, null, null, thisElement); | 1125 closureData = new ClosureClassMap(null, null, null, thisElement); |
1126 if (element is MethodElement) { | 1126 if (element is MethodElement) { |
1127 needsRti = compiler.options.enableTypeAssertions || | 1127 needsRti = compiler.options.enableTypeAssertions || |
1128 compiler.backend.rtiNeed.methodNeedsRti(element); | 1128 compiler.backend.rtiNeed.methodNeedsRti(element); |
1129 } | 1129 } |
1130 } | 1130 } |
1131 closureMappingCache[element] = closureData; | 1131 closureMappingCache[element] = closureData; |
1132 closureMappingCache[element.declaration] = closureData; | 1132 closureMappingCache[element.declaration] = closureData; |
1133 if (closureData.callElement != null) { | 1133 if (closureData.callElement != null) { |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1244 /// | 1244 /// |
1245 /// Move the below classes to a JS model eventually. | 1245 /// Move the below classes to a JS model eventually. |
1246 /// | 1246 /// |
1247 abstract class JSEntity implements MemberEntity { | 1247 abstract class JSEntity implements MemberEntity { |
1248 Local get declaredEntity; | 1248 Local get declaredEntity; |
1249 } | 1249 } |
1250 | 1250 |
1251 abstract class PrivatelyNamedJSEntity implements JSEntity { | 1251 abstract class PrivatelyNamedJSEntity implements JSEntity { |
1252 Entity get rootOfScope; | 1252 Entity get rootOfScope; |
1253 } | 1253 } |
OLD | NEW |