mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 02:07:06 +00:00
Handle static fields in js_model/model_test
R=sigmund@google.com Review-Url: https://codereview.chromium.org/2970673004 .
This commit is contained in:
parent
550b74233f
commit
e340ee517a
|
@ -16,9 +16,7 @@ import '../js_backend/native_data.dart';
|
|||
import '../kernel/elements.dart';
|
||||
import '../kernel/element_map_impl.dart';
|
||||
import '../native/behavior.dart';
|
||||
import '../ordered_typeset.dart';
|
||||
import '../universe/class_set.dart';
|
||||
import '../universe/selector.dart';
|
||||
import '../universe/world_builder.dart';
|
||||
import '../world.dart';
|
||||
|
||||
|
@ -521,7 +519,9 @@ class JTypeVariable implements TypeVariableEntity {
|
|||
}
|
||||
|
||||
class JsClosedWorld extends ClosedWorldBase with KernelClosedWorldMixin {
|
||||
JsClosedWorld(
|
||||
final JsKernelToElementMap elementMap;
|
||||
|
||||
JsClosedWorld(this.elementMap,
|
||||
{ElementEnvironment elementEnvironment,
|
||||
DartTypes dartTypes,
|
||||
CommonElements commonElements,
|
||||
|
@ -554,57 +554,10 @@ class JsClosedWorld extends ClosedWorldBase with KernelClosedWorldMixin {
|
|||
classHierarchyNodes,
|
||||
classSets);
|
||||
|
||||
@override
|
||||
bool hasConcreteMatch(ClassEntity cls, Selector selector,
|
||||
{ClassEntity stopAtSuperclass}) {
|
||||
throw new UnimplementedError('JsClosedWorld.hasConcreteMatch');
|
||||
}
|
||||
|
||||
@override
|
||||
void registerClosureClass(ClassElement cls) {
|
||||
throw new UnimplementedError('JsClosedWorld.registerClosureClass');
|
||||
}
|
||||
|
||||
@override
|
||||
bool checkEntity(Entity element) => true;
|
||||
|
||||
@override
|
||||
bool checkClass(ClassEntity cls) => true;
|
||||
|
||||
@override
|
||||
bool checkInvariants(ClassEntity cls, {bool mustBeInstantiated: true}) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@override
|
||||
OrderedTypeSet getOrderedTypeSet(ClassEntity cls) {
|
||||
throw new UnimplementedError('JsClosedWorld.getOrderedTypeSet');
|
||||
}
|
||||
|
||||
@override
|
||||
int getHierarchyDepth(ClassEntity cls) {
|
||||
throw new UnimplementedError('JsClosedWorld.getHierarchyDepth');
|
||||
}
|
||||
|
||||
@override
|
||||
ClassEntity getSuperClass(ClassEntity cls) {
|
||||
throw new UnimplementedError('JsClosedWorld.getSuperClass');
|
||||
}
|
||||
|
||||
@override
|
||||
Iterable<ClassEntity> getInterfaces(ClassEntity cls) {
|
||||
throw new UnimplementedError('JsClosedWorld.getInterfaces');
|
||||
}
|
||||
|
||||
@override
|
||||
ClassEntity getAppliedMixin(ClassEntity cls) {
|
||||
throw new UnimplementedError('JsClosedWorld.getAppliedMixin');
|
||||
}
|
||||
|
||||
@override
|
||||
bool isNamedMixinApplication(ClassEntity cls) {
|
||||
throw new UnimplementedError('JsClosedWorld.isNamedMixinApplication');
|
||||
}
|
||||
}
|
||||
|
||||
class JsNativeData implements NativeData {
|
||||
|
|
|
@ -123,7 +123,7 @@ class JsBackendStrategy implements KernelBackendStrategy {
|
|||
uses.map(_map.toBackendClass).toSet();
|
||||
});
|
||||
|
||||
return new JsClosedWorld(
|
||||
return new JsClosedWorld(_elementMap,
|
||||
elementEnvironment: _elementEnvironment,
|
||||
dartTypes: _elementMap.types,
|
||||
commonElements: _commonElements,
|
||||
|
@ -135,10 +135,10 @@ class JsBackendStrategy implements KernelBackendStrategy {
|
|||
classSets: classSets,
|
||||
implementedClasses: implementedClasses,
|
||||
liveInstanceMembers: liveInstanceMembers,
|
||||
mixinUses: mixinUses,
|
||||
// TODO(johnniwinther): Support these.
|
||||
allTypedefs: new ImmutableEmptySet<TypedefElement>(),
|
||||
resolutionWorldBuilder: null,
|
||||
mixinUses: mixinUses,
|
||||
typesImplementedBySubclasses: null);
|
||||
}
|
||||
|
||||
|
|
|
@ -972,12 +972,44 @@ class KernelToElementMapForImpactImpl2 extends KernelToElementMapBase
|
|||
: super(reporter, environment);
|
||||
}
|
||||
|
||||
/// Mixin for implementing [KernelToElementMapForBuilding] shared between
|
||||
/// classes that extend [KernelToElementMapBase], i.e. not [KernelAstAdapter].
|
||||
abstract class KernelToElementMapForBuildingFromBaseMixin
|
||||
implements KernelToElementMapForBuilding, KernelToElementMapBase {
|
||||
@override
|
||||
ConstantValue getFieldConstantValue(ir.Field field) {
|
||||
// TODO(johnniwinther): Cache the result in [FieldData].
|
||||
return getConstantValue(field.initializer,
|
||||
requireConstant: field.isConst, implicitNull: !field.isConst);
|
||||
}
|
||||
|
||||
bool hasConstantFieldInitializer(covariant IndexedField field) {
|
||||
FieldData data = _memberData[field.memberIndex];
|
||||
return getFieldConstantValue(data.node) != null;
|
||||
}
|
||||
|
||||
ConstantValue getConstantFieldInitializer(covariant IndexedField field) {
|
||||
FieldData data = _memberData[field.memberIndex];
|
||||
ConstantValue value = getFieldConstantValue(data.node);
|
||||
assert(value != null,
|
||||
failedAt(field, "Field $field doesn't have a constant initial value."));
|
||||
return value;
|
||||
}
|
||||
|
||||
void forEachParameter(covariant IndexedFunction function,
|
||||
void f(DartType type, String name, ConstantValue defaultValue)) {
|
||||
FunctionData data = _memberData[function.memberIndex];
|
||||
data.forEachParameter(this, f);
|
||||
}
|
||||
}
|
||||
|
||||
/// Element builder used for creating elements and types corresponding to Kernel
|
||||
/// IR nodes.
|
||||
// TODO(johnniwinther): Use this in the JsStrategy
|
||||
class KernelToElementMapForBuildingImpl extends KernelToElementMapBase
|
||||
with
|
||||
KernelToElementMapForBuildingMixin,
|
||||
KernelToElementMapForBuildingFromBaseMixin,
|
||||
ElementCreatorMixin,
|
||||
KElementCreatorMixin
|
||||
implements KernelToWorldBuilder {
|
||||
|
@ -987,37 +1019,11 @@ class KernelToElementMapForBuildingImpl extends KernelToElementMapBase
|
|||
|
||||
ConstantEnvironment get constantEnvironment => _constantEnvironment;
|
||||
|
||||
@override
|
||||
ConstantValue getFieldConstantValue(ir.Field field) {
|
||||
// TODO(johnniwinther): Cache the result in [FieldData].
|
||||
return getConstantValue(field.initializer,
|
||||
requireConstant: field.isConst, implicitNull: !field.isConst);
|
||||
}
|
||||
|
||||
ir.Library getKernelLibrary(KLibrary entity) =>
|
||||
_libraryEnvs[entity.libraryIndex].library;
|
||||
|
||||
ir.Class getKernelClass(KClass entity) => _classEnvs[entity.classIndex].cls;
|
||||
|
||||
bool hasConstantFieldInitializer(covariant KField field) {
|
||||
FieldData data = _memberData[field.memberIndex];
|
||||
return getFieldConstantValue(data.node) != null;
|
||||
}
|
||||
|
||||
ConstantValue getConstantFieldInitializer(covariant KField field) {
|
||||
FieldData data = _memberData[field.memberIndex];
|
||||
ConstantValue value = getFieldConstantValue(data.node);
|
||||
assert(value != null,
|
||||
failedAt(field, "Field $field doesn't have a constant initial value."));
|
||||
return value;
|
||||
}
|
||||
|
||||
void forEachParameter(covariant KFunction function,
|
||||
void f(DartType type, String name, ConstantValue defaultValue)) {
|
||||
FunctionData data = _memberData[function.memberIndex];
|
||||
data.forEachParameter(this, f);
|
||||
}
|
||||
|
||||
@override
|
||||
Spannable getSpannable(MemberEntity member, ir.Node node) {
|
||||
return _getSpannable(member, node);
|
||||
|
@ -1467,7 +1473,9 @@ class KernelResolutionWorldBuilder extends KernelResolutionWorldBuilderBase {
|
|||
bool checkClass(ClassEntity cls) => true;
|
||||
}
|
||||
|
||||
abstract class KernelClosedWorldMixin implements ClosedWorld {
|
||||
abstract class KernelClosedWorldMixin implements ClosedWorldBase {
|
||||
KernelToElementMapBase get elementMap;
|
||||
|
||||
@override
|
||||
bool hasElementIn(ClassEntity cls, Selector selector, Entity element) {
|
||||
while (cls != null) {
|
||||
|
@ -1482,12 +1490,59 @@ abstract class KernelClosedWorldMixin implements ClosedWorld {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
bool hasConcreteMatch(ClassEntity cls, Selector selector,
|
||||
{ClassEntity stopAtSuperclass}) {
|
||||
throw new UnimplementedError('KernelClosedWorldMixin.hasConcreteMatch');
|
||||
}
|
||||
|
||||
@override
|
||||
bool isNamedMixinApplication(ClassEntity cls) {
|
||||
throw new UnimplementedError(
|
||||
'KernelClosedWorldMixin.isNamedMixinApplication');
|
||||
}
|
||||
|
||||
@override
|
||||
ClassEntity getAppliedMixin(ClassEntity cls) {
|
||||
throw new UnimplementedError('KernelClosedWorldMixin.getAppliedMixin');
|
||||
}
|
||||
|
||||
@override
|
||||
Iterable<ClassEntity> getInterfaces(ClassEntity cls) {
|
||||
throw new UnimplementedError('KernelClosedWorldMixin.getInterfaces');
|
||||
}
|
||||
|
||||
@override
|
||||
ClassEntity getSuperClass(ClassEntity cls) {
|
||||
throw new UnimplementedError('KernelClosedWorldMixin.getSuperClass');
|
||||
}
|
||||
|
||||
@override
|
||||
int getHierarchyDepth(ClassEntity cls) {
|
||||
return elementMap._getHierarchyDepth(cls);
|
||||
}
|
||||
|
||||
@override
|
||||
OrderedTypeSet getOrderedTypeSet(ClassEntity cls) {
|
||||
return elementMap._getOrderedTypeSet(cls);
|
||||
}
|
||||
|
||||
@override
|
||||
bool checkInvariants(ClassEntity cls, {bool mustBeInstantiated: true}) =>
|
||||
true;
|
||||
|
||||
@override
|
||||
bool checkClass(ClassEntity cls) => true;
|
||||
|
||||
@override
|
||||
bool checkEntity(Entity element) => true;
|
||||
}
|
||||
|
||||
class KernelClosedWorld extends ClosedWorldBase with KernelClosedWorldMixin {
|
||||
final KernelToElementMapForImpactImpl _elementMap;
|
||||
final KernelToElementMapForImpactImpl elementMap;
|
||||
|
||||
KernelClosedWorld(this._elementMap,
|
||||
KernelClosedWorld(this.elementMap,
|
||||
{ElementEnvironment elementEnvironment,
|
||||
DartTypes dartTypes,
|
||||
CommonElements commonElements,
|
||||
|
@ -1520,52 +1575,6 @@ class KernelClosedWorld extends ClosedWorldBase with KernelClosedWorldMixin {
|
|||
classHierarchyNodes,
|
||||
classSets);
|
||||
|
||||
@override
|
||||
bool hasConcreteMatch(ClassEntity cls, Selector selector,
|
||||
{ClassEntity stopAtSuperclass}) {
|
||||
throw new UnimplementedError('KernelClosedWorld.hasConcreteMatch');
|
||||
}
|
||||
|
||||
@override
|
||||
bool isNamedMixinApplication(ClassEntity cls) {
|
||||
throw new UnimplementedError('KernelClosedWorld.isNamedMixinApplication');
|
||||
}
|
||||
|
||||
@override
|
||||
ClassEntity getAppliedMixin(ClassEntity cls) {
|
||||
throw new UnimplementedError('KernelClosedWorld.getAppliedMixin');
|
||||
}
|
||||
|
||||
@override
|
||||
Iterable<ClassEntity> getInterfaces(ClassEntity cls) {
|
||||
throw new UnimplementedError('KernelClosedWorld.getInterfaces');
|
||||
}
|
||||
|
||||
@override
|
||||
ClassEntity getSuperClass(ClassEntity cls) {
|
||||
throw new UnimplementedError('KernelClosedWorld.getSuperClass');
|
||||
}
|
||||
|
||||
@override
|
||||
int getHierarchyDepth(ClassEntity cls) {
|
||||
return _elementMap._getHierarchyDepth(cls);
|
||||
}
|
||||
|
||||
@override
|
||||
OrderedTypeSet getOrderedTypeSet(ClassEntity cls) {
|
||||
return _elementMap._getOrderedTypeSet(cls);
|
||||
}
|
||||
|
||||
@override
|
||||
bool checkInvariants(ClassEntity cls, {bool mustBeInstantiated: true}) =>
|
||||
true;
|
||||
|
||||
@override
|
||||
bool checkClass(ClassEntity cls) => true;
|
||||
|
||||
@override
|
||||
bool checkEntity(Entity element) => true;
|
||||
|
||||
@override
|
||||
void registerClosureClass(ClassElement cls) {
|
||||
throw new UnimplementedError('KernelClosedWorld.registerClosureClass');
|
||||
|
@ -1686,6 +1695,7 @@ class JsToFrontendMapImpl extends JsToFrontendMapBase
|
|||
class JsKernelToElementMap extends KernelToElementMapBase
|
||||
with
|
||||
KernelToElementMapForBuildingMixin,
|
||||
KernelToElementMapForBuildingFromBaseMixin,
|
||||
JsElementCreatorMixin,
|
||||
// TODO(johnniwinther): Avoid mixin in [ElementCreatorMixin]. The
|
||||
// codegen world should be a strict subset of the resolution world and
|
||||
|
@ -1814,27 +1824,4 @@ class JsKernelToElementMap extends KernelToElementMapBase
|
|||
ir.Class getClassNode(ClassEntity cls) {
|
||||
return _getClassNode(cls);
|
||||
}
|
||||
|
||||
@override
|
||||
ConstantValue getFieldConstantValue(ir.Field field) {
|
||||
throw new UnsupportedError("JsKernelToElementMap.getFieldConstantValue");
|
||||
}
|
||||
|
||||
@override
|
||||
void forEachParameter(FunctionEntity function,
|
||||
void f(DartType type, String name, ConstantValue defaultValue)) {
|
||||
throw new UnsupportedError("JsKernelToElementMap.forEachParameter");
|
||||
}
|
||||
|
||||
@override
|
||||
ConstantValue getConstantFieldInitializer(FieldEntity field) {
|
||||
throw new UnsupportedError(
|
||||
"JsKernelToElementMap.getConstantFieldInitializer");
|
||||
}
|
||||
|
||||
@override
|
||||
bool hasConstantFieldInitializer(FieldEntity field) {
|
||||
throw new UnsupportedError(
|
||||
"JsKernelToElementMap.hasConstantFieldInitializer");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1012,6 +1012,8 @@ abstract class ClosedWorldBase implements ClosedWorld, ClosedWorldRefiner {
|
|||
|
||||
void _ensureFunctionSet() {
|
||||
if (_allFunctions == null) {
|
||||
// [FunctionSet] is created lazily because it is not used when we switch
|
||||
// from a frontend to a backend model before inference.
|
||||
_allFunctions = new FunctionSet(liveInstanceMembers);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ foo({named}) => 1;
|
|||
bar(a) => !a;
|
||||
class Class {
|
||||
var field;
|
||||
static var staticField;
|
||||
|
||||
Class();
|
||||
Class.named(this.field);
|
||||
|
@ -40,6 +41,14 @@ main() {
|
|||
new Object();
|
||||
new Class.named('');
|
||||
new SubClass().method();
|
||||
Class.staticField;
|
||||
var x = null;
|
||||
var y1 = x == null;
|
||||
var y2 = null == x;
|
||||
var z1 = x?.toString();
|
||||
var z2 = x ?? y1;
|
||||
var z3 = x ??= y2;
|
||||
return x;
|
||||
}
|
||||
'''
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue