Chromium Code Reviews| 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 "elements/elements.dart"; | 7 import "elements/elements.dart"; |
| 8 import "dart2jslib.dart"; | 8 import "dart2jslib.dart"; |
| 9 import "dart_types.dart"; | 9 import "dart_types.dart"; |
| 10 import "js_backend/js_backend.dart" show JavaScriptBackend; | 10 import "js_backend/js_backend.dart" show JavaScriptBackend; |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 265 | 265 |
| 266 /// Call method of a closure class. | 266 /// Call method of a closure class. |
| 267 class SynthesizedCallMethodElementX extends BaseFunctionElementX { | 267 class SynthesizedCallMethodElementX extends BaseFunctionElementX { |
| 268 final LocalFunctionElement expression; | 268 final LocalFunctionElement expression; |
| 269 | 269 |
| 270 SynthesizedCallMethodElementX(String name, | 270 SynthesizedCallMethodElementX(String name, |
| 271 LocalFunctionElementX other, | 271 LocalFunctionElementX other, |
| 272 ClosureClassElement enclosing) | 272 ClosureClassElement enclosing) |
| 273 : expression = other, | 273 : expression = other, |
| 274 super(name, other.kind, other.modifiers, enclosing, false) { | 274 super(name, other.kind, other.modifiers, enclosing, false) { |
| 275 asyncMarker = other.asyncMarker; | |
| 275 functionSignatureCache = other.functionSignature; | 276 functionSignatureCache = other.functionSignature; |
| 276 } | 277 } |
| 277 | 278 |
| 278 /// Use [closureClass] instead. | 279 /// Use [closureClass] instead. |
| 279 @deprecated | 280 @deprecated |
| 280 get enclosingElement => super.enclosingElement; | 281 get enclosingElement => super.enclosingElement; |
| 281 | 282 |
| 282 ClosureClassElement get closureClass => super.enclosingElement; | 283 ClosureClassElement get closureClass => super.enclosingElement; |
| 283 | 284 |
| 284 MemberElement get memberContext { | 285 MemberElement get memberContext { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 340 final Map<Local, CapturedVariable> freeVariableMap = | 341 final Map<Local, CapturedVariable> freeVariableMap = |
| 341 new Map<Local, CapturedVariable>(); | 342 new Map<Local, CapturedVariable>(); |
| 342 | 343 |
| 343 // Maps [Loop] and [FunctionExpression] nodes to their | 344 // Maps [Loop] and [FunctionExpression] nodes to their |
| 344 // [ClosureScope] which contains their box and the | 345 // [ClosureScope] which contains their box and the |
| 345 // captured variables that are stored in the box. | 346 // captured variables that are stored in the box. |
| 346 // This map will be empty if the method/closure of this [ClosureData] does not | 347 // This map will be empty if the method/closure of this [ClosureData] does not |
| 347 // contain any nested closure. | 348 // contain any nested closure. |
| 348 final Map<Node, ClosureScope> capturingScopes = new Map<Node, ClosureScope>(); | 349 final Map<Node, ClosureScope> capturingScopes = new Map<Node, ClosureScope>(); |
| 349 | 350 |
| 350 final Set<Local> usedVariablesInTry = new Set<Local>(); | 351 final Set<Local> variablesUsedInTryOrGenerator = new Set<Local>(); |
|
floitsch
2015/02/02 22:00:06
Add comment.
Not every variable in a generator is
sigurdm
2015/02/03 16:59:27
Done.
| |
| 351 | 352 |
| 352 ClosureClassMap(this.closureElement, | 353 ClosureClassMap(this.closureElement, |
| 353 this.closureClassElement, | 354 this.closureClassElement, |
| 354 this.callElement, | 355 this.callElement, |
| 355 this.thisLocal); | 356 this.thisLocal); |
| 356 | 357 |
| 357 void addFreeVariable(Local element) { | 358 void addFreeVariable(Local element) { |
| 358 assert(freeVariableMap[element] == null); | 359 assert(freeVariableMap[element] == null); |
| 359 freeVariableMap[element] = null; | 360 freeVariableMap[element] = null; |
| 360 } | 361 } |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 420 }); | 421 }); |
| 421 } | 422 } |
| 422 } | 423 } |
| 423 | 424 |
| 424 class ClosureTranslator extends Visitor { | 425 class ClosureTranslator extends Visitor { |
| 425 final Compiler compiler; | 426 final Compiler compiler; |
| 426 final TreeElements elements; | 427 final TreeElements elements; |
| 427 int closureFieldCounter = 0; | 428 int closureFieldCounter = 0; |
| 428 int boxedFieldCounter = 0; | 429 int boxedFieldCounter = 0; |
| 429 bool inTryStatement = false; | 430 bool inTryStatement = false; |
| 431 | |
| 430 final Map<Node, ClosureClassMap> closureMappingCache; | 432 final Map<Node, ClosureClassMap> closureMappingCache; |
| 431 | 433 |
| 432 // Map of captured variables. Initially they will map to `null`. If | 434 // Map of captured variables. Initially they will map to `null`. If |
| 433 // a variable needs to be boxed then the scope declaring the variable | 435 // a variable needs to be boxed then the scope declaring the variable |
| 434 // will update this to mapping to the capturing [BoxFieldElement]. | 436 // will update this to mapping to the capturing [BoxFieldElement]. |
| 435 Map<Local, BoxFieldElement> _capturedVariableMapping = | 437 Map<Local, BoxFieldElement> _capturedVariableMapping = |
| 436 new Map<Local, BoxFieldElement>(); | 438 new Map<Local, BoxFieldElement>(); |
| 437 | 439 |
| 438 // List of encountered closures. | 440 // List of encountered closures. |
| 439 List<Expression> closures = <Expression>[]; | 441 List<Expression> closures = <Expression>[]; |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 581 } | 583 } |
| 582 | 584 |
| 583 if (insideClosure && !inCurrentContext(variable)) { | 585 if (insideClosure && !inCurrentContext(variable)) { |
| 584 closureData.addFreeVariable(variable); | 586 closureData.addFreeVariable(variable); |
| 585 } else if (inTryStatement) { | 587 } else if (inTryStatement) { |
| 586 // Don't mark the this-element or a self-reference. This would complicate | 588 // Don't mark the this-element or a self-reference. This would complicate |
| 587 // things in the builder. | 589 // things in the builder. |
| 588 // Note that nested (named) functions are immutable. | 590 // Note that nested (named) functions are immutable. |
| 589 if (variable != closureData.thisLocal && | 591 if (variable != closureData.thisLocal && |
| 590 variable != closureData.closureElement) { | 592 variable != closureData.closureElement) { |
| 591 // TODO(ngeoffray): only do this if the variable is mutated. | 593 // TODO(ngeoffray): only do this if the variable is mutated. |
|
floitsch
2015/02/02 22:00:06
We should have an "isEffectivelyFinal" getter on v
sigurdm
2015/02/03 16:59:27
Done.
| |
| 592 closureData.usedVariablesInTry.add(variable); | 594 closureData.variablesUsedInTryOrGenerator.add(variable); |
| 593 } | 595 } |
| 596 } else if (variable is LocalParameterElement && | |
| 597 variable.functionDeclaration.asyncMarker == AsyncMarker.SYNC_STAR) { | |
| 598 // Parameters in a sync* function are shared between each Iterator created | |
| 599 // by the Iterable returned by the function, therefore they must be boxed. | |
| 600 // TODO(sigurdm): only do this if the variable is mutated. | |
| 601 closureData.variablesUsedInTryOrGenerator.add(variable); | |
| 594 } | 602 } |
| 595 } | 603 } |
| 596 | 604 |
| 597 void useTypeVariableAsLocal(TypeVariableType typeVariable) { | 605 void useTypeVariableAsLocal(TypeVariableType typeVariable) { |
| 598 useLocal(new TypeVariableLocal(typeVariable, outermostElement)); | 606 useLocal(new TypeVariableLocal(typeVariable, outermostElement)); |
| 599 } | 607 } |
| 600 | 608 |
| 601 void declareLocal(LocalVariableElement element) { | 609 void declareLocal(LocalVariableElement element) { |
| 602 scopeVariables.add(element); | 610 scopeVariables.add(element); |
| 603 } | 611 } |
| (...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1027 | 1035 |
| 1028 String get name => typeVariable.name; | 1036 String get name => typeVariable.name; |
| 1029 | 1037 |
| 1030 int get hashCode => typeVariable.hashCode; | 1038 int get hashCode => typeVariable.hashCode; |
| 1031 | 1039 |
| 1032 bool operator ==(other) { | 1040 bool operator ==(other) { |
| 1033 if (other is! TypeVariableLocal) return false; | 1041 if (other is! TypeVariableLocal) return false; |
| 1034 return typeVariable == other.typeVariable; | 1042 return typeVariable == other.typeVariable; |
| 1035 } | 1043 } |
| 1036 } | 1044 } |
| OLD | NEW |