Index: pkg/compiler/lib/src/kernel/element_map_impl.dart |
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart |
index 9d7f74ecfbb5ec409d3e6a5192fd491f45719b3f..50ae4244f69a982dc3d0b2462c0807998bdc3c7b 100644 |
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart |
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart |
@@ -37,6 +37,7 @@ import '../native/native.dart' as native; |
import '../native/resolver.dart'; |
import '../ordered_typeset.dart'; |
import '../options.dart'; |
+import '../ssa/kernel_impact.dart'; |
import '../universe/class_set.dart'; |
import '../universe/selector.dart'; |
import '../universe/world_builder.dart'; |
@@ -135,38 +136,20 @@ abstract class KernelToElementMapBase extends KernelToElementMapBaseMixin { |
Iterable<LibraryEntity> get _libraries; |
- SourceSpan _getSourceSpanFromTreeNode(ir.TreeNode node) { |
- // TODO(johnniwinther): Use [ir.Location] directly as a [SourceSpan]. |
- Uri uri; |
- int offset; |
- while (node != null) { |
- if (node.fileOffset != ir.TreeNode.noOffset) { |
- offset = node.fileOffset; |
- uri = Uri.parse(node.location.file); |
- break; |
- } |
- node = node.parent; |
- } |
- if (uri != null) { |
- return new SourceSpan(uri, offset, offset + 1); |
- } |
- return null; |
- } |
- |
SourceSpan getSourceSpan(Spannable spannable, Entity currentElement) { |
SourceSpan fromSpannable(Spannable spannable) { |
if (spannable is IndexedLibrary && |
spannable.libraryIndex < _libraryEnvs.length) { |
LibraryEnv env = _libraryEnvs[spannable.libraryIndex]; |
- return _getSourceSpanFromTreeNode(env.library); |
+ return computeSourceSpanFromTreeNode(env.library); |
} else if (spannable is IndexedClass && |
spannable.classIndex < _classEnvs.length) { |
- ClassEnv env = _classEnvs[spannable.classIndex]; |
- return _getSourceSpanFromTreeNode(env.cls); |
+ ClassData data = _classData[spannable.classIndex]; |
+ return data.definition.location; |
} else if (spannable is IndexedMember && |
spannable.memberIndex < _memberData.length) { |
MemberData data = _memberData[spannable.memberIndex]; |
- return _getSourceSpanFromTreeNode(data.node); |
+ return data.definition.location; |
} |
return null; |
} |
@@ -229,15 +212,13 @@ abstract class KernelToElementMapBase extends KernelToElementMapBaseMixin { |
{bool setter: false}) { |
assert(checkFamily(cls)); |
ClassEnv classEnv = _classEnvs[cls.classIndex]; |
- ir.Member member = classEnv.lookupMember(name, setter: setter); |
- return member != null ? getMember(member) : null; |
+ return classEnv.lookupMember(this, name, setter: setter); |
} |
ConstructorEntity lookupConstructor(IndexedClass cls, String name) { |
assert(checkFamily(cls)); |
ClassEnv classEnv = _classEnvs[cls.classIndex]; |
- ir.Member member = classEnv.lookupConstructor(name); |
- return member != null ? getConstructor(member) : null; |
+ return classEnv.lookupConstructor(this, name); |
} |
@override |
@@ -367,9 +348,10 @@ abstract class KernelToElementMapBase extends KernelToElementMapBaseMixin { |
IndexedClass superclass = _getSuperType(cls)?.element; |
while (superclass != null) { |
ClassEnv env = _classEnvs[superclass.classIndex]; |
- ir.Member superMember = env.lookupMember(name.name, setter: setter); |
+ MemberEntity superMember = |
+ env.lookupMember(this, name.name, setter: setter); |
if (superMember != null) { |
- return getMember(superMember); |
+ return superMember; |
} |
superclass = _getSuperType(superclass)?.element; |
} |
@@ -392,9 +374,9 @@ abstract class KernelToElementMapBase extends KernelToElementMapBaseMixin { |
return target; |
} |
ClassEnv env = _classEnvs[superClass.classIndex]; |
- ir.Member member = env.lookupConstructor(target.name); |
- if (member != null) { |
- return getConstructor(member); |
+ ConstructorEntity constructor = env.lookupConstructor(this, target.name); |
+ if (constructor != null) { |
+ return constructor; |
} |
throw failedAt(source, "Super constructor for $source not found."); |
} |
@@ -530,9 +512,7 @@ abstract class KernelToElementMapBase extends KernelToElementMapBaseMixin { |
void _forEachConstructor(IndexedClass cls, void f(ConstructorEntity member)) { |
assert(checkFamily(cls)); |
ClassEnv env = _classEnvs[cls.classIndex]; |
- env.forEachConstructor((ir.Member member) { |
- f(getConstructor(member)); |
- }); |
+ env.forEachConstructor(this, f); |
} |
void _forEachConstructorBody( |
@@ -545,8 +525,8 @@ abstract class KernelToElementMapBase extends KernelToElementMapBaseMixin { |
IndexedClass cls, void f(ClassEntity cls, MemberEntity member)) { |
assert(checkFamily(cls)); |
ClassEnv env = _classEnvs[cls.classIndex]; |
- env.forEachMember((ir.Member member) { |
- f(cls, getMember(member)); |
+ env.forEachMember(this, (MemberEntity member) { |
+ f(cls, member); |
}); |
ClassData data = _classData[cls.classIndex]; |
_ensureSupertypes(cls, data); |
@@ -602,7 +582,7 @@ abstract class KernelToElementMapBase extends KernelToElementMapBaseMixin { |
Spannable _getSpannable(MemberEntity member, ir.Node node) { |
SourceSpan sourceSpan; |
if (node is ir.TreeNode) { |
- sourceSpan = _getSourceSpanFromTreeNode(node); |
+ sourceSpan = computeSourceSpanFromTreeNode(node); |
} |
sourceSpan ??= getSourceSpan(member, null); |
return sourceSpan; |
@@ -761,12 +741,29 @@ abstract class ElementCreatorMixin { |
throw failedAt( |
NO_LOCATION_SPANNABLE, "Unexpected constructor node: ${node}."); |
} |
- _memberData.add(new ConstructorData(node, functionNode, definition)); |
+ _memberData.add(new ConstructorDataImpl(node, functionNode, definition)); |
_memberList.add(constructor); |
return constructor; |
}); |
} |
+ AsyncMarker _getAsyncMarker(ir.FunctionNode node) { |
+ switch (node.asyncMarker) { |
+ case ir.AsyncMarker.Async: |
+ return AsyncMarker.ASYNC; |
+ case ir.AsyncMarker.AsyncStar: |
+ return AsyncMarker.ASYNC_STAR; |
+ case ir.AsyncMarker.Sync: |
+ return AsyncMarker.SYNC; |
+ case ir.AsyncMarker.SyncStar: |
+ return AsyncMarker.SYNC_STAR; |
+ case ir.AsyncMarker.SyncYielding: |
+ default: |
+ throw new UnsupportedError( |
+ "Async marker ${node.asyncMarker} is not supported."); |
+ } |
+ } |
+ |
FunctionEntity _getMethod(ir.Procedure node) { |
return _methodMap.putIfAbsent(node, () { |
int memberIndex = _memberData.length; |
@@ -783,24 +780,7 @@ abstract class ElementCreatorMixin { |
bool isExternal = node.isExternal; |
bool isAbstract = node.isAbstract; |
IndexedFunction function; |
- AsyncMarker asyncMarker; |
- switch (node.function.asyncMarker) { |
- case ir.AsyncMarker.Async: |
- asyncMarker = AsyncMarker.ASYNC; |
- break; |
- case ir.AsyncMarker.AsyncStar: |
- asyncMarker = AsyncMarker.ASYNC_STAR; |
- break; |
- case ir.AsyncMarker.Sync: |
- asyncMarker = AsyncMarker.SYNC; |
- break; |
- case ir.AsyncMarker.SyncStar: |
- asyncMarker = AsyncMarker.SYNC_STAR; |
- break; |
- case ir.AsyncMarker.SyncYielding: |
- throw new UnsupportedError( |
- "Async marker ${node.function.asyncMarker} is not supported."); |
- } |
+ AsyncMarker asyncMarker = _getAsyncMarker(node.function); |
switch (node.kind) { |
case ir.ProcedureKind.Factory: |
throw new UnsupportedError("Cannot create method from factory."); |
@@ -828,7 +808,7 @@ abstract class ElementCreatorMixin { |
isAbstract: isAbstract); |
break; |
} |
- _memberData.add(new FunctionData( |
+ _memberData.add(new FunctionDataImpl( |
node, node.function, new RegularMemberDefinition(function, node))); |
_memberList.add(function); |
return function; |
@@ -853,8 +833,8 @@ abstract class ElementCreatorMixin { |
isStatic: isStatic, |
isAssignable: node.isMutable, |
isConst: node.isConst); |
- _memberData |
- .add(new FieldData(node, new RegularMemberDefinition(field, node))); |
+ _memberData.add( |
+ new FieldDataImpl(node, new RegularMemberDefinition(field, node))); |
_memberList.add(field); |
return field; |
}); |
@@ -1039,17 +1019,18 @@ class KernelToElementMapForImpactImpl extends KernelToElementMapBase |
_nativeBehaviorBuilder ??= new KernelBehaviorBuilder(commonElements); |
ResolutionImpact computeWorldImpact(KMember member) { |
- return _memberData[member.memberIndex].getWorldImpact(this); |
+ return buildKernelImpact( |
+ _memberData[member.memberIndex].definition.node, this); |
} |
ClosureModel computeClosureModel(KMember member) { |
- ir.Member node = _memberData[member.memberIndex].node; |
+ ir.Member node = _memberData[member.memberIndex].definition.node; |
return KernelClosureAnalysis.computeClosureModel(member, node); |
} |
/// Returns the kernel [ir.Procedure] node for the [method]. |
ir.Procedure _lookupProcedure(KFunction method) { |
- return _memberData[method.memberIndex].node; |
+ return _memberData[method.memberIndex].definition.node; |
} |
Iterable<ConstantValue> _getClassMetadata(KClass cls) { |
@@ -1710,14 +1691,14 @@ class KernelNativeMemberResolver extends NativeMemberResolverBase { |
@override |
native.NativeBehavior computeNativeFieldStoreBehavior( |
covariant KField field) { |
- ir.Field node = elementMap._memberData[field.memberIndex].node; |
+ ir.Field node = elementMap._memberData[field.memberIndex].definition.node; |
return elementMap.getNativeBehaviorForFieldStore(node); |
} |
@override |
native.NativeBehavior computeNativeFieldLoadBehavior(covariant KField field, |
{bool isJsInterop}) { |
- ir.Field node = elementMap._memberData[field.memberIndex].node; |
+ ir.Field node = elementMap._memberData[field.memberIndex].definition.node; |
return elementMap.getNativeBehaviorForFieldLoad(node, |
isJsInterop: isJsInterop); |
} |
@@ -1726,7 +1707,8 @@ class KernelNativeMemberResolver extends NativeMemberResolverBase { |
native.NativeBehavior computeNativeMethodBehavior( |
covariant KFunction function, |
{bool isJsInterop}) { |
- ir.Member node = elementMap._memberData[function.memberIndex].node; |
+ ir.Member node = |
+ elementMap._memberData[function.memberIndex].definition.node; |
return elementMap.getNativeBehaviorForMethod(node, |
isJsInterop: isJsInterop); |
} |
@@ -1734,7 +1716,8 @@ class KernelNativeMemberResolver extends NativeMemberResolverBase { |
@override |
bool isNativeMethod(covariant KFunction function) { |
if (!native.maybeEnableNative(function.library.canonicalUri)) return false; |
- ir.Member node = elementMap._memberData[function.memberIndex].node; |
+ ir.Member node = |
+ elementMap._memberData[function.memberIndex].definition.node; |
return node.isExternal && |
!elementMap.isForeignLibrary(node.enclosingLibrary); |
} |
@@ -1820,7 +1803,7 @@ class JsKernelToElementMap extends KernelToElementMapBase |
for (int memberIndex = 0; |
memberIndex < _elementMap._memberData.length; |
memberIndex++) { |
- MemberData data = _elementMap._memberData[memberIndex]; |
+ MemberDataImpl data = _elementMap._memberData[memberIndex]; |
MemberEntity oldMember = _elementMap._memberList[memberIndex]; |
IndexedLibrary oldLibrary = oldMember.library; |
IndexedClass oldClass = oldMember.enclosingClass; |
@@ -1919,16 +1902,21 @@ class JsKernelToElementMap extends KernelToElementMapBase |
FunctionEntity _getConstructorBody( |
ir.Constructor node, covariant IndexedConstructor constructor) { |
- ConstructorData data = _memberData[constructor.memberIndex]; |
+ ConstructorDataImpl data = _memberData[constructor.memberIndex]; |
if (data.constructorBody == null) { |
- data.constructorBody = |
+ ConstructorBodyEntity constructorBody = data.constructorBody = |
createConstructorBody(_memberList.length, constructor); |
- _memberList.add(data.constructorBody); |
- _memberData.add(new FunctionData( |
+ _memberList.add(constructorBody); |
+ _memberData.add(new FunctionDataImpl( |
node, |
node.function, |
new SpecialMemberDefinition( |
- data.constructorBody, node, MemberKind.constructorBody))); |
+ constructorBody, node, MemberKind.constructorBody))); |
+ IndexedClass cls = constructor.enclosingClass; |
+ ClassEnvImpl classEnv = _classEnvs[cls.classIndex]; |
+ // TODO(johnniwinther): Avoid this by only including live members in the |
+ // js-model. |
+ classEnv.addConstructorBody(constructorBody); |
} |
return data.constructorBody; |
} |
@@ -1955,12 +1943,12 @@ class JsKernelToElementMap extends KernelToElementMapBase |
bool hasConstantFieldInitializer(covariant IndexedField field) { |
FieldData data = _memberData[field.memberIndex]; |
- return getFieldConstantValue(data.node) != null; |
+ return getFieldConstantValue(data.definition.node) != null; |
} |
ConstantValue getConstantFieldInitializer(covariant IndexedField field) { |
FieldData data = _memberData[field.memberIndex]; |
- ConstantValue value = getFieldConstantValue(data.node); |
+ ConstantValue value = getFieldConstantValue(data.definition.node); |
assert(value != null, |
failedAt(field, "Field $field doesn't have a constant initial value.")); |
return value; |
@@ -1975,17 +1963,7 @@ class JsKernelToElementMap extends KernelToElementMapBase |
void _forEachConstructorBody( |
IndexedClass cls, void f(ConstructorBodyEntity member)) { |
ClassEnv env = _classEnvs[cls.classIndex]; |
- env.forEachConstructor((ir.Member member) { |
- IndexedConstructor constructor = _constructorMap[member]; |
- if (constructor == null) { |
- // The constructor is not live. |
- return; |
- } |
- ConstructorData data = _memberData[constructor.memberIndex]; |
- if (data.constructorBody != null) { |
- f(data.constructorBody); |
- } |
- }); |
+ env.forEachConstructorBody(f); |
} |
KernelClosureClass constructClosureClass( |
@@ -1997,15 +1975,16 @@ class JsKernelToElementMap extends KernelToElementMapBase |
KernelToLocalsMap localsMap, |
InterfaceType supertype) { |
String name = _computeClosureName(node); |
- KernelClosureClass cls = new KernelClosureClass.fromScopeInfo(node, name, |
- _classEnvs.length, enclosingLibrary, info, location, localsMap); |
+ KernelClosureClass cls = new KernelClosureClass.fromScopeInfo( |
+ node, name, _classEnvs.length, enclosingLibrary, info, localsMap); |
_classList.add(cls); |
- _classEnvs.add(new ClassEnv.closureClass()); |
+ Map<String, MemberEntity> memberMap = <String, MemberEntity>{}; |
+ _classEnvs.add(new ClosureClassEnv(memberMap)); |
// Create a classData and set up the interfaces and subclass |
// relationships that _ensureSupertypes and _ensureThisAndRawType are doing |
- var closureData = |
- new ClassData(null, new ClosureClassDefinition(cls, cls.location)); |
+ var closureData = new ClassData(null, |
+ new ClosureClassDefinition(cls, computeSourceSpanFromTreeNode(node))); |
closureData |
..isMixinApplication = false |
..thisType = |
@@ -2021,25 +2000,30 @@ class JsKernelToElementMap extends KernelToElementMapBase |
for (ir.VariableDeclaration variable in info.freeVariables) { |
// Make a corresponding field entity in this closure class for every |
// single freeVariable in the KernelScopeInfo.freeVariable. |
- _constructClosureFields( |
- member, cls, variable, i, info.capturedVariablesAccessor, localsMap); |
+ _constructClosureFields(member, cls, memberMap, variable, i, |
+ info.capturedVariablesAccessor, localsMap); |
i++; |
} |
- cls.callMethod = new JClosureCallMethod(_memberData.length, cls, member); |
+ FunctionEntity callMethod = cls.callMethod = new JClosureCallMethod( |
+ _memberData.length, |
+ cls, |
+ _getParameterStructure(node), |
+ _getAsyncMarker(node)); |
_memberList.add(cls.callMethod); |
- _memberData.add(new MemberData( |
- null, |
- new ClosureMemberDefinition( |
- member, cls.location, MemberKind.closureCall, node.parent))); |
- // TODO(efortuna): Does getMetadata get called in ClassData for this object? |
+ _memberData.add(new ClosureFunctionData( |
+ new ClosureMemberDefinition(callMethod, closureData.definition.location, |
+ MemberKind.closureCall, node.parent), |
+ getFunctionType(node))); |
+ memberMap[cls.callMethod.name] = cls.callMethod; |
return cls; |
} |
_constructClosureFields( |
MemberEntity member, |
KernelClosureClass cls, |
+ Map<String, MemberEntity> memberMap, |
ir.VariableDeclaration variable, |
int fieldNumber, |
NodeBox box, |
@@ -2049,7 +2033,7 @@ class JsKernelToElementMap extends KernelToElementMapBase |
// all the others. |
Local capturedLocal = localsMap.getLocalVariable(variable); |
if (cls.isBoxed(capturedLocal)) { |
- var boxedField = new JBoxedField( |
+ FieldEntity boxedField = new JBoxedField( |
_getClosureVariableName(capturedLocal.name, fieldNumber), |
_memberData.length, |
new BoxLocal(box.name, |
@@ -2059,12 +2043,14 @@ class JsKernelToElementMap extends KernelToElementMapBase |
variable.isFinal || variable.isConst); |
cls.localToFieldMap[capturedLocal] = boxedField; |
_memberList.add(boxedField); |
- _memberData.add(new MemberData( |
- null, |
- new ClosureMemberDefinition(boxedField, variable.location, |
- MemberKind.closureField, variable))); |
+ _memberData.add(new ClosureFieldData(new ClosureMemberDefinition( |
+ boxedField, |
+ computeSourceSpanFromTreeNode(variable), |
+ MemberKind.closureField, |
+ variable))); |
+ memberMap[boxedField.name] = boxedField; |
} else { |
- var closureField = new JClosureField( |
+ FieldEntity closureField = new JClosureField( |
_getClosureVariableName(capturedLocal.name, fieldNumber), |
_memberData.length, |
cls, |
@@ -2072,10 +2058,12 @@ class JsKernelToElementMap extends KernelToElementMapBase |
variable.isFinal || variable.isConst); |
cls.localToFieldMap[capturedLocal] = closureField; |
_memberList.add(closureField); |
- _memberData.add(new MemberData( |
- null, |
- new ClosureMemberDefinition(cls.localToFieldMap[capturedLocal], |
- variable.location, MemberKind.closureField, variable))); |
+ _memberData.add(new ClosureFieldData(new ClosureMemberDefinition( |
+ cls.localToFieldMap[capturedLocal], |
+ computeSourceSpanFromTreeNode(variable), |
+ MemberKind.closureField, |
+ variable))); |
+ memberMap[closureField.name] = closureField; |
} |
} |
@@ -2088,11 +2076,7 @@ class JsKernelToElementMap extends KernelToElementMapBase |
parts.add('closure'); |
} |
ir.TreeNode node = treeNode.parent; |
- while (node != null && |
- (node is ir.Constructor || |
- node is ir.Class || |
- node is ir.FunctionNode || |
- node is ir.Procedure)) { |
+ while (node != null) { |
// TODO(johnniwinther): Simplify computed names. |
if (node is ir.Constructor || |
node.parent is ir.Constructor || |
@@ -2105,13 +2089,11 @@ class JsKernelToElementMap extends KernelToElementMapBase |
} |
parts.add(utils.reconstructConstructorName(entity)); |
} else { |
- String surroundingName = ''; |
if (node is ir.Class) { |
- surroundingName = Elements.operatorNameToIdentifier(node.name); |
+ parts.add(Elements.operatorNameToIdentifier(node.name)); |
} else if (node is ir.Procedure) { |
- surroundingName = Elements.operatorNameToIdentifier(node.name.name); |
+ parts.add(Elements.operatorNameToIdentifier(node.name.name)); |
} |
- parts.add(surroundingName); |
} |
// A generative constructors's parent is the class; the class name is |
// already part of the generative constructor's name. |