[dart2js] Clean up .isXXX members on ConstantValue.

Bug: #48974
Change-Id: If70fac64e69f60fb5228492eac5591d620f25f77
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/244360
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Mayank Patke <fishythefish@google.com>
This commit is contained in:
Mayank Patke 2022-05-11 20:25:44 +00:00 committed by Commit Bot
parent f7c7076fe8
commit 41ba014616
28 changed files with 260 additions and 322 deletions

View file

@ -81,7 +81,7 @@ NumConstantValue createInt(BigInt i) =>
NumConstantValue createIntFromInt(int i) => createInt(BigInt.from(i));
NumConstantValue _createInt32(BigInt i) => IntConstantValue(i.toUnsigned(32));
IntConstantValue _createInt32(BigInt i) => IntConstantValue(i.toUnsigned(32));
NumConstantValue createDouble(double d) =>
_convertToJavaScriptConstant(DoubleConstantValue(d));
@ -98,7 +98,7 @@ ListConstantValue createList(CommonElements commonElements,
return ListConstantValue(type, values);
}
ConstantValue createType(CommonElements commonElements, DartType type) {
TypeConstantValue createType(CommonElements commonElements, DartType type) {
InterfaceType instanceType = commonElements.typeLiteralType;
return TypeConstantValue(type, instanceType);
}
@ -112,23 +112,23 @@ ConstantValue createType(CommonElements commonElements, DartType type) {
///
/// We consistently match that runtime semantics at compile time as well.
bool isInt(ConstantValue constant) =>
constant.isInt ||
constant is IntConstantValue ||
constant.isMinusZero ||
constant.isPositiveInfinity ||
constant.isNegativeInfinity;
/// Returns true if the [constant] is a double at runtime.
bool isDouble(ConstantValue constant) =>
constant.isDouble && !constant.isMinusZero;
constant is DoubleConstantValue && !constant.isMinusZero;
/// Returns true if the [constant] is a string at runtime.
bool isString(ConstantValue constant) => constant.isString;
bool isString(ConstantValue constant) => constant is StringConstantValue;
/// Returns true if the [constant] is a boolean at runtime.
bool isBool(ConstantValue constant) => constant.isBool;
bool isBool(ConstantValue constant) => constant is BoolConstantValue;
/// Returns true if the [constant] is null at runtime.
bool isNull(ConstantValue constant) => constant.isNull;
bool isNull(ConstantValue constant) => constant is NullConstantValue;
bool isSubtype(DartTypes types, DartType s, DartType t) {
// At runtime, an integer is both an integer and a double: the
@ -175,7 +175,8 @@ MapConstantValue createMap(
return JavaScriptMapConstant(type, keysList, values, onlyStringKeys);
}
ConstantValue createSymbol(CommonElements commonElements, String text) {
ConstructedConstantValue createSymbol(
CommonElements commonElements, String text) {
InterfaceType type = commonElements.symbolImplementationType;
FieldEntity field = commonElements.symbolField;
ConstantValue argument = createString(text);
@ -207,7 +208,7 @@ class BitNotOperation implements UnaryOperation {
const BitNotOperation();
@override
ConstantValue? fold(ConstantValue constant) {
IntConstantValue? fold(ConstantValue constant) {
if (isInt(constant)) {
// In JavaScript we don't check for -0 and treat it as if it was zero.
if (constant.isMinusZero) {
@ -229,8 +230,8 @@ class NegateOperation implements UnaryOperation {
const NegateOperation();
@override
ConstantValue? fold(ConstantValue constant) {
ConstantValue? _fold(ConstantValue constant) {
NumConstantValue? fold(ConstantValue constant) {
NumConstantValue? _fold(ConstantValue constant) {
if (constant is IntConstantValue) {
return createInt(-constant.intValue);
}
@ -256,7 +257,7 @@ class NotOperation implements UnaryOperation {
const NotOperation();
@override
ConstantValue? fold(ConstantValue constant) {
BoolConstantValue? fold(ConstantValue constant) {
if (constant is BoolConstantValue) {
return createBool(!constant.boolValue);
}
@ -269,7 +270,7 @@ abstract class BinaryBitOperation implements BinaryOperation {
const BinaryBitOperation();
@override
ConstantValue? fold(ConstantValue left, ConstantValue right) {
IntConstantValue? fold(ConstantValue left, ConstantValue right) {
IntConstantValue? _fold(ConstantValue left, ConstantValue right) {
if (left is IntConstantValue && right is IntConstantValue) {
BigInt? resultValue = foldInts(left.intValue, right.intValue);
@ -361,7 +362,7 @@ class ShiftRightOperation extends BinaryBitOperation {
const ShiftRightOperation();
@override
ConstantValue? fold(ConstantValue left, ConstantValue right) {
IntConstantValue? fold(ConstantValue left, ConstantValue right) {
// Truncate the input value to 32 bits. The web implementation of '>>' is a
// signed shift for negative values, and an unsigned for shift for
// non-negative values.
@ -409,7 +410,7 @@ abstract class BinaryBoolOperation implements BinaryOperation {
const BinaryBoolOperation();
@override
ConstantValue? fold(ConstantValue left, ConstantValue right) {
BoolConstantValue? fold(ConstantValue left, ConstantValue right) {
if (left is BoolConstantValue && right is BoolConstantValue) {
bool resultValue = foldBools(left.boolValue, right.boolValue);
return createBool(resultValue);
@ -450,7 +451,7 @@ abstract class ArithmeticNumOperation implements BinaryOperation {
const ArithmeticNumOperation();
@override
ConstantValue? fold(ConstantValue left, ConstantValue right) {
NumConstantValue? fold(ConstantValue left, ConstantValue right) {
NumConstantValue? _fold(ConstantValue left, ConstantValue right) {
if (left is NumConstantValue && right is NumConstantValue) {
var foldedValue;
@ -638,7 +639,7 @@ abstract class RelationalNumOperation implements BinaryOperation {
const RelationalNumOperation();
@override
ConstantValue? fold(ConstantValue left, ConstantValue right) {
BoolConstantValue? fold(ConstantValue left, ConstantValue right) {
if (left is NumConstantValue && right is NumConstantValue) {
bool foldedValue;
if (left is IntConstantValue && right is IntConstantValue) {
@ -727,7 +728,7 @@ class EqualsOperation implements BinaryOperation {
const EqualsOperation();
@override
ConstantValue? fold(ConstantValue left, ConstantValue right) {
BoolConstantValue? fold(ConstantValue left, ConstantValue right) {
// Numbers need to be treated specially because: NaN != NaN, -0.0 == 0.0,
// and 1 == 1.0.
if (left is IntConstantValue && right is IntConstantValue) {
@ -740,8 +741,8 @@ class EqualsOperation implements BinaryOperation {
return createBool(result);
}
if (left.isConstructedObject) {
if (right.isNull) {
if (left is ConstructedConstantValue) {
if (right is NullConstantValue) {
return createBool(false);
}
// Unless we know that the user-defined object does not implement the
@ -796,7 +797,7 @@ class IfNullOperation implements BinaryOperation {
@override
ConstantValue fold(ConstantValue left, ConstantValue right) {
if (left.isNull) return right;
if (left is NullConstantValue) return right;
return left;
}
@ -811,7 +812,7 @@ class CodeUnitAtOperation implements BinaryOperation {
const CodeUnitAtOperation();
@override
ConstantValue? fold(ConstantValue left, ConstantValue right) {
NumConstantValue? fold(ConstantValue left, ConstantValue right) {
if (left is StringConstantValue && right is IntConstantValue) {
String string = left.stringValue;
int index = right.intValue.toInt();
@ -833,10 +834,10 @@ class RoundOperation implements UnaryOperation {
const RoundOperation();
@override
ConstantValue? fold(ConstantValue constant) {
NumConstantValue? fold(ConstantValue constant) {
// Be careful to round() only values that do not throw on either the host or
// target platform.
ConstantValue? tryToRound(double value) {
NumConstantValue? tryToRound(double value) {
// Due to differences between browsers, only 'round' easy cases. Avoid
// cases where nudging the value up or down changes the answer.
// 13 digits is safely within the ~15 digit precision of doubles.
@ -874,7 +875,7 @@ class ToIntOperation implements UnaryOperation {
const ToIntOperation();
@override
ConstantValue? fold(ConstantValue constant) {
NumConstantValue? fold(ConstantValue constant) {
if (constant is IntConstantValue) {
double value = constant.doubleValue;
// The code below is written to work for any `double`, even though
@ -968,8 +969,6 @@ class JavaScriptMapConstant extends MapConstantValue {
List<ConstantValue> values, this.onlyStringKeys)
: this.keyList = keyList,
super(type, keyList.entries, values);
@override
bool get isMap => true;
@override
List<ConstantValue> getDependencies() {

View file

@ -74,28 +74,7 @@ abstract class ConstantValue {
/// `true` if this is a valid constant value.
bool get isConstant => true;
// TODO(48974): Clean up all these predicate getters.
bool get isNull => false;
bool get isBool => false;
bool get isTrue => false;
bool get isFalse => false;
bool get isInt => false;
bool get isDouble => false;
bool get isNum => false;
bool get isString => false;
bool get isList => false;
bool get isSet => false;
bool get isMap => false;
bool get isConstructedObject => false;
bool get isFunction => false;
/// Returns true if the constant is null, a bool, a number or a string.
bool get isPrimitive => false;
/// Returns true if the constant is a list, a map or a constructed object.
bool get isObject => false;
bool get isType => false;
bool get isInterceptor => false;
bool get isDummy => false;
bool get isNaN => false;
@ -143,9 +122,6 @@ class FunctionConstantValue extends ConstantValue {
FunctionConstantValue(this.element, this.type);
@override
bool get isFunction => true;
@override
bool operator ==(var other) {
if (other is! FunctionConstantValue) return false;
@ -185,9 +161,6 @@ class FunctionConstantValue extends ConstantValue {
abstract class PrimitiveConstantValue extends ConstantValue {
const PrimitiveConstantValue();
@override
bool get isPrimitive => true;
@override
bool operator ==(var other) {
// Making this method abstract does not give us an error.
@ -210,9 +183,6 @@ class NullConstantValue extends PrimitiveConstantValue {
const NullConstantValue._internal();
@override
bool get isNull => true;
@override
DartType getType(CommonElements types) => types.nullType;
@ -239,9 +209,6 @@ class NullConstantValue extends PrimitiveConstantValue {
abstract class NumConstantValue extends PrimitiveConstantValue {
double get doubleValue;
@override
bool get isNum => true;
const NumConstantValue();
}
@ -268,9 +235,6 @@ class IntConstantValue extends NumConstantValue {
const IntConstantValue._internal(this.intValue);
@override
bool get isInt => true;
bool isUInt31() => intValue.toUnsigned(31) == intValue;
bool isUInt32() => intValue.toUnsigned(32) == intValue;
@ -333,9 +297,6 @@ class DoubleConstantValue extends NumConstantValue {
const DoubleConstantValue._internal(this.doubleValue);
@override
bool get isDouble => true;
@override
bool get isNaN => doubleValue.isNaN;
@ -396,9 +357,6 @@ abstract class BoolConstantValue extends PrimitiveConstantValue {
const BoolConstantValue._internal();
@override
bool get isBool => true;
bool get boolValue;
@override
@ -422,9 +380,6 @@ class TrueConstantValue extends BoolConstantValue {
const TrueConstantValue._internal() : super._internal();
@override
bool get isTrue => true;
@override
bool get boolValue => true;
@ -448,9 +403,6 @@ class FalseConstantValue extends BoolConstantValue {
const FalseConstantValue._internal() : super._internal();
@override
bool get isFalse => true;
@override
bool get boolValue => false;
@ -480,9 +432,6 @@ class StringConstantValue extends PrimitiveConstantValue {
: this.stringValue = value,
this.hashCode = value.hashCode;
@override
bool get isString => true;
@override
DartType getType(CommonElements types) => types.stringType;
@ -519,9 +468,6 @@ abstract class ObjectConstantValue extends ConstantValue {
ObjectConstantValue(this.type);
@override
bool get isObject => true;
@override
DartType getType(CommonElements types) => type;
@ -540,9 +486,6 @@ class TypeConstantValue extends ObjectConstantValue {
TypeConstantValue(this.representedType, InterfaceType type) : super(type);
@override
bool get isType => true;
@override
bool operator ==(other) {
return other is TypeConstantValue &&
@ -579,9 +522,6 @@ class ListConstantValue extends ObjectConstantValue {
hashCode = Hashing.listHash(entries, Hashing.objectHash(type)),
super(type);
@override
bool get isList => true;
@override
bool operator ==(var other) {
if (identical(this, other)) return true;
@ -645,9 +585,6 @@ abstract class SetConstantValue extends ObjectConstantValue {
hashCode = Hashing.listHash(values, Hashing.objectHash(type)),
super(type);
@override
bool get isSet => true;
@override
bool operator ==(var other) {
if (identical(this, other)) return true;
@ -716,9 +653,6 @@ abstract class MapConstantValue extends ObjectConstantValue {
assert(keys.length == values.length);
}
@override
bool get isMap => true;
@override
bool operator ==(var other) {
if (identical(this, other)) return true;
@ -794,9 +728,6 @@ class InterceptorConstantValue extends ConstantValue {
InterceptorConstantValue(this.cls);
@override
bool get isInterceptor => true;
@override
bool operator ==(other) {
return other is InterceptorConstantValue && cls == other.cls;
@ -982,9 +913,6 @@ class ConstructedConstantValue extends ObjectConstantValue {
assert(!fields.containsValue(null));
}
@override
bool get isConstructedObject => true;
@override
bool operator ==(var otherVar) {
if (identical(this, otherVar)) return true;

View file

@ -284,7 +284,7 @@ import '../common/metrics.dart'
show Metric, Metrics, CountMetric, DurationMetric;
import '../common/tasks.dart' show CompilerTask;
import '../compiler.dart' show Compiler;
import '../constants/values.dart' show ConstantValue;
import '../constants/values.dart';
import '../elements/types.dart';
import '../elements/entities.dart';
import '../kernel/element_map.dart';
@ -586,7 +586,7 @@ class DeferredLoadTask extends CompilerTask {
var value = d.entity;
// Skip primitive values: they are not stored in the constant tables and
// if they are shared, they end up duplicated anyways across output units.
if (value.isPrimitive) return;
if (value is PrimitiveConstantValue) return;
constantMap
.putIfAbsent(importSet.unit, () => [])
.add(value.toStructuredText(dartTypes));

View file

@ -1285,10 +1285,12 @@ class KernelTypeGraphBuilder extends ir.Visitor<TypeInformation>
if (member.isField) {
FieldAnalysisData fieldData =
_closedWorld.fieldAnalysis.getFieldData(member);
if (fieldData.isEffectivelyConstant && fieldData.constantValue.isInt) {
IntConstantValue intValue = fieldData.constantValue;
if (intValue.intValue.isValidInt) {
return finish(intValue.intValue.toInt());
ConstantValue constantValue = fieldData.constantValue;
if (fieldData.isEffectivelyConstant &&
constantValue is IntConstantValue) {
BigInt intValue = constantValue.intValue;
if (intValue.isValidInt) {
return finish(intValue.toInt());
}
}
}

View file

@ -586,10 +586,8 @@ class InferrerEngine {
// constant folding that could give more precise results.
ConstantValue value = _getFieldConstant(field);
if (value != null) {
if (value.isFunction) {
FunctionConstantValue functionConstant = value;
FunctionEntity function = functionConstant.element;
type = types.allocateClosure(function);
if (value is FunctionConstantValue) {
type = types.allocateClosure(value.element);
} else {
// Although we might find a better type, we have to keep
// the old type around to ensure that we get a complete view

View file

@ -193,13 +193,13 @@ class PowersetBitsDomain {
bool isPrimitiveValue(int value) => isSingleton(value);
int computeAbstractValueForConstant(ConstantValue value) {
if (value.isTrue) {
if (value is TrueConstantValue) {
return trueValue;
}
if (value.isFalse) {
if (value is FalseConstantValue) {
return falseValue;
}
if (value.isNull) {
if (value is NullConstantValue) {
return nullValue;
}

View file

@ -165,24 +165,21 @@ class CodegenEnqueuerListener extends EnqueuerListener {
DartType type = constant.getType(_commonElements);
_computeImpactForInstantiatedConstantType(type, impactBuilder);
if (constant.isFunction) {
FunctionConstantValue function = constant;
if (constant is FunctionConstantValue) {
impactBuilder
.registerStaticUse(StaticUse.staticTearOff(function.element));
} else if (constant.isInterceptor) {
.registerStaticUse(StaticUse.staticTearOff(constant.element));
} else if (constant is InterceptorConstantValue) {
// An interceptor constant references the class's prototype chain.
InterceptorConstantValue interceptor = constant;
ClassEntity cls = interceptor.cls;
ClassEntity cls = constant.cls;
_computeImpactForInstantiatedConstantType(
_elementEnvironment.getThisType(cls), impactBuilder);
} else if (constant.isType) {
} else if (constant is TypeConstantValue) {
impactBuilder
.registerTypeUse(TypeUse.instantiation(_commonElements.typeType));
// If the type is a web component, we need to ensure the constructors are
// available to 'upgrade' the native object.
TypeConstantValue type = constant;
if (type.representedType is InterfaceType) {
InterfaceType representedType = type.representedType;
if (constant.representedType is InterfaceType) {
InterfaceType representedType = constant.representedType;
_customElementsAnalysis.registerTypeConstant(representedType.element);
}
} else if (constant is InstantiationConstantValue) {

View file

@ -132,7 +132,7 @@ class ModularConstantEmitter
@override
jsAst.Expression visitBool(BoolConstantValue constant, [_]) {
if (_options.enableMinification) {
if (constant.isTrue) {
if (constant is TrueConstantValue) {
// Use !0 for true.
return js("!0");
} else {
@ -140,7 +140,7 @@ class ModularConstantEmitter
return js("!1");
}
} else {
return constant.isTrue ? js('true') : js('false');
return constant is TrueConstantValue ? js('true') : js('false');
}
}

View file

@ -371,10 +371,10 @@ class JFieldAnalysis {
assert(value != null);
if (!memberUsage.hasWrite && canBeElided(kField)) {
isEffectivelyConstant = true;
} else if (value.isNull ||
value.isInt ||
value.isBool ||
value.isString ||
} else if (value is NullConstantValue ||
value is IntConstantValue ||
value is BoolConstantValue ||
value is StringConstantValue ||
value is LateSentinelConstantValue) {
// TODO(johnniwinther,sra): Support non-primitive constants in
// allocators when it does cause allocators to deoptimized

View file

@ -611,7 +611,7 @@ class Namer extends ModularNamer {
// In the current implementation it doesn't make sense to give names to
// function constants since the function-implementation itself serves as
// constant and can be accessed directly.
assert(!constant.isFunction);
assert(constant is! FunctionConstantValue);
jsAst.Name result = _constantNames[constant];
if (result == null) {
String longName = constantLongName(constant);
@ -1707,7 +1707,7 @@ class ConstantNamingVisitor implements ConstantValueVisitor {
@override
void visitBool(BoolConstantValue constant, [_]) {
add(constant.isTrue ? 'true' : 'false');
add(constant is TrueConstantValue ? 'true' : 'false');
}
@override
@ -1882,7 +1882,7 @@ class ConstantCanonicalHasher implements ConstantValueVisitor<int, Null> {
@override
int visitBool(BoolConstantValue constant, [_]) {
return constant.isTrue ? 2 : 3;
return constant is TrueConstantValue ? 2 : 3;
}
@override

View file

@ -208,16 +208,14 @@ class ResolutionEnqueuerListener extends EnqueuerListener {
DartType type = constant.getType(_commonElements);
_computeImpactForInstantiatedConstantType(type, impactBuilder);
if (constant.isFunction) {
FunctionConstantValue function = constant;
if (constant is FunctionConstantValue) {
impactBuilder
.registerStaticUse(StaticUse.staticTearOff(function.element));
} else if (constant.isInterceptor) {
.registerStaticUse(StaticUse.staticTearOff(constant.element));
} else if (constant is InterceptorConstantValue) {
// An interceptor constant references the class's prototype chain.
InterceptorConstantValue interceptor = constant;
InterfaceType type = _elementEnvironment.getThisType(interceptor.cls);
InterfaceType type = _elementEnvironment.getThisType(constant.cls);
_computeImpactForInstantiatedConstantType(type, impactBuilder);
} else if (constant.isType) {
} else if (constant is TypeConstantValue) {
FunctionEntity helper = _commonElements.createRuntimeType;
impactBuilder.registerStaticUse(StaticUse.staticInvoke(
helper, helper.parameterStructure.callStructure));

View file

@ -158,7 +158,7 @@ class ParameterStubGenerator {
targetArguments[count] =
_emitter.constantReference(NullConstantValue());
} else {
if (!value.isNull) {
if (value is! NullConstantValue) {
// If the value is the null constant, we should not pass it
// down to the native method.
indexOfLastOptionalArgumentInParameters = count;

View file

@ -123,7 +123,7 @@ class Collector {
for (ConstantValue constant in constants) {
if (_emitter.isConstantInlinedOrAlreadyEmitted(constant)) continue;
if (constant.isList) outputContainsConstantList = true;
if (constant is ListConstantValue) outputContainsConstantList = true;
OutputUnit constantUnit = _outputUnitData.outputUnitForConstant(constant);
if (constantUnit == null) {

View file

@ -9,8 +9,7 @@ library dart2js.js_emitter.program_builder;
import '../../common.dart';
import '../../common/elements.dart' show JCommonElements, JElementEnvironment;
import '../../common/names.dart' show Names, Selectors;
import '../../constants/values.dart'
show ConstantValue, InterceptorConstantValue;
import '../../constants/values.dart';
import '../../deferred_load/output_unit.dart'
show deferredPartFileName, OutputUnit, OutputUnitData;
import '../../elements/entities.dart';

View file

@ -110,9 +110,8 @@ class ModularEmitterImpl extends ModularEmitterBase {
@override
js.Expression constantReference(ConstantValue constant) {
if (constant.isFunction) {
FunctionConstantValue function = constant;
return staticClosureAccess(function.element);
if (constant is FunctionConstantValue) {
return staticClosureAccess(constant.element);
}
js.Expression expression = _constantEmitter.generate(constant);
if (expression != null) {

View file

@ -1571,7 +1571,7 @@ class FragmentEmitter {
]);
_dumpInfoTask.registerConstantAst(constant.value, assignment);
assignments.add(assignment);
if (constant.value.isList) hasList = true;
if (constant.value is ListConstantValue) hasList = true;
}
if (hasList) {
assignments.insert(

View file

@ -39,8 +39,7 @@ import '../../../compiler_api.dart' as api;
import '../../common.dart';
import '../../common/elements.dart' show CommonElements, JElementEnvironment;
import '../../common/tasks.dart';
import '../../constants/values.dart'
show ConstantValue, FunctionConstantValue, LateSentinelConstantValue;
import '../../constants/values.dart';
import '../../deferred_load/output_unit.dart' show OutputUnit;
import '../../dump_info.dart';
import '../../elements/entities.dart';
@ -181,8 +180,8 @@ class ModelEmitter {
}
bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant) {
if (constant.isFunction) return true; // Already emitted.
if (constant.isPrimitive) return true; // Inlined.
if (constant is FunctionConstantValue) return true; // Already emitted.
if (constant is PrimitiveConstantValue) return true; // Inlined.
if (constant.isDummy) return true; // Inlined.
if (constant is LateSentinelConstantValue) return true; // Inlined.
return false;
@ -198,8 +197,10 @@ class ModelEmitter {
// Emit constant interceptors first. Constant interceptors for primitives
// might be used by code that builds other constants. See Issue 18173.
if (a.isInterceptor != b.isInterceptor) {
return a.isInterceptor ? -1 : 1;
bool aIsInterceptor = a is InterceptorConstantValue;
bool bIsInterceptor = b is InterceptorConstantValue;
if (aIsInterceptor != bIsInterceptor) {
return aIsInterceptor ? -1 : 1;
}
// Sorting by the long name clusters constants with the same constructor
@ -212,9 +213,8 @@ class ModelEmitter {
}
js.Expression generateConstantReference(ConstantValue value) {
if (value.isFunction) {
FunctionConstantValue functionConstant = value;
return _emitter.staticClosureAccess(functionConstant.element);
if (value is FunctionConstantValue) {
return _emitter.staticClosureAccess(value.element);
}
// We are only interested in the "isInlined" part, but it does not hurt to

View file

@ -852,7 +852,7 @@ class KernelImpactConverter implements ImpactRegistry {
} else if (type == commonElements.functionType) {
reporter.reportErrorMessage(computeSourceSpanFromTreeNode(node),
MessageKind.SWITCH_CASE_FORBIDDEN, {'type': "Function"});
} else if (value.isObject &&
} else if (value is ObjectConstantValue &&
type != commonElements.typeLiteralType &&
overridesEquals(type)) {
reporter.reportErrorMessage(

View file

@ -946,19 +946,24 @@ List<String> _getAnnotations(DartTypes dartTypes, DiagnosticReporter reporter,
Iterable<ConstantValue> metadata, ClassEntity cls) {
List<String> annotations = [];
for (ConstantValue value in metadata) {
if (!value.isConstructedObject) continue;
ConstructedConstantValue constructedObject = value;
if (constructedObject.type.element != cls) continue;
if (value is ConstructedConstantValue) {
if (value.type.element != cls) continue;
Iterable<ConstantValue> fields = constructedObject.fields.values;
// TODO(sra): Better validation of the constant.
if (fields.length != 1 || !fields.single.isString) {
reporter.internalError(CURRENT_ELEMENT_SPANNABLE,
'Annotations needs one string: ${value.toStructuredText(dartTypes)}');
Iterable<ConstantValue> fields = value.fields.values;
// TODO(sra): Better validation of the constant.
if (fields.length == 1) {
ConstantValue field = fields.single;
if (field is StringConstantValue) {
annotations.add(field.stringValue);
continue;
}
}
reporter.internalError(
CURRENT_ELEMENT_SPANNABLE,
'Annotations needs one string: '
'${value.toStructuredText(dartTypes)}');
}
StringConstantValue specStringConstant = fields.single;
String specString = specStringConstant.stringValue;
annotations.add(specString);
}
return annotations;
}

View file

@ -124,9 +124,10 @@ class NativeClassFinder {
/// Returns `true` if [value] is named annotation based on [annotationClass].
bool isAnnotation(
Spannable spannable, ConstantValue value, ClassEntity annotationClass) {
if (!value.isConstructedObject) return null;
ConstructedConstantValue constructedObject = value;
return constructedObject.type.element == annotationClass;
if (value is ConstructedConstantValue) {
return value.type.element == annotationClass;
}
return null;
}
/// Extracts the name if [value] is a named annotation based on
@ -134,24 +135,25 @@ bool isAnnotation(
String readAnnotationName(DartTypes dartTypes, Spannable spannable,
ConstantValue value, ClassEntity annotationClass,
{String defaultValue}) {
if (!value.isConstructedObject) return null;
ConstructedConstantValue constructedObject = value;
if (constructedObject.type.element != annotationClass) return null;
if (value is ConstructedConstantValue) {
if (value.type.element != annotationClass) return null;
Iterable<ConstantValue> fields = constructedObject.fields.values;
// TODO(sra): Better validation of the constant.
if (fields.length != 1) {
failedAt(spannable,
'Annotations needs one string: ${value.toStructuredText(dartTypes)}');
return null;
} else if (fields.single is StringConstantValue) {
StringConstantValue specStringConstant = fields.single;
return specStringConstant.stringValue;
} else if (defaultValue != null && fields.single is NullConstantValue) {
return defaultValue;
} else {
failedAt(spannable,
'Annotations needs one string: ${value.toStructuredText(dartTypes)}');
return null;
Iterable<ConstantValue> fields = value.fields.values;
// TODO(sra): Better validation of the constant.
if (fields.length != 1) {
failedAt(spannable,
'Annotations needs one string: ${value.toStructuredText(dartTypes)}');
return null;
} else if (fields.single is StringConstantValue) {
StringConstantValue specStringConstant = fields.single;
return specStringConstant.stringValue;
} else if (defaultValue != null && fields.single is NullConstantValue) {
return defaultValue;
} else {
failedAt(spannable,
'Annotations needs one string: ${value.toStructuredText(dartTypes)}');
return null;
}
}
return null;
}

View file

@ -1826,7 +1826,7 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
if (condition.isConstant()) {
HConstant constant = condition;
if (constant.constant.isTrue) {
if (constant.constant is TrueConstantValue) {
generateStatements(info.thenGraph);
} else {
generateStatements(info.elseGraph);
@ -2491,10 +2491,10 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
generateConstant(node.constant, node.sourceInformation);
_registry.registerConstantUse(ConstantUse.literal(node.constant));
if (node.constant.isType) {
TypeConstantValue typeConstant = node.constant;
_registry.registerTypeUse(
TypeUse.constTypeLiteral(typeConstant.representedType));
ConstantValue constant = node.constant;
if (constant is TypeConstantValue) {
_registry
.registerTypeUse(TypeUse.constTypeLiteral(constant.representedType));
}
}

View file

@ -158,8 +158,9 @@ class SsaInstructionSelection extends HBaseVisitor with CodegenPhase {
// We also leave HIf nodes in place when one branch is dead.
HInstruction condition = current.inputs.first;
if (condition is HConstant) {
bool isTrue = condition.constant.isTrue;
successor = isTrue ? current.thenBlock : current.elseBlock;
successor = condition.constant is TrueConstantValue
? current.thenBlock
: current.elseBlock;
}
}
if (successor != null && successor.id > current.block.id) {
@ -1195,17 +1196,17 @@ class SsaShareRegionConstants extends HBaseVisitor with CodegenPhase {
if (node.usedBy.length <= 1) return;
ConstantValue constant = node.constant;
if (constant.isNull) {
if (constant is NullConstantValue) {
_handleNull(node);
return;
}
if (constant.isInt) {
if (constant is IntConstantValue) {
_handleInt(node, constant);
return;
}
if (constant.isString) {
if (constant is StringConstantValue) {
_handleString(node, constant);
return;
}

View file

@ -2946,26 +2946,27 @@ class HConstant extends HInstruction {
@override
bool isConstant() => true;
@override
bool isConstantBoolean() => constant.isBool;
bool isConstantBoolean() => constant is BoolConstantValue;
@override
bool isConstantNull() => constant.isNull;
bool isConstantNull() => constant is NullConstantValue;
@override
bool isConstantNumber() => constant.isNum;
bool isConstantNumber() => constant is NumConstantValue;
@override
bool isConstantInteger() => constant.isInt;
bool isConstantInteger() => constant is IntConstantValue;
@override
bool isConstantString() => constant.isString;
bool isConstantString() => constant is StringConstantValue;
@override
bool isConstantList() => constant.isList;
bool isConstantList() => constant is ListConstantValue;
@override
bool isConstantMap() => constant.isMap;
bool isConstantMap() => constant is MapConstantValue;
@override
bool isConstantFalse() => constant.isFalse;
bool isConstantFalse() => constant is FalseConstantValue;
@override
bool isConstantTrue() => constant.isTrue;
bool isConstantTrue() => constant is TrueConstantValue;
@override
bool isInterceptor(JClosedWorld closedWorld) => constant.isInterceptor;
bool isInterceptor(JClosedWorld closedWorld) =>
constant is InterceptorConstantValue;
// Maybe avoid this if the literal is big?
@override

View file

@ -460,7 +460,7 @@ class SsaInstructionSimplifier extends HBaseVisitor
node.isLateSentinel(_abstractValueDomain).isDefinitelyFalse) {
ConstantValue value =
_abstractValueDomain.getPrimitiveValue(node.instructionType);
if (value.isBool) {
if (value is BoolConstantValue) {
return value;
}
// TODO(het): consider supporting other values (short strings?)
@ -562,9 +562,8 @@ class SsaInstructionSimplifier extends HBaseVisitor
assert(inputs.length == 1);
HInstruction input = inputs[0];
if (input is HConstant) {
HConstant constant = input;
bool isTrue = constant.constant.isTrue;
return _graph.addConstantBool(!isTrue, _closedWorld);
return _graph.addConstantBool(
input.constant is! TrueConstantValue, _closedWorld);
} else if (input is HNot) {
return input.inputs[0];
}
@ -1059,7 +1058,7 @@ class SsaInstructionSimplifier extends HBaseVisitor
}
if (index.isConstant()) {
HConstant constantInstruction = index;
assert(!constantInstruction.constant.isInt);
assert(constantInstruction.constant is! IntConstantValue);
if (!constant_system.isInt(constantInstruction.constant)) {
// -0.0 is a double but will pass the runtime integer check.
node.staticChecks = HBoundsCheck.ALWAYS_FALSE;
@ -1146,7 +1145,7 @@ class SsaInstructionSimplifier extends HBaseVisitor
}
HInstruction compareConstant(HConstant constant, HInstruction input) {
if (constant.constant.isTrue) {
if (constant.constant is TrueConstantValue) {
return input;
} else {
return HNot(input, _abstractValueDomain.boolType);
@ -1428,10 +1427,8 @@ class SsaInstructionSimplifier extends HBaseVisitor
// field.
if (receiver is HConstant) {
ConstantValue constant = receiver.constant;
if (constant.isConstructedObject) {
ConstructedConstantValue constructedConstant = constant;
Map<FieldEntity, ConstantValue> fields = constructedConstant.fields;
ConstantValue value = fields[node.element];
if (constant is ConstructedConstantValue) {
ConstantValue value = constant.fields[node.element];
if (value != null) {
return _graph.addConstant(value, _closedWorld);
}
@ -1735,7 +1732,7 @@ class SsaInstructionSimplifier extends HBaseVisitor
HInstruction firstArgument = node.inputs[0];
if (firstArgument is HConstant) {
HConstant constant = firstArgument;
if (constant.constant.isTrue) return constant;
if (constant.constant is TrueConstantValue) return constant;
}
}
} else if (commonElements.isCheckInt(element)) {
@ -1765,8 +1762,8 @@ class SsaInstructionSimplifier extends HBaseVisitor
HInstruction argument = node.inputs[0];
if (argument is HConstant) {
ConstantValue constant = argument.constant;
if (constant.isBool) {
bool value = constant.isTrue;
if (constant is BoolConstantValue) {
bool value = constant is TrueConstantValue;
if (element == commonElements.assertTest) {
// `assertTest(argument)` effectively negates the argument.
return _graph.addConstantBool(!value, _closedWorld);
@ -1882,8 +1879,7 @@ class SsaInstructionSimplifier extends HBaseVisitor
HInstruction tryConstant() {
if (!input.isConstant()) return null;
HConstant constant = input;
if (!constant.constant.isPrimitive) return null;
PrimitiveConstantValue value = constant.constant;
ConstantValue value = constant.constant;
if (value is IntConstantValue) {
// Only constant-fold int.toString() when Dart and JS results the same.
// TODO(18103): We should be able to remove this work-around when issue
@ -2477,8 +2473,9 @@ class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase {
// We also leave HIf nodes in place when one branch is dead.
HInstruction condition = current.inputs.first;
if (condition is HConstant) {
bool isTrue = condition.constant.isTrue;
successor = isTrue ? current.thenBlock : current.elseBlock;
successor = condition.constant is TrueConstantValue
? current.thenBlock
: current.elseBlock;
assert(!analyzer.isDeadBlock(successor));
}
}

View file

@ -127,55 +127,71 @@ class IntValue extends Value {
const IntValue(this.value, info) : super(info);
@override
Value operator +(dynamic other) {
Value operator +(Value other) {
if (other.isZero) return this;
if (other is! IntValue) return other + this;
dynamic constant = constant_system.add.fold(
constant_system.createInt(value),
constant_system.createInt(other.value));
if (!constant.isInt) return const UnknownValue();
return info.newIntValue(constant.intValue);
if (other is IntValue) {
ConstantValue constant = constant_system.add.fold(
constant_system.createInt(value),
constant_system.createInt(other.value));
if (constant is IntConstantValue) {
return info.newIntValue(constant.intValue);
}
return const UnknownValue();
}
return other + this;
}
@override
Value operator -(dynamic other) {
Value operator -(Value other) {
if (other.isZero) return this;
if (other is! IntValue) return -other + this;
dynamic constant = constant_system.subtract.fold(
constant_system.createInt(value),
constant_system.createInt(other.value));
if (!constant.isInt) return const UnknownValue();
return info.newIntValue(constant.intValue);
if (other is IntValue) {
ConstantValue constant = constant_system.subtract.fold(
constant_system.createInt(value),
constant_system.createInt(other.value));
if (constant is IntConstantValue) {
return info.newIntValue(constant.intValue);
}
return const UnknownValue();
}
return -other + this;
}
@override
Value operator -() {
if (isZero) return this;
dynamic constant =
ConstantValue constant =
constant_system.negate.fold(constant_system.createInt(value));
if (!constant.isInt) return const UnknownValue();
return info.newIntValue(constant.intValue);
if (constant is IntConstantValue) {
return info.newIntValue(constant.intValue);
}
return const UnknownValue();
}
@override
Value operator &(dynamic other) {
if (other is! IntValue) return const UnknownValue();
dynamic constant = constant_system.bitAnd.fold(
constant_system.createInt(value),
constant_system.createInt(other.value));
return info.newIntValue(constant.intValue);
Value operator &(Value other) {
if (other is IntValue) {
IntConstantValue constant = constant_system.bitAnd.fold(
constant_system.createInt(value),
constant_system.createInt(other.value));
return info.newIntValue(constant.intValue);
}
return const UnknownValue();
}
@override
Value min(dynamic other) {
if (other is! IntValue) return other.min(this);
return this.value < other.value ? this : other;
Value min(Value other) {
if (other is IntValue) {
return this.value < other.value ? this : other;
}
return other.min(this);
}
@override
Value max(dynamic other) {
if (other is! IntValue) return other.max(this);
return this.value < other.value ? other : this;
Value max(Value other) {
if (other is IntValue) {
return this.value < other.value ? other : this;
}
return other.max(this);
}
@override
@ -1082,67 +1098,69 @@ class SsaValueRangeAnalyzer extends HBaseVisitor implements OptimizationPhase {
@override
Range visitConditionalBranch(HConditionalBranch branch) {
dynamic condition = branch.condition;
HInstruction condition = branch.condition;
// TODO(ngeoffray): Handle complex conditions.
if (condition is! HRelational) return info.newUnboundRange();
if (condition is HIdentity) return info.newUnboundRange();
HInstruction right = condition.right;
HInstruction left = condition.left;
if (left.isInteger(closedWorld.abstractValueDomain).isPotentiallyFalse) {
if (condition is HRelational) {
if (condition is HIdentity) return info.newUnboundRange();
HInstruction right = condition.right;
HInstruction left = condition.left;
if (left.isInteger(closedWorld.abstractValueDomain).isPotentiallyFalse) {
return info.newUnboundRange();
}
if (right.isInteger(closedWorld.abstractValueDomain).isPotentiallyFalse) {
return info.newUnboundRange();
}
Range rightRange = ranges[right];
Range leftRange = ranges[left];
constant_system.Operation operation = condition.operation();
constant_system.Operation mirrorOp = flipOperation(operation);
// Only update the true branch if this block is the only
// predecessor.
if (branch.trueBranch.predecessors.length == 1) {
assert(branch.trueBranch.predecessors[0] == branch.block);
// Update the true branch to use narrower ranges for [left] and
// [right].
Range range = computeConstrainedRange(operation, leftRange, rightRange);
if (leftRange != range) {
HInstruction instruction =
createRangeConversion(branch.trueBranch.first, left);
ranges[instruction] = range;
}
range = computeConstrainedRange(mirrorOp, rightRange, leftRange);
if (rightRange != range) {
HInstruction instruction =
createRangeConversion(branch.trueBranch.first, right);
ranges[instruction] = range;
}
}
// Only update the false branch if this block is the only
// predecessor.
if (branch.falseBranch.predecessors.length == 1) {
assert(branch.falseBranch.predecessors[0] == branch.block);
constant_system.Operation reverse = negateOperation(operation);
constant_system.Operation reversedMirror = flipOperation(reverse);
// Update the false branch to use narrower ranges for [left] and
// [right].
Range range = computeConstrainedRange(reverse, leftRange, rightRange);
if (leftRange != range) {
HInstruction instruction =
createRangeConversion(branch.falseBranch.first, left);
ranges[instruction] = range;
}
range = computeConstrainedRange(reversedMirror, rightRange, leftRange);
if (rightRange != range) {
HInstruction instruction =
createRangeConversion(branch.falseBranch.first, right);
ranges[instruction] = range;
}
}
return info.newUnboundRange();
}
if (right.isInteger(closedWorld.abstractValueDomain).isPotentiallyFalse) {
return info.newUnboundRange();
}
Range rightRange = ranges[right];
Range leftRange = ranges[left];
constant_system.Operation operation = condition.operation();
constant_system.Operation mirrorOp = flipOperation(operation);
// Only update the true branch if this block is the only
// predecessor.
if (branch.trueBranch.predecessors.length == 1) {
assert(branch.trueBranch.predecessors[0] == branch.block);
// Update the true branch to use narrower ranges for [left] and
// [right].
Range range = computeConstrainedRange(operation, leftRange, rightRange);
if (leftRange != range) {
HInstruction instruction =
createRangeConversion(branch.trueBranch.first, left);
ranges[instruction] = range;
}
range = computeConstrainedRange(mirrorOp, rightRange, leftRange);
if (rightRange != range) {
HInstruction instruction =
createRangeConversion(branch.trueBranch.first, right);
ranges[instruction] = range;
}
}
// Only update the false branch if this block is the only
// predecessor.
if (branch.falseBranch.predecessors.length == 1) {
assert(branch.falseBranch.predecessors[0] == branch.block);
constant_system.Operation reverse = negateOperation(operation);
constant_system.Operation reversedMirror = flipOperation(reverse);
// Update the false branch to use narrower ranges for [left] and
// [right].
Range range = computeConstrainedRange(reverse, leftRange, rightRange);
if (leftRange != range) {
HInstruction instruction =
createRangeConversion(branch.falseBranch.first, left);
ranges[instruction] = range;
}
range = computeConstrainedRange(reversedMirror, rightRange, leftRange);
if (rightRange != range) {
HInstruction instruction =
createRangeConversion(branch.falseBranch.first, right);
ranges[instruction] = range;
}
}
return info.newUnboundRange();
}

View file

@ -56,13 +56,6 @@
"pkg/compiler/lib/src/serialization/binary_sink.dart": {
"Dynamic access of 'index'.": 1
},
"pkg/compiler/lib/src/ssa/value_range_analyzer.dart": {
"Dynamic access of 'isZero'.": 2,
"Dynamic invocation of '+'.": 2,
"Dynamic invocation of 'max'.": 1,
"Dynamic invocation of 'min'.": 1,
"Dynamic invocation of 'unary-'.": 1
},
"pkg/compiler/lib/src/util/enumset.dart": {
"Dynamic access of 'index'.": 4
},

View file

@ -37,7 +37,8 @@ void main() {
for (String stringValue in ["cA", "cB", "cC"]) {
StringConstantValue constant =
allConstants.firstWhere((dynamic constant) {
return constant.isString && constant.stringValue == stringValue;
return constant is StringConstantValue &&
constant.stringValue == stringValue;
});
Expect.notEquals(
null,

View file

@ -289,7 +289,7 @@ class OutputUnitIrComputer extends IrDataExtractor<Features> {
if (node is ir.Field && node.isConst) {
ir.Expression initializer = node.initializer;
ConstantValue constant = _elementMap.getConstantValue(node, initializer);
if (!constant.isPrimitive) {
if (constant is! PrimitiveConstantValue) {
SourceSpan span = computeSourceSpanFromTreeNode(initializer);
if (initializer is ir.ConstructorInvocation) {
// Adjust the source-span to match the AST-based location. The kernel FE
@ -321,7 +321,7 @@ class OutputUnitIrComputer extends IrDataExtractor<Features> {
@override
visitConstantExpression(ir.ConstantExpression node) {
ConstantValue constant = _elementMap.getConstantValue(null, node);
if (!constant.isPrimitive) {
if (constant is! PrimitiveConstantValue) {
_constants.add('${constant.toStructuredText(_elementMap.types)}='
'${outputUnitString(_data.outputUnitForConstant(constant))}');
}