Index: pkg/compiler/lib/src/kernel/env.dart |
diff --git a/pkg/compiler/lib/src/kernel/env.dart b/pkg/compiler/lib/src/kernel/env.dart |
index c258e7653292a44e26229ca333d7b12ababf2229..7ffc47166df72f505dafeb0034804792bdd8de1c 100644 |
--- a/pkg/compiler/lib/src/kernel/env.dart |
+++ b/pkg/compiler/lib/src/kernel/env.dart |
@@ -9,14 +9,12 @@ import 'package:kernel/clone.dart'; |
import 'package:kernel/type_algebra.dart'; |
import '../common.dart'; |
-import '../common/resolution.dart'; |
import '../constants/constructors.dart'; |
import '../constants/expressions.dart'; |
import '../constants/values.dart'; |
import '../elements/entities.dart'; |
import '../elements/types.dart'; |
import '../ordered_typeset.dart'; |
-import '../ssa/kernel_impact.dart'; |
import 'element_map.dart'; |
import 'element_map_impl.dart'; |
import 'element_map_mixins.dart'; |
@@ -86,7 +84,7 @@ class LibraryEnv { |
if (_classMap == null) { |
_classMap = <String, ClassEnv>{}; |
for (ir.Class cls in library.classes) { |
- _classMap[cls.name] = new ClassEnv(cls); |
+ _classMap[cls.name] = new ClassEnvImpl(cls); |
} |
} |
} |
@@ -165,8 +163,39 @@ class LibraryData { |
} |
} |
+/// Member data for a class. |
+abstract class ClassEnv { |
+ /// The [ir.Class] that defined the class, if any. |
+ ir.Class get cls; |
+ |
+ /// Whether the class is an unnamed mixin application. |
+ bool get isUnnamedMixinApplication; |
+ |
+ /// Return the [MemberEntity] for the member [name] in the class. If [setter] |
+ /// is `true`, the setter or assignable field corresponding to [name] is |
+ /// returned. |
+ MemberEntity lookupMember(KernelToElementMap elementMap, String name, |
+ {bool setter: false}); |
+ |
+ /// Calls [f] for each member of the class. |
+ void forEachMember( |
+ KernelToElementMap elementMap, void f(MemberEntity member)); |
+ |
+ /// Return the [ConstructorEntity] for the constructor [name] in the class. |
+ ConstructorEntity lookupConstructor( |
+ KernelToElementMap elementMap, String name); |
+ |
+ /// Calls [f] for each constructor of the class. |
+ void forEachConstructor( |
+ KernelToElementMap elementMap, void f(ConstructorEntity constructor)); |
+ |
+ /// Calls [f] for each constructor body for the live constructors in the |
+ /// class. |
+ void forEachConstructorBody(void f(ConstructorBodyEntity constructor)); |
+} |
+ |
/// Environment for fast lookup of class members. |
-class ClassEnv { |
+class ClassEnvImpl implements ClassEnv { |
final ir.Class cls; |
final bool isUnnamedMixinApplication; |
@@ -174,21 +203,15 @@ class ClassEnv { |
Map<String, ir.Member> _memberMap; |
Map<String, ir.Member> _setterMap; |
- ClassEnv(this.cls) |
+ /// Constructor bodies created for this class. |
+ List<ConstructorBodyEntity> _constructorBodyList; |
+ |
+ ClassEnvImpl(this.cls) |
// TODO(johnniwinther): Change this to use a property on [cls] when such |
// is added to kernel. |
: isUnnamedMixinApplication = |
cls.name.contains('+') || cls.name.contains('&'); |
- // TODO(efortuna): This is gross because even though the closure class *has* |
- // members, we're not populating this because they aren't ir.Member types. :-( |
- ClassEnv.closureClass() |
- : cls = null, |
- isUnnamedMixinApplication = false, |
- _constructorMap = const <String, ir.Member>{}, |
- _memberMap = const <String, ir.Member>{}, |
- _setterMap = const <String, ir.Member>{}; |
- |
/// Copied from 'package:kernel/transformations/mixin_full_resolution.dart'. |
ir.Constructor _buildForwardingConstructor( |
CloneVisitor cloner, ir.Constructor superclassConstructor) { |
@@ -299,38 +322,107 @@ class ClassEnv { |
} |
} |
- /// Return the [ir.Member] for the member [name] in [library]. |
- ir.Member lookupMember(String name, {bool setter: false}) { |
- _ensureMaps(); |
- return setter ? _setterMap[name] : _memberMap[name]; |
- } |
- |
- /// Return the [ir.Member] for the member [name] in [library]. |
- ir.Member lookupConstructor(String name) { |
+ /// Return the [MemberEntity] for the member [name] in [cls]. If [setter] is |
+ /// `true`, the setter or assignable field corresponding to [name] is |
+ /// returned. |
+ MemberEntity lookupMember(KernelToElementMap elementMap, String name, |
+ {bool setter: false}) { |
_ensureMaps(); |
- return _constructorMap[name]; |
+ ir.Member member = setter ? _setterMap[name] : _memberMap[name]; |
+ return member != null ? elementMap.getMember(member) : null; |
} |
- void forEachMember(void f(ir.Member member)) { |
+ /// Calls [f] for each member of [cls]. |
+ void forEachMember( |
+ KernelToElementMap elementMap, void f(MemberEntity member)) { |
_ensureMaps(); |
- _memberMap.values.forEach(f); |
+ _memberMap.values.forEach((ir.Member member) { |
+ f(elementMap.getMember(member)); |
+ }); |
for (ir.Member member in _setterMap.values) { |
if (member is ir.Procedure) { |
- f(member); |
+ f(elementMap.getMember(member)); |
} else { |
// Skip fields; these are also in _memberMap. |
} |
} |
} |
- void forEachConstructor(void f(ir.Member member)) { |
+ /// Return the [ConstructorEntity] for the constructor [name] in [cls]. |
+ ConstructorEntity lookupConstructor( |
+ KernelToElementMap elementMap, String name) { |
_ensureMaps(); |
- _constructorMap.values.forEach(f); |
+ ir.Member constructor = _constructorMap[name]; |
+ return constructor != null ? elementMap.getConstructor(constructor) : null; |
+ } |
+ |
+ /// Calls [f] for each constructor of [cls]. |
+ void forEachConstructor( |
+ KernelToElementMap elementMap, void f(ConstructorEntity constructor)) { |
+ _ensureMaps(); |
+ _constructorMap.values.forEach((ir.Member constructor) { |
+ f(elementMap.getConstructor(constructor)); |
+ }); |
+ } |
+ |
+ void addConstructorBody(ConstructorBodyEntity constructorBody) { |
+ _constructorBodyList ??= <ConstructorBodyEntity>[]; |
+ _constructorBodyList.add(constructorBody); |
+ } |
+ |
+ void forEachConstructorBody(void f(ConstructorBodyEntity constructor)) { |
+ _constructorBodyList?.forEach(f); |
+ } |
+} |
+ |
+class ClosureClassEnv implements ClassEnv { |
+ final Map<String, MemberEntity> _memberMap; |
+ |
+ ClosureClassEnv(this._memberMap); |
+ |
+ @override |
+ void forEachConstructorBody(void f(ConstructorBodyEntity constructor)) { |
+ // We do not create constructor bodies for closure classes. |
+ } |
+ |
+ @override |
+ void forEachConstructor( |
+ KernelToElementMap elementMap, void f(ConstructorEntity constructor)) { |
+ // We do not create constructors for closure classes. |
+ } |
+ |
+ @override |
+ ConstructorEntity lookupConstructor( |
+ KernelToElementMap elementMap, String name) { |
+ // We do not create constructors for closure classes. |
+ return null; |
+ } |
+ |
+ @override |
+ void forEachMember( |
+ KernelToElementMap elementMap, void f(MemberEntity member)) { |
+ _memberMap.values.forEach(f); |
} |
+ |
+ @override |
+ MemberEntity lookupMember(KernelToElementMap elementMap, String name, |
+ {bool setter: false}) { |
+ if (setter) { |
+ // All closure fields are final. |
+ return null; |
+ } |
+ return _memberMap[name]; |
+ } |
+ |
+ @override |
+ bool get isUnnamedMixinApplication => false; |
+ |
+ @override |
+ ir.Class get cls => null; |
} |
class ClassData { |
- /// TODO(johnniwinther): Remove this from the [MemberData] interface. Use |
+ /// TODO(johnniwinther): Remove this from the [ClassData] interface. Use |
/// `definition.node` instead. |
final ir.Class cls; |
final ClassDefinition definition; |
@@ -356,7 +448,13 @@ class ClassData { |
} |
} |
-class MemberData { |
+abstract class MemberData { |
+ MemberDefinition get definition; |
+ |
+ Iterable<ConstantValue> getMetadata(KernelToElementMap elementMap); |
+} |
+ |
+class MemberDataImpl implements MemberData { |
/// TODO(johnniwinther): Remove this from the [MemberData] interface. Use |
/// `definition.node` instead. |
final ir.Member node; |
@@ -365,29 +463,34 @@ class MemberData { |
Iterable<ConstantValue> _metadata; |
- MemberData(this.node, this.definition); |
+ MemberDataImpl(this.node, this.definition); |
- ResolutionImpact getWorldImpact(KernelToElementMapForImpact elementMap) { |
- return buildKernelImpact(node, elementMap); |
- } |
- |
- Iterable<ConstantValue> getMetadata(KernelToElementMapBase elementMap) { |
+ Iterable<ConstantValue> getMetadata( |
+ covariant KernelToElementMapBase elementMap) { |
return _metadata ??= elementMap.getMetadata(node.annotations); |
} |
MemberData copy() { |
- return new MemberData(node, definition); |
+ return new MemberDataImpl(node, definition); |
} |
} |
-class FunctionData extends MemberData { |
+abstract class FunctionData implements MemberData { |
+ FunctionType getFunctionType(KernelToElementMap elementMap); |
+ |
+ void forEachParameter(KernelToElementMapForBuilding elementMap, |
+ void f(DartType type, String name, ConstantValue defaultValue)); |
+} |
+ |
+class FunctionDataImpl extends MemberDataImpl implements FunctionData { |
final ir.FunctionNode functionNode; |
FunctionType _type; |
- FunctionData(ir.Member node, this.functionNode, MemberDefinition definition) |
+ FunctionDataImpl( |
+ ir.Member node, this.functionNode, MemberDefinition definition) |
: super(node, definition); |
- FunctionType getFunctionType(KernelToElementMapBase elementMap) { |
+ FunctionType getFunctionType(covariant KernelToElementMapBase elementMap) { |
return _type ??= elementMap.getFunctionType(functionNode); |
} |
@@ -418,15 +521,20 @@ class FunctionData extends MemberData { |
@override |
FunctionData copy() { |
- return new FunctionData(node, functionNode, definition); |
+ return new FunctionDataImpl(node, functionNode, definition); |
} |
} |
-class ConstructorData extends FunctionData { |
+abstract class ConstructorData extends FunctionData { |
+ ConstantConstructor getConstructorConstant( |
+ KernelToElementMapBase elementMap, ConstructorEntity constructor); |
+} |
+ |
+class ConstructorDataImpl extends FunctionDataImpl implements ConstructorData { |
ConstantConstructor _constantConstructor; |
ConstructorBodyEntity constructorBody; |
- ConstructorData( |
+ ConstructorDataImpl( |
ir.Member node, ir.FunctionNode functionNode, MemberDefinition definition) |
: super(node, functionNode, definition); |
@@ -440,7 +548,7 @@ class ConstructorData extends FunctionData { |
failedAt( |
constructor, |
"Unexpected constructor $constructor in " |
- "KernelWorldBuilder._getConstructorConstant"); |
+ "ConstructorDataImpl._getConstructorConstant"); |
} |
} |
return _constantConstructor; |
@@ -448,14 +556,19 @@ class ConstructorData extends FunctionData { |
@override |
ConstructorData copy() { |
- return new ConstructorData(node, functionNode, definition); |
+ return new ConstructorDataImpl(node, functionNode, definition); |
} |
} |
-class FieldData extends MemberData { |
+abstract class FieldData extends MemberData { |
+ ConstantExpression getFieldConstant( |
+ KernelToElementMapBase elementMap, FieldEntity field); |
+} |
+ |
+class FieldDataImpl extends MemberDataImpl implements FieldData { |
ConstantExpression _constant; |
- FieldData(ir.Field node, MemberDefinition definition) |
+ FieldDataImpl(ir.Field node, MemberDefinition definition) |
: super(node, definition); |
ir.Field get node => super.node; |
@@ -469,7 +582,7 @@ class FieldData extends MemberData { |
failedAt( |
field, |
"Unexpected field $field in " |
- "KernelWorldBuilder._getConstructorConstant"); |
+ "FieldDataImpl.getFieldConstant"); |
} |
} |
return _constant; |
@@ -477,6 +590,6 @@ class FieldData extends MemberData { |
@override |
FieldData copy() { |
- return new FieldData(node, definition); |
+ return new FieldDataImpl(node, definition); |
} |
} |