[dart2js] Fork backend subtyping into legacy and null-safe variants.

Change-Id: I64a20b5c64d700b873ac6210e5845c8d59192991
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/133331
Commit-Queue: Mayank Patke <fishythefish@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
This commit is contained in:
Mayank Patke 2020-01-30 17:02:38 +00:00 committed by commit-bot@chromium.org
parent 637a801e64
commit a52d6ea9b9
49 changed files with 357 additions and 257 deletions

View file

@ -958,7 +958,7 @@ class ModularExpression extends js.DeferredExpression
StringBuffer sb = new StringBuffer();
sb.write('ModularExpression(kind=$kind,data=');
if (data is ConstantValue) {
sb.write((data as ConstantValue).toStructuredText());
sb.write((data as ConstantValue).toStructuredText(null));
} else {
sb.write(data);
}

View file

@ -20,6 +20,8 @@ import 'universe/selector.dart' show Selector;
/// The common elements and types in Dart.
abstract class CommonElements {
DartTypes get dartTypes;
/// The `Object` class defined in 'dart:core'.
ClassEntity get objectClass;
@ -658,10 +660,12 @@ abstract class JCommonElements implements CommonElements {
class CommonElementsImpl
implements CommonElements, KCommonElements, JCommonElements {
@override
final DartTypes dartTypes;
final ElementEnvironment _env;
final CompilerOptions _options;
CommonElementsImpl(this._env, this._options);
CommonElementsImpl(this.dartTypes, this._env, this._options);
ClassEntity _objectClass;
@override
@ -1025,7 +1029,7 @@ class CommonElementsImpl
@override
InterfaceType getConstantListTypeFor(InterfaceType sourceType) =>
sourceType.treatAsRaw
dartTypes.treatAsRawType(sourceType)
? _env.getRawType(jsArrayClass)
: _env.createInterfaceType(jsArrayClass, sourceType.typeArguments);
@ -1036,7 +1040,7 @@ class CommonElementsImpl
? (hasProtoKey ? constantProtoMapClass : constantStringMapClass)
: generalConstantMapClass;
List<DartType> typeArgument = sourceType.typeArguments;
if (sourceType.treatAsRaw) {
if (dartTypes.treatAsRawType(sourceType)) {
return _env.getRawType(classElement);
} else {
return _env.createInterfaceType(classElement, typeArgument);
@ -1045,7 +1049,7 @@ class CommonElementsImpl
@override
InterfaceType getConstantSetTypeFor(InterfaceType sourceType) =>
sourceType.treatAsRaw
dartTypes.treatAsRawType(sourceType)
? _env.getRawType(constSetLiteralClass)
: _env.createInterfaceType(
constSetLiteralClass, sourceType.typeArguments);

View file

@ -173,7 +173,7 @@ MapConstantValue createMap(
bool hasProtoKey = (protoValue != null);
InterfaceType keysType;
if (sourceType.treatAsRaw) {
if (commonElements.dartTypes.treatAsRawType(sourceType)) {
keysType = commonElements.listType();
} else {
keysType = commonElements.listType(sourceType.typeArguments.first);

View file

@ -114,10 +114,10 @@ abstract class ConstantValue {
/// For the synthetic constants, [DeferredConstantValue],
/// [DeferredGlobalConstantValue], [SyntheticConstantValue],
/// [InterceptorConstantValue] the unparse is descriptive only.
String toDartText();
String toDartText(DartTypes dartTypes);
/// Returns a structured representation of this constant suited for debugging.
String toStructuredText();
String toStructuredText(DartTypes dartTypes);
ConstantValueKind get kind;
@ -126,7 +126,7 @@ abstract class ConstantValue {
assertDebugMode("Use ConstantValue.toDartText() or "
"ConstantValue.toStructuredText() "
"instead of ConstantValue.toString().");
return toStructuredText();
return toStructuredText(null);
}
}
@ -162,7 +162,7 @@ class FunctionConstantValue extends ConstantValue {
ConstantValueKind get kind => ConstantValueKind.FUNCTION;
@override
String toDartText() {
String toDartText(DartTypes dartTypes) {
if (element.enclosingClass != null) {
return '${element.enclosingClass.name}.${element.name}';
} else {
@ -171,8 +171,8 @@ class FunctionConstantValue extends ConstantValue {
}
@override
String toStructuredText() {
return 'FunctionConstant(${toDartText()})';
String toStructuredText(DartTypes dartTypes) {
return 'FunctionConstant(${toDartText(dartTypes)})';
}
}
@ -224,10 +224,10 @@ class NullConstantValue extends PrimitiveConstantValue {
ConstantValueKind get kind => ConstantValueKind.NULL;
@override
String toStructuredText() => 'NullConstant';
String toStructuredText(DartTypes dartTypes) => 'NullConstant';
@override
String toDartText() => 'null';
String toDartText(DartTypes dartTypes) => 'null';
}
abstract class NumConstantValue extends PrimitiveConstantValue {
@ -298,10 +298,11 @@ class IntConstantValue extends NumConstantValue {
ConstantValueKind get kind => ConstantValueKind.INT;
@override
String toStructuredText() => 'IntConstant(${toDartText()})';
String toStructuredText(DartTypes dartTypes) =>
'IntConstant(${toDartText(dartTypes)})';
@override
String toDartText() => intValue.toString();
String toDartText(DartTypes dartTypes) => intValue.toString();
}
class DoubleConstantValue extends NumConstantValue {
@ -375,10 +376,11 @@ class DoubleConstantValue extends NumConstantValue {
ConstantValueKind get kind => ConstantValueKind.DOUBLE;
@override
String toStructuredText() => 'DoubleConstant(${toDartText()})';
String toStructuredText(DartTypes dartTypes) =>
'DoubleConstant(${toDartText(dartTypes)})';
@override
String toDartText() => doubleValue.toString();
String toDartText(DartTypes dartTypes) => doubleValue.toString();
}
abstract class BoolConstantValue extends PrimitiveConstantValue {
@ -405,7 +407,8 @@ abstract class BoolConstantValue extends PrimitiveConstantValue {
ConstantValueKind get kind => ConstantValueKind.BOOL;
@override
String toStructuredText() => 'BoolConstant(${toDartText()})';
String toStructuredText(DartTypes dartTypes) =>
'BoolConstant(${toDartText(dartTypes)})';
}
class TrueConstantValue extends BoolConstantValue {
@ -431,7 +434,7 @@ class TrueConstantValue extends BoolConstantValue {
int get hashCode => 499;
@override
String toDartText() => boolValue.toString();
String toDartText(DartTypes dartTypes) => boolValue.toString();
}
class FalseConstantValue extends BoolConstantValue {
@ -457,7 +460,7 @@ class FalseConstantValue extends BoolConstantValue {
int get hashCode => 536555975;
@override
String toDartText() => boolValue.toString();
String toDartText(DartTypes dartTypes) => boolValue.toString();
}
class StringConstantValue extends PrimitiveConstantValue {
@ -498,10 +501,11 @@ class StringConstantValue extends PrimitiveConstantValue {
// TODO(johnniwinther): Ensure correct escaping.
@override
String toDartText() => '"${stringValue}"';
String toDartText(DartTypes dartTypes) => '"${stringValue}"';
@override
String toStructuredText() => 'StringConstant(${toDartText()})';
String toStructuredText(DartTypes dartTypes) =>
'StringConstant(${toDartText(dartTypes)})';
}
abstract class ObjectConstantValue extends ConstantValue {
@ -515,8 +519,8 @@ abstract class ObjectConstantValue extends ConstantValue {
@override
DartType getType(CommonElements types) => type;
void _unparseTypeArguments(StringBuffer sb) {
if (!type.treatAsRaw) {
void _unparseTypeArguments(DartTypes dartTypes, StringBuffer sb) {
if (dartTypes == null || !dartTypes.treatAsRawType(type)) {
sb.write('<');
sb.write(type.typeArguments.join(', '));
sb.write('>');
@ -552,10 +556,11 @@ class TypeConstantValue extends ObjectConstantValue {
ConstantValueKind get kind => ConstantValueKind.TYPE;
@override
String toDartText() => '$representedType';
String toDartText(DartTypes dartTypes) => '$representedType';
@override
String toStructuredText() => 'TypeConstant(${representedType})';
String toStructuredText(DartTypes dartTypes) =>
'TypeConstant(${representedType})';
}
class ListConstantValue extends ObjectConstantValue {
@ -597,27 +602,27 @@ class ListConstantValue extends ObjectConstantValue {
ConstantValueKind get kind => ConstantValueKind.LIST;
@override
String toDartText() {
String toDartText(DartTypes dartTypes) {
StringBuffer sb = new StringBuffer();
_unparseTypeArguments(sb);
_unparseTypeArguments(dartTypes, sb);
sb.write('[');
for (int i = 0; i < length; i++) {
if (i > 0) sb.write(',');
sb.write(entries[i].toDartText());
sb.write(entries[i].toDartText(dartTypes));
}
sb.write(']');
return sb.toString();
}
@override
String toStructuredText() {
String toStructuredText(DartTypes dartTypes) {
StringBuffer sb = new StringBuffer();
sb.write('ListConstant(');
_unparseTypeArguments(sb);
_unparseTypeArguments(dartTypes, sb);
sb.write('[');
for (int i = 0; i < length; i++) {
if (i > 0) sb.write(', ');
sb.write(entries[i].toStructuredText());
sb.write(entries[i].toStructuredText(dartTypes));
}
sb.write('])');
return sb.toString();
@ -660,22 +665,26 @@ abstract class SetConstantValue extends ObjectConstantValue {
accept(ConstantValueVisitor visitor, arg) => visitor.visitSet(this, arg);
@override
String toDartText() {
String toDartText(DartTypes dartTypes) {
StringBuffer sb = new StringBuffer();
_unparseTypeArguments(sb);
_unparseTypeArguments(dartTypes, sb);
sb.write('{');
sb.writeAll(values.map((v) => v.toDartText()), ',');
sb.writeAll(values.map((v) => v.toDartText(dartTypes)), ',');
sb.write('}');
return sb.toString();
}
@override
String toStructuredText() {
String toStructuredText(DartTypes dartTypes) {
StringBuffer sb = new StringBuffer();
sb.write('SetConstant(');
_unparseTypeArguments(sb);
_unparseTypeArguments(dartTypes, sb);
sb.write('{');
sb.writeAll(values.map((v) => v.toStructuredText()), ', ');
sb.writeAll(
values.map((v) => v.toStructuredText(
dartTypes,
)),
', ');
sb.write('})');
return sb.toString();
}
@ -742,31 +751,31 @@ abstract class MapConstantValue extends ObjectConstantValue {
ConstantValueKind get kind => ConstantValueKind.MAP;
@override
String toDartText() {
String toDartText(DartTypes dartTypes) {
StringBuffer sb = new StringBuffer();
_unparseTypeArguments(sb);
_unparseTypeArguments(dartTypes, sb);
sb.write('{');
for (int i = 0; i < length; i++) {
if (i > 0) sb.write(',');
sb.write(keys[i].toDartText());
sb.write(keys[i].toDartText(dartTypes));
sb.write(':');
sb.write(values[i].toDartText());
sb.write(values[i].toDartText(dartTypes));
}
sb.write('}');
return sb.toString();
}
@override
String toStructuredText() {
String toStructuredText(DartTypes dartTypes) {
StringBuffer sb = new StringBuffer();
sb.write('MapConstant(');
_unparseTypeArguments(sb);
_unparseTypeArguments(dartTypes, sb);
sb.write('{');
for (int i = 0; i < length; i++) {
if (i > 0) sb.write(', ');
sb.write(keys[i].toStructuredText());
sb.write(keys[i].toStructuredText(dartTypes));
sb.write(': ');
sb.write(values[i].toStructuredText());
sb.write(values[i].toStructuredText(dartTypes));
}
sb.write('})');
return sb.toString();
@ -806,12 +815,12 @@ class InterceptorConstantValue extends ConstantValue {
ConstantValueKind get kind => ConstantValueKind.INTERCEPTOR;
@override
String toDartText() {
String toDartText(DartTypes dartTypes) {
return 'interceptor($cls)';
}
@override
String toStructuredText() {
String toStructuredText(DartTypes dartTypes) {
return 'InterceptorConstant(${cls.name})';
}
}
@ -847,10 +856,10 @@ class JsNameConstantValue extends ConstantValue {
ConstantValueKind get kind => ConstantValueKind.JS_NAME;
@override
String toDartText() => 'js_name(${name})';
String toDartText(DartTypes dartTypes) => 'js_name(${name})';
@override
String toStructuredText() => 'JsNameConstant(${name})';
String toStructuredText(DartTypes dartTypes) => 'JsNameConstant(${name})';
}
/// A constant used as the dummy interceptor value for intercepted calls with
@ -887,10 +896,11 @@ class DummyInterceptorConstantValue extends ConstantValue {
ConstantValueKind get kind => ConstantValueKind.DUMMY_INTERCEPTOR;
@override
String toDartText() => 'dummy_interceptor($abstractValue)';
String toDartText(DartTypes dartTypes) => 'dummy_interceptor($abstractValue)';
@override
String toStructuredText() => 'DummyInterceptorConstant($abstractValue)';
String toStructuredText(DartTypes dartTypes) =>
'DummyInterceptorConstant($abstractValue)';
}
// A constant with an empty type used in [HInstruction]s of an expression
@ -916,10 +926,10 @@ class UnreachableConstantValue extends ConstantValue {
ConstantValueKind get kind => ConstantValueKind.UNREACHABLE;
@override
String toDartText() => 'unreachable()';
String toDartText(DartTypes dartTypes) => 'unreachable()';
@override
String toStructuredText() => 'UnreachableConstant()';
String toStructuredText(DartTypes dartTypes) => 'UnreachableConstant()';
}
class ConstructedConstantValue extends ObjectConstantValue {
@ -972,10 +982,10 @@ class ConstructedConstantValue extends ObjectConstantValue {
}
@override
String toDartText() {
String toDartText(DartTypes dartTypes) {
StringBuffer sb = new StringBuffer();
sb.write(type.element.name);
_unparseTypeArguments(sb);
_unparseTypeArguments(dartTypes, sb);
sb.write('(');
int i = 0;
for (FieldEntity field in _fieldsSortedByName) {
@ -983,7 +993,7 @@ class ConstructedConstantValue extends ObjectConstantValue {
if (i > 0) sb.write(',');
sb.write(field.name);
sb.write('=');
sb.write(value.toDartText());
sb.write(value.toDartText(dartTypes));
i++;
}
sb.write(')');
@ -991,7 +1001,7 @@ class ConstructedConstantValue extends ObjectConstantValue {
}
@override
String toStructuredText() {
String toStructuredText(DartTypes dartTypes) {
StringBuffer sb = new StringBuffer();
sb.write('ConstructedConstant(');
sb.write(type);
@ -1002,7 +1012,7 @@ class ConstructedConstantValue extends ObjectConstantValue {
if (i > 0) sb.write(',');
sb.write(field.name);
sb.write('=');
sb.write(value.toStructuredText());
sb.write(value.toStructuredText(dartTypes));
i++;
}
sb.write('))');
@ -1046,13 +1056,13 @@ class InstantiationConstantValue extends ConstantValue {
ConstantValueKind get kind => ConstantValueKind.INSTANTIATION;
@override
String toDartText() =>
'<${typeArguments.join(', ')}>(${function.toDartText()})';
String toDartText(DartTypes dartTypes) =>
'<${typeArguments.join(', ')}>(${function.toDartText(dartTypes)})';
@override
String toStructuredText() {
String toStructuredText(DartTypes dartTypes) {
return 'InstantiationConstant($typeArguments,'
'${function.toStructuredText()})';
'${function.toStructuredText(dartTypes)})';
}
}
@ -1100,11 +1110,12 @@ class DeferredGlobalConstantValue extends ConstantValue {
ConstantValueKind get kind => ConstantValueKind.DEFERRED_GLOBAL;
@override
String toDartText() => 'deferred_global(${referenced.toDartText()})';
String toDartText(DartTypes dartTypes) =>
'deferred_global(${referenced.toDartText(dartTypes)})';
@override
String toStructuredText() {
return 'DeferredGlobalConstant(${referenced.toStructuredText()})';
String toStructuredText(DartTypes dartTypes) {
return 'DeferredGlobalConstant(${referenced.toStructuredText(dartTypes)})';
}
}
@ -1130,8 +1141,8 @@ class NonConstantValue extends ConstantValue {
ConstantValueKind get kind => ConstantValueKind.NON_CONSTANT;
@override
String toStructuredText() => 'NonConstant';
String toStructuredText(DartTypes dartTypes) => 'NonConstant';
@override
String toDartText() => '>>non-constant<<';
String toDartText(DartTypes dartTypes) => '>>non-constant<<';
}

View file

@ -148,6 +148,7 @@ abstract class DeferredLoadTask extends CompilerTask {
compiler.frontendStrategy.elementEnvironment;
CommonElements get commonElements => compiler.frontendStrategy.commonElements;
DartTypes get dartTypes => commonElements.dartTypes;
DiagnosticReporter get reporter => compiler.reporter;
@ -416,8 +417,8 @@ abstract class DeferredLoadTask extends CompilerTask {
newSet != importSets.mainSet || oldSet != null,
failedAt(
NO_LOCATION_SPANNABLE,
"Tried to assign ${constant.toDartText()} to the main output "
"unit, but it was assigned to $currentSet."));
"Tried to assign ${constant.toDartText(closedWorld.dartTypes)} "
"to the main output unit, but it was assigned to $currentSet."));
queue.addConstant(constant, newSet);
}
}
@ -915,7 +916,7 @@ abstract class DeferredLoadTask extends CompilerTask {
if (value.isPrimitive) return;
constantMap
.putIfAbsent(importSet.unit, () => <String>[])
.add(value.toStructuredText());
.add(value.toStructuredText(dartTypes));
});
Map<OutputUnit, String> text = {};

View file

@ -36,11 +36,10 @@ abstract class DartType {
DartType get unaliased => this;
/// Is `true` if this type is a top type.
// TODO(fishythefish): Update this for NNBD.
bool get isTop => false;
bool _isTop(bool isLegacy) => false;
/// Is `true` if this type has no non-top type arguments.
bool get treatAsRaw => true;
bool _treatAsRaw(bool isLegacy) => true;
/// Whether this type contains a type variable.
bool get containsTypeVariables => false;
@ -89,14 +88,14 @@ abstract class DartType {
/// This method handles the common cases of identity and top types. Types
/// should add any additional logic by implementing
/// [_equalsModuloTopInternal].
bool _equalsModuloTop(DartType other) {
bool _equalsModuloTop(DartType other, bool isLegacy) {
other = other.unaliased;
if (identical(this, other)) return true;
if (isTop) return other.isTop;
return _equalsModuloTopInternal(other);
if (_isTop(isLegacy)) return other._isTop(isLegacy);
return _equalsModuloTopInternal(other, isLegacy);
}
bool _equalsModuloTopInternal(DartType other);
bool _equalsModuloTopInternal(DartType other, bool isLegacy);
@override
String toString() => _DartTypeToStringVisitor().run(this);
@ -197,9 +196,9 @@ class LegacyType extends DartType {
baseType._equals(other.baseType, assumptions);
@override
bool _equalsModuloTopInternal(DartType other) {
bool _equalsModuloTopInternal(DartType other, bool isLegacy) {
if (other is LegacyType) {
return baseType._equalsModuloTop(other.baseType);
return baseType._equalsModuloTop(other.baseType, isLegacy);
}
return false;
}
@ -210,6 +209,9 @@ class NullableType extends DartType {
NullableType(this.baseType);
@override
bool _isTop(bool isLegacy) => isLegacy ? false : baseType.isObject;
@override
bool get containsTypeVariables => baseType.containsTypeVariables;
@ -243,9 +245,9 @@ class NullableType extends DartType {
baseType._equals(other.baseType, assumptions);
@override
bool _equalsModuloTopInternal(DartType other) {
bool _equalsModuloTopInternal(DartType other, bool isLegacy) {
if (other is NullableType) {
return baseType._equalsModuloTop(other.baseType);
return baseType._equalsModuloTop(other.baseType, isLegacy);
}
return false;
}
@ -259,7 +261,7 @@ class InterfaceType extends DartType {
: assert(typeArguments.every((e) => e != null));
@override
bool get isTop => isObject;
bool _isTop(bool isLegacy) => isLegacy ? isObject : false;
@override
bool get isObject =>
@ -280,9 +282,9 @@ class InterfaceType extends DartType {
}
@override
bool get treatAsRaw {
bool _treatAsRaw(bool isLegacy) {
for (DartType type in typeArguments) {
if (!type.isTop) return false;
if (!type._isTop(isLegacy)) return false;
}
return true;
}
@ -321,10 +323,10 @@ class InterfaceType extends DartType {
}
@override
bool _equalsModuloTopInternal(DartType other) {
bool _equalsModuloTopInternal(DartType other, bool isLegacy) {
if (other is InterfaceType) {
return identical(element, other.element) &&
_equalTypesModuloTop(typeArguments, other.typeArguments);
_equalTypesModuloTop(typeArguments, other.typeArguments, isLegacy);
}
return false;
}
@ -339,7 +341,7 @@ class TypedefType extends DartType {
TypedefType(this.element, this.typeArguments, this.unaliased);
@override
bool get isTop => unaliased.isTop;
bool _isTop(bool isLegacy) => unaliased._isTop(isLegacy);
@override
bool get containsTypeVariables =>
@ -351,9 +353,9 @@ class TypedefType extends DartType {
}
@override
bool get treatAsRaw {
bool _treatAsRaw(bool isLegacy) {
for (DartType type in typeArguments) {
if (!type.isTop) return false;
if (!type._isTop(isLegacy)) return false;
}
return true;
}
@ -392,10 +394,11 @@ class TypedefType extends DartType {
}
@override
bool _equalsModuloTop(DartType other) => unaliased._equalsModuloTop(other);
bool _equalsModuloTop(DartType other, bool isLegacy) =>
unaliased._equalsModuloTop(other, isLegacy);
@override
bool _equalsModuloTopInternal(DartType other) => false;
bool _equalsModuloTopInternal(DartType other, bool isLegacy) => false;
}
class TypeVariableType extends DartType {
@ -433,7 +436,7 @@ class TypeVariableType extends DartType {
}
@override
bool _equalsModuloTopInternal(DartType other) {
bool _equalsModuloTopInternal(DartType other, bool legacy) {
if (other is TypeVariableType) {
return identical(other.element, element);
}
@ -489,7 +492,7 @@ class FunctionTypeVariable extends DartType {
}
@override
bool _equalsModuloTopInternal(DartType other) {
bool _equalsModuloTopInternal(DartType other, bool legacy) {
if (other is FunctionTypeVariable) {
return index == other.index;
}
@ -518,7 +521,7 @@ class NeverType extends DartType {
identical(this, other);
@override
bool _equalsModuloTopInternal(DartType other) => false;
bool _equalsModuloTopInternal(DartType other, bool isLegacy) => false;
}
class VoidType extends DartType {
@ -527,7 +530,7 @@ class VoidType extends DartType {
factory VoidType() => const VoidType._();
@override
bool get isTop => true;
bool _isTop(bool isLegacy) => true;
@override
R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
@ -542,7 +545,7 @@ class VoidType extends DartType {
}
@override
bool _equalsModuloTopInternal(DartType other) => false;
bool _equalsModuloTopInternal(DartType other, bool isLegacy) => false;
}
class DynamicType extends DartType {
@ -551,7 +554,7 @@ class DynamicType extends DartType {
factory DynamicType() => const DynamicType._();
@override
bool get isTop => true;
bool _isTop(bool isLegacy) => true;
@override
R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
@ -566,7 +569,7 @@ class DynamicType extends DartType {
}
@override
bool _equalsModuloTopInternal(DartType other) => false;
bool _equalsModuloTopInternal(DartType other, bool isLegacy) => false;
}
class ErasedType extends DartType {
@ -575,7 +578,7 @@ class ErasedType extends DartType {
factory ErasedType() => const ErasedType._();
@override
bool get isTop => true;
bool _isTop(bool isLegacy) => true;
@override
R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
@ -589,7 +592,7 @@ class ErasedType extends DartType {
identical(this, other);
@override
bool _equalsModuloTopInternal(DartType other) => false;
bool _equalsModuloTopInternal(DartType other, bool isLegacy) => false;
}
/// Represents a type which is simultaneously top and bottom.
@ -609,7 +612,7 @@ class AnyType extends DartType {
factory AnyType() => const AnyType._();
@override
bool get isTop => true;
bool _isTop(bool isLegacy) => true;
@override
R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
@ -623,7 +626,7 @@ class AnyType extends DartType {
identical(this, other);
@override
bool _equalsModuloTopInternal(DartType other) => false;
bool _equalsModuloTopInternal(DartType other, bool isLegacy) => false;
}
class FunctionType extends DartType {
@ -752,16 +755,18 @@ class FunctionType extends DartType {
}
@override
bool _equalsModuloTopInternal(DartType other) {
bool _equalsModuloTopInternal(DartType other, bool isLegacy) {
if (other is FunctionType) {
return returnType._equalsModuloTop(other.returnType) &&
_equalTypesModuloTop(parameterTypes, other.parameterTypes) &&
return returnType._equalsModuloTop(other.returnType, isLegacy) &&
_equalTypesModuloTop(
optionalParameterTypes, other.optionalParameterTypes) &&
parameterTypes, other.parameterTypes, isLegacy) &&
_equalTypesModuloTop(
optionalParameterTypes, other.optionalParameterTypes, isLegacy) &&
equalElements(namedParameters, other.namedParameters) &&
_equalTypesModuloTop(
namedParameterTypes, other.namedParameterTypes) &&
_equalTypesModuloTop(typeVariableBounds, other.typeVariableBounds);
namedParameterTypes, other.namedParameterTypes, isLegacy) &&
_equalTypesModuloTop(
typeVariableBounds, other.typeVariableBounds, isLegacy);
}
return false;
}
@ -773,7 +778,7 @@ class FutureOrType extends DartType {
FutureOrType(this.typeArgument);
@override
bool get isTop => typeArgument.isTop;
bool _isTop(bool isLegacy) => typeArgument._isTop(isLegacy);
@override
bool get containsTypeVariables => typeArgument.containsTypeVariables;
@ -809,9 +814,9 @@ class FutureOrType extends DartType {
}
@override
bool _equalsModuloTopInternal(DartType other) {
bool _equalsModuloTopInternal(DartType other, bool isLegacy) {
if (other is FutureOrType) {
return typeArgument._equalsModuloTop(other.typeArgument);
return typeArgument._equalsModuloTop(other.typeArgument, isLegacy);
}
return false;
}
@ -827,10 +832,10 @@ bool _equalTypes(List<DartType> a, List<DartType> b, _Assumptions assumptions) {
return true;
}
bool _equalTypesModuloTop(List<DartType> a, List<DartType> b) {
bool _equalTypesModuloTop(List<DartType> a, List<DartType> b, bool isLegacy) {
if (a.length != b.length) return false;
for (int i = 0; i < a.length; i++) {
if (!a[i]._equalsModuloTop(b[i])) return false;
if (!a[i]._equalsModuloTop(b[i], isLegacy)) return false;
}
return true;
}
@ -1590,6 +1595,16 @@ abstract class DartTypes {
/// The types defined in 'dart:core'.
CommonElements get commonElements;
bool get useLegacySubtyping;
/// Returns `true` if every type argument of [t] is a top type.
// TODO(fishythefish): Should we instead check if each type argument is at its
// bound?
bool treatAsRawType(DartType t) => t._treatAsRaw(useLegacySubtyping);
/// Returns `true` if [t] is a top type, that is, a supertype of every type.
bool isTopType(DartType t) => t._isTop(useLegacySubtyping);
/// Returns `true` if [s] is a subtype of [t].
bool isSubtype(DartType s, DartType t) => _subtypeHelper(s, t);
@ -1627,7 +1642,7 @@ abstract class DartTypes {
s.index == t.index) return true;
// Right Top:
if (t.isTop) return true;
if (isTopType(t)) return true;
if (s is AnyType) return true;
if (allowPotentialSubtypes &&
@ -1636,12 +1651,14 @@ abstract class DartTypes {
(s is FunctionTypeVariable || t is FunctionTypeVariable)) return true;
// Left Top:
if (s.isTop) return false;
if (isTopType(s)) return false;
// Left Bottom:
// TODO(fishythefish): Update for NNBD - check for `Never` instead of
// `Null`.
if (s.isNull) return true;
if (useLegacySubtyping) {
if (s.isNull) return true;
} else {
if (s is NeverType) return true;
}
// Left Type Variable Bound 1:
if (s is TypeVariableType) {
@ -1655,7 +1672,7 @@ abstract class DartTypes {
// Left Null:
// Note: Interchanging the Left Null and Right Object rules allows us to
// reduce casework.
if (s.isNull) {
if (!useLegacySubtyping && s.isNull) {
if (t is FutureOrType) {
return _isSubtype(s, sEnv, t.typeArgument, tEnv);
}
@ -1663,7 +1680,7 @@ abstract class DartTypes {
}
// Right Object:
if (t.isObject) {
if (!useLegacySubtyping && t.isObject) {
if (s is FutureOrType) {
return _isSubtype(s.typeArgument, sEnv, t, tEnv);
}
@ -1680,7 +1697,8 @@ abstract class DartTypes {
// Right Legacy:
if (t is LegacyType) {
return _isSubtype(s, sEnv, NullableType(t.baseType), tEnv);
return _isSubtype(s, sEnv,
useLegacySubtyping ? t.baseType : NullableType(t.baseType), tEnv);
}
// Left FutureOr:
@ -1692,7 +1710,8 @@ abstract class DartTypes {
// Left Nullable:
if (s is NullableType) {
return _isSubtype(commonElements.nullType, sEnv, t, tEnv) &&
return (useLegacySubtyping ||
_isSubtype(commonElements.nullType, sEnv, t, tEnv)) &&
_isSubtype(s.baseType, sEnv, t, tEnv);
}
@ -1712,7 +1731,8 @@ abstract class DartTypes {
// Right Nullable:
if (t is NullableType) {
return _isSubtype(s, sEnv, commonElements.nullType, tEnv) ||
return (!useLegacySubtyping &&
_isSubtype(s, sEnv, commonElements.nullType, tEnv)) ||
_isSubtype(s, sEnv, t.baseType, tEnv);
}
@ -1736,8 +1756,8 @@ abstract class DartTypes {
if (s is FunctionType) {
if (t.isGeneric) {
if (!s.isGeneric) return false;
if (!_equalTypesModuloTop(
s.typeVariableBounds, t.typeVariableBounds)) {
if (!_equalTypesModuloTop(s.typeVariableBounds,
t.typeVariableBounds, useLegacySubtyping)) {
return false;
}
sEnv = sEnv.toSet()..addAll(s.typeVariables);

View file

@ -2253,7 +2253,7 @@ AbstractValue _narrowType(
{bool isNullable: true}) {
AbstractValueDomain abstractValueDomain = closedWorld.abstractValueDomain;
AbstractValue otherType;
if (annotation.isTop) {
if (closedWorld.dartTypes.isTopType(annotation)) {
return type;
} else if (annotation is InterfaceType) {
if (annotation.element == closedWorld.commonElements.objectClass) {

View file

@ -319,7 +319,7 @@ class TypeSystem {
{bool isNullable: true}) {
AbstractValue otherType;
if (annotation is VoidType) return type;
if (annotation.isTop) {
if (_closedWorld.dartTypes.isTopType(annotation)) {
if (isNullable) return type;
// If the input is already narrowed to be not-null, there is no value
// in adding another narrowing node.

View file

@ -43,6 +43,7 @@ class CommonMasks implements AbstractValueDomain {
CommonMasks(this._closedWorld);
CommonElements get commonElements => _closedWorld.commonElements;
DartTypes get dartTypes => _closedWorld.dartTypes;
TypeMask _dynamicType;
TypeMask _nonNullType;
@ -883,7 +884,7 @@ class CommonMasks implements AbstractValueDomain {
@override
String getCompactText(AbstractValue value) {
return formatType(value);
return formatType(dartTypes, value);
}
@override
@ -903,7 +904,7 @@ class CommonMasks implements AbstractValueDomain {
///
/// The default format is too verbose for the graph format since long strings
/// create oblong nodes that obstruct the graph layout.
String formatType(TypeMask type) {
String formatType(DartTypes dartTypes, TypeMask type) {
if (type is FlatTypeMask) {
// TODO(asgerf): Disambiguate classes whose name is not unique. Using the
// library name for all classes is not a good idea, since library names
@ -916,22 +917,22 @@ String formatType(TypeMask type) {
return '${type.base.name}$nullFlag$subFlag';
}
if (type is UnionTypeMask) {
return type.disjointMasks.map(formatType).join(' | ');
return type.disjointMasks.map((m) => formatType(dartTypes, m)).join(' | ');
}
if (type is ContainerTypeMask) {
String container = formatType(type.forwardTo);
String member = formatType(type.elementType);
String container = formatType(dartTypes, type.forwardTo);
String member = formatType(dartTypes, type.elementType);
return '$container<$member>';
}
if (type is MapTypeMask) {
String container = formatType(type.forwardTo);
String key = formatType(type.keyType);
String value = formatType(type.valueType);
String container = formatType(dartTypes, type.forwardTo);
String key = formatType(dartTypes, type.keyType);
String value = formatType(dartTypes, type.valueType);
return '$container<$key,$value>';
}
if (type is ValueTypeMask) {
String baseType = formatType(type.forwardTo);
String value = type.value.toStructuredText();
String baseType = formatType(dartTypes, type.forwardTo);
String value = type.value.toStructuredText(dartTypes);
return '$baseType=$value';
}
return '$type'; // Fall back on toString if not supported here.

View file

@ -73,6 +73,6 @@ class ValueTypeMask extends ForwardingTypeMask {
@override
String toString() {
return 'Value($forwardTo, value: ${value.toDartText()})';
return 'Value($forwardTo, value: ${value.toDartText(null)})';
}
}

View file

@ -11,8 +11,10 @@ import 'element_map.dart';
/// Support for subtype checks of kernel based [DartType]s.
class KernelDartTypes extends DartTypes {
final IrToElementMap elementMap;
@override
final bool useLegacySubtyping;
KernelDartTypes(this.elementMap);
KernelDartTypes(this.elementMap, this.useLegacySubtyping);
@override
InterfaceType getThisType(ClassEntity cls) {

View file

@ -205,6 +205,8 @@ class CheckedModeHelpers {
{bool typeCast, bool nativeCheckOnly}) {
assert(type is! TypedefType);
DartTypes dartTypes = commonElements.dartTypes;
if (type is TypeVariableType) {
return typeCast
? 'subtypeOfRuntimeTypeCast'
@ -275,16 +277,17 @@ class CheckedModeHelpers {
if ((element == commonElements.listClass ||
element == commonElements.jsArrayClass) &&
type.treatAsRaw) {
dartTypes.treatAsRawType(type)) {
if (nativeCheckOnly) return null;
return 'list$suffix';
}
if (commonElements.isListSupertype(element) && type.treatAsRaw) {
if (commonElements.isListSupertype(element) &&
dartTypes.treatAsRawType(type)) {
return nativeCheck ? 'listSuperNative$suffix' : 'listSuper$suffix';
}
if (type is InterfaceType && !type.treatAsRaw) {
if (type is InterfaceType && !dartTypes.treatAsRawType(type)) {
return typeCast ? 'subtypeCast' : 'assertSubtype';
}

View file

@ -392,7 +392,7 @@ class ConstantEmitter extends ModularConstantEmitter {
throw failedAt(
NO_LOCATION_SPANNABLE,
"Unexpected type variable '${variable}'"
" in constant '${constant.toDartText()}'");
" in constant '${constant.toDartText(_commonElements.dartTypes)}'");
}
jsAst.Expression rti =
@ -463,7 +463,7 @@ class ConstantEmitter extends ModularConstantEmitter {
jsAst.Expression maybeAddTypeArguments(
ConstantValue constant, InterfaceType type, jsAst.Expression value) {
if (type is InterfaceType &&
!type.treatAsRaw &&
!_commonElements.dartTypes.treatAsRawType(type) &&
_rtiNeed.classNeedsTypeArguments(type.element)) {
return new jsAst.Call(
getHelperProperty(_commonElements.setRuntimeTypeInfo),
@ -490,7 +490,7 @@ class ConstantEmitter extends ModularConstantEmitter {
throw failedAt(
NO_LOCATION_SPANNABLE,
"Unexpected type variable '${variable}'"
" in constant '${constant.toDartText()}'");
" in constant '${constant.toDartText(_commonElements.dartTypes)}'");
}
List<jsAst.Expression> arguments = <jsAst.Expression>[];

View file

@ -9,6 +9,7 @@ import '../common.dart';
import '../constants/values.dart';
import '../elements/entities.dart';
import '../elements/entity_utils.dart';
import '../elements/types.dart';
import '../ir/scope_visitor.dart';
import '../js_model/elements.dart' show JField;
import '../js_model/js_world_builder.dart';
@ -170,7 +171,7 @@ class AllocatorData {
@override
String toString() =>
'AllocatorData(initialValue=${initialValue?.toStructuredText()},'
'AllocatorData(initialValue=${initialValue?.toStructuredText(null)},'
'initializers=$initializers)';
}
@ -206,14 +207,14 @@ class Initializer {
name = null,
value = null;
String get shortText {
String shortText(DartTypes dartTypes) {
switch (kind) {
case InitializerKind.direct:
return value.toStructuredText();
return value.toStructuredText(dartTypes);
case InitializerKind.positional:
return '$index:${value.toStructuredText()}';
return '$index:${value.toStructuredText(dartTypes)}';
case InitializerKind.named:
return '$name:${value.toStructuredText()}';
return '$name:${value.toStructuredText(dartTypes)}';
case InitializerKind.complex:
return '?';
}
@ -221,7 +222,7 @@ class Initializer {
}
@override
String toString() => shortText;
String toString() => shortText(null);
}
class JFieldAnalysis {
@ -631,7 +632,7 @@ class FieldAnalysisData {
@override
String toString() =>
'FieldAnalysisData(initialValue=${initialValue?.toStructuredText()},'
'FieldAnalysisData(initialValue=${initialValue?.toStructuredText(null)},'
'isInitializedInAllocator=$isInitializedInAllocator,'
'isEffectivelyFinal=$isEffectivelyFinal,isElided=$isElided,'
'isEager=$isEager,eagerCreationIndex=$eagerCreationIndex,'

View file

@ -58,6 +58,8 @@ class JavaScriptImpactTransformer extends ImpactTransformer {
this._classHierarchyBuilder,
this._annotationsData);
DartTypes get _dartTypes => _commonElements.dartTypes;
@override
WorldImpact transformResolutionImpact(ResolutionImpact worldImpact) {
TransformedWorldImpact transformed =
@ -330,7 +332,7 @@ class JavaScriptImpactTransformer extends ImpactTransformer {
type = _elementEnvironment.getUnaliasedType(type);
registerImpact(_impacts.typeCheck);
if (!type.treatAsRaw ||
if (!_dartTypes.treatAsRawType(type) ||
type.containsTypeVariables ||
type is FunctionType) {
registerImpact(_impacts.genericTypeCheck);
@ -382,7 +384,8 @@ class CodegenImpactTransformer {
type = type.unaliased;
_impacts.typeCheck.registerImpact(transformed, _elementEnvironment);
if (!type.treatAsRaw || type.containsTypeVariables) {
if (!_closedWorld.dartTypes.treatAsRawType(type) ||
type.containsTypeVariables) {
_impacts.genericIsCheck.registerImpact(transformed, _elementEnvironment);
}
if (type is InterfaceType && _nativeData.isNativeClass(type.element)) {

View file

@ -277,7 +277,7 @@ class InterceptorDataImpl implements InterceptorData {
// We can use an instanceof check for raw types that have no subclass that
// is mixed-in or in an implements clause.
if (!type.treatAsRaw) return false;
if (!closedWorld.dartTypes.treatAsRawType(type)) return false;
if (type is FutureOrType) return false;
InterfaceType interfaceType = type;
ClassEntity classElement = interfaceType.element;

View file

@ -832,8 +832,8 @@ class RuntimeTypesEncoderImpl implements RuntimeTypesEncoder {
RuntimeTypesEncoderImpl(this.rtiTags, NativeBasicData nativeData,
this._elementEnvironment, this.commonElements, this._rtiNeed)
: _representationGenerator =
new TypeRepresentationGenerator(rtiTags, nativeData);
: _representationGenerator = new TypeRepresentationGenerator(
commonElements.dartTypes, rtiTags, nativeData);
/// Returns the JavaScript template to determine at runtime if a type object
/// is a function type.
@ -969,6 +969,7 @@ class RuntimeTypeTags {
class TypeRepresentationGenerator
implements DartTypeVisitor<jsAst.Expression, ModularEmitter> {
final DartTypes _dartTypes;
final RuntimeTypeTags _rtiTags;
final NativeBasicData _nativeData;
@ -977,7 +978,7 @@ class TypeRepresentationGenerator
Map<TypeVariableType, jsAst.Expression> typedefBindings;
List<FunctionTypeVariable> functionTypeVariables = <FunctionTypeVariable>[];
TypeRepresentationGenerator(this._rtiTags, this._nativeData);
TypeRepresentationGenerator(this._dartTypes, this._rtiTags, this._nativeData);
/// Creates a type representation for [type]. [onVariable] is called to
/// provide the type representation for type variables.
@ -1245,7 +1246,7 @@ class TypeRepresentationGenerator
jsAst.ObjectInitializer initializer = visit(unaliasedType, emitter);
// We have to encode the aliased type.
jsAst.Expression name = getJavaScriptClassName(type.element, emitter);
jsAst.Expression encodedTypedef = type.treatAsRaw
jsAst.Expression encodedTypedef = _dartTypes.treatAsRawType(type)
? name
: visitList(type.typeArguments, emitter, head: name);

View file

@ -130,10 +130,10 @@ abstract class RuntimeTypesSubstitutions {
Set<ClassEntity> getClassesUsedInSubstitutions(TypeChecks checks);
static bool hasTypeArguments(DartType type) {
static bool hasTypeArguments(DartTypes dartTypes, DartType type) {
if (type is InterfaceType) {
InterfaceType interfaceType = type;
return !interfaceType.treatAsRaw;
return !dartTypes.treatAsRawType(interfaceType);
}
return false;
}

View file

@ -1057,7 +1057,7 @@ class RuntimeTypesNeedBuilderImpl implements RuntimeTypesNeedBuilder {
checks.forEach((DartType type) {
if (type is InterfaceType) {
InterfaceType itf = type;
if (!itf.treatAsRaw) {
if (!closedWorld.dartTypes.treatAsRawType(itf)) {
potentiallyNeedTypeArguments(itf.element);
}
} else {

View file

@ -182,7 +182,7 @@ class Constant {
@override
String toString() {
return 'Constant(name=${name.key},value=${value.toStructuredText()})';
return 'Constant(name=${name.key},value=${value.toStructuredText(null)})';
}
}

View file

@ -158,6 +158,6 @@ class FieldVisitor {
// We never generate accessors for top-level/static fields.
if (!member.isInstanceMember) return true;
DartType type = _elementEnvironment.getFieldType(member);
return type.isTop;
return _closedWorld.dartTypes.isTopType(type);
}
}

View file

@ -141,10 +141,10 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
AnnotationsData annotations)
: this.options = _elementMap.options {
_elementEnvironment = new JsElementEnvironment(this);
_commonElements =
new CommonElementsImpl(_elementEnvironment, _elementMap.options);
_typeConverter = new DartTypeConverter(this);
_types = new KernelDartTypes(this);
_types = new KernelDartTypes(this, options.useLegacySubtyping);
_commonElements = new CommonElementsImpl(
_types, _elementEnvironment, _elementMap.options);
_constantValuefier = new ConstantValuefier(this);
programEnv = _elementMap.env.convert();
@ -321,9 +321,10 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
JsKernelToElementMap.readFromDataSource(this.options, this.reporter,
this._environment, ir.Component component, DataSource source) {
_elementEnvironment = new JsElementEnvironment(this);
_commonElements = new CommonElementsImpl(_elementEnvironment, options);
_typeConverter = new DartTypeConverter(this);
_types = new KernelDartTypes(this);
_types = new KernelDartTypes(this, options.useLegacySubtyping);
_commonElements =
new CommonElementsImpl(_types, _elementEnvironment, options);
_constantValuefier = new ConstantValuefier(this);
source.registerComponentLookup(new ComponentLookup(component));
@ -1816,7 +1817,7 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
new RecordContainerDefinition(getMemberDefinition(member).location),
thisType,
supertype,
getOrderedTypeSet(supertype.element).extendClass(thisType));
getOrderedTypeSet(supertype.element).extendClass(_types, thisType));
classes.register(container, containerData, new RecordEnv(memberMap));
InterfaceType memberThisType = member.enclosingClass != null
@ -1878,7 +1879,7 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
new ClosureClassDefinition(location),
thisType,
supertype,
getOrderedTypeSet(supertype.element).extendClass(thisType));
getOrderedTypeSet(supertype.element).extendClass(_types, thisType));
classes.register(classEntity, closureData, new ClosureClassEnv(memberMap));
Local closureEntity;

View file

@ -729,7 +729,8 @@ class JsToFrontendMapImpl extends JsToFrontendMap {
}
return null;
}
return constant.accept(new _ConstantConverter(toBackendEntity), null);
return constant.accept(
new _ConstantConverter(_backend.types, toBackendEntity), null);
}
}
@ -853,10 +854,11 @@ class _TypeConverter implements DartTypeVisitor<DartType, _EntityConverter> {
}
class _ConstantConverter implements ConstantValueVisitor<ConstantValue, Null> {
final DartTypes _dartTypes;
final Entity Function(Entity) toBackendEntity;
final _TypeConverter typeConverter;
_ConstantConverter(this.toBackendEntity)
_ConstantConverter(this._dartTypes, this.toBackendEntity)
: typeConverter = new _TypeConverter();
@override
@ -952,14 +954,14 @@ class _ConstantConverter implements ConstantValueVisitor<ConstantValue, Null> {
ConstantValue visitInterceptor(InterceptorConstantValue constant, _) {
// Interceptor constants are only created in the SSA graph builder.
throw new UnsupportedError(
"Unexpected visitInterceptor ${constant.toStructuredText()}");
"Unexpected visitInterceptor ${constant.toStructuredText(_dartTypes)}");
}
@override
ConstantValue visitDeferredGlobal(DeferredGlobalConstantValue constant, _) {
// Deferred global constants are only created in the SSA graph builder.
throw new UnsupportedError(
"Unexpected DeferredGlobalConstantValue ${constant.toStructuredText()}");
"Unexpected DeferredGlobalConstantValue ${constant.toStructuredText(_dartTypes)}");
}
@override

View file

@ -119,9 +119,10 @@ class KernelToElementMapImpl implements KernelToElementMap, IrToElementMap {
KernelToElementMapImpl(
this.reporter, this._environment, this._frontendStrategy, this.options) {
_elementEnvironment = new KernelElementEnvironment(this);
_commonElements = new CommonElementsImpl(_elementEnvironment, options);
_typeConverter = new DartTypeConverter(this);
_types = new KernelDartTypes(this);
_types = new KernelDartTypes(this, options.useLegacySubtyping);
_commonElements =
new CommonElementsImpl(_types, _elementEnvironment, options);
_constantValuefier = new ConstantValuefier(this);
}

View file

@ -58,7 +58,8 @@ class KernelImpactBuilder extends ImpactBuilderBase
VariableScopeModel variableScopeModel,
this._annotations,
this._constantValuefier)
: this.impactBuilder = new ResolutionWorldImpactBuilder(currentMember),
: this.impactBuilder = new ResolutionWorldImpactBuilder(
elementMap.commonElements.dartTypes, currentMember),
super(staticTypeContext, elementMap.classHierarchy, variableScopeModel);
@override
@ -95,7 +96,8 @@ class KernelImpactConverter extends KernelImpactRegistryMixin {
KernelImpactConverter(this.elementMap, this.currentMember, this.reporter,
this._options, this._constantValuefier, this.staticTypeContext)
: this.impactBuilder = new ResolutionWorldImpactBuilder(currentMember);
: this.impactBuilder = new ResolutionWorldImpactBuilder(
elementMap.commonElements.dartTypes, currentMember);
@override
ir.TypeEnvironment get typeEnvironment => elementMap.typeEnvironment;
@ -124,6 +126,7 @@ abstract class KernelImpactRegistryMixin implements ImpactRegistry {
ResolutionWorldImpactBuilder get impactBuilder;
ir.TypeEnvironment get typeEnvironment;
CommonElements get commonElements;
DartTypes get dartTypes => commonElements.dartTypes;
NativeBasicData get _nativeBasicData;
ConstantValuefier get _constantValuefier;
ir.StaticTypeContext get staticTypeContext;
@ -171,9 +174,9 @@ abstract class KernelImpactRegistryMixin implements ImpactRegistry {
List<ConstantValue> metadata =
elementMap.elementEnvironment.getMemberMetadata(member);
Iterable<String> createsAnnotations =
getCreatesAnnotations(reporter, commonElements, metadata);
getCreatesAnnotations(dartTypes, reporter, commonElements, metadata);
Iterable<String> returnsAnnotations =
getReturnsAnnotations(reporter, commonElements, metadata);
getReturnsAnnotations(dartTypes, reporter, commonElements, metadata);
impactBuilder.registerNativeData(elementMap.getNativeBehaviorForFieldLoad(
field, createsAnnotations, returnsAnnotations,
isJsInterop: isJsInterop));
@ -192,9 +195,9 @@ abstract class KernelImpactRegistryMixin implements ImpactRegistry {
List<ConstantValue> metadata =
elementMap.elementEnvironment.getMemberMetadata(member);
Iterable<String> createsAnnotations =
getCreatesAnnotations(reporter, commonElements, metadata);
getCreatesAnnotations(dartTypes, reporter, commonElements, metadata);
Iterable<String> returnsAnnotations =
getReturnsAnnotations(reporter, commonElements, metadata);
getReturnsAnnotations(dartTypes, reporter, commonElements, metadata);
impactBuilder.registerNativeData(elementMap.getNativeBehaviorForMethod(
constructor, createsAnnotations, returnsAnnotations,
isJsInterop: isJsInterop));
@ -238,9 +241,9 @@ abstract class KernelImpactRegistryMixin implements ImpactRegistry {
List<ConstantValue> metadata =
elementMap.elementEnvironment.getMemberMetadata(member);
Iterable<String> createsAnnotations =
getCreatesAnnotations(reporter, commonElements, metadata);
getCreatesAnnotations(dartTypes, reporter, commonElements, metadata);
Iterable<String> returnsAnnotations =
getReturnsAnnotations(reporter, commonElements, metadata);
getReturnsAnnotations(dartTypes, reporter, commonElements, metadata);
impactBuilder.registerNativeData(elementMap.getNativeBehaviorForMethod(
procedure, createsAnnotations, returnsAnnotations,
isJsInterop: isJsInterop));

View file

@ -32,8 +32,8 @@ class KernelAnnotationProcessor implements AnnotationProcessor {
KCommonElements commonElements = elementMap.commonElements;
String annotationName;
for (ConstantValue value in metadata) {
String name = readAnnotationName(
spannable, value, commonElements.jsAnnotationClass,
String name = readAnnotationName(commonElements.dartTypes, spannable,
value, commonElements.jsAnnotationClass,
defaultValue: '');
if (annotationName == null) {
annotationName = name;

View file

@ -912,7 +912,7 @@ abstract class BehaviorBuilder {
}
}
List<String> _getAnnotations(DiagnosticReporter reporter,
List<String> _getAnnotations(DartTypes dartTypes, DiagnosticReporter reporter,
Iterable<ConstantValue> metadata, ClassEntity cls) {
List<String> annotations = [];
for (ConstantValue value in metadata) {
@ -924,7 +924,7 @@ List<String> _getAnnotations(DiagnosticReporter reporter,
// 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()}');
'Annotations needs one string: ${value.toStructuredText(dartTypes)}');
}
StringConstantValue specStringConstant = fields.single;
String specString = specStringConstant.stringValue;
@ -933,14 +933,20 @@ List<String> _getAnnotations(DiagnosticReporter reporter,
return annotations;
}
List<String> getCreatesAnnotations(DiagnosticReporter reporter,
CommonElements commonElements, Iterable<ConstantValue> metadata) {
List<String> getCreatesAnnotations(
DartTypes dartTypes,
DiagnosticReporter reporter,
CommonElements commonElements,
Iterable<ConstantValue> metadata) {
return _getAnnotations(
reporter, metadata, commonElements.annotationCreatesClass);
dartTypes, reporter, metadata, commonElements.annotationCreatesClass);
}
List<String> getReturnsAnnotations(DiagnosticReporter reporter,
CommonElements commonElements, Iterable<ConstantValue> metadata) {
List<String> getReturnsAnnotations(
DartTypes dartTypes,
DiagnosticReporter reporter,
CommonElements commonElements,
Iterable<ConstantValue> metadata) {
return _getAnnotations(
reporter, metadata, commonElements.annotationReturnsClass);
dartTypes, reporter, metadata, commonElements.annotationReturnsClass);
}

View file

@ -8,6 +8,7 @@ import '../common.dart';
import '../common_elements.dart' show KElementEnvironment;
import '../constants/values.dart';
import '../elements/entities.dart';
import '../elements/types.dart';
import '../ir/annotations.dart';
import '../js_backend/native_data.dart';
@ -143,8 +144,8 @@ bool isAnnotation(
/// Extracts the name if [value] is a named annotation based on
/// [annotationClass], otherwise returns `null`.
String readAnnotationName(
Spannable spannable, ConstantValue value, ClassEntity annotationClass,
String readAnnotationName(DartTypes dartTypes, Spannable spannable,
ConstantValue value, ClassEntity annotationClass,
{String defaultValue}) {
if (!value.isConstructedObject) return null;
ConstructedConstantValue constructedObject = value;
@ -153,8 +154,8 @@ String readAnnotationName(
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()}');
failedAt(spannable,
'Annotations needs one string: ${value.toStructuredText(dartTypes)}');
return null;
} else if (fields.single is StringConstantValue) {
StringConstantValue specStringConstant = fields.single;
@ -162,8 +163,8 @@ String readAnnotationName(
} else if (defaultValue != null && fields.single is NullConstantValue) {
return defaultValue;
} else {
failedAt(
spannable, 'Annotations needs one string: ${value.toStructuredText()}');
failedAt(spannable,
'Annotations needs one string: ${value.toStructuredText(dartTypes)}');
return null;
}
}

View file

@ -334,6 +334,12 @@ class CompilerOptions implements DiagnosticOptions {
/// weak or strong semantics.
bool useWeakNullSafetySemantics = false;
/// Whether to use legacy subtype semantics rather than null-safe semantics.
/// This is `true` if null-safety is disabled, i.e. all code is legacy code,
/// or if weak null-safety semantics are being used, since we do not emit
/// warnings.
bool get useLegacySubtyping => !useNullSafety || useWeakNullSafetySemantics;
/// The path to the file that contains the profiled allocations.
///
/// The file must contain the Map that was produced by using

View file

@ -98,9 +98,9 @@ class OrderedTypeSet {
/// Creates a new [OrderedTypeSet] for [type] when it directly extends the
/// class which this set represents. This is for instance used to create the
/// type set for [ClosureClassElement] which extends [Closure].
OrderedTypeSet extendClass(InterfaceType type) {
OrderedTypeSet extendClass(DartTypes dartTypes, InterfaceType type) {
assert(
types.head.treatAsRaw,
dartTypes.treatAsRawType(types.head),
failedAt(
type.element,
'Cannot extend generic class ${types.head} using '

View file

@ -7,6 +7,7 @@ library dart2js.resolution.registry;
import '../common/resolution.dart' show ResolutionImpact;
import '../constants/values.dart';
import '../elements/entities.dart' show ClassEntity, MemberEntity;
import '../elements/types.dart';
import '../universe/feature.dart';
import '../universe/world_impact.dart' show WorldImpact, WorldImpactBuilderImpl;
import '../util/enumset.dart' show EnumSet;
@ -14,6 +15,7 @@ import '../util/util.dart' show Setlet;
class ResolutionWorldImpactBuilder extends WorldImpactBuilderImpl
implements ResolutionImpact {
final DartTypes _dartTypes;
@override
final MemberEntity member;
EnumSet<Feature> _features;
@ -27,7 +29,7 @@ class ResolutionWorldImpactBuilder extends WorldImpactBuilderImpl
Set<RuntimeTypeUse> _runtimeTypeUses;
Set<GenericInstantiation> _genericInstantiations;
ResolutionWorldImpactBuilder(this.member);
ResolutionWorldImpactBuilder(this._dartTypes, this.member);
@override
bool get isEmpty => false;
@ -174,7 +176,7 @@ class ResolutionWorldImpactBuilder extends WorldImpactBuilderImpl
if (_constantLiterals != null) {
sb.write('\n const-literals:');
for (ConstantValue constant in _constantLiterals) {
sb.write('\n ${constant.toDartText()}');
sb.write('\n ${constant.toDartText(_dartTypes)}');
}
}
if (_constSymbolNames != null) {

View file

@ -217,7 +217,7 @@ class KernelSsaGraphBuilder extends ir.Visitor {
InferredData get _inferredData => globalInferenceResults.inferredData;
DartTypes get types => closedWorld.dartTypes;
DartTypes get dartTypes => closedWorld.dartTypes;
void push(HInstruction instruction) {
add(instruction);
@ -3109,7 +3109,8 @@ class KernelSsaGraphBuilder extends ir.Visitor {
/// Set the runtime type information if necessary.
HInstruction _setListRuntimeTypeInfoIfNeeded(HInstruction object,
InterfaceType type, SourceInformation sourceInformation) {
if (!_rtiNeed.classNeedsTypeArguments(type.element) || type.treatAsRaw) {
if (!_rtiNeed.classNeedsTypeArguments(type.element) ||
dartTypes.treatAsRawType(type)) {
return object;
}
if (options.useNewRti) {
@ -4046,7 +4047,7 @@ class KernelSsaGraphBuilder extends ir.Visitor {
localsHandler.substInContext(_elementMap.getDartType(type));
if (typeValue is! InterfaceType) return false;
InterfaceType interfaceType = typeValue;
if (!interfaceType.treatAsRaw) return false;
if (!dartTypes.treatAsRawType(interfaceType)) return false;
ClassEntity cls = interfaceType.element;
InterfaceType thisType = _elementEnvironment.getThisType(cls);
@ -5434,7 +5435,7 @@ class KernelSsaGraphBuilder extends ir.Visitor {
DartType typeValue =
localsHandler.substInContext(_elementMap.getDartType(type));
if (typeValue.isTop) {
if (dartTypes.isTopType(typeValue)) {
stack.add(graph.addConstantBool(true, closedWorld));
return;
}
@ -5567,7 +5568,7 @@ class KernelSsaGraphBuilder extends ir.Visitor {
List<DartType> bounds = thisType.typeArguments;
for (int i = 0; i < bounds.length; i++) {
DartType arg = type.typeArguments[i];
if (arg.isTop) continue;
if (dartTypes.isTopType(arg)) continue;
TypeVariableType typeVariable = bounds[i];
DartType bound =
_elementEnvironment.getTypeVariableBound(typeVariable.element);

View file

@ -3,11 +3,16 @@
// BSD-style license that can be found in the LICENSE file.
import '../elements/entities.dart';
import '../elements/types.dart';
import 'package:_fe_analyzer_shared/src/testing/features.dart';
import 'nodes.dart';
/// Log used for unit testing optimizations.
class OptimizationTestLog {
final DartTypes _dartTypes;
OptimizationTestLog(this._dartTypes);
List<OptimizationLogEntry> entries = [];
Map<String, Set<HInstruction>> _unconverted;
@ -76,7 +81,7 @@ class OptimizationTestLog {
HInvokeDynamicGetter original, FieldEntity field, HConstant converted) {
Features features = new Features();
features['name'] = '${field.enclosingClass.name}.${field.name}';
features['value'] = converted.constant.toStructuredText();
features['value'] = converted.constant.toStructuredText(_dartTypes);
entries.add(new OptimizationLogEntry('ConstantFieldGet', features));
}
@ -84,7 +89,7 @@ class OptimizationTestLog {
HInvokeDynamicMethod original, FieldEntity field, HConstant converted) {
Features features = new Features();
features['name'] = '${field.enclosingClass.name}.${field.name}';
features['value'] = converted.constant.toStructuredText();
features['value'] = converted.constant.toStructuredText(_dartTypes);
entries.add(new OptimizationLogEntry('ConstantFieldCall', features));
}
@ -202,7 +207,7 @@ class OptimizationTestLog {
void registerCompareTo(HInvokeDynamic original, [HConstant converted]) {
Features features = new Features();
if (converted != null) {
features['constant'] = converted.constant.toDartText();
features['constant'] = converted.constant.toDartText(_dartTypes);
}
entries.add(new OptimizationLogEntry('CompareTo', features));
}

View file

@ -1410,7 +1410,7 @@ abstract class HInstruction implements Spannable {
// instructions with generics. It has the generic type context
// available.
assert(type is! TypeVariableType);
assert(type.treatAsRaw || type is FunctionType);
assert(closedWorld.dartTypes.treatAsRawType(type) || type is FunctionType);
if (type is DynamicType) return this;
if (type is VoidType) return this;
if (type == closedWorld.commonElements.objectType) return this;
@ -1419,7 +1419,8 @@ abstract class HInstruction implements Spannable {
closedWorld.abstractValueDomain.dynamicType, this, sourceInformation);
}
assert(type is InterfaceType);
if (kind == HTypeConversion.TYPE_CHECK && !type.treatAsRaw) {
if (kind == HTypeConversion.TYPE_CHECK &&
!closedWorld.dartTypes.treatAsRawType(type)) {
throw 'creating compound check to $type (this = ${this})';
} else {
InterfaceType interfaceType = type;
@ -2940,7 +2941,7 @@ class HConstant extends HInstruction {
: super(<HInstruction>[], constantType);
@override
toString() => 'literal: ${constant.toStructuredText()}';
toString() => 'literal: ${constant.toStructuredText(null)}';
@override
accept(HVisitor visitor) => visitor.visitConstant(this);
@ -3757,7 +3758,7 @@ class HTypeConversion extends HCheck {
// TODO(johnniwinther): Optimize FutureOr type conversions.
return false;
}
if (!type.treatAsRaw) {
if (!closedWorld.dartTypes.treatAsRawType(type)) {
// `null` always passes type conversion.
if (checkedInput.isNull(abstractValueDomain).isDefinitelyTrue) {
return true;
@ -4611,7 +4612,7 @@ AbstractBool _isTestResult(HInstruction expression, DartType dartType,
// Currently, the abstract value domain cannot (soundly) state that an is-test
// is definitely false, so we reuse some of the case-by-case logic from the
// old [HIs] optimization.
if (dartType.isTop) return AbstractBool.True;
if (closedWorld.dartTypes.isTopType(dartType)) return AbstractBool.True;
if (dartType is! InterfaceType) return AbstractBool.Maybe;
InterfaceType type = dartType;
ClassEntity element = type.element;
@ -4660,7 +4661,7 @@ AbstractBool _isTestResult(HInstruction expression, DartType dartType,
// We need the raw check because we don't have the notion of generics in the
// backend. For example, `this` in a class `A<T>` is currently always
// considered to have the raw type.
if (type.treatAsRaw) {
if (closedWorld.dartTypes.treatAsRawType(type)) {
return abstractValueDomain.isInstanceOf(subsetType, element);
}
return AbstractBool.Maybe;

View file

@ -81,7 +81,8 @@ class SsaOptimizerTask extends CompilerTask {
OptimizationTestLog log;
if (retainDataForTesting) {
loggersForTesting ??= {};
loggersForTesting[member] = log = new OptimizationTestLog();
loggersForTesting[member] =
log = new OptimizationTestLog(closedWorld.dartTypes);
}
measure(() {
@ -1174,7 +1175,7 @@ class SsaInstructionSimplifier extends HBaseVisitor
return node;
}
if (type.isTop) {
if (_closedWorld.dartTypes.isTopType(type)) {
return _graph.addConstantBool(true, _closedWorld);
}
InterfaceType interfaceType = type;
@ -1222,7 +1223,8 @@ class SsaInstructionSimplifier extends HBaseVisitor
// the notion of generics in the backend. For example, [:this:] in
// a class [:A<T>:], is currently always considered to have the
// raw type.
} else if (!RuntimeTypesSubstitutions.hasTypeArguments(type)) {
} else if (!RuntimeTypesSubstitutions.hasTypeArguments(
_closedWorld.dartTypes, type)) {
AbstractValue expressionMask = expression.instructionType;
AbstractBool isInstanceOf =
_abstractValueDomain.isInstanceOf(expressionMask, element);
@ -1247,7 +1249,8 @@ class SsaInstructionSimplifier extends HBaseVisitor
rep.kind == TypeInfoExpressionKind.COMPLETE &&
rep.inputs.isEmpty) {
DartType type = rep.dartType;
if (type is InterfaceType && type.treatAsRaw) {
if (type is InterfaceType &&
_closedWorld.dartTypes.treatAsRawType(type)) {
return node.checkedInput.convertType(_closedWorld, type, node.kind)
..sourceInformation = node.sourceInformation;
}
@ -1518,7 +1521,7 @@ class SsaInstructionSimplifier extends HBaseVisitor
return node;
}
if (!fieldType.treatAsRaw ||
if (!_closedWorld.dartTypes.treatAsRawType(fieldType) ||
fieldType is TypeVariableType ||
fieldType.unaliased is FunctionType ||
fieldType.unaliased is FutureOrType) {
@ -2136,7 +2139,7 @@ class SsaInstructionSimplifier extends HBaseVisitor
return HAsCheckSimple(node.checkedInput, dartType, checkedType,
node.isTypeError, specializedCheck, node.instructionType);
}
if (dartType.isTop) {
if (_closedWorld.dartTypes.isTopType(dartType)) {
return node.checkedInput;
}
}
@ -2163,7 +2166,7 @@ class SsaInstructionSimplifier extends HBaseVisitor
if (typeInput is HLoadType) {
TypeExpressionRecipe recipe = typeInput.typeExpression;
DartType dartType = recipe.type;
if (dartType.isTop) {
if (_closedWorld.dartTypes.isTopType(dartType)) {
return _graph.addConstantBool(true, _closedWorld);
}

View file

@ -433,7 +433,7 @@ abstract class TypeBuilder {
if (type == null) return original;
type = type.unaliased;
if (type is InterfaceType && !type.treatAsRaw) {
if (type is InterfaceType && !_closedWorld.dartTypes.treatAsRawType(type)) {
InterfaceType interfaceType = type;
AbstractValue subtype =
_abstractValueDomain.createNullableSubtype(interfaceType.element);

View file

@ -52,7 +52,7 @@ class AbstractValueFactory {
.createNonNullExact(commonElements.objectClass);
} else if (type is VoidType) {
return abstractValueDomain.nullType;
} else if (type.isTop) {
} else if (closedWorld.dartTypes.isTopType(type)) {
return abstractValueDomain.dynamicType;
} else if (type == commonElements.nullType) {
return abstractValueDomain.nullType;

View file

@ -356,7 +356,7 @@ class PropertyUsage extends MemberUsage {
'potentialWrites=${potentialWrites.iterable(Access.values)},'
'potentialInvokes=${potentialInvokes.iterable(Access.values)},'
'pendingUse=${_pendingUse.iterable(MemberUse.values)},'
'initialConstants=${initialConstants?.map((c) => c.toStructuredText())})';
'initialConstants=${initialConstants?.map((c) => c.toStructuredText(null))})';
}
/// Member usage tracking for a field.
@ -492,7 +492,7 @@ class FieldUsage extends MemberUsage {
'potentialWrites=${potentialWrites.iterable(Access.values)},'
'potentialInvokes=${potentialInvokes.iterable(Access.values)},'
'pendingUse=${_pendingUse.iterable(MemberUse.values)},'
'initialConstants=${initialConstants.map((c) => c.toStructuredText())})';
'initialConstants=${initialConstants.map((c) => c.toStructuredText(null))})';
}
/// Member usage tracking for a constructor or method.

View file

@ -293,7 +293,7 @@ class StaticUse {
}
if (constant != null) {
sb.write('=');
sb.write(constant.toStructuredText());
sb.write(constant.toStructuredText(null));
}
return sb.toString();
}
@ -908,7 +908,7 @@ class ConstantUse {
/// Short textual representation use for testing.
String get shortText {
return value.toDartText();
return value.toDartText(null);
}
/// Constant used as the initial value of a field.
@ -934,5 +934,5 @@ class ConstantUse {
int get hashCode => value.hashCode;
@override
String toString() => 'ConstantUse(${value.toStructuredText()})';
String toString() => 'ConstantUse(${value.toStructuredText(null)})';
}

View file

@ -192,7 +192,6 @@
"Dynamic invocation of 'addSuccessor'.": 1
},
"pkg/compiler/lib/src/ssa/types.dart": {
"Dynamic access of 'isTop'.": 1,
"Dynamic access of 'element'.": 1
},
"pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart": {

View file

@ -10,6 +10,7 @@ import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/constants/values.dart';
import 'package:compiler/src/deferred_load.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/elements/types.dart';
import 'package:compiler/src/js_emitter/model.dart';
import 'package:compiler/src/util/util.dart';
import 'package:expect/expect.dart';
@ -31,6 +32,7 @@ run(Map<String, String> sourceFiles, List<OutputUnitDescriptor> outputUnits,
CompilationResult result = await runCompiler(
memorySourceFiles: sourceFiles, outputProvider: collector);
Compiler compiler = result.compiler;
DartTypes dartTypes = compiler.frontendStrategy.commonElements.dartTypes;
ProgramLookup lookup = new ProgramLookup(compiler.backendStrategy);
var closedWorld = compiler.backendClosedWorldForTesting;
var elementEnvironment = closedWorld.elementEnvironment;
@ -59,7 +61,7 @@ run(Map<String, String> sourceFiles, List<OutputUnitDescriptor> outputUnits,
void processFragment(String fragmentName, Fragment fragment) {
for (Constant constant in fragment.constants) {
String text = constant.value.toStructuredText();
String text = constant.value.toStructuredText(dartTypes);
Set<String> expectedConstantUnit = expectedOutputUnits[text];
if (expectedConstantUnit == null) {
if (constant.value is DeferredGlobalConstantValue) {

View file

@ -7,6 +7,7 @@
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/constants/values.dart';
import 'package:compiler/src/elements/types.dart';
import 'package:expect/expect.dart';
import '../helpers/memory_compiler.dart';
@ -16,6 +17,7 @@ void main() {
await runCompiler(memorySourceFiles: MEMORY_SOURCE_FILES);
Compiler compiler = result.compiler;
DartTypes dartTypes = compiler.frontendStrategy.commonElements.dartTypes;
var closedWorld = compiler.backendClosedWorldForTesting;
var outputUnitForConstant =
closedWorld.outputUnitData.outputUnitForConstant;
@ -35,12 +37,15 @@ void main() {
allConstants.firstWhere((dynamic constant) {
return constant.isString && constant.stringValue == stringValue;
});
Expect.notEquals(null, outputUnitForConstant(constant),
"Constant value ${constant.toStructuredText()} has no output unit.");
Expect.notEquals(
null,
outputUnitForConstant(constant),
"Constant value ${constant.toStructuredText(dartTypes)} has no "
"output unit.");
Expect.notEquals(
mainOutputUnit,
outputUnitForConstant(constant),
"Constant value ${constant.toStructuredText()} "
"Constant value ${constant.toStructuredText(dartTypes)} "
"is in the main output unit.");
}
}

View file

@ -175,7 +175,7 @@ class OutputUnitIrComputer extends IrDataExtractor<String> {
visitConstantExpression(ir.ConstantExpression node) {
ConstantValue constant = _elementMap.getConstantValue(null, node);
if (!constant.isPrimitive) {
_constants.add('${constant.toStructuredText()}='
_constants.add('${constant.toStructuredText(_elementMap.types)}='
'${outputUnitString(_data.outputUnitForConstant(constant))}');
}
return super.visitConstantExpression(node);

View file

@ -7,6 +7,7 @@ import 'package:_fe_analyzer_shared/src/testing/features.dart';
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/elements/types.dart';
import 'package:compiler/src/js_backend/field_analysis.dart';
import 'package:compiler/src/js_model/js_world.dart';
import 'package:kernel/ast.dart' as ir;
@ -40,6 +41,7 @@ class JAllocatorAnalysisDataComputer extends DataComputer<Features> {
Map<Id, ActualData<Features>> actualMap,
{bool verbose: false}) {
if (member.isField) {
DartTypes dartTypes = compiler.frontendStrategy.commonElements.dartTypes;
JsClosedWorld closedWorld = compiler.backendClosedWorldForTesting;
JFieldAnalysis fieldAnalysis = closedWorld.fieldAnalysis;
ir.Member node = closedWorld.elementMap.getMemberDefinition(member).node;
@ -53,9 +55,10 @@ class JAllocatorAnalysisDataComputer extends DataComputer<Features> {
}
if (fieldData.isEffectivelyConstant) {
features[Tags.constantValue] =
fieldData.constantValue.toStructuredText();
fieldData.constantValue.toStructuredText(dartTypes);
} else if (fieldData.initialValue != null) {
features[Tags.initialValue] = fieldData.initialValue.toStructuredText();
features[Tags.initialValue] =
fieldData.initialValue.toStructuredText(dartTypes);
} else if (fieldData.isEager) {
if (fieldData.eagerCreationIndex != null) {
features[Tags.eagerCreationIndex] =

View file

@ -7,6 +7,7 @@ import 'package:_fe_analyzer_shared/src/testing/features.dart';
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/elements/types.dart';
import 'package:compiler/src/js_backend/field_analysis.dart';
import 'package:compiler/src/kernel/kernel_strategy.dart';
import 'package:kernel/ast.dart' as ir;
@ -35,6 +36,7 @@ class KAllocatorAnalysisDataComputer extends DataComputer<Features> {
{bool verbose: false}) {
if (member.isField) {
KernelFrontendStrategy frontendStrategy = compiler.frontendStrategy;
DartTypes dartTypes = frontendStrategy.commonElements.dartTypes;
KFieldAnalysis allocatorAnalysis =
frontendStrategy.fieldAnalysisForTesting;
ir.Member node = frontendStrategy.elementMap.getMemberNode(member);
@ -44,11 +46,12 @@ class KAllocatorAnalysisDataComputer extends DataComputer<Features> {
allocatorAnalysis.getAllocatorDataForTesting(member);
if (data != null) {
if (data.initialValue != null) {
features[Tags.initialValue] = data.initialValue.toStructuredText();
features[Tags.initialValue] =
data.initialValue.toStructuredText(dartTypes);
}
data.initializers.forEach((constructor, value) {
features['${constructor.enclosingClass.name}.${constructor.name}'] =
value?.shortText;
value?.shortText(dartTypes);
});
}
} else {
@ -56,7 +59,7 @@ class KAllocatorAnalysisDataComputer extends DataComputer<Features> {
allocatorAnalysis.getStaticFieldDataForTesting(member);
if (staticFieldData.initialValue != null) {
features[Tags.initialValue] =
staticFieldData.initialValue.toStructuredText();
staticFieldData.initialValue.toStructuredText(dartTypes);
}
features[Tags.complexity] = staticFieldData.complexity.shortText;
}

View file

@ -6,9 +6,9 @@ import 'package:compiler/src/constants/values.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/elements/types.dart';
String constantToText(ConstantValue constant) {
String constantToText(DartTypes dartTypes, ConstantValue constant) {
StringBuffer sb = new StringBuffer();
new ConstantToTextVisitor().visit(constant, sb);
new ConstantToTextVisitor(dartTypes).visit(constant, sb);
return sb.toString();
}
@ -118,8 +118,11 @@ class DartTypeToTextVisitor extends DartTypeVisitor<void, StringBuffer> {
class ConstantToTextVisitor
implements ConstantValueVisitor<void, StringBuffer> {
final DartTypes _dartTypes;
final DartTypeToTextVisitor typeToText = new DartTypeToTextVisitor();
ConstantToTextVisitor(this._dartTypes);
void visit(ConstantValue constant, StringBuffer sb) =>
constant.accept(this, sb);
@ -224,33 +227,33 @@ class ConstantToTextVisitor
@override
void visitInterceptor(InterceptorConstantValue constant, StringBuffer sb) {
throw new UnsupportedError(
'Unsupported constant value: ${constant.toStructuredText()}');
'Unsupported constant value: ${constant.toStructuredText(_dartTypes)}');
}
@override
void visitDummyInterceptor(
DummyInterceptorConstantValue constant, StringBuffer sb) {
throw new UnsupportedError(
'Unsupported constant value: ${constant.toStructuredText()}');
'Unsupported constant value: ${constant.toStructuredText(_dartTypes)}');
}
@override
void visitUnreachable(UnreachableConstantValue constant, StringBuffer sb) {
throw new UnsupportedError(
'Unsupported constant value: ${constant.toStructuredText()}');
'Unsupported constant value: ${constant.toStructuredText(_dartTypes)}');
}
@override
void visitJsName(JsNameConstantValue constant, StringBuffer sb) {
throw new UnsupportedError(
'Unsupported constant value: ${constant.toStructuredText()}');
'Unsupported constant value: ${constant.toStructuredText(_dartTypes)}');
}
@override
void visitDeferredGlobal(
DeferredGlobalConstantValue constant, StringBuffer sb) {
throw new UnsupportedError(
'Unsupported constant value: ${constant.toStructuredText()}');
'Unsupported constant value: ${constant.toStructuredText(_dartTypes)}');
}
@override

View file

@ -13,6 +13,7 @@ import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/constants/values.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/elements/indexed.dart';
import 'package:compiler/src/elements/types.dart';
import 'package:compiler/src/ir/constants.dart';
import 'package:compiler/src/ir/visitors.dart';
import 'package:compiler/src/kernel/kernel_strategy.dart';
@ -576,6 +577,7 @@ Future testData(TestData data) async {
Compiler compiler = result.compiler;
KernelFrontendStrategy frontEndStrategy = compiler.frontendStrategy;
KernelToElementMapImpl elementMap = frontEndStrategy.elementMap;
DartTypes dartTypes = elementMap.types;
ir.TypeEnvironment typeEnvironment = elementMap.typeEnvironment;
KElementEnvironment elementEnvironment =
compiler.frontendStrategy.elementEnvironment;
@ -619,7 +621,7 @@ Future testData(TestData data) async {
"Expected non-null value from evaluation of "
"`${data.code}`.");
String valueText = value.toStructuredText();
String valueText = value.toStructuredText(dartTypes);
Expect.equals(
expectedText,
valueText,

View file

@ -85,8 +85,10 @@ class ConstantDataExtractor extends IrDataExtractor<String> {
@override
String computeNodeValue(Id id, ir.TreeNode node) {
if (node is ir.ConstantExpression) {
return constantToText(elementMap.getConstantValue(
elementMap.getStaticTypeContext(member), node));
return constantToText(
elementMap.types,
elementMap.getConstantValue(
elementMap.getStaticTypeContext(member), node));
}
return null;
}

View file

@ -70,7 +70,9 @@ main() {
RuntimeTypeTags rtiTags = const RuntimeTypeTags();
TypeRepresentationGenerator typeRepresentation =
new TypeRepresentationGenerator(
rtiTags, compiler.backendClosedWorldForTesting.nativeData);
compiler.frontendStrategy.commonElements.dartTypes,
rtiTags,
compiler.backendClosedWorldForTesting.nativeData);
Expression onVariable(TypeVariableType _variable) {
TypeVariableType variable = _variable;