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

Side by Side Diff: pkg/compiler/lib/src/kernel/env.dart

Issue 2992863002: Support forEachClassMember on closure classes (Closed)
Patch Set: Updated cf. comments Created 3 years, 4 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
OLDNEW
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, 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 dart2js.kernel.env; 5 library dart2js.kernel.env;
6 6
7 import 'package:kernel/ast.dart' as ir; 7 import 'package:kernel/ast.dart' as ir;
8 import 'package:kernel/clone.dart'; 8 import 'package:kernel/clone.dart';
9 import 'package:kernel/type_algebra.dart'; 9 import 'package:kernel/type_algebra.dart';
10 10
11 import '../common.dart'; 11 import '../common.dart';
12 import '../common/resolution.dart';
13 import '../constants/constructors.dart'; 12 import '../constants/constructors.dart';
14 import '../constants/expressions.dart'; 13 import '../constants/expressions.dart';
15 import '../constants/values.dart'; 14 import '../constants/values.dart';
16 import '../elements/entities.dart'; 15 import '../elements/entities.dart';
17 import '../elements/types.dart'; 16 import '../elements/types.dart';
18 import '../ordered_typeset.dart'; 17 import '../ordered_typeset.dart';
19 import '../ssa/kernel_impact.dart';
20 import 'element_map.dart'; 18 import 'element_map.dart';
21 import 'element_map_impl.dart'; 19 import 'element_map_impl.dart';
22 import 'element_map_mixins.dart'; 20 import 'element_map_mixins.dart';
23 21
24 /// Environment for fast lookup of program libraries. 22 /// Environment for fast lookup of program libraries.
25 class ProgramEnv { 23 class ProgramEnv {
26 final Set<ir.Program> _programs = new Set<ir.Program>(); 24 final Set<ir.Program> _programs = new Set<ir.Program>();
27 25
28 Map<Uri, LibraryEnv> _libraryMap; 26 Map<Uri, LibraryEnv> _libraryMap;
29 27
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 Map<String, ClassEnv> _classMap; 77 Map<String, ClassEnv> _classMap;
80 Map<String, ir.Member> _memberMap; 78 Map<String, ir.Member> _memberMap;
81 Map<String, ir.Member> _setterMap; 79 Map<String, ir.Member> _setterMap;
82 80
83 LibraryEnv(this.library); 81 LibraryEnv(this.library);
84 82
85 void _ensureClassMap() { 83 void _ensureClassMap() {
86 if (_classMap == null) { 84 if (_classMap == null) {
87 _classMap = <String, ClassEnv>{}; 85 _classMap = <String, ClassEnv>{};
88 for (ir.Class cls in library.classes) { 86 for (ir.Class cls in library.classes) {
89 _classMap[cls.name] = new ClassEnv(cls); 87 _classMap[cls.name] = new ClassEnvImpl(cls);
90 } 88 }
91 } 89 }
92 } 90 }
93 91
94 /// Return the [ClassEnv] for the class [name] in [library]. 92 /// Return the [ClassEnv] for the class [name] in [library].
95 ClassEnv lookupClass(String name) { 93 ClassEnv lookupClass(String name) {
96 _ensureClassMap(); 94 _ensureClassMap();
97 return _classMap[name]; 95 return _classMap[name];
98 } 96 }
99 97
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 156
159 Iterable<ConstantValue> getMetadata(KernelToElementMapBase elementMap) { 157 Iterable<ConstantValue> getMetadata(KernelToElementMapBase elementMap) {
160 return _metadata ??= elementMap.getMetadata(library.annotations); 158 return _metadata ??= elementMap.getMetadata(library.annotations);
161 } 159 }
162 160
163 LibraryData copy() { 161 LibraryData copy() {
164 return new LibraryData(library); 162 return new LibraryData(library);
165 } 163 }
166 } 164 }
167 165
166 /// Member data for a class.
167 abstract class ClassEnv {
168 /// The [ir.Class] that defined the class, if any.
169 ir.Class get cls;
170
171 /// Whether the class is an unnamed mixin application.
172 bool get isUnnamedMixinApplication;
173
174 /// Return the [MemberEntity] for the member [name] in the class. If [setter]
175 /// is `true`, the setter or assignable field corresponding to [name] is
176 /// returned.
177 MemberEntity lookupMember(KernelToElementMap elementMap, String name,
178 {bool setter: false});
179
180 /// Calls [f] for each member of the class.
181 void forEachMember(
182 KernelToElementMap elementMap, void f(MemberEntity member));
183
184 /// Return the [ConstructorEntity] for the constructor [name] in the class.
185 ConstructorEntity lookupConstructor(
186 KernelToElementMap elementMap, String name);
187
188 /// Calls [f] for each constructor of the class.
189 void forEachConstructor(
190 KernelToElementMap elementMap, void f(ConstructorEntity constructor));
191
192 /// Calls [f] for each constructor body for the live constructors in the
193 /// class.
194 void forEachConstructorBody(void f(ConstructorBodyEntity constructor));
195 }
196
168 /// Environment for fast lookup of class members. 197 /// Environment for fast lookup of class members.
169 class ClassEnv { 198 class ClassEnvImpl implements ClassEnv {
170 final ir.Class cls; 199 final ir.Class cls;
171 final bool isUnnamedMixinApplication; 200 final bool isUnnamedMixinApplication;
172 201
173 Map<String, ir.Member> _constructorMap; 202 Map<String, ir.Member> _constructorMap;
174 Map<String, ir.Member> _memberMap; 203 Map<String, ir.Member> _memberMap;
175 Map<String, ir.Member> _setterMap; 204 Map<String, ir.Member> _setterMap;
176 205
177 ClassEnv(this.cls) 206 /// Constructor bodies created for this class.
207 List<ConstructorBodyEntity> _constructorBodyList;
208
209 ClassEnvImpl(this.cls)
178 // TODO(johnniwinther): Change this to use a property on [cls] when such 210 // TODO(johnniwinther): Change this to use a property on [cls] when such
179 // is added to kernel. 211 // is added to kernel.
180 : isUnnamedMixinApplication = 212 : isUnnamedMixinApplication =
181 cls.name.contains('+') || cls.name.contains('&'); 213 cls.name.contains('+') || cls.name.contains('&');
182 214
183 // TODO(efortuna): This is gross because even though the closure class *has*
184 // members, we're not populating this because they aren't ir.Member types. :-(
185 ClassEnv.closureClass()
186 : cls = null,
187 isUnnamedMixinApplication = false,
188 _constructorMap = const <String, ir.Member>{},
189 _memberMap = const <String, ir.Member>{},
190 _setterMap = const <String, ir.Member>{};
191
192 /// Copied from 'package:kernel/transformations/mixin_full_resolution.dart'. 215 /// Copied from 'package:kernel/transformations/mixin_full_resolution.dart'.
193 ir.Constructor _buildForwardingConstructor( 216 ir.Constructor _buildForwardingConstructor(
194 CloneVisitor cloner, ir.Constructor superclassConstructor) { 217 CloneVisitor cloner, ir.Constructor superclassConstructor) {
195 var superFunction = superclassConstructor.function; 218 var superFunction = superclassConstructor.function;
196 219
197 // We keep types and default values for the parameters but always mark the 220 // We keep types and default values for the parameters but always mark the
198 // parameters as final (since we just forward them to the super 221 // parameters as final (since we just forward them to the super
199 // constructor). 222 // constructor).
200 ir.VariableDeclaration cloneVariable(ir.VariableDeclaration variable) { 223 ir.VariableDeclaration cloneVariable(ir.VariableDeclaration variable) {
201 ir.VariableDeclaration clone = cloner.clone(variable); 224 ir.VariableDeclaration clone = cloner.clone(variable);
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 var forwardingConstructor = _buildForwardingConstructor( 315 var forwardingConstructor = _buildForwardingConstructor(
293 superclassCloner, superclassConstructor); 316 superclassCloner, superclassConstructor);
294 cls.addMember(forwardingConstructor); 317 cls.addMember(forwardingConstructor);
295 _constructorMap[forwardingConstructor.name.name] = 318 _constructorMap[forwardingConstructor.name.name] =
296 forwardingConstructor; 319 forwardingConstructor;
297 } 320 }
298 } 321 }
299 } 322 }
300 } 323 }
301 324
302 /// Return the [ir.Member] for the member [name] in [library]. 325 /// Return the [MemberEntity] for the member [name] in [cls]. If [setter] is
303 ir.Member lookupMember(String name, {bool setter: false}) { 326 /// `true`, the setter or assignable field corresponding to [name] is
327 /// returned.
328 MemberEntity lookupMember(KernelToElementMap elementMap, String name,
329 {bool setter: false}) {
304 _ensureMaps(); 330 _ensureMaps();
305 return setter ? _setterMap[name] : _memberMap[name]; 331 ir.Member member = setter ? _setterMap[name] : _memberMap[name];
332 return member != null ? elementMap.getMember(member) : null;
306 } 333 }
307 334
308 /// Return the [ir.Member] for the member [name] in [library]. 335 /// Calls [f] for each member of [cls].
309 ir.Member lookupConstructor(String name) { 336 void forEachMember(
337 KernelToElementMap elementMap, void f(MemberEntity member)) {
310 _ensureMaps(); 338 _ensureMaps();
311 return _constructorMap[name]; 339 _memberMap.values.forEach((ir.Member member) {
312 } 340 f(elementMap.getMember(member));
313 341 });
314 void forEachMember(void f(ir.Member member)) {
315 _ensureMaps();
316 _memberMap.values.forEach(f);
317 for (ir.Member member in _setterMap.values) { 342 for (ir.Member member in _setterMap.values) {
318 if (member is ir.Procedure) { 343 if (member is ir.Procedure) {
319 f(member); 344 f(elementMap.getMember(member));
320 } else { 345 } else {
321 // Skip fields; these are also in _memberMap. 346 // Skip fields; these are also in _memberMap.
322 } 347 }
323 } 348 }
324 } 349 }
325 350
326 void forEachConstructor(void f(ir.Member member)) { 351 /// Return the [ConstructorEntity] for the constructor [name] in [cls].
352 ConstructorEntity lookupConstructor(
353 KernelToElementMap elementMap, String name) {
327 _ensureMaps(); 354 _ensureMaps();
328 _constructorMap.values.forEach(f); 355 ir.Member constructor = _constructorMap[name];
356 return constructor != null ? elementMap.getConstructor(constructor) : null;
357 }
358
359 /// Calls [f] for each constructor of [cls].
360 void forEachConstructor(
361 KernelToElementMap elementMap, void f(ConstructorEntity constructor)) {
362 _ensureMaps();
363 _constructorMap.values.forEach((ir.Member constructor) {
364 f(elementMap.getConstructor(constructor));
365 });
366 }
367
368 void addConstructorBody(ConstructorBodyEntity constructorBody) {
369 _constructorBodyList ??= <ConstructorBodyEntity>[];
370 _constructorBodyList.add(constructorBody);
371 }
372
373 void forEachConstructorBody(void f(ConstructorBodyEntity constructor)) {
374 _constructorBodyList?.forEach(f);
329 } 375 }
330 } 376 }
331 377
378 class ClosureClassEnv implements ClassEnv {
379 final Map<String, MemberEntity> _memberMap;
380
381 ClosureClassEnv(this._memberMap);
382
383 @override
384 void forEachConstructorBody(void f(ConstructorBodyEntity constructor)) {
385 // We do not create constructor bodies for closure classes.
386 }
387
388 @override
389 void forEachConstructor(
390 KernelToElementMap elementMap, void f(ConstructorEntity constructor)) {
391 // We do not create constructors for closure classes.
392 }
393
394 @override
395 ConstructorEntity lookupConstructor(
396 KernelToElementMap elementMap, String name) {
397 // We do not create constructors for closure classes.
398 return null;
399 }
400
401 @override
402 void forEachMember(
403 KernelToElementMap elementMap, void f(MemberEntity member)) {
404 _memberMap.values.forEach(f);
405 }
406
407 @override
408 MemberEntity lookupMember(KernelToElementMap elementMap, String name,
409 {bool setter: false}) {
410 if (setter) {
411 // All closure fields are final.
412 return null;
413 }
414 return _memberMap[name];
415 }
416
417 @override
418 bool get isUnnamedMixinApplication => false;
419
420 @override
421 ir.Class get cls => null;
422 }
423
332 class ClassData { 424 class ClassData {
333 /// TODO(johnniwinther): Remove this from the [MemberData] interface. Use 425 /// TODO(johnniwinther): Remove this from the [ClassData] interface. Use
334 /// `definition.node` instead. 426 /// `definition.node` instead.
335 final ir.Class cls; 427 final ir.Class cls;
336 final ClassDefinition definition; 428 final ClassDefinition definition;
337 bool isMixinApplication; 429 bool isMixinApplication;
338 430
339 InterfaceType thisType; 431 InterfaceType thisType;
340 InterfaceType rawType; 432 InterfaceType rawType;
341 InterfaceType supertype; 433 InterfaceType supertype;
342 InterfaceType mixedInType; 434 InterfaceType mixedInType;
343 List<InterfaceType> interfaces; 435 List<InterfaceType> interfaces;
344 OrderedTypeSet orderedTypeSet; 436 OrderedTypeSet orderedTypeSet;
345 437
346 Iterable<ConstantValue> _metadata; 438 Iterable<ConstantValue> _metadata;
347 439
348 ClassData(this.cls, this.definition); 440 ClassData(this.cls, this.definition);
349 441
350 Iterable<ConstantValue> getMetadata(KernelToElementMapBase elementMap) { 442 Iterable<ConstantValue> getMetadata(KernelToElementMapBase elementMap) {
351 return _metadata ??= elementMap.getMetadata(cls.annotations); 443 return _metadata ??= elementMap.getMetadata(cls.annotations);
352 } 444 }
353 445
354 ClassData copy() { 446 ClassData copy() {
355 return new ClassData(cls, definition); 447 return new ClassData(cls, definition);
356 } 448 }
357 } 449 }
358 450
359 class MemberData { 451 abstract class MemberData {
452 MemberDefinition get definition;
453
454 Iterable<ConstantValue> getMetadata(KernelToElementMap elementMap);
455 }
456
457 class MemberDataImpl implements MemberData {
360 /// TODO(johnniwinther): Remove this from the [MemberData] interface. Use 458 /// TODO(johnniwinther): Remove this from the [MemberData] interface. Use
361 /// `definition.node` instead. 459 /// `definition.node` instead.
362 final ir.Member node; 460 final ir.Member node;
363 461
364 final MemberDefinition definition; 462 final MemberDefinition definition;
365 463
366 Iterable<ConstantValue> _metadata; 464 Iterable<ConstantValue> _metadata;
367 465
368 MemberData(this.node, this.definition); 466 MemberDataImpl(this.node, this.definition);
369 467
370 ResolutionImpact getWorldImpact(KernelToElementMapForImpact elementMap) { 468 Iterable<ConstantValue> getMetadata(
371 return buildKernelImpact(node, elementMap); 469 covariant KernelToElementMapBase elementMap) {
372 }
373
374 Iterable<ConstantValue> getMetadata(KernelToElementMapBase elementMap) {
375 return _metadata ??= elementMap.getMetadata(node.annotations); 470 return _metadata ??= elementMap.getMetadata(node.annotations);
376 } 471 }
377 472
378 MemberData copy() { 473 MemberData copy() {
379 return new MemberData(node, definition); 474 return new MemberDataImpl(node, definition);
380 } 475 }
381 } 476 }
382 477
383 class FunctionData extends MemberData { 478 abstract class FunctionData implements MemberData {
479 FunctionType getFunctionType(KernelToElementMap elementMap);
480
481 void forEachParameter(KernelToElementMapForBuilding elementMap,
482 void f(DartType type, String name, ConstantValue defaultValue));
483 }
484
485 class FunctionDataImpl extends MemberDataImpl implements FunctionData {
384 final ir.FunctionNode functionNode; 486 final ir.FunctionNode functionNode;
385 FunctionType _type; 487 FunctionType _type;
386 488
387 FunctionData(ir.Member node, this.functionNode, MemberDefinition definition) 489 FunctionDataImpl(
490 ir.Member node, this.functionNode, MemberDefinition definition)
388 : super(node, definition); 491 : super(node, definition);
389 492
390 FunctionType getFunctionType(KernelToElementMapBase elementMap) { 493 FunctionType getFunctionType(covariant KernelToElementMapBase elementMap) {
391 return _type ??= elementMap.getFunctionType(functionNode); 494 return _type ??= elementMap.getFunctionType(functionNode);
392 } 495 }
393 496
394 void forEachParameter(KernelToElementMapForBuilding elementMap, 497 void forEachParameter(KernelToElementMapForBuilding elementMap,
395 void f(DartType type, String name, ConstantValue defaultValue)) { 498 void f(DartType type, String name, ConstantValue defaultValue)) {
396 void handleParameter(ir.VariableDeclaration node, {bool isOptional: true}) { 499 void handleParameter(ir.VariableDeclaration node, {bool isOptional: true}) {
397 DartType type = elementMap.getDartType(node.type); 500 DartType type = elementMap.getDartType(node.type);
398 String name = node.name; 501 String name = node.name;
399 ConstantValue defaultValue; 502 ConstantValue defaultValue;
400 if (isOptional) { 503 if (isOptional) {
(...skipping 10 matching lines...) Expand all
411 handleParameter(functionNode.positionalParameters[i], 514 handleParameter(functionNode.positionalParameters[i],
412 isOptional: i < functionNode.requiredParameterCount); 515 isOptional: i < functionNode.requiredParameterCount);
413 } 516 }
414 functionNode.namedParameters.toList() 517 functionNode.namedParameters.toList()
415 ..sort(namedOrdering) 518 ..sort(namedOrdering)
416 ..forEach(handleParameter); 519 ..forEach(handleParameter);
417 } 520 }
418 521
419 @override 522 @override
420 FunctionData copy() { 523 FunctionData copy() {
421 return new FunctionData(node, functionNode, definition); 524 return new FunctionDataImpl(node, functionNode, definition);
422 } 525 }
423 } 526 }
424 527
425 class ConstructorData extends FunctionData { 528 abstract class ConstructorData extends FunctionData {
529 ConstantConstructor getConstructorConstant(
530 KernelToElementMapBase elementMap, ConstructorEntity constructor);
531 }
532
533 class ConstructorDataImpl extends FunctionDataImpl implements ConstructorData {
426 ConstantConstructor _constantConstructor; 534 ConstantConstructor _constantConstructor;
427 ConstructorBodyEntity constructorBody; 535 ConstructorBodyEntity constructorBody;
428 536
429 ConstructorData( 537 ConstructorDataImpl(
430 ir.Member node, ir.FunctionNode functionNode, MemberDefinition definition) 538 ir.Member node, ir.FunctionNode functionNode, MemberDefinition definition)
431 : super(node, functionNode, definition); 539 : super(node, functionNode, definition);
432 540
433 ConstantConstructor getConstructorConstant( 541 ConstantConstructor getConstructorConstant(
434 KernelToElementMapBase elementMap, ConstructorEntity constructor) { 542 KernelToElementMapBase elementMap, ConstructorEntity constructor) {
435 if (_constantConstructor == null) { 543 if (_constantConstructor == null) {
436 if (node is ir.Constructor && constructor.isConst) { 544 if (node is ir.Constructor && constructor.isConst) {
437 _constantConstructor = 545 _constantConstructor =
438 new Constantifier(elementMap).computeConstantConstructor(node); 546 new Constantifier(elementMap).computeConstantConstructor(node);
439 } else { 547 } else {
440 failedAt( 548 failedAt(
441 constructor, 549 constructor,
442 "Unexpected constructor $constructor in " 550 "Unexpected constructor $constructor in "
443 "KernelWorldBuilder._getConstructorConstant"); 551 "ConstructorDataImpl._getConstructorConstant");
444 } 552 }
445 } 553 }
446 return _constantConstructor; 554 return _constantConstructor;
447 } 555 }
448 556
449 @override 557 @override
450 ConstructorData copy() { 558 ConstructorData copy() {
451 return new ConstructorData(node, functionNode, definition); 559 return new ConstructorDataImpl(node, functionNode, definition);
452 } 560 }
453 } 561 }
454 562
455 class FieldData extends MemberData { 563 abstract class FieldData extends MemberData {
564 ConstantExpression getFieldConstant(
565 KernelToElementMapBase elementMap, FieldEntity field);
566 }
567
568 class FieldDataImpl extends MemberDataImpl implements FieldData {
456 ConstantExpression _constant; 569 ConstantExpression _constant;
457 570
458 FieldData(ir.Field node, MemberDefinition definition) 571 FieldDataImpl(ir.Field node, MemberDefinition definition)
459 : super(node, definition); 572 : super(node, definition);
460 573
461 ir.Field get node => super.node; 574 ir.Field get node => super.node;
462 575
463 ConstantExpression getFieldConstant( 576 ConstantExpression getFieldConstant(
464 KernelToElementMapBase elementMap, FieldEntity field) { 577 KernelToElementMapBase elementMap, FieldEntity field) {
465 if (_constant == null) { 578 if (_constant == null) {
466 if (node.isConst) { 579 if (node.isConst) {
467 _constant = new Constantifier(elementMap).visit(node.initializer); 580 _constant = new Constantifier(elementMap).visit(node.initializer);
468 } else { 581 } else {
469 failedAt( 582 failedAt(
470 field, 583 field,
471 "Unexpected field $field in " 584 "Unexpected field $field in "
472 "KernelWorldBuilder._getConstructorConstant"); 585 "FieldDataImpl.getFieldConstant");
473 } 586 }
474 } 587 }
475 return _constant; 588 return _constant;
476 } 589 }
477 590
478 @override 591 @override
479 FieldData copy() { 592 FieldData copy() {
480 return new FieldData(node, definition); 593 return new FieldDataImpl(node, definition);
481 } 594 }
482 } 595 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/kernel/element_map_impl.dart ('k') | pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698