Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(494)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/closure.dart

Issue 15414004: When recording the type of a captured variable/parameter, use the closure field it maps to. Otherwi… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/elements/elements.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "scanner/scannerlib.dart" show Token; 10 import "scanner/scannerlib.dart" show Token;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 } 60 }
61 return nestedClosureData; 61 return nestedClosureData;
62 }); 62 });
63 } 63 }
64 } 64 }
65 65
66 // TODO(ahe): These classes continuously cause problems. We need to 66 // TODO(ahe): These classes continuously cause problems. We need to
67 // move these classes to elements/modelx.dart or see if we can find a 67 // move these classes to elements/modelx.dart or see if we can find a
68 // more general solution. 68 // more general solution.
69 class ClosureFieldElement extends ElementX { 69 class ClosureFieldElement extends ElementX {
70 ClosureFieldElement(SourceString name, ClassElement enclosing) 70 ClosureFieldElement(SourceString name,
71 this.variableElement,
72 ClassElement enclosing)
71 : super(name, ElementKind.FIELD, enclosing); 73 : super(name, ElementKind.FIELD, enclosing);
72 74
73 bool isInstanceMember() => true; 75 bool isInstanceMember() => true;
74 bool isAssignable() => false; 76 bool isAssignable() => false;
75 // The names of closure variables don't need renaming, since their use is very 77 // The names of closure variables don't need renaming, since their use is very
76 // simple and they have 1-character names in the minified mode. 78 // simple and they have 1-character names in the minified mode.
77 bool hasFixedBackendName() => true; 79 bool hasFixedBackendName() => true;
78 String fixedBackendName() => name.slowToString(); 80 String fixedBackendName() => name.slowToString();
79 81
80 DartType computeType(Compiler compiler) => compiler.types.dynamicType; 82 DartType computeType(Compiler compiler) {
83 return variableElement.computeType(compiler);
84 }
81 85
82 String toString() => "ClosureFieldElement($name)"; 86 String toString() => "ClosureFieldElement($name)";
87
88 /**
89 * The source variable this element refers to.
90 */
91 final Element variableElement;
83 } 92 }
84 93
85 // TODO(ahe): These classes continuously cause problems. We need to 94 // TODO(ahe): These classes continuously cause problems. We need to
86 // move these classes to elements/modelx.dart or see if we can find a 95 // move these classes to elements/modelx.dart or see if we can find a
87 // more general solution. 96 // more general solution.
88 class ClosureClassElement extends ClassElementX { 97 class ClosureClassElement extends ClassElementX {
89 DartType rawType; 98 DartType rawType;
90 DartType thisType; 99 DartType thisType;
91 /// Node that corresponds to this closure, used for source position. 100 /// Node that corresponds to this closure, used for source position.
92 final FunctionExpression node; 101 final FunctionExpression node;
(...skipping 19 matching lines...) Expand all
112 121
113 bool isClosure() => true; 122 bool isClosure() => true;
114 123
115 Token position() => node.getBeginToken(); 124 Token position() => node.getBeginToken();
116 125
117 Node parseNode(DiagnosticListener listener) => node; 126 Node parseNode(DiagnosticListener listener) => node;
118 127
119 /** 128 /**
120 * The most outer method this closure is declared into. 129 * The most outer method this closure is declared into.
121 */ 130 */
122 Element methodElement; 131 final Element methodElement;
123 } 132 }
124 133
125 // TODO(ahe): These classes continuously cause problems. We need to 134 // TODO(ahe): These classes continuously cause problems. We need to
126 // move these classes to elements/modelx.dart or see if we can find a 135 // move these classes to elements/modelx.dart or see if we can find a
127 // more general solution. 136 // more general solution.
128 class BoxElement extends ElementX { 137 class BoxElement extends ElementX {
129 BoxElement(SourceString name, Element enclosingElement) 138 BoxElement(SourceString name, Element enclosingElement)
130 : super(name, ElementKind.VARIABLE, enclosingElement); 139 : super(name, ElementKind.VARIABLE, enclosingElement);
140
141 DartType computeType(Compiler compiler) => compiler.types.dynamicType;
142 }
143
144 // TODO(ngeoffray, ahe): These classes continuously cause problems. We need to
145 // move these classes to elements/modelx.dart or see if we can find a
146 // more general solution.
147 class BoxFieldElement extends ElementX {
148 BoxFieldElement(SourceString name,
149 this.variableElement,
150 BoxElement enclosingBox)
151 : super(name, ElementKind.FIELD, enclosingBox);
152
153 DartType computeType(Compiler compiler) {
154 return variableElement.computeType(compiler);
155 }
156
157 final Element variableElement;
131 } 158 }
132 159
133 // TODO(ahe): These classes continuously cause problems. We need to 160 // TODO(ahe): These classes continuously cause problems. We need to
134 // move these classes to elements/modelx.dart or see if we can find a 161 // move these classes to elements/modelx.dart or see if we can find a
135 // more general solution. 162 // more general solution.
136 class ThisElement extends ElementX { 163 class ThisElement extends ElementX {
137 ThisElement(Element enclosing) 164 ThisElement(Element enclosing)
138 : super(const SourceString('this'), ElementKind.PARAMETER, enclosing); 165 : super(const SourceString('this'), ElementKind.PARAMETER, enclosing);
139 166
140 bool isAssignable() => false; 167 bool isAssignable() => false;
141 168
169 DartType computeType(Compiler compiler) => compiler.types.dynamicType;
170
142 // Since there is no declaration corresponding to 'this', use the position of 171 // Since there is no declaration corresponding to 'this', use the position of
143 // the enclosing method. 172 // the enclosing method.
144 Token position() => enclosingElement.position(); 173 Token position() => enclosingElement.position();
145 } 174 }
146 175
147 // TODO(ahe): These classes continuously cause problems. We need to 176 // TODO(ahe): These classes continuously cause problems. We need to
148 // move these classes to elements/modelx.dart or see if we can find a 177 // move these classes to elements/modelx.dart or see if we can find a
149 // more general solution. 178 // more general solution.
150 class CheckVariableElement extends ElementX { 179 class CheckVariableElement extends ElementX {
151 Element parameter; 180 Element parameter;
152 CheckVariableElement(SourceString name, this.parameter, Element enclosing) 181 CheckVariableElement(SourceString name, this.parameter, Element enclosing)
153 : super(name, ElementKind.VARIABLE, enclosing); 182 : super(name, ElementKind.VARIABLE, enclosing);
154 183
184 DartType computeType(Compiler compiler) => compiler.types.dynamicType;
185
155 // Since there is no declaration for the synthetic 'check' variable, use 186 // Since there is no declaration for the synthetic 'check' variable, use
156 // parameter. 187 // parameter.
157 Token position() => parameter.position(); 188 Token position() => parameter.position();
158 } 189 }
159 190
160 // The box-element for a scope, and the captured variables that need to be 191 // The box-element for a scope, and the captured variables that need to be
161 // stored in the box. 192 // stored in the box.
162 class ClosureScope { 193 class ClosureScope {
163 Element boxElement; 194 Element boxElement;
164 Map<Element, Element> capturedVariableMapping; 195 Map<Element, Element> capturedVariableMapping;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 252
222 bool isVariableCaptured(Element element) { 253 bool isVariableCaptured(Element element) {
223 freeVariableMapping.containsKey(element); 254 freeVariableMapping.containsKey(element);
224 } 255 }
225 256
226 bool isVariableBoxed(Element element) { 257 bool isVariableBoxed(Element element) {
227 Element copy = freeVariableMapping[element]; 258 Element copy = freeVariableMapping[element];
228 return copy != null && !copy.isMember(); 259 return copy != null && !copy.isMember();
229 } 260 }
230 261
231 void forEachCapturedVariable(void f(Element element)) { 262 void forEachCapturedVariable(void f(Element local, Element field)) {
232 freeVariableMapping.forEach((variable, _) { 263 freeVariableMapping.forEach((variable, copy) {
233 if (variable is BoxElement) return; 264 if (variable is BoxElement) return;
234 f(variable); 265 f(variable, copy);
235 }); 266 });
236 } 267 }
237 268
238 void forEachBoxedVariable(void f(Element element)) { 269 void forEachBoxedVariable(void f(Element local, Element field)) {
239 freeVariableMapping.forEach((variable, copy) { 270 freeVariableMapping.forEach((variable, copy) {
240 if (!isVariableBoxed(variable)) return; 271 if (!isVariableBoxed(variable)) return;
241 f(variable); 272 f(variable, copy);
242 }); 273 });
243 } 274 }
244 275
245 void forEachNonBoxedCapturedVariable(void f(Element element)) { 276 void forEachNonBoxedCapturedVariable(void f(Element local, Element field)) {
246 freeVariableMapping.forEach((variable, copy) { 277 freeVariableMapping.forEach((variable, copy) {
247 if (variable is BoxElement) return; 278 if (variable is BoxElement) return;
248 if (isVariableBoxed(variable)) return; 279 if (isVariableBoxed(variable)) return;
249 f(variable); 280 f(variable, copy);
250 }); 281 });
251 } 282 }
252 } 283 }
253 284
254 class ClosureTranslator extends Visitor { 285 class ClosureTranslator extends Visitor {
255 final Compiler compiler; 286 final Compiler compiler;
256 final TreeElements elements; 287 final TreeElements elements;
257 int closureFieldCounter = 0; 288 int closureFieldCounter = 0;
258 int boxedFieldCounter = 0; 289 int boxedFieldCounter = 0;
259 bool inTryStatement = false; 290 bool inTryStatement = false;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 freeVariableMapping[fromElement] = updatedElement; 368 freeVariableMapping[fromElement] = updatedElement;
338 Element boxElement = updatedElement.enclosingElement; 369 Element boxElement = updatedElement.enclosingElement;
339 assert(boxElement.kind == ElementKind.VARIABLE); 370 assert(boxElement.kind == ElementKind.VARIABLE);
340 boxes.add(boxElement); 371 boxes.add(boxElement);
341 } 372 }
342 }); 373 });
343 ClassElement closureElement = data.closureClassElement; 374 ClassElement closureElement = data.closureClassElement;
344 assert(closureElement != null || 375 assert(closureElement != null ||
345 (fieldCaptures.isEmpty && boxes.isEmpty)); 376 (fieldCaptures.isEmpty && boxes.isEmpty));
346 void addElement(Element element, SourceString name) { 377 void addElement(Element element, SourceString name) {
347 Element fieldElement = new ClosureFieldElement(name, closureElement); 378 Element fieldElement = new ClosureFieldElement(
379 name, element, closureElement);
348 closureElement.addMember(fieldElement, compiler); 380 closureElement.addMember(fieldElement, compiler);
349 data.capturedFieldMapping[fieldElement] = element; 381 data.capturedFieldMapping[fieldElement] = element;
350 freeVariableMapping[element] = fieldElement; 382 freeVariableMapping[element] = fieldElement;
351 } 383 }
352 // Add the box elements first so we get the same ordering. 384 // Add the box elements first so we get the same ordering.
353 // TODO(sra): What is the canonical order of multiple boxes? 385 // TODO(sra): What is the canonical order of multiple boxes?
354 for (Element capturedElement in boxes) { 386 for (Element capturedElement in boxes) {
355 addElement(capturedElement, capturedElement.name); 387 addElement(capturedElement, capturedElement.name);
356 } 388 }
357 for (Element capturedElement in 389 for (Element capturedElement in
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 SourceString boxName = 595 SourceString boxName =
564 namer.getClosureVariableName(const SourceString('box'), 596 namer.getClosureVariableName(const SourceString('box'),
565 closureFieldCounter++); 597 closureFieldCounter++);
566 box = new BoxElement(boxName, currentElement); 598 box = new BoxElement(boxName, currentElement);
567 } 599 }
568 String elementName = element.name.slowToString(); 600 String elementName = element.name.slowToString();
569 SourceString boxedName = 601 SourceString boxedName =
570 namer.getClosureVariableName(new SourceString(elementName), 602 namer.getClosureVariableName(new SourceString(elementName),
571 boxedFieldCounter++); 603 boxedFieldCounter++);
572 // TODO(kasperl): Should this be a FieldElement instead? 604 // TODO(kasperl): Should this be a FieldElement instead?
573 Element boxed = new ElementX(boxedName, ElementKind.FIELD, box); 605 Element boxed = new BoxFieldElement(boxedName, element, box);
574 // No need to rename the fields of a box, so we give them a native name 606 // No need to rename the fields of a box, so we give them a native name
575 // right now. 607 // right now.
576 boxed.setFixedBackendName(boxedName.slowToString()); 608 boxed.setFixedBackendName(boxedName.slowToString());
577 scopeMapping[element] = boxed; 609 scopeMapping[element] = boxed;
578 capturedVariableMapping[element] = boxed; 610 capturedVariableMapping[element] = boxed;
579 } 611 }
580 } 612 }
581 if (!scopeMapping.isEmpty) { 613 if (!scopeMapping.isEmpty) {
582 ClosureScope scope = new ClosureScope(box, scopeMapping); 614 ClosureScope scope = new ClosureScope(box, scopeMapping);
583 closureData.capturingScopes[node] = scope; 615 closureData.capturingScopes[node] = scope;
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
767 } 799 }
768 800
769 visitTryStatement(TryStatement node) { 801 visitTryStatement(TryStatement node) {
770 // TODO(ngeoffray): implement finer grain state. 802 // TODO(ngeoffray): implement finer grain state.
771 bool oldInTryStatement = inTryStatement; 803 bool oldInTryStatement = inTryStatement;
772 inTryStatement = true; 804 inTryStatement = true;
773 node.visitChildren(this); 805 node.visitChildren(this);
774 inTryStatement = oldInTryStatement; 806 inTryStatement = oldInTryStatement;
775 } 807 }
776 } 808 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/elements/elements.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698