| 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 |