| 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.dart'; | 7 import 'common.dart'; |
| 8 import 'common/names.dart' show Identifiers; | 8 import 'common/names.dart' show Identifiers; |
| 9 import 'common/resolution.dart' show ParsingContext, Resolution; | 9 import 'common/resolution.dart' show ParsingContext, Resolution; |
| 10 import 'common/tasks.dart' show CompilerTask; | 10 import 'common/tasks.dart' show CompilerTask; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 // The translator will store the computed closure-mappings inside the | 48 // The translator will store the computed closure-mappings inside the |
| 49 // cache. One for given node and one for each nested closure. | 49 // cache. One for given node and one for each nested closure. |
| 50 if (node is FunctionExpression) { | 50 if (node is FunctionExpression) { |
| 51 translator.translateFunction(element, node); | 51 translator.translateFunction(element, node); |
| 52 } else if (element.isSynthesized) { | 52 } else if (element.isSynthesized) { |
| 53 reporter.internalError( | 53 reporter.internalError( |
| 54 element, "Unexpected synthesized element: $element"); | 54 element, "Unexpected synthesized element: $element"); |
| 55 return new ClosureClassMap(null, null, null, new ThisLocal(element)); | 55 return new ClosureClassMap(null, null, null, new ThisLocal(element)); |
| 56 } else { | 56 } else { |
| 57 assert(element.isField); | 57 assert(element.isField); |
| 58 VariableElement field = element; | 58 Node initializer = resolvedAst.body; |
| 59 if (field.initializer != null) { | 59 if (initializer != null) { |
| 60 // The lazy initializer of a static. | 60 // The lazy initializer of a static. |
| 61 translator.translateLazyInitializer(element, node, field.initializer); | 61 translator.translateLazyInitializer(element, node, initializer); |
| 62 } else { | 62 } else { |
| 63 assert(element.isInstanceMember); | 63 assert(element.isInstanceMember); |
| 64 closureMappingCache[node] = | 64 closureMappingCache[node] = |
| 65 new ClosureClassMap(null, null, null, new ThisLocal(element)); | 65 new ClosureClassMap(null, null, null, new ThisLocal(element)); |
| 66 } | 66 } |
| 67 } | 67 } |
| 68 assert(closureMappingCache[node] != null); | 68 assert(closureMappingCache[node] != null); |
| 69 return closureMappingCache[node]; | 69 return closureMappingCache[node]; |
| 70 }); | 70 }); |
| 71 } | 71 } |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 | 313 |
| 314 String get name => 'this'; | 314 String get name => 'this'; |
| 315 | 315 |
| 316 ClassElement get enclosingClass => executableContext.enclosingClass; | 316 ClassElement get enclosingClass => executableContext.enclosingClass; |
| 317 } | 317 } |
| 318 | 318 |
| 319 /// Call method of a closure class. | 319 /// Call method of a closure class. |
| 320 class SynthesizedCallMethodElementX extends BaseFunctionElementX | 320 class SynthesizedCallMethodElementX extends BaseFunctionElementX |
| 321 implements MethodElement { | 321 implements MethodElement { |
| 322 final LocalFunctionElement expression; | 322 final LocalFunctionElement expression; |
| 323 final FunctionExpression node; |
| 324 final TreeElements treeElements; |
| 323 | 325 |
| 324 SynthesizedCallMethodElementX( | 326 SynthesizedCallMethodElementX( |
| 325 String name, LocalFunctionElementX other, ClosureClassElement enclosing) | 327 String name, |
| 328 LocalFunctionElement other, |
| 329 ClosureClassElement enclosing, |
| 330 this.node, |
| 331 this.treeElements) |
| 326 : expression = other, | 332 : expression = other, |
| 327 super(name, other.kind, other.modifiers, enclosing) { | 333 super(name, other.kind, Modifiers.EMPTY, enclosing) { |
| 328 asyncMarker = other.asyncMarker; | 334 asyncMarker = other.asyncMarker; |
| 329 functionSignature = other.functionSignature; | 335 functionSignature = other.functionSignature; |
| 330 } | 336 } |
| 331 | 337 |
| 332 /// Use [closureClass] instead. | 338 /// Use [closureClass] instead. |
| 333 @deprecated | 339 @deprecated |
| 334 get enclosingElement => super.enclosingElement; | 340 get enclosingElement => super.enclosingElement; |
| 335 | 341 |
| 336 ClosureClassElement get closureClass => super.enclosingElement; | 342 ClosureClassElement get closureClass => super.enclosingElement; |
| 337 | 343 |
| 338 MemberElement get memberContext { | 344 MemberElement get memberContext { |
| 339 return closureClass.methodElement.memberContext; | 345 return closureClass.methodElement.memberContext; |
| 340 } | 346 } |
| 341 | 347 |
| 342 bool get hasNode => expression.hasNode; | 348 bool get hasNode => node != null; |
| 343 | |
| 344 FunctionExpression get node => expression.node; | |
| 345 | 349 |
| 346 FunctionExpression parseNode(ParsingContext parsing) => node; | 350 FunctionExpression parseNode(ParsingContext parsing) => node; |
| 347 | 351 |
| 352 Element get analyzableElement => closureClass.methodElement.analyzableElement; |
| 353 |
| 348 ResolvedAst get resolvedAst { | 354 ResolvedAst get resolvedAst { |
| 349 return new ParsedResolvedAst(this, node, node.body, treeElements); | 355 return new ParsedResolvedAst(this, node, node.body, treeElements); |
| 350 } | 356 } |
| 351 | 357 |
| 352 Element get analyzableElement => closureClass.methodElement.analyzableElement; | |
| 353 | |
| 354 accept(ElementVisitor visitor, arg) { | 358 accept(ElementVisitor visitor, arg) { |
| 355 return visitor.visitMethodElement(this, arg); | 359 return visitor.visitMethodElement(this, arg); |
| 356 } | 360 } |
| 357 } | 361 } |
| 358 | 362 |
| 359 // The box-element for a scope, and the captured variables that need to be | 363 // The box-element for a scope, and the captured variables that need to be |
| 360 // stored in the box. | 364 // stored in the box. |
| 361 class ClosureScope { | 365 class ClosureScope { |
| 362 final BoxLocal boxElement; | 366 final BoxLocal boxElement; |
| 363 final Map<Local, BoxFieldElement> capturedVariables; | 367 final Map<Local, BoxFieldElement> capturedVariables; |
| (...skipping 661 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1025 | 1029 |
| 1026 ClosureClassMap globalizeClosure( | 1030 ClosureClassMap globalizeClosure( |
| 1027 FunctionExpression node, LocalFunctionElement element) { | 1031 FunctionExpression node, LocalFunctionElement element) { |
| 1028 String closureName = computeClosureName(element); | 1032 String closureName = computeClosureName(element); |
| 1029 ClosureClassElement globalizedElement = | 1033 ClosureClassElement globalizedElement = |
| 1030 new ClosureClassElement(node, closureName, compiler, element); | 1034 new ClosureClassElement(node, closureName, compiler, element); |
| 1031 // Extend [globalizedElement] as an instantiated class in the closed world. | 1035 // Extend [globalizedElement] as an instantiated class in the closed world. |
| 1032 compiler.world | 1036 compiler.world |
| 1033 .registerClass(globalizedElement, isDirectlyInstantiated: true); | 1037 .registerClass(globalizedElement, isDirectlyInstantiated: true); |
| 1034 FunctionElement callElement = new SynthesizedCallMethodElementX( | 1038 FunctionElement callElement = new SynthesizedCallMethodElementX( |
| 1035 Identifiers.call, element, globalizedElement); | 1039 Identifiers.call, element, globalizedElement, node, elements); |
| 1036 backend.maybeMarkClosureAsNeededForReflection( | 1040 backend.maybeMarkClosureAsNeededForReflection( |
| 1037 globalizedElement, callElement, element); | 1041 globalizedElement, callElement, element); |
| 1038 MemberElement enclosing = element.memberContext; | 1042 MemberElement enclosing = element.memberContext; |
| 1039 enclosing.nestedClosures.add(callElement); | 1043 enclosing.nestedClosures.add(callElement); |
| 1040 globalizedElement.addMember(callElement, reporter); | 1044 globalizedElement.addMember(callElement, reporter); |
| 1041 globalizedElement.computeAllClassMembers(compiler); | 1045 globalizedElement.computeAllClassMembers(compiler); |
| 1042 // The nested function's 'this' is the same as the one for the outer | 1046 // The nested function's 'this' is the same as the one for the outer |
| 1043 // function. It could be [null] if we are inside a static method. | 1047 // function. It could be [null] if we are inside a static method. |
| 1044 ThisLocal thisElement = closureData.thisLocal; | 1048 ThisLocal thisElement = closureData.thisLocal; |
| 1045 | 1049 |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1167 /// | 1171 /// |
| 1168 /// Move the below classes to a JS model eventually. | 1172 /// Move the below classes to a JS model eventually. |
| 1169 /// | 1173 /// |
| 1170 abstract class JSEntity implements Entity { | 1174 abstract class JSEntity implements Entity { |
| 1171 Entity get declaredEntity; | 1175 Entity get declaredEntity; |
| 1172 } | 1176 } |
| 1173 | 1177 |
| 1174 abstract class PrivatelyNamedJSEntity implements JSEntity { | 1178 abstract class PrivatelyNamedJSEntity implements JSEntity { |
| 1175 Entity get rootOfScope; | 1179 Entity get rootOfScope; |
| 1176 } | 1180 } |
| OLD | NEW |