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 |