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 'common.dart'; | 7 import 'common.dart'; |
| 8 import 'common/names.dart' show | 8 import 'common/names.dart' show |
| 9 Identifiers; | 9 Identifiers; |
| 10 import 'common/resolution.dart' show | 10 import 'common/resolution.dart' show |
| 11 Parsing, | 11 Parsing, |
| 12 Resolution; | 12 Resolution; |
| 13 import 'common/tasks.dart' show | 13 import 'common/tasks.dart' show |
| 14 CompilerTask; | 14 CompilerTask; |
| 15 import 'compiler.dart' show | 15 import 'compiler.dart' show |
| 16 Compiler; | 16 Compiler; |
| 17 import 'constants/expressions.dart'; | 17 import 'constants/expressions.dart'; |
| 18 import 'dart_types.dart'; | 18 import 'dart_types.dart'; |
| 19 import 'elements/elements.dart'; | 19 import 'elements/elements.dart'; |
| 20 import 'elements/modelx.dart' show | 20 import 'elements/modelx.dart' show |
| 21 BaseFunctionElementX, | 21 BaseFunctionElementX, |
| 22 ClassElementX, | 22 ClassElementX, |
| 23 ElementX, | 23 ElementX, |
| 24 LocalFunctionElementX; | 24 LocalFunctionElementX; |
| 25 import 'elements/visitor.dart' show ElementVisitor; | 25 import 'elements/visitor.dart' show ElementVisitor; |
| 26 import 'js_backend/js_backend.dart' show JavaScriptBackend; | 26 import 'js_backend/js_backend.dart' show |
| 27 JavaScriptBackend, | |
| 28 NamingScope, | |
| 29 NameProposingEntity, | |
| 30 ScopeBearingEntity; | |
| 27 import 'resolution/tree_elements.dart' show TreeElements; | 31 import 'resolution/tree_elements.dart' show TreeElements; |
| 28 import 'tokens/token.dart' show Token; | 32 import 'tokens/token.dart' show Token; |
| 29 import 'tree/tree.dart'; | 33 import 'tree/tree.dart'; |
| 30 import 'util/util.dart'; | 34 import 'util/util.dart'; |
| 31 import 'universe/universe.dart' show | 35 import 'universe/universe.dart' show |
| 32 Universe; | 36 Universe; |
| 33 | 37 |
| 34 class ClosureTask extends CompilerTask { | 38 class ClosureTask extends CompilerTask { |
| 35 Map<Node, ClosureClassMap> closureMappingCache; | 39 Map<Node, ClosureClassMap> closureMappingCache; |
| 36 ClosureTask(Compiler compiler) | 40 ClosureTask(Compiler compiler) |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 96 } | 100 } |
| 97 } | 101 } |
| 98 | 102 |
| 99 /// Common interface for [BoxFieldElement] and [ClosureFieldElement] as | 103 /// Common interface for [BoxFieldElement] and [ClosureFieldElement] as |
| 100 /// non-elements. | 104 /// non-elements. |
| 101 abstract class CapturedVariable implements Element {} | 105 abstract class CapturedVariable implements Element {} |
| 102 | 106 |
| 103 // TODO(ahe): These classes continuously cause problems. We need to | 107 // TODO(ahe): These classes continuously cause problems. We need to |
| 104 // find a more general solution. | 108 // find a more general solution. |
| 105 class ClosureFieldElement extends ElementX | 109 class ClosureFieldElement extends ElementX |
| 106 implements FieldElement, CapturedVariable { | 110 implements FieldElement, CapturedVariable, ScopeBearingEntity, |
| 111 NameProposingEntity { | |
|
sra1
2015/11/04 02:27:48
I'm a bit concerned that such an early phase depen
herhut
2015/11/04 15:25:47
I have renamed NameProposingEntity to JsEntity wit
| |
| 107 /// The [BoxLocal] or [LocalElement] being accessed through the field. | 112 /// The [BoxLocal] or [LocalElement] being accessed through the field. |
| 108 final Local local; | 113 final Local local; |
| 109 | 114 |
| 110 ClosureFieldElement(String name, | 115 ClosureFieldElement(String name, |
| 111 this.local, | 116 this.local, |
| 112 ClosureClassElement enclosing) | 117 ClosureClassElement enclosing) |
| 113 : super(name, ElementKind.FIELD, enclosing); | 118 : super(name, ElementKind.FIELD, enclosing); |
| 114 | 119 |
| 115 /// Use [closureClass] instead. | 120 /// Use [closureClass] instead. |
| 116 @deprecated | 121 @deprecated |
| 117 get enclosingElement => super.enclosingElement; | 122 get enclosingElement => super.enclosingElement; |
| 118 | 123 |
| 119 ClosureClassElement get closureClass => super.enclosingElement; | 124 ClosureClassElement get closureClass => super.enclosingElement; |
| 120 | 125 |
| 121 MemberElement get memberContext => closureClass.methodElement.memberContext; | 126 MemberElement get memberContext => closureClass.methodElement.memberContext; |
| 122 | 127 |
| 128 String proposeName() => local.name; | |
|
sra1
2015/11/04 04:09:25
Can this propose that the boxes are named nicely?
herhut
2015/11/04 15:25:47
No, this is just responsible for the name of the f
sra1
2015/11/04 17:59:22
The field is named after the BoxLocal.
I tried it
herhut
2015/11/05 10:33:47
Oh yeah, you are right. But it would be nice to gi
| |
| 129 NamingScope get namingScope => closureClass.fieldScope; | |
| 130 | |
| 123 bool get hasNode => false; | 131 bool get hasNode => false; |
| 124 | 132 |
| 125 Node get node { | 133 Node get node { |
| 126 throw new SpannableAssertionFailure(local, | 134 throw new SpannableAssertionFailure(local, |
| 127 'Should not access node of ClosureFieldElement.'); | 135 'Should not access node of ClosureFieldElement.'); |
| 128 } | 136 } |
| 129 | 137 |
| 130 bool get hasResolvedAst => hasTreeElements; | 138 bool get hasResolvedAst => hasTreeElements; |
| 131 | 139 |
| 132 ResolvedAst get resolvedAst { | 140 ResolvedAst get resolvedAst { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 174 FunctionType callType; | 182 FunctionType callType; |
| 175 /// Node that corresponds to this closure, used for source position. | 183 /// Node that corresponds to this closure, used for source position. |
| 176 final FunctionExpression node; | 184 final FunctionExpression node; |
| 177 | 185 |
| 178 /** | 186 /** |
| 179 * The element for the declaration of the function expression. | 187 * The element for the declaration of the function expression. |
| 180 */ | 188 */ |
| 181 final LocalFunctionElement methodElement; | 189 final LocalFunctionElement methodElement; |
| 182 | 190 |
| 183 final List<ClosureFieldElement> _closureFields = <ClosureFieldElement>[]; | 191 final List<ClosureFieldElement> _closureFields = <ClosureFieldElement>[]; |
| 192 final NamingScope fieldScope = new NamingScope(); | |
| 184 | 193 |
| 185 ClosureClassElement(this.node, | 194 ClosureClassElement(this.node, |
| 186 String name, | 195 String name, |
| 187 Compiler compiler, | 196 Compiler compiler, |
| 188 LocalFunctionElement closure) | 197 LocalFunctionElement closure) |
| 189 : this.methodElement = closure, | 198 : this.methodElement = closure, |
| 190 super(name, | 199 super(name, |
| 191 closure.compilationUnit, | 200 closure.compilationUnit, |
| 192 // By assigning a fresh class-id we make sure that the hashcode | 201 // By assigning a fresh class-id we make sure that the hashcode |
| 193 // is unique, but also emit closure classes after all other | 202 // is unique, but also emit closure classes after all other |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 232 accept(ElementVisitor visitor, arg) { | 241 accept(ElementVisitor visitor, arg) { |
| 233 return visitor.visitClosureClassElement(this, arg); | 242 return visitor.visitClosureClassElement(this, arg); |
| 234 } | 243 } |
| 235 } | 244 } |
| 236 | 245 |
| 237 /// A local variable that contains the box object holding the [BoxFieldElement] | 246 /// A local variable that contains the box object holding the [BoxFieldElement] |
| 238 /// fields. | 247 /// fields. |
| 239 class BoxLocal extends Local { | 248 class BoxLocal extends Local { |
| 240 final String name; | 249 final String name; |
| 241 final ExecutableElement executableContext; | 250 final ExecutableElement executableContext; |
| 251 final NamingScope boxScope = new NamingScope(); | |
|
sra1
2015/11/04 02:27:48
Is it possible to make this data emphemeral to the
herhut
2015/11/04 15:25:47
I have now changed the interface, so that all Fiel
| |
| 242 | 252 |
| 243 BoxLocal(this.name, this.executableContext); | 253 BoxLocal(this.name, this.executableContext); |
| 244 } | 254 } |
| 245 | 255 |
| 246 // TODO(ngeoffray, ahe): These classes continuously cause problems. We need to | 256 // TODO(ngeoffray, ahe): These classes continuously cause problems. We need to |
| 247 // find a more general solution. | 257 // find a more general solution. |
| 248 class BoxFieldElement extends ElementX | 258 class BoxFieldElement extends ElementX |
| 249 implements TypedElement, CapturedVariable, FieldElement { | 259 implements TypedElement, CapturedVariable, FieldElement, |
| 260 NameProposingEntity, ScopeBearingEntity { | |
| 250 final BoxLocal box; | 261 final BoxLocal box; |
| 251 | 262 |
| 252 BoxFieldElement(String name, this.variableElement, BoxLocal box) | 263 BoxFieldElement(String name, this.variableElement, |
| 264 BoxLocal box) | |
| 253 : this.box = box, | 265 : this.box = box, |
| 254 super(name, ElementKind.FIELD, box.executableContext); | 266 super(name, ElementKind.FIELD, box.executableContext); |
| 255 | 267 |
| 256 DartType computeType(Resolution resolution) => type; | 268 DartType computeType(Resolution resolution) => type; |
| 257 | 269 |
| 258 DartType get type => variableElement.type; | 270 DartType get type => variableElement.type; |
| 259 | 271 |
| 272 String proposeName() => variableElement.name; | |
|
Siggi Cherem (dart-lang)
2015/11/03 17:21:34
totally up to you: it seems that all these cases f
herhut
2015/11/04 15:25:47
Done.
| |
| 273 NamingScope get namingScope => box.boxScope; | |
| 274 | |
| 260 final VariableElement variableElement; | 275 final VariableElement variableElement; |
| 261 | 276 |
| 262 accept(ElementVisitor visitor, arg) { | 277 accept(ElementVisitor visitor, arg) { |
| 263 return visitor.visitBoxFieldElement(this, arg); | 278 return visitor.visitBoxFieldElement(this, arg); |
| 264 } | 279 } |
| 265 | 280 |
| 266 @override | 281 @override |
| 267 bool get hasNode => false; | 282 bool get hasNode => false; |
| 268 | 283 |
| 269 @override | 284 @override |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 513 /// Generate a unique name for the [id]th closure field, with proposed name | 528 /// Generate a unique name for the [id]th closure field, with proposed name |
| 514 /// [name]. | 529 /// [name]. |
| 515 /// | 530 /// |
| 516 /// The result is used as the name of [ClosureFieldElement]s, and must | 531 /// The result is used as the name of [ClosureFieldElement]s, and must |
| 517 /// therefore be unique to avoid breaking an invariant in the element model | 532 /// therefore be unique to avoid breaking an invariant in the element model |
| 518 /// (classes cannot declare multiple fields with the same name). | 533 /// (classes cannot declare multiple fields with the same name). |
| 519 /// | 534 /// |
| 520 /// Also, the names should be distinct from real field names to prevent | 535 /// Also, the names should be distinct from real field names to prevent |
| 521 /// clashes with selectors for those fields. | 536 /// clashes with selectors for those fields. |
| 522 String getClosureVariableName(String name, int id) { | 537 String getClosureVariableName(String name, int id) { |
| 523 return "_captured_${name}_$id"; | 538 return "_captured_${name}_$id"; |
|
sra1
2015/11/04 02:27:48
Why do we still need this if we have a scope?
If
herhut
2015/11/04 15:25:47
This is the name of the element, which has to obey
| |
| 524 } | 539 } |
| 525 | 540 |
| 526 /// Generate a unique name for the [id]th box field, with proposed name | 541 /// Generate a unique name for the [id]th box field, with proposed name |
| 527 /// [name]. | 542 /// [name]. |
| 528 /// | 543 /// |
| 529 /// The result is used as the name of [BoxFieldElement]s, and must | 544 /// The result is used as the name of [BoxFieldElement]s, and must |
| 530 /// therefore be unique to avoid breaking an invariant in the element model | 545 /// therefore be unique to avoid breaking an invariant in the element model |
| 531 /// (classes cannot declare multiple fields with the same name). | 546 /// (classes cannot declare multiple fields with the same name). |
| 532 /// | 547 /// |
| 533 /// Also, the names should be distinct from real field names to prevent | 548 /// Also, the names should be distinct from real field names to prevent |
| 534 /// clashes with selectors for those fields. | 549 /// clashes with selectors for those fields. |
| 550 /// | |
| 551 /// These names are not used in generated code, just as element name. | |
| 535 String getBoxFieldName(int id) { | 552 String getBoxFieldName(int id) { |
| 536 return "_box_$id"; | 553 return "_box_$id"; |
| 537 } | 554 } |
| 538 | 555 |
| 539 bool isCapturedVariable(Local element) { | 556 bool isCapturedVariable(Local element) { |
| 540 return _capturedVariableMapping.containsKey(element); | 557 return _capturedVariableMapping.containsKey(element); |
| 541 } | 558 } |
| 542 | 559 |
| 543 void addCapturedVariable(Node node, Local variable) { | 560 void addCapturedVariable(Node node, Local variable) { |
| 544 if (_capturedVariableMapping[variable] != null) { | 561 if (_capturedVariableMapping[variable] != null) { |
| (...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1127 | 1144 |
| 1128 String get name => typeVariable.name; | 1145 String get name => typeVariable.name; |
| 1129 | 1146 |
| 1130 int get hashCode => typeVariable.hashCode; | 1147 int get hashCode => typeVariable.hashCode; |
| 1131 | 1148 |
| 1132 bool operator ==(other) { | 1149 bool operator ==(other) { |
| 1133 if (other is! TypeVariableLocal) return false; | 1150 if (other is! TypeVariableLocal) return false; |
| 1134 return typeVariable == other.typeVariable; | 1151 return typeVariable == other.typeVariable; |
| 1135 } | 1152 } |
| 1136 } | 1153 } |
| OLD | NEW |