mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 00:29:48 +00:00
[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:
parent
637a801e64
commit
a52d6ea9b9
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<<';
|
||||
}
|
||||
|
|
|
@ -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 = {};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -73,6 +73,6 @@ class ValueTypeMask extends ForwardingTypeMask {
|
|||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Value($forwardTo, value: ${value.toDartText()})';
|
||||
return 'Value($forwardTo, value: ${value.toDartText(null)})';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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';
|
||||
}
|
||||
|
||||
|
|
|
@ -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>[];
|
||||
|
|
|
@ -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,'
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)})';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 '
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)})';
|
||||
}
|
||||
|
|
|
@ -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": {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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.");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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] =
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue