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 |