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

Side by Side Diff: pkg/compiler/lib/src/closure.dart

Issue 2926663002: Reapply (plus add some more) Entity-ify some portions of LocalsHandler and Closure. (Closed)
Patch Set: a few more entity changes to make dartanalyzer happy. Created 3 years, 6 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
« no previous file with comments | « no previous file | pkg/compiler/lib/src/inferrer/inferrer_engine.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 'common/names.dart' show Identifiers; 7 import 'common/names.dart' show Identifiers;
8 import 'common/resolution.dart' show ParsingContext, Resolution; 8 import 'common/resolution.dart' show ParsingContext, Resolution;
9 import 'common/tasks.dart' show CompilerTask; 9 import 'common/tasks.dart' show CompilerTask;
10 import 'common.dart'; 10 import 'common.dart';
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 } 123 }
124 } 124 }
125 assert(_closureMappingCache[element] != null, 125 assert(_closureMappingCache[element] != null,
126 failedAt(element, "No ClosureClassMap computed for ${element}.")); 126 failedAt(element, "No ClosureClassMap computed for ${element}."));
127 return _closureMappingCache[element]; 127 return _closureMappingCache[element];
128 }); 128 });
129 }); 129 });
130 } 130 }
131 } 131 }
132 132
133 /// Common interface for [BoxFieldElement] and [ClosureFieldElement] as
134 /// non-elements.
135 // TODO(johnniwinther): Remove `implements Element`.
136 abstract class CapturedVariable implements Element {}
137
138 // TODO(ahe): These classes continuously cause problems. We need to 133 // TODO(ahe): These classes continuously cause problems. We need to
139 // find a more general solution. 134 // find a more general solution.
140 class ClosureFieldElement extends ElementX 135 class ClosureFieldElement extends ElementX
141 implements FieldElement, CapturedVariable, PrivatelyNamedJSEntity { 136 implements FieldElement, PrivatelyNamedJSEntity {
142 /// The [BoxLocal] or [LocalElement] being accessed through the field. 137 /// The [BoxLocal] or [LocalElement] being accessed through the field.
143 final Local local; 138 final Local local;
144 139
145 ClosureFieldElement(String name, this.local, ClosureClassElement enclosing) 140 ClosureFieldElement(String name, this.local, ClosureClassElement enclosing)
146 : super(name, ElementKind.FIELD, enclosing); 141 : super(name, ElementKind.FIELD, enclosing);
147 142
148 /// Use [closureClass] instead. 143 /// Use [closureClass] instead.
149 @deprecated 144 @deprecated
150 get enclosingElement => super.enclosingElement; 145 get enclosingElement => super.enclosingElement;
151 146
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 283
289 @override 284 @override
290 MemberElement get memberContext => executableContext.memberContext; 285 MemberElement get memberContext => executableContext.memberContext;
291 286
292 String toString() => 'BoxLocal($name)'; 287 String toString() => 'BoxLocal($name)';
293 } 288 }
294 289
295 // TODO(ngeoffray, ahe): These classes continuously cause problems. We need to 290 // TODO(ngeoffray, ahe): These classes continuously cause problems. We need to
296 // find a more general solution. 291 // find a more general solution.
297 class BoxFieldElement extends ElementX 292 class BoxFieldElement extends ElementX
298 implements 293 implements TypedElement, FieldElement, PrivatelyNamedJSEntity {
299 TypedElement,
300 CapturedVariable,
301 FieldElement,
302 PrivatelyNamedJSEntity {
303 final BoxLocal box; 294 final BoxLocal box;
304 295
305 BoxFieldElement(String name, this.variableElement, BoxLocal box) 296 BoxFieldElement(String name, this.variableElement, BoxLocal box)
306 : this.box = box, 297 : this.box = box,
307 super(name, ElementKind.FIELD, box.executableContext); 298 super(name, ElementKind.FIELD, box.executableContext);
308 299
309 ResolutionDartType computeType(Resolution resolution) => type; 300 ResolutionDartType computeType(Resolution resolution) => type;
310 301
311 ResolutionDartType get type => variableElement.type; 302 ResolutionDartType get type => variableElement.type;
312 303
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 406
416 // The box-element for a scope, and the captured variables that need to be 407 // The box-element for a scope, and the captured variables that need to be
417 // stored in the box. 408 // stored in the box.
418 class ClosureScope { 409 class ClosureScope {
419 final BoxLocal boxElement; 410 final BoxLocal boxElement;
420 final Map<Local, BoxFieldElement> capturedVariables; 411 final Map<Local, BoxFieldElement> capturedVariables;
421 412
422 // If the scope is attached to a [For] contains the variables that are 413 // If the scope is attached to a [For] contains the variables that are
423 // declared in the initializer of the [For] and that need to be boxed. 414 // declared in the initializer of the [For] and that need to be boxed.
424 // Otherwise contains the empty List. 415 // Otherwise contains the empty List.
425 List<VariableElement> boxedLoopVariables = const <VariableElement>[]; 416 List<Local> boxedLoopVariables = const <Local>[];
426 417
427 ClosureScope(this.boxElement, this.capturedVariables); 418 ClosureScope(this.boxElement, this.capturedVariables);
428 419
429 bool hasBoxedLoopVariables() => !boxedLoopVariables.isEmpty; 420 bool hasBoxedLoopVariables() => !boxedLoopVariables.isEmpty;
430 421
431 bool isCapturedVariable(VariableElement variable) { 422 bool isCapturedVariable(VariableElement variable) {
432 return capturedVariables.containsKey(variable); 423 return capturedVariables.containsKey(variable);
433 } 424 }
434 425
435 void forEachCapturedVariable( 426 void forEachCapturedVariable(
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 /// 466 ///
476 /// The callElement will be null for methods that are not local closures. 467 /// The callElement will be null for methods that are not local closures.
477 final MethodElement callElement; 468 final MethodElement callElement;
478 469
479 /// The [thisElement] makes handling 'this' easier by treating it like any 470 /// The [thisElement] makes handling 'this' easier by treating it like any
480 /// other argument. It is only set for instance-members. 471 /// other argument. It is only set for instance-members.
481 final ThisLocal thisLocal; 472 final ThisLocal thisLocal;
482 473
483 /// Maps free locals, arguments, function elements, and box locals to 474 /// Maps free locals, arguments, function elements, and box locals to
484 /// their locations. 475 /// their locations.
485 final Map<Local, CapturedVariable> freeVariableMap = 476 final Map<Local, FieldEntity> freeVariableMap = new Map<Local, FieldEntity>();
486 new Map<Local, CapturedVariable>();
487 477
488 /// Maps [Loop] and [FunctionExpression] nodes to their [ClosureScope] which 478 /// Maps [Loop] and [FunctionExpression] nodes to their [ClosureScope] which
489 /// contains their box and the captured variables that are stored in the box. 479 /// contains their box and the captured variables that are stored in the box.
490 /// This map will be empty if the method/closure of this [ClosureData] does 480 /// This map will be empty if the method/closure of this [ClosureData] does
491 /// not contain any nested closure. 481 /// not contain any nested closure.
492 final Map<Node, ClosureScope> capturingScopes = new Map<Node, ClosureScope>(); 482 final Map<Node, ClosureScope> capturingScopes = new Map<Node, ClosureScope>();
493 483
494 /// Variables that are used in a try must be treated as boxed because the 484 /// Variables that are used in a try must be treated as boxed because the
495 /// control flow can be non-linear. 485 /// control flow can be non-linear.
496 /// 486 ///
497 /// Also parameters to a `sync*` generator must be boxed, because of the way 487 /// Also parameters to a `sync*` generator must be boxed, because of the way
498 /// we rewrite sync* functions. See also comments in [useLocal]. 488 /// we rewrite sync* functions. See also comments in [useLocal].
499 // TODO(johnniwinther): Add variables to this only if the variable is mutated. 489 // TODO(johnniwinther): Add variables to this only if the variable is mutated.
500 final Set<Local> variablesUsedInTryOrGenerator = new Set<Local>(); 490 final Set<Local> variablesUsedInTryOrGenerator = new Set<Local>();
501 491
502 ClosureClassMap(this.closureElement, this.closureClassElement, 492 ClosureClassMap(this.closureElement, this.closureClassElement,
503 this.callElement, this.thisLocal); 493 this.callElement, this.thisLocal);
504 494
505 void addFreeVariable(Local element) { 495 void addFreeVariable(Local element) {
506 assert(freeVariableMap[element] == null); 496 assert(freeVariableMap[element] == null);
507 freeVariableMap[element] = null; 497 freeVariableMap[element] = null;
508 } 498 }
509 499
510 Iterable<Local> get freeVariables => freeVariableMap.keys; 500 Iterable<Local> get freeVariables => freeVariableMap.keys;
511 501
512 bool isFreeVariable(Local element) { 502 bool isFreeVariable(Local element) {
513 return freeVariableMap.containsKey(element); 503 return freeVariableMap.containsKey(element);
514 } 504 }
515 505
516 void forEachFreeVariable(f(Local variable, CapturedVariable field)) { 506 void forEachFreeVariable(f(Local variable, FieldEntity field)) {
517 freeVariableMap.forEach(f); 507 freeVariableMap.forEach(f);
518 } 508 }
519 509
520 Local getLocalVariableForClosureField(ClosureFieldElement field) { 510 Local getLocalVariableForClosureField(ClosureFieldElement field) {
521 return field.local; 511 return field.local;
522 } 512 }
523 513
524 bool get isClosure => closureElement != null; 514 bool get isClosure => closureElement != null;
525 515
526 bool capturingScopesBox(Local variable) { 516 bool capturingScopesBox(Local variable) {
527 return capturingScopes.values.any((scope) { 517 return capturingScopes.values.any((scope) {
528 return scope.boxedLoopVariables.contains(variable); 518 return scope.boxedLoopVariables.contains(variable);
529 }); 519 });
530 } 520 }
531 521
532 bool isVariableBoxed(Local variable) { 522 bool isVariableBoxed(Local variable) {
533 CapturedVariable copy = freeVariableMap[variable]; 523 FieldEntity copy = freeVariableMap[variable];
534 if (copy is BoxFieldElement) { 524 if (copy is BoxFieldElement) {
535 return true; 525 return true;
536 } 526 }
537 return capturingScopesBox(variable); 527 return capturingScopesBox(variable);
538 } 528 }
539 529
540 void forEachCapturedVariable(void f(Local variable, CapturedVariable field)) { 530 void forEachCapturedVariable(void f(Local variable, FieldEntity field)) {
541 freeVariableMap.forEach((variable, copy) { 531 freeVariableMap.forEach((variable, copy) {
542 if (variable is BoxLocal) return; 532 if (variable is BoxLocal) return;
543 f(variable, copy); 533 f(variable, copy);
544 }); 534 });
545 capturingScopes.values.forEach((ClosureScope scope) { 535 capturingScopes.values.forEach((ClosureScope scope) {
546 scope.forEachCapturedVariable(f); 536 scope.forEachCapturedVariable(f);
547 }); 537 });
548 } 538 }
549 539
550 void forEachBoxedVariable( 540 void forEachBoxedVariable(
(...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after
1238 /// 1228 ///
1239 /// Move the below classes to a JS model eventually. 1229 /// Move the below classes to a JS model eventually.
1240 /// 1230 ///
1241 abstract class JSEntity implements Entity { 1231 abstract class JSEntity implements Entity {
1242 Entity get declaredEntity; 1232 Entity get declaredEntity;
1243 } 1233 }
1244 1234
1245 abstract class PrivatelyNamedJSEntity implements JSEntity { 1235 abstract class PrivatelyNamedJSEntity implements JSEntity {
1246 Entity get rootOfScope; 1236 Entity get rootOfScope;
1247 } 1237 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/inferrer/inferrer_engine.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698