mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
[dart2js] Normalize DartTypes.
Change-Id: I2c3ddbecf9f9bbaac8f940398a7d5949c441fca4 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/134941 Reviewed-by: Sigmund Cherem <sigmund@google.com>
This commit is contained in:
parent
573f470615
commit
1591ddcf1e
|
@ -41,7 +41,8 @@ main() {
|
|||
typedefWithFutureOr);
|
||||
|
||||
print(
|
||||
/*TypeLiteral(FutureOr<dynamic>)*/
|
||||
/*cfe|analyzer.TypeLiteral(FutureOr<dynamic>)*/
|
||||
/*dart2js.TypeLiteral(dynamic)*/
|
||||
futureOr);
|
||||
|
||||
print(
|
||||
|
|
|
@ -178,37 +178,38 @@ abstract class CommonElements {
|
|||
/// [elementType] as its type argument.
|
||||
///
|
||||
/// If no type argument is provided, the canonical raw type is returned.
|
||||
InterfaceType listType([DartType elementType]);
|
||||
InterfaceType listType(Nullability nullability, [DartType elementType]);
|
||||
|
||||
/// Returns an instance of the `Set` type defined in 'dart:core' with
|
||||
/// [elementType] as its type argument.
|
||||
///
|
||||
/// If no type argument is provided, the canonical raw type is returned.
|
||||
InterfaceType setType([DartType elementType]);
|
||||
InterfaceType setType(Nullability nullability, [DartType elementType]);
|
||||
|
||||
/// Returns an instance of the `Map` type defined in 'dart:core' with
|
||||
/// [keyType] and [valueType] as its type arguments.
|
||||
///
|
||||
/// If no type arguments are provided, the canonical raw type is returned.
|
||||
InterfaceType mapType([DartType keyType, DartType valueType]);
|
||||
InterfaceType mapType(Nullability nullability,
|
||||
[DartType keyType, DartType valueType]);
|
||||
|
||||
/// Returns an instance of the `Iterable` type defined in 'dart:core' with
|
||||
/// [elementType] as its type argument.
|
||||
///
|
||||
/// If no type argument is provided, the canonical raw type is returned.
|
||||
InterfaceType iterableType([DartType elementType]);
|
||||
InterfaceType iterableType(Nullability nullability, [DartType elementType]);
|
||||
|
||||
/// Returns an instance of the `Future` type defined in 'dart:async' with
|
||||
/// [elementType] as its type argument.
|
||||
///
|
||||
/// If no type argument is provided, the canonical raw type is returned.
|
||||
InterfaceType futureType([DartType elementType]);
|
||||
InterfaceType futureType(Nullability nullability, [DartType elementType]);
|
||||
|
||||
/// Returns an instance of the `Stream` type defined in 'dart:async' with
|
||||
/// [elementType] as its type argument.
|
||||
///
|
||||
/// If no type argument is provided, the canonical raw type is returned.
|
||||
InterfaceType streamType([DartType elementType]);
|
||||
InterfaceType streamType(Nullability nullability, [DartType elementType]);
|
||||
|
||||
/// Returns `true` if [element] is a superclass of `String` or `num`.
|
||||
bool isNumberOrStringSupertype(ClassEntity element);
|
||||
|
@ -928,23 +929,24 @@ class CommonElementsImpl
|
|||
InterfaceType get stackTraceType => _getRawType(stackTraceClass);
|
||||
|
||||
@override
|
||||
InterfaceType listType([DartType elementType]) {
|
||||
InterfaceType listType(Nullability nullability, [DartType elementType]) {
|
||||
if (elementType == null) {
|
||||
return _getRawType(listClass);
|
||||
}
|
||||
return _createInterfaceType(listClass, [elementType]);
|
||||
return _createInterfaceType(listClass, [elementType], nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
InterfaceType setType([DartType elementType]) {
|
||||
InterfaceType setType(Nullability nullability, [DartType elementType]) {
|
||||
if (elementType == null) {
|
||||
return _getRawType(setClass);
|
||||
}
|
||||
return _createInterfaceType(setClass, [elementType]);
|
||||
return _createInterfaceType(setClass, [elementType], nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
InterfaceType mapType([DartType keyType, DartType valueType]) {
|
||||
InterfaceType mapType(Nullability nullability,
|
||||
[DartType keyType, DartType valueType]) {
|
||||
if (keyType == null && valueType == null) {
|
||||
return _getRawType(mapClass);
|
||||
} else if (keyType == null) {
|
||||
|
@ -952,31 +954,31 @@ class CommonElementsImpl
|
|||
} else if (valueType == null) {
|
||||
valueType = dynamicType;
|
||||
}
|
||||
return _createInterfaceType(mapClass, [keyType, valueType]);
|
||||
return _createInterfaceType(mapClass, [keyType, valueType], nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
InterfaceType iterableType([DartType elementType]) {
|
||||
InterfaceType iterableType(Nullability nullability, [DartType elementType]) {
|
||||
if (elementType == null) {
|
||||
return _getRawType(iterableClass);
|
||||
}
|
||||
return _createInterfaceType(iterableClass, [elementType]);
|
||||
return _createInterfaceType(iterableClass, [elementType], nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
InterfaceType futureType([DartType elementType]) {
|
||||
InterfaceType futureType(Nullability nullability, [DartType elementType]) {
|
||||
if (elementType == null) {
|
||||
return _getRawType(futureClass);
|
||||
}
|
||||
return _createInterfaceType(futureClass, [elementType]);
|
||||
return _createInterfaceType(futureClass, [elementType], nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
InterfaceType streamType([DartType elementType]) {
|
||||
InterfaceType streamType(Nullability nullability, [DartType elementType]) {
|
||||
if (elementType == null) {
|
||||
return _getRawType(streamClass);
|
||||
}
|
||||
return _createInterfaceType(streamClass, [elementType]);
|
||||
return _createInterfaceType(streamClass, [elementType], nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1021,17 +1023,19 @@ class CommonElementsImpl
|
|||
return _env.getRawType(cls);
|
||||
}
|
||||
|
||||
/// Create the instantiation of [cls] with the given [typeArguments].
|
||||
/// Create the instantiation of [cls] with the given [typeArguments] and
|
||||
/// [nullability].
|
||||
InterfaceType _createInterfaceType(
|
||||
ClassEntity cls, List<DartType> typeArguments) {
|
||||
return _env.createInterfaceType(cls, typeArguments);
|
||||
ClassEntity cls, List<DartType> typeArguments, Nullability nullability) {
|
||||
return _env.createInterfaceType(cls, typeArguments, nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
InterfaceType getConstantListTypeFor(InterfaceType sourceType) =>
|
||||
dartTypes.treatAsRawType(sourceType)
|
||||
? _env.getRawType(jsArrayClass)
|
||||
: _env.createInterfaceType(jsArrayClass, sourceType.typeArguments);
|
||||
: _env.createInterfaceType(
|
||||
jsArrayClass, sourceType.typeArguments, sourceType.nullability);
|
||||
|
||||
@override
|
||||
InterfaceType getConstantMapTypeFor(InterfaceType sourceType,
|
||||
|
@ -1039,11 +1043,11 @@ class CommonElementsImpl
|
|||
ClassEntity classElement = onlyStringKeys
|
||||
? (hasProtoKey ? constantProtoMapClass : constantStringMapClass)
|
||||
: generalConstantMapClass;
|
||||
List<DartType> typeArgument = sourceType.typeArguments;
|
||||
if (dartTypes.treatAsRawType(sourceType)) {
|
||||
return _env.getRawType(classElement);
|
||||
} else {
|
||||
return _env.createInterfaceType(classElement, typeArgument);
|
||||
return _env.createInterfaceType(
|
||||
classElement, sourceType.typeArguments, sourceType.nullability);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1051,8 +1055,8 @@ class CommonElementsImpl
|
|||
InterfaceType getConstantSetTypeFor(InterfaceType sourceType) =>
|
||||
dartTypes.treatAsRawType(sourceType)
|
||||
? _env.getRawType(constSetLiteralClass)
|
||||
: _env.createInterfaceType(
|
||||
constSetLiteralClass, sourceType.typeArguments);
|
||||
: _env.createInterfaceType(constSetLiteralClass,
|
||||
sourceType.typeArguments, sourceType.nullability);
|
||||
|
||||
@override
|
||||
FieldEntity get symbolField => symbolImplementationField;
|
||||
|
@ -2285,9 +2289,10 @@ abstract class ElementEnvironment {
|
|||
/// Calls [f] for each supertype of [cls].
|
||||
void forEachSupertype(ClassEntity cls, void f(InterfaceType supertype));
|
||||
|
||||
/// Create the instantiation of [cls] with the given [typeArguments].
|
||||
/// Create the instantiation of [cls] with the given [typeArguments] and
|
||||
/// [nullability].
|
||||
InterfaceType createInterfaceType(
|
||||
ClassEntity cls, List<DartType> typeArguments);
|
||||
ClassEntity cls, List<DartType> typeArguments, Nullability nullability);
|
||||
|
||||
/// Returns the `dynamic` type.
|
||||
DartType get dynamicType;
|
||||
|
|
|
@ -142,8 +142,8 @@ SetConstantValue createSet(CommonElements commonElements,
|
|||
InterfaceType sourceType, List<ConstantValue> values) {
|
||||
InterfaceType type = commonElements.getConstantSetTypeFor(sourceType);
|
||||
DartType elementType = type.typeArguments.first;
|
||||
InterfaceType mapType =
|
||||
commonElements.mapType(elementType, commonElements.nullType);
|
||||
InterfaceType mapType = commonElements.mapType(
|
||||
Nullability.none, elementType, commonElements.nullType);
|
||||
List<NullConstantValue> nulls = new List<NullConstantValue>.filled(
|
||||
values.length, const NullConstantValue());
|
||||
MapConstantValue entries = createMap(commonElements, mapType, values, nulls);
|
||||
|
@ -174,9 +174,10 @@ MapConstantValue createMap(
|
|||
bool hasProtoKey = (protoValue != null);
|
||||
InterfaceType keysType;
|
||||
if (commonElements.dartTypes.treatAsRawType(sourceType)) {
|
||||
keysType = commonElements.listType();
|
||||
keysType = commonElements.listType(Nullability.none);
|
||||
} else {
|
||||
keysType = commonElements.listType(sourceType.typeArguments.first);
|
||||
keysType = commonElements.listType(
|
||||
Nullability.none, sourceType.typeArguments.first);
|
||||
}
|
||||
ListConstantValue keysList = createList(commonElements, keysType, keys);
|
||||
InterfaceType type = commonElements.getConstantMapTypeFor(sourceType,
|
||||
|
|
|
@ -1049,7 +1049,7 @@ class InstantiationConstantValue extends ConstantValue {
|
|||
@override
|
||||
DartType getType(CommonElements types) {
|
||||
FunctionType type = function.getType(types);
|
||||
return type.instantiate(typeArguments);
|
||||
return types.dartTypes.instantiate(type, typeArguments);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
import '../common/names.dart';
|
||||
import '../common_elements.dart';
|
||||
import '../serialization/serialization.dart';
|
||||
import '../util/util.dart' show equalElements;
|
||||
import 'entities.dart';
|
||||
|
||||
|
@ -38,17 +39,87 @@ extension NullabilityUtils on Nullability {
|
|||
int compareTo(Nullability other) => index.compareTo(other.index);
|
||||
}
|
||||
|
||||
abstract class DartType {
|
||||
final Nullability nullability;
|
||||
extension on DataSource {
|
||||
List<DartType> _readDartTypes(
|
||||
List<FunctionTypeVariable> functionTypeVariables) {
|
||||
int count = readInt();
|
||||
List<DartType> types = List<DartType>(count);
|
||||
for (int index = 0; index < count; index++) {
|
||||
types[index] = DartType.readFromDataSource(this, functionTypeVariables);
|
||||
}
|
||||
return types;
|
||||
}
|
||||
}
|
||||
|
||||
const DartType(this.nullability);
|
||||
extension on DataSink {
|
||||
void _writeDartTypes(
|
||||
List<DartType> types, List<FunctionTypeVariable> functionTypeVariables) {
|
||||
writeInt(types.length);
|
||||
for (DartType type in types) {
|
||||
type.writeToDataSink(this, functionTypeVariables);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract class DartType {
|
||||
Nullability get nullability;
|
||||
|
||||
const DartType();
|
||||
|
||||
factory DartType.readFromDataSource(
|
||||
DataSource source, List<FunctionTypeVariable> functionTypeVariables) {
|
||||
DartTypeKind kind = source.readEnum(DartTypeKind.values);
|
||||
switch (kind) {
|
||||
case DartTypeKind.none:
|
||||
return null;
|
||||
case DartTypeKind.neverType:
|
||||
return NeverType._readFromDataSource(source, functionTypeVariables);
|
||||
case DartTypeKind.voidType:
|
||||
return VoidType._readFromDataSource(source, functionTypeVariables);
|
||||
case DartTypeKind.typeVariable:
|
||||
return TypeVariableType._readFromDataSource(
|
||||
source, functionTypeVariables);
|
||||
case DartTypeKind.functionTypeVariable:
|
||||
return FunctionTypeVariable._readFromDataSource(
|
||||
source, functionTypeVariables);
|
||||
case DartTypeKind.functionType:
|
||||
return FunctionType._readFromDataSource(source, functionTypeVariables);
|
||||
case DartTypeKind.interfaceType:
|
||||
return InterfaceType._readFromDataSource(source, functionTypeVariables);
|
||||
case DartTypeKind.dynamicType:
|
||||
return DynamicType._readFromDataSource(source, functionTypeVariables);
|
||||
case DartTypeKind.erasedType:
|
||||
return ErasedType._readFromDataSource(source, functionTypeVariables);
|
||||
case DartTypeKind.anyType:
|
||||
return AnyType._readFromDataSource(source, functionTypeVariables);
|
||||
case DartTypeKind.futureOr:
|
||||
return FutureOrType._readFromDataSource(source, functionTypeVariables);
|
||||
}
|
||||
throw UnsupportedError('Unexpected DartTypeKind $kind');
|
||||
}
|
||||
|
||||
void writeToDataSink(
|
||||
DataSink sink, List<FunctionTypeVariable> functionTypeVariables);
|
||||
|
||||
/// Returns a new type formed by replacing the current [nullability] with the
|
||||
/// specified one.
|
||||
///
|
||||
/// Caution: This directly manipulates the type without renormalizing.
|
||||
DartType _withNullability(Nullability nullability);
|
||||
|
||||
DartType _withoutNullability() => _withNullability(Nullability.none);
|
||||
DartType _withQuestion() => _withNullability(Nullability.question);
|
||||
/// Returns a new type formed by removing the [nullability] suffix from this
|
||||
/// type.
|
||||
DartType get _toNonNullable => _withNullability(Nullability.none);
|
||||
|
||||
/// Returns a new type formed by replacing the [nullability] suffix on this
|
||||
/// type with [Nullability.question].
|
||||
/// Caution: This directly manipulates the type without renormalizing.
|
||||
DartType get _toNullable => _withNullability(Nullability.question);
|
||||
|
||||
/// Returns a new type formed by replacing the [nullability] suffix on this
|
||||
/// type with [Nullability.star].
|
||||
/// Caution: This directly manipulates the type without renormalizing.
|
||||
DartType get _toLegacy => _withNullability(Nullability.star);
|
||||
|
||||
/// Is `true` if this type is a top type.
|
||||
bool _isTop(bool useNullSafety) => false;
|
||||
|
@ -81,22 +152,6 @@ abstract class DartType {
|
|||
/// type. This excludes function type variables, whether free or bound.
|
||||
void forEachTypeVariable(f(TypeVariableType variable)) {}
|
||||
|
||||
/// Performs the substitution `[arguments[i]/parameters[i]]this`.
|
||||
///
|
||||
/// The notation is known from this lambda calculus rule:
|
||||
///
|
||||
/// (lambda x.e0)e1 -> [e1/x]e0.
|
||||
///
|
||||
/// See [TypeVariableType] for a motivation for this method.
|
||||
///
|
||||
/// Invariant: There must be the same number of [arguments] and [parameters].
|
||||
DartType subst(List<DartType> arguments, List<DartType> parameters) {
|
||||
assert(arguments.length == parameters.length);
|
||||
if (parameters.isEmpty) return this;
|
||||
return SimpleDartTypeSubstitutionVisitor(arguments, parameters)
|
||||
.substitute(this);
|
||||
}
|
||||
|
||||
/// Calls the visit method on [visitor] corresponding to this type.
|
||||
R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument);
|
||||
|
||||
|
@ -184,14 +239,32 @@ class _Assumptions {
|
|||
class InterfaceType extends DartType {
|
||||
final ClassEntity element;
|
||||
final List<DartType> typeArguments;
|
||||
@override
|
||||
final Nullability nullability;
|
||||
|
||||
InterfaceType(this.element, this.typeArguments, Nullability nullability)
|
||||
: assert(typeArguments.every((e) => e != null)),
|
||||
super(nullability);
|
||||
InterfaceType._(this.element, this.typeArguments, this.nullability)
|
||||
: assert(typeArguments.every((e) => e != null));
|
||||
|
||||
factory InterfaceType._readFromDataSource(
|
||||
DataSource source, List<FunctionTypeVariable> functionTypeVariables) {
|
||||
ClassEntity element = source.readClass();
|
||||
List<DartType> typeArguments = source._readDartTypes(functionTypeVariables);
|
||||
Nullability nullability = source.readEnum(Nullability.values);
|
||||
return InterfaceType._(element, typeArguments, nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
void writeToDataSink(
|
||||
DataSink sink, List<FunctionTypeVariable> functionTypeVariables) {
|
||||
sink.writeEnum(DartTypeKind.interfaceType);
|
||||
sink.writeClass(element);
|
||||
sink._writeDartTypes(typeArguments, functionTypeVariables);
|
||||
sink.writeEnum(nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
DartType _withNullability(Nullability nullability) =>
|
||||
InterfaceType(element, typeArguments, nullability);
|
||||
InterfaceType._(element, typeArguments, nullability);
|
||||
|
||||
@override
|
||||
bool _isTop(bool useNullSafety) =>
|
||||
|
@ -265,13 +338,29 @@ class InterfaceType extends DartType {
|
|||
|
||||
class TypeVariableType extends DartType {
|
||||
final TypeVariableEntity element;
|
||||
@override
|
||||
final Nullability nullability;
|
||||
|
||||
const TypeVariableType(this.element, Nullability nullability)
|
||||
: super(nullability);
|
||||
const TypeVariableType._(this.element, this.nullability);
|
||||
|
||||
factory TypeVariableType._readFromDataSource(
|
||||
DataSource source, List<FunctionTypeVariable> functionTypeVariables) {
|
||||
TypeVariableEntity element = source.readTypeVariable();
|
||||
Nullability nullability = source.readEnum(Nullability.values);
|
||||
return TypeVariableType._(element, nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
void writeToDataSink(
|
||||
DataSink sink, List<FunctionTypeVariable> functionTypeVariables) {
|
||||
sink.writeEnum(DartTypeKind.typeVariable);
|
||||
sink.writeTypeVariable(element);
|
||||
sink.writeEnum(nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
DartType _withNullability(Nullability nullability) =>
|
||||
TypeVariableType(element, nullability);
|
||||
TypeVariableType._(element, nullability);
|
||||
|
||||
@override
|
||||
bool get containsTypeVariables => true;
|
||||
|
@ -313,15 +402,37 @@ class FunctionTypeVariable extends DartType {
|
|||
/// type.
|
||||
final int index;
|
||||
|
||||
@override
|
||||
final Nullability nullability;
|
||||
|
||||
/// The bound of this function type variable.
|
||||
DartType _bound;
|
||||
|
||||
FunctionTypeVariable(this.index, Nullability nullability)
|
||||
: super(nullability);
|
||||
FunctionTypeVariable._(this.index, this.nullability);
|
||||
|
||||
factory FunctionTypeVariable._readFromDataSource(
|
||||
DataSource source, List<FunctionTypeVariable> functionTypeVariables) {
|
||||
int index = source.readInt();
|
||||
assert(0 <= index && index < functionTypeVariables.length);
|
||||
return functionTypeVariables[index];
|
||||
}
|
||||
|
||||
@override
|
||||
void writeToDataSink(
|
||||
DataSink sink, List<FunctionTypeVariable> functionTypeVariables) {
|
||||
int index = functionTypeVariables.indexOf(this);
|
||||
if (index == -1) {
|
||||
// TODO(johnniwinther): Avoid free variables.
|
||||
const DynamicType._().writeToDataSink(sink, functionTypeVariables);
|
||||
} else {
|
||||
sink.writeEnum(DartTypeKind.functionTypeVariable);
|
||||
sink.writeInt(index);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
DartType _withNullability(Nullability nullability) =>
|
||||
FunctionTypeVariable(index, nullability)..bound = bound;
|
||||
FunctionTypeVariable._(index, nullability)..bound = bound;
|
||||
|
||||
DartType get bound {
|
||||
assert(_bound != null, "Bound has not been set.");
|
||||
|
@ -348,10 +459,27 @@ class FunctionTypeVariable extends DartType {
|
|||
}
|
||||
|
||||
class NeverType extends DartType {
|
||||
const NeverType(Nullability nullability) : super(nullability);
|
||||
@override
|
||||
final Nullability nullability;
|
||||
|
||||
const NeverType._(this.nullability);
|
||||
|
||||
factory NeverType._readFromDataSource(
|
||||
DataSource source, List<FunctionTypeVariable> functionTypeVariables) {
|
||||
Nullability nullability = source.readEnum(Nullability.values);
|
||||
return NeverType._(nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
DartType _withNullability(Nullability nullability) => NeverType(nullability);
|
||||
void writeToDataSink(
|
||||
DataSink sink, List<FunctionTypeVariable> functionTypeVariables) {
|
||||
sink.writeEnum(DartTypeKind.neverType);
|
||||
sink.writeEnum(nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
DartType _withNullability(Nullability nullability) =>
|
||||
NeverType._(nullability);
|
||||
|
||||
@override
|
||||
R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
|
||||
|
@ -370,9 +498,20 @@ class NeverType extends DartType {
|
|||
}
|
||||
|
||||
class VoidType extends DartType {
|
||||
const VoidType._() : super(Nullability.none);
|
||||
const VoidType._();
|
||||
|
||||
factory VoidType() => const VoidType._();
|
||||
factory VoidType._readFromDataSource(DataSource source,
|
||||
List<FunctionTypeVariable> functionTypeVariables) =>
|
||||
const VoidType._();
|
||||
|
||||
@override
|
||||
void writeToDataSink(
|
||||
DataSink sink, List<FunctionTypeVariable> functionTypeVariables) {
|
||||
sink.writeEnum(DartTypeKind.voidType);
|
||||
}
|
||||
|
||||
@override
|
||||
Nullability get nullability => Nullability.none;
|
||||
|
||||
@override
|
||||
DartType _withNullability(Nullability nullability) => this;
|
||||
|
@ -395,9 +534,20 @@ class VoidType extends DartType {
|
|||
}
|
||||
|
||||
class DynamicType extends DartType {
|
||||
const DynamicType._() : super(Nullability.none);
|
||||
const DynamicType._();
|
||||
|
||||
factory DynamicType() => const DynamicType._();
|
||||
factory DynamicType._readFromDataSource(DataSource source,
|
||||
List<FunctionTypeVariable> functionTypeVariables) =>
|
||||
const DynamicType._();
|
||||
|
||||
@override
|
||||
void writeToDataSink(
|
||||
DataSink sink, List<FunctionTypeVariable> functionTypeVariables) {
|
||||
sink.writeEnum(DartTypeKind.dynamicType);
|
||||
}
|
||||
|
||||
@override
|
||||
Nullability get nullability => Nullability.none;
|
||||
|
||||
@override
|
||||
DartType _withNullability(Nullability nullability) => this;
|
||||
|
@ -420,9 +570,20 @@ class DynamicType extends DartType {
|
|||
}
|
||||
|
||||
class ErasedType extends DartType {
|
||||
const ErasedType._() : super(Nullability.none);
|
||||
const ErasedType._();
|
||||
|
||||
factory ErasedType() => const ErasedType._();
|
||||
factory ErasedType._readFromDataSource(DataSource source,
|
||||
List<FunctionTypeVariable> functionTypeVariables) =>
|
||||
const ErasedType._();
|
||||
|
||||
@override
|
||||
void writeToDataSink(
|
||||
DataSink sink, List<FunctionTypeVariable> functionTypeVariables) {
|
||||
sink.writeEnum(DartTypeKind.erasedType);
|
||||
}
|
||||
|
||||
@override
|
||||
Nullability get nullability => Nullability.none;
|
||||
|
||||
@override
|
||||
DartType _withNullability(Nullability nullability) => this;
|
||||
|
@ -456,9 +617,20 @@ class ErasedType extends DartType {
|
|||
/// * Representing types appearing as generic method bounds which contain type
|
||||
/// variables. (See issue 33422.)
|
||||
class AnyType extends DartType {
|
||||
const AnyType._() : super(Nullability.none);
|
||||
const AnyType._();
|
||||
|
||||
factory AnyType() => const AnyType._();
|
||||
factory AnyType._readFromDataSource(DataSource source,
|
||||
List<FunctionTypeVariable> functionTypeVariables) =>
|
||||
const AnyType._();
|
||||
|
||||
@override
|
||||
void writeToDataSink(
|
||||
DataSink sink, List<FunctionTypeVariable> functionTypeVariables) {
|
||||
sink.writeEnum(DartTypeKind.anyType);
|
||||
}
|
||||
|
||||
@override
|
||||
Nullability get nullability => Nullability.none;
|
||||
|
||||
@override
|
||||
DartType _withNullability(Nullability nullability) => this;
|
||||
|
@ -494,15 +666,17 @@ class FunctionType extends DartType {
|
|||
|
||||
final List<FunctionTypeVariable> typeVariables;
|
||||
|
||||
FunctionType(
|
||||
@override
|
||||
final Nullability nullability;
|
||||
|
||||
FunctionType._(
|
||||
this.returnType,
|
||||
this.parameterTypes,
|
||||
this.optionalParameterTypes,
|
||||
this.namedParameters,
|
||||
this.namedParameterTypes,
|
||||
this.typeVariables,
|
||||
Nullability nullability)
|
||||
: super(nullability) {
|
||||
this.nullability) {
|
||||
assert(returnType != null, "Invalid return type in $this.");
|
||||
assert(!parameterTypes.contains(null), "Invalid parameter types in $this.");
|
||||
assert(!optionalParameterTypes.contains(null),
|
||||
|
@ -514,8 +688,62 @@ class FunctionType extends DartType {
|
|||
assert(!typeVariables.contains(null), "Invalid type variables in $this.");
|
||||
}
|
||||
|
||||
factory FunctionType._readFromDataSource(
|
||||
DataSource source, List<FunctionTypeVariable> functionTypeVariables) {
|
||||
int typeVariableCount = source.readInt();
|
||||
List<FunctionTypeVariable> typeVariables =
|
||||
List<FunctionTypeVariable>.generate(typeVariableCount, (int index) {
|
||||
Nullability nullability = source.readEnum(Nullability.values);
|
||||
return FunctionTypeVariable._(index, nullability);
|
||||
});
|
||||
functionTypeVariables = List<FunctionTypeVariable>.of(functionTypeVariables)
|
||||
..addAll(typeVariables);
|
||||
for (int index = 0; index < typeVariableCount; index++) {
|
||||
typeVariables[index].bound =
|
||||
DartType.readFromDataSource(source, functionTypeVariables);
|
||||
}
|
||||
DartType returnType =
|
||||
DartType.readFromDataSource(source, functionTypeVariables);
|
||||
List<DartType> parameterTypes =
|
||||
source._readDartTypes(functionTypeVariables);
|
||||
List<DartType> optionalParameterTypes =
|
||||
source._readDartTypes(functionTypeVariables);
|
||||
List<DartType> namedParameterTypes =
|
||||
source._readDartTypes(functionTypeVariables);
|
||||
List<String> namedParameters = List<String>(namedParameterTypes.length);
|
||||
for (int i = 0; i < namedParameters.length; i++) {
|
||||
namedParameters[i] = source.readString();
|
||||
}
|
||||
Nullability nullability = source.readEnum(Nullability.values);
|
||||
return FunctionType._(returnType, parameterTypes, optionalParameterTypes,
|
||||
namedParameters, namedParameterTypes, typeVariables, nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
DartType _withNullability(Nullability nullability) => FunctionType(
|
||||
void writeToDataSink(
|
||||
DataSink sink, List<FunctionTypeVariable> functionTypeVariables) {
|
||||
sink.writeEnum(DartTypeKind.functionType);
|
||||
functionTypeVariables = List<FunctionTypeVariable>.of(functionTypeVariables)
|
||||
..addAll(typeVariables);
|
||||
sink.writeInt(typeVariables.length);
|
||||
for (FunctionTypeVariable variable in typeVariables) {
|
||||
sink.writeEnum(variable.nullability);
|
||||
}
|
||||
for (FunctionTypeVariable variable in typeVariables) {
|
||||
variable.bound.writeToDataSink(sink, functionTypeVariables);
|
||||
}
|
||||
returnType.writeToDataSink(sink, functionTypeVariables);
|
||||
sink._writeDartTypes(parameterTypes, functionTypeVariables);
|
||||
sink._writeDartTypes(optionalParameterTypes, functionTypeVariables);
|
||||
sink._writeDartTypes(namedParameterTypes, functionTypeVariables);
|
||||
for (String namedParameter in namedParameters) {
|
||||
sink.writeString(namedParameter);
|
||||
}
|
||||
sink.writeEnum(nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
DartType _withNullability(Nullability nullability) => FunctionType._(
|
||||
returnType,
|
||||
parameterTypes,
|
||||
optionalParameterTypes,
|
||||
|
@ -542,10 +770,6 @@ class FunctionType extends DartType {
|
|||
namedParameterTypes.forEach((type) => type.forEachTypeVariable(f));
|
||||
}
|
||||
|
||||
FunctionType instantiate(List<DartType> arguments) {
|
||||
return subst(arguments, typeVariables);
|
||||
}
|
||||
|
||||
@override
|
||||
R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
|
||||
visitor.visitFunctionType(this, argument);
|
||||
|
@ -612,12 +836,30 @@ class FunctionType extends DartType {
|
|||
class FutureOrType extends DartType {
|
||||
final DartType typeArgument;
|
||||
|
||||
const FutureOrType(this.typeArgument, Nullability nullability)
|
||||
: super(nullability);
|
||||
@override
|
||||
final Nullability nullability;
|
||||
|
||||
const FutureOrType._(this.typeArgument, this.nullability);
|
||||
|
||||
factory FutureOrType._readFromDataSource(
|
||||
DataSource source, List<FunctionTypeVariable> functionTypeVariables) {
|
||||
DartType typeArgument =
|
||||
DartType.readFromDataSource(source, functionTypeVariables);
|
||||
Nullability nullability = source.readEnum(Nullability.values);
|
||||
return FutureOrType._(typeArgument, nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
void writeToDataSink(
|
||||
DataSink sink, List<FunctionTypeVariable> functionTypeVariables) {
|
||||
sink.writeEnum(DartTypeKind.futureOr);
|
||||
typeArgument.writeToDataSink(sink, functionTypeVariables);
|
||||
sink.writeEnum(nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
DartType _withNullability(Nullability nullability) =>
|
||||
FutureOrType(typeArgument, nullability);
|
||||
FutureOrType._(typeArgument, nullability);
|
||||
|
||||
@override
|
||||
bool get containsTypeVariables => typeArgument.containsTypeVariables;
|
||||
|
@ -741,6 +983,8 @@ abstract class BaseDartTypeVisitor<R, A> extends DartTypeVisitor<R, A> {
|
|||
|
||||
abstract class DartTypeSubstitutionVisitor<A>
|
||||
extends DartTypeVisitor<DartType, A> {
|
||||
DartTypes get dartTypes;
|
||||
|
||||
// The input type is a DAG and we must preserve the sharing.
|
||||
Map<DartType, DartType> _map = Map.identity();
|
||||
|
||||
|
@ -813,16 +1057,30 @@ abstract class DartTypeSubstitutionVisitor<A>
|
|||
return _mapped(type, type);
|
||||
}
|
||||
|
||||
List<FunctionTypeVariable> normalizableVariables = [];
|
||||
for (int i = 0; i < newTypeVariables.length; i++) {
|
||||
FunctionTypeVariable t = newTypeVariables[i];
|
||||
if (identical(t, type.typeVariables[i])) continue;
|
||||
DartType bound = t.bound;
|
||||
if (bound.nullability.isNone && bound is NeverType) {
|
||||
normalizableVariables.add(t);
|
||||
}
|
||||
}
|
||||
|
||||
return _mapped(
|
||||
type,
|
||||
FunctionType(
|
||||
newReturnType,
|
||||
newParameterTypes,
|
||||
newOptionalParameterTypes,
|
||||
type.namedParameters,
|
||||
newNamedParameterTypes,
|
||||
newTypeVariables,
|
||||
type.nullability));
|
||||
dartTypes.subst(
|
||||
List<DartType>.filled(normalizableVariables.length,
|
||||
dartTypes.neverType(Nullability.none)),
|
||||
normalizableVariables,
|
||||
dartTypes.functionType(
|
||||
newReturnType,
|
||||
newParameterTypes,
|
||||
newOptionalParameterTypes,
|
||||
type.namedParameters,
|
||||
newNamedParameterTypes,
|
||||
newTypeVariables,
|
||||
type.nullability)));
|
||||
}
|
||||
|
||||
List<FunctionTypeVariable> _handleFunctionTypeVariables(
|
||||
|
@ -870,8 +1128,8 @@ abstract class DartTypeSubstitutionVisitor<A>
|
|||
changed = true;
|
||||
undecided[i] = null;
|
||||
newVariables ??= variables.toList();
|
||||
FunctionTypeVariable newVariable =
|
||||
FunctionTypeVariable(variable.index, variable.nullability);
|
||||
FunctionTypeVariable newVariable = dartTypes.functionTypeVariable(
|
||||
variable.index, variable.nullability);
|
||||
newVariables[i] = newVariable;
|
||||
_mapped(variable, newVariable);
|
||||
}
|
||||
|
@ -906,7 +1164,9 @@ abstract class DartTypeSubstitutionVisitor<A>
|
|||
return _mapped(type, type);
|
||||
}
|
||||
return _mapped(
|
||||
type, InterfaceType(type.element, newTypeArguments, type.nullability));
|
||||
type,
|
||||
dartTypes.interfaceType(
|
||||
type.element, newTypeArguments, type.nullability));
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -928,7 +1188,8 @@ abstract class DartTypeSubstitutionVisitor<A>
|
|||
if (identical(type.typeArgument, newTypeArgument)) {
|
||||
return _mapped(type, type);
|
||||
}
|
||||
return _mapped(type, FutureOrType(newTypeArgument, type.nullability));
|
||||
return _mapped(
|
||||
type, dartTypes.futureOrType(newTypeArgument, type.nullability));
|
||||
}
|
||||
|
||||
List<DartType> _substTypes(List<DartType> types, A argument) {
|
||||
|
@ -1080,10 +1341,13 @@ class _ContainsFreeTypeVariablesVisitor
|
|||
|
||||
class SimpleDartTypeSubstitutionVisitor
|
||||
extends DartTypeSubstitutionVisitor<Null> {
|
||||
@override
|
||||
final DartTypes dartTypes;
|
||||
final List<DartType> arguments;
|
||||
final List<DartType> parameters;
|
||||
|
||||
SimpleDartTypeSubstitutionVisitor(this.arguments, this.parameters);
|
||||
SimpleDartTypeSubstitutionVisitor(
|
||||
this.dartTypes, this.arguments, this.parameters);
|
||||
|
||||
DartType substitute(DartType input) => visit(input, null);
|
||||
|
||||
|
@ -1346,6 +1610,126 @@ abstract class DartTypes {
|
|||
bool get useNullSafety;
|
||||
bool get useLegacySubtyping;
|
||||
|
||||
DartType interfaceType(ClassEntity element, List<DartType> typeArguments,
|
||||
Nullability nullability) =>
|
||||
_normalizeNullability(
|
||||
InterfaceType._(element, typeArguments, Nullability.none),
|
||||
nullability);
|
||||
|
||||
// Since all [TypeVariableType] bounds come from the CFE, we assume that no
|
||||
// bound will ever be `Never` (or else the CFE would have already normalized
|
||||
// the type variable to `Never`). Therefore, we can skip normalization.
|
||||
TypeVariableType typeVariableType(
|
||||
TypeVariableEntity element, Nullability nullability) =>
|
||||
TypeVariableType._(element, nullability);
|
||||
|
||||
// We normalize when we substitute function types.
|
||||
DartType functionTypeVariable(int index, Nullability nullability) =>
|
||||
FunctionTypeVariable._(index, nullability);
|
||||
|
||||
DartType neverType(Nullability nullability) => nullability.isQuestion
|
||||
? commonElements.nullType
|
||||
: NeverType._(nullability);
|
||||
|
||||
VoidType voidType() => const VoidType._();
|
||||
|
||||
DynamicType dynamicType() => const DynamicType._();
|
||||
|
||||
ErasedType erasedType() => const ErasedType._();
|
||||
|
||||
AnyType anyType() => const AnyType._();
|
||||
|
||||
FunctionType functionType(
|
||||
DartType returnType,
|
||||
List<DartType> parameterTypes,
|
||||
List<DartType> optionalParameterTypes,
|
||||
List<String> namedParameters,
|
||||
List<DartType> namedParameterTypes,
|
||||
List<FunctionTypeVariable> typeVariables,
|
||||
Nullability nullability) =>
|
||||
FunctionType._(returnType, parameterTypes, optionalParameterTypes,
|
||||
namedParameters, namedParameterTypes, typeVariables, nullability);
|
||||
|
||||
DartType futureOrType(DartType typeArgument, Nullability nullability) {
|
||||
DartType result;
|
||||
if (isTopType(typeArgument) || typeArgument.isObject) {
|
||||
result = typeArgument;
|
||||
} else if (typeArgument is NeverType) {
|
||||
result = commonElements.futureType(
|
||||
Nullability.none, neverType(Nullability.none));
|
||||
} else if (typeArgument.isNull) {
|
||||
result = commonElements.futureType(
|
||||
useNullSafety ? Nullability.question : Nullability.none,
|
||||
commonElements.nullType);
|
||||
} else {
|
||||
result = FutureOrType._(typeArgument, nullability);
|
||||
}
|
||||
return _normalizeNullability(result, nullability);
|
||||
}
|
||||
|
||||
DartType _normalizeNullability(DartType t, Nullability nullability) {
|
||||
switch (nullability) {
|
||||
case Nullability.question:
|
||||
return _normalizeQuestionOf(t);
|
||||
case Nullability.star:
|
||||
return _normalizeStarOf(t);
|
||||
default:
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
DartType _normalizeQuestionOf(DartType t) {
|
||||
bool _isNullable(DartType t) =>
|
||||
// Note that we can assume NNBD is enabled here.
|
||||
t.isNull ||
|
||||
t.nullability.isQuestion ||
|
||||
_isStrongTopType(t) ||
|
||||
t is FutureOrType && _isNullable(t.typeArgument);
|
||||
|
||||
DartType result;
|
||||
if (t.isNull || t.nullability.isQuestion || _isStrongTopType(t)) {
|
||||
result = t;
|
||||
} else if (t is NeverType) {
|
||||
result = commonElements.nullType;
|
||||
} else if (t is FutureOrType && _isNullable(t.typeArgument)) {
|
||||
result = t.nullability.isStar ? t._toNonNullable : t;
|
||||
} else {
|
||||
result = t._toNullable;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DartType _normalizeStarOf(DartType t) {
|
||||
DartType result;
|
||||
if (t.isNull || t.nullability.isPotentiallyNull || isTopType(t)) {
|
||||
result = t;
|
||||
} else {
|
||||
result = t._toLegacy;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Performs the substitution `[arguments[i]/parameters[i]]t`.
|
||||
///
|
||||
/// The notation is known from this lambda calculus rule:
|
||||
///
|
||||
/// (lambda x.e0)e1 -> [e1/x]e0.
|
||||
///
|
||||
/// See [TypeVariableType] for a motivation for this method.
|
||||
///
|
||||
/// Invariant: There must be the same number of [arguments] and [parameters].
|
||||
DartType subst(
|
||||
List<DartType> arguments, List<DartType> parameters, DartType t) {
|
||||
assert(arguments.length == parameters.length);
|
||||
if (parameters.isEmpty) return t;
|
||||
return SimpleDartTypeSubstitutionVisitor(this, arguments, parameters)
|
||||
.substitute(t);
|
||||
}
|
||||
|
||||
DartType instantiate(FunctionType t, List<DartType> arguments) {
|
||||
return subst(arguments, t.typeVariables, t);
|
||||
}
|
||||
|
||||
// TODO(fishythefish): Clean up all uses of [defaultNullability].
|
||||
Nullability get defaultNullability =>
|
||||
useNullSafety ? Nullability.star : Nullability.none;
|
||||
|
@ -1442,21 +1826,23 @@ abstract class DartTypes {
|
|||
return _isSubtype(s.typeArgument, t, env);
|
||||
}
|
||||
if (s.nullability.isStar) {
|
||||
return _isSubtype(s._withoutNullability(), t, env);
|
||||
return _isSubtype(s._toNonNullable, t, env);
|
||||
}
|
||||
return !s.nullability.isQuestion;
|
||||
}
|
||||
|
||||
// Left Legacy:
|
||||
if (s.nullability.isStar) {
|
||||
return _isSubtype(s._withoutNullability(), t, env);
|
||||
return _isSubtype(s._toNonNullable, t, env);
|
||||
}
|
||||
|
||||
// Right Legacy:
|
||||
if (t.nullability.isStar) {
|
||||
// Note that to convert `T*` to `T?`, we can't just say `t._toNullable`.
|
||||
// The resulting type `T?` may be normalizable (e.g. if `T` is `Never`).
|
||||
return _isSubtype(
|
||||
s,
|
||||
useLegacySubtyping ? t._withoutNullability() : t._withQuestion(),
|
||||
useLegacySubtyping ? t._toNonNullable : _normalizeQuestionOf(t),
|
||||
env);
|
||||
}
|
||||
|
||||
|
@ -1464,14 +1850,17 @@ abstract class DartTypes {
|
|||
if (s is FutureOrType && s.nullability.isNone) {
|
||||
DartType typeArgument = s.typeArgument;
|
||||
return _isSubtype(typeArgument, t, env) &&
|
||||
_isSubtype(commonElements.futureType(typeArgument), t, env);
|
||||
_isSubtype(
|
||||
commonElements.futureType(Nullability.none, typeArgument),
|
||||
t,
|
||||
env);
|
||||
}
|
||||
|
||||
// Left Nullable:
|
||||
if (s.nullability.isQuestion) {
|
||||
return (useLegacySubtyping ||
|
||||
_isSubtype(commonElements.nullType, t, env)) &&
|
||||
_isSubtype(s._withoutNullability(), t, env);
|
||||
_isSubtype(s._toNonNullable, t, env);
|
||||
}
|
||||
|
||||
// Type Variable Reflexivity 1 is subsumed by Reflexivity and therefore
|
||||
|
@ -1485,14 +1874,15 @@ abstract class DartTypes {
|
|||
if (t is FutureOrType && t.nullability.isNone) {
|
||||
DartType typeArgument = t.typeArgument;
|
||||
return _isSubtype(s, typeArgument, env) ||
|
||||
_isSubtype(s, commonElements.futureType(typeArgument), env);
|
||||
_isSubtype(s,
|
||||
commonElements.futureType(Nullability.none, typeArgument), env);
|
||||
}
|
||||
|
||||
// Right Nullable:
|
||||
if (t.nullability.isQuestion) {
|
||||
return (!useLegacySubtyping &&
|
||||
_isSubtype(s, commonElements.nullType, env)) ||
|
||||
_isSubtype(s, t._withoutNullability(), env);
|
||||
_isSubtype(s, t._toNonNullable, env);
|
||||
}
|
||||
|
||||
// Left Promoted Variable does not apply because we do not represent
|
||||
|
|
|
@ -48,6 +48,8 @@ class KernelTypeGraphBuilder extends ir.Visitor<TypeInformation> {
|
|||
final GlobalTypeInferenceElementData _memberData;
|
||||
final bool _inGenerativeConstructor;
|
||||
|
||||
DartTypes get _dartTypes => _closedWorld.dartTypes;
|
||||
|
||||
LocalState _stateInternal;
|
||||
LocalState _stateAfterWhenTrueInternal;
|
||||
LocalState _stateAfterWhenFalseInternal;
|
||||
|
@ -1705,7 +1707,7 @@ class KernelTypeGraphBuilder extends ir.Visitor<TypeInformation> {
|
|||
TypeInformation mask;
|
||||
DartType type = node.guard != null
|
||||
? _elementMap.getDartType(node.guard)
|
||||
: DynamicType();
|
||||
: _dartTypes.dynamicType();
|
||||
if (type is InterfaceType) {
|
||||
InterfaceType interfaceType = type;
|
||||
mask = _types.nonNullSubtype(interfaceType.element);
|
||||
|
@ -1713,8 +1715,8 @@ class KernelTypeGraphBuilder extends ir.Visitor<TypeInformation> {
|
|||
mask = _types.dynamicType;
|
||||
}
|
||||
Local local = _localsMap.getLocalVariable(exception);
|
||||
_state.updateLocal(
|
||||
_inferrer, _capturedAndBoxed, local, mask, node, DynamicType(),
|
||||
_state.updateLocal(_inferrer, _capturedAndBoxed, local, mask, node,
|
||||
_dartTypes.dynamicType(),
|
||||
isNullable: false /* `throw null` produces a NullThrownError */);
|
||||
}
|
||||
ir.VariableDeclaration stackTrace = node.stackTrace;
|
||||
|
@ -1724,7 +1726,7 @@ class KernelTypeGraphBuilder extends ir.Visitor<TypeInformation> {
|
|||
// Note: stack trace may be null if users omit a stack in
|
||||
// `completer.completeError`.
|
||||
_state.updateLocal(_inferrer, _capturedAndBoxed, local,
|
||||
_types.dynamicType, node, DynamicType());
|
||||
_types.dynamicType, node, _dartTypes.dynamicType());
|
||||
}
|
||||
visit(node.body);
|
||||
return null;
|
||||
|
|
|
@ -43,9 +43,9 @@ abstract class IrToElementMap {
|
|||
FunctionType getFunctionType(ir.FunctionNode node);
|
||||
|
||||
/// Return the [InterfaceType] corresponding to the [cls] with the given
|
||||
/// [typeArguments].
|
||||
/// [typeArguments] and [nullability].
|
||||
InterfaceType createInterfaceType(
|
||||
ir.Class cls, List<ir.DartType> typeArguments);
|
||||
ir.Class cls, List<ir.DartType> typeArguments, Nullability nullability);
|
||||
|
||||
/// Returns the [CallStructure] corresponding to the [arguments].
|
||||
CallStructure getCallStructure(ir.Arguments arguments);
|
||||
|
|
|
@ -68,9 +68,8 @@ class KernelDartTypes extends DartTypes {
|
|||
for (int index = 0; index < typeArguments.length; index++) {
|
||||
DartType typeArgument = typeArguments[index];
|
||||
TypeVariableType typeVariable = typeVariables[index];
|
||||
DartType bound = elementMap
|
||||
.getTypeVariableBound(typeVariable.element)
|
||||
.subst(typeArguments, typeVariables);
|
||||
DartType bound = subst(typeArguments, typeVariables,
|
||||
elementMap.getTypeVariableBound(typeVariable.element));
|
||||
checkTypeVariableBound(context, typeArgument, typeVariable, bound);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ class DartTypeConverter extends ir.DartTypeVisitor<DartType> {
|
|||
|
||||
InterfaceType visitSupertype(ir.Supertype node) {
|
||||
ClassEntity cls = elementMap.getClass(node.classNode);
|
||||
return new InterfaceType(
|
||||
return _dartTypes.interfaceType(
|
||||
cls, visitTypes(node.typeArguments), _dartTypes.defaultNullability);
|
||||
}
|
||||
|
||||
|
@ -84,9 +84,12 @@ class DartTypeConverter extends ir.DartTypeVisitor<DartType> {
|
|||
if (node.parameter.parent is ir.Typedef) {
|
||||
// Typedefs are only used in type literals so we never need their type
|
||||
// variables.
|
||||
return DynamicType();
|
||||
return _dartTypes.dynamicType();
|
||||
}
|
||||
return new TypeVariableType(elementMap.getTypeVariable(node.parameter),
|
||||
// We assume the incoming type is already normalized, so the bound is not
|
||||
// `Never`. Attempting to check the bound here will overflow the stack.
|
||||
return _dartTypes.typeVariableType(
|
||||
elementMap.getTypeVariable(node.parameter),
|
||||
_dartTypes.defaultNullability);
|
||||
}
|
||||
|
||||
|
@ -96,7 +99,7 @@ class DartTypeConverter extends ir.DartTypeVisitor<DartType> {
|
|||
List<FunctionTypeVariable> typeVariables;
|
||||
for (ir.TypeParameter typeParameter in node.typeParameters) {
|
||||
FunctionTypeVariable typeVariable =
|
||||
new FunctionTypeVariable(index, _dartTypes.defaultNullability);
|
||||
_dartTypes.functionTypeVariable(index, _dartTypes.defaultNullability);
|
||||
currentFunctionTypeParameters[typeParameter] = typeVariable;
|
||||
typeVariables ??= <FunctionTypeVariable>[];
|
||||
typeVariables.add(typeVariable);
|
||||
|
@ -109,7 +112,7 @@ class DartTypeConverter extends ir.DartTypeVisitor<DartType> {
|
|||
}
|
||||
}
|
||||
|
||||
FunctionType type = new FunctionType(
|
||||
FunctionType type = _dartTypes.functionType(
|
||||
visitType(node.returnType),
|
||||
visitTypes(node.positionalParameters
|
||||
.take(node.requiredParameterCount)
|
||||
|
@ -132,28 +135,28 @@ class DartTypeConverter extends ir.DartTypeVisitor<DartType> {
|
|||
ClassEntity cls = elementMap.getClass(node.classNode);
|
||||
if (cls.name == 'FutureOr' &&
|
||||
cls.library == elementMap.commonElements.asyncLibrary) {
|
||||
return new FutureOrType(
|
||||
return _dartTypes.futureOrType(
|
||||
visitTypes(node.typeArguments).single, _dartTypes.defaultNullability);
|
||||
}
|
||||
return new InterfaceType(
|
||||
return _dartTypes.interfaceType(
|
||||
cls, visitTypes(node.typeArguments), _dartTypes.defaultNullability);
|
||||
}
|
||||
|
||||
@override
|
||||
DartType visitVoidType(ir.VoidType node) {
|
||||
return VoidType();
|
||||
return _dartTypes.voidType();
|
||||
}
|
||||
|
||||
@override
|
||||
DartType visitDynamicType(ir.DynamicType node) {
|
||||
return DynamicType();
|
||||
return _dartTypes.dynamicType();
|
||||
}
|
||||
|
||||
@override
|
||||
DartType visitInvalidType(ir.InvalidType node) {
|
||||
// Root uses such a `o is Unresolved` and `o as Unresolved` must be special
|
||||
// cased in the builder, nested invalid types are treated as `dynamic`.
|
||||
return DynamicType();
|
||||
return _dartTypes.dynamicType();
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -205,8 +208,8 @@ class ConstantValuefier extends ir.ComputeOnceConstantVisitor<ConstantValue> {
|
|||
|
||||
@override
|
||||
ConstantValue visitInstanceConstant(ir.InstanceConstant node) {
|
||||
InterfaceType type =
|
||||
elementMap.createInterfaceType(node.classNode, node.typeArguments);
|
||||
InterfaceType type = elementMap.createInterfaceType(
|
||||
node.classNode, node.typeArguments, Nullability.none);
|
||||
Map<FieldEntity, ConstantValue> fields = {};
|
||||
node.fieldValues.forEach((ir.Reference reference, ir.Constant value) {
|
||||
FieldEntity field = elementMap.getField(reference.asField);
|
||||
|
@ -222,7 +225,7 @@ class ConstantValuefier extends ir.ComputeOnceConstantVisitor<ConstantValue> {
|
|||
elements.add(visitConstant(element));
|
||||
}
|
||||
DartType type = elementMap.commonElements
|
||||
.listType(elementMap.getDartType(node.typeArgument));
|
||||
.listType(Nullability.none, elementMap.getDartType(node.typeArgument));
|
||||
return constant_system.createList(
|
||||
elementMap.commonElements, type, elements);
|
||||
}
|
||||
|
@ -234,7 +237,7 @@ class ConstantValuefier extends ir.ComputeOnceConstantVisitor<ConstantValue> {
|
|||
elements.add(visitConstant(element));
|
||||
}
|
||||
DartType type = elementMap.commonElements
|
||||
.setType(elementMap.getDartType(node.typeArgument));
|
||||
.setType(Nullability.none, elementMap.getDartType(node.typeArgument));
|
||||
return constant_system.createSet(elementMap.commonElements, type, elements);
|
||||
}
|
||||
|
||||
|
@ -247,6 +250,7 @@ class ConstantValuefier extends ir.ComputeOnceConstantVisitor<ConstantValue> {
|
|||
values.add(visitConstant(element.value));
|
||||
}
|
||||
DartType type = elementMap.commonElements.mapType(
|
||||
Nullability.none,
|
||||
elementMap.getDartType(node.keyType),
|
||||
elementMap.getDartType(node.valueType));
|
||||
return constant_system.createMap(
|
||||
|
|
|
@ -447,8 +447,8 @@ class ConstantEmitter extends ModularConstantEmitter {
|
|||
_constantReferenceGenerator(constant.function)
|
||||
];
|
||||
if (_options.useNewRti) {
|
||||
fields.add(_reifiedTypeNewRti(InterfaceType(cls, constant.typeArguments,
|
||||
_commonElements.dartTypes.defaultNullability)));
|
||||
fields.add(_reifiedTypeNewRti(_commonElements.dartTypes
|
||||
.interfaceType(cls, constant.typeArguments, Nullability.none)));
|
||||
} else {
|
||||
fields.add(_reifiedTypeArguments(constant, constant.typeArguments));
|
||||
}
|
||||
|
|
|
@ -44,10 +44,10 @@ FunctionType buildJsFunctionType(DartTypes dartTypes) {
|
|||
// TODO(jacobr): consider using codegenWorldBuilder.isChecks to determine the
|
||||
// range of positional arguments that need to be supported by JavaScript
|
||||
// function types.
|
||||
return new FunctionType(
|
||||
DynamicType(),
|
||||
return dartTypes.functionType(
|
||||
dartTypes.dynamicType(),
|
||||
const <DartType>[],
|
||||
new List<DartType>.filled(16, DynamicType()),
|
||||
new List<DartType>.filled(16, dartTypes.dynamicType()),
|
||||
const <String>[],
|
||||
const <DartType>[],
|
||||
const <FunctionTypeVariable>[],
|
||||
|
|
|
@ -570,7 +570,8 @@ class TypeVariableTests {
|
|||
void addImplicitCheck(DartType type) {
|
||||
if (implicitIsChecks.add(type)) {
|
||||
if (type is FutureOrType) {
|
||||
addImplicitCheck(commonElements.futureType(type.typeArgument));
|
||||
addImplicitCheck(
|
||||
commonElements.futureType(Nullability.none, type.typeArgument));
|
||||
addImplicitCheck(type.typeArgument);
|
||||
}
|
||||
}
|
||||
|
@ -582,7 +583,8 @@ class TypeVariableTests {
|
|||
|
||||
world.isChecks.forEach((DartType type) {
|
||||
if (type is FutureOrType) {
|
||||
addImplicitCheck(commonElements.futureType(type.typeArgument));
|
||||
addImplicitCheck(
|
||||
commonElements.futureType(Nullability.none, type.typeArgument));
|
||||
addImplicitCheck(type.typeArgument);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -55,6 +55,7 @@ class ParameterStubGenerator {
|
|||
this._closedWorld,
|
||||
this._sourceInformationStrategy);
|
||||
|
||||
DartTypes get _dartTypes => _closedWorld.dartTypes;
|
||||
JElementEnvironment get _elementEnvironment =>
|
||||
_closedWorld.elementEnvironment;
|
||||
|
||||
|
@ -249,8 +250,8 @@ class ParameterStubGenerator {
|
|||
Set<TypeVariableType> variables = Set();
|
||||
type.forEachTypeVariable(variables.add);
|
||||
assert(variables.isNotEmpty);
|
||||
return type.subst(
|
||||
List.filled(variables.length, AnyType()), variables.toList());
|
||||
return _dartTypes.subst(List.filled(variables.length, _dartTypes.anyType()),
|
||||
variables.toList(), type);
|
||||
}
|
||||
|
||||
// We fill the lists depending on possible/invoked selectors. For example,
|
||||
|
|
|
@ -108,6 +108,7 @@ class ProgramBuilder {
|
|||
final Set<TypeVariableType> _lateNamedTypeVariablesNewRti = {};
|
||||
|
||||
ClassHierarchy get _classHierarchy => _closedWorld.classHierarchy;
|
||||
DartTypes get _dartTypes => _closedWorld.dartTypes;
|
||||
|
||||
ProgramBuilder(
|
||||
this._options,
|
||||
|
@ -1009,9 +1010,11 @@ class ProgramBuilder {
|
|||
if (!_rtiNeed.classNeedsTypeArguments(enclosingClass)) {
|
||||
// Erase type arguments.
|
||||
List<DartType> typeArguments = enclosingType.typeArguments;
|
||||
type = type.subst(
|
||||
List<DartType>.filled(typeArguments.length, ErasedType()),
|
||||
typeArguments);
|
||||
type = _dartTypes.subst(
|
||||
List<DartType>.filled(
|
||||
typeArguments.length, _dartTypes.erasedType()),
|
||||
typeArguments,
|
||||
type);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,9 +47,9 @@ abstract class JsToElementMap {
|
|||
FunctionType getFunctionType(ir.FunctionNode node);
|
||||
|
||||
/// Return the [InterfaceType] corresponding to the [cls] with the given
|
||||
/// [typeArguments].
|
||||
/// [typeArguments] and [nullability].
|
||||
InterfaceType createInterfaceType(
|
||||
ir.Class cls, List<ir.DartType> typeArguments);
|
||||
ir.Class cls, List<ir.DartType> typeArguments, Nullability nullability);
|
||||
|
||||
/// Returns the [CallStructure] corresponding to the [arguments].
|
||||
CallStructure getCallStructure(ir.Arguments arguments);
|
||||
|
|
|
@ -618,9 +618,9 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
|
|||
|
||||
@override
|
||||
InterfaceType createInterfaceType(
|
||||
ir.Class cls, List<ir.DartType> typeArguments) {
|
||||
return new InterfaceType(
|
||||
getClass(cls), getDartTypes(typeArguments), types.defaultNullability);
|
||||
ir.Class cls, List<ir.DartType> typeArguments, Nullability nullability) {
|
||||
return types.interfaceType(
|
||||
getClass(cls), getDartTypes(typeArguments), nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -642,22 +642,22 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
|
|||
if (data is JClassDataImpl && data.thisType == null) {
|
||||
ir.Class node = data.cls;
|
||||
if (node.typeParameters.isEmpty) {
|
||||
data.thisType = data.rawType = new InterfaceType(
|
||||
data.thisType = data.rawType = types.interfaceType(
|
||||
cls, const <DartType>[], types.defaultNullability);
|
||||
} else {
|
||||
data.thisType = new InterfaceType(
|
||||
data.thisType = types.interfaceType(
|
||||
cls,
|
||||
new List<DartType>.generate(node.typeParameters.length,
|
||||
(int index) {
|
||||
return new TypeVariableType(
|
||||
return types.typeVariableType(
|
||||
getTypeVariableInternal(node.typeParameters[index]),
|
||||
types.defaultNullability);
|
||||
}),
|
||||
types.defaultNullability);
|
||||
data.rawType = new InterfaceType(
|
||||
data.rawType = types.interfaceType(
|
||||
cls,
|
||||
new List<DartType>.filled(
|
||||
node.typeParameters.length, DynamicType()),
|
||||
node.typeParameters.length, types.dynamicType()),
|
||||
types.defaultNullability);
|
||||
}
|
||||
}
|
||||
|
@ -671,9 +671,9 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
|
|||
_ensureThisAndRawType(cls, data);
|
||||
data.jsInteropType = data.thisType;
|
||||
} else {
|
||||
data.jsInteropType = InterfaceType(
|
||||
data.jsInteropType = types.interfaceType(
|
||||
cls,
|
||||
List<DartType>.filled(node.typeParameters.length, AnyType()),
|
||||
List<DartType>.filled(node.typeParameters.length, types.anyType()),
|
||||
types.defaultNullability);
|
||||
}
|
||||
}
|
||||
|
@ -868,7 +868,7 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
|
|||
if (node.parent is ir.Constructor) {
|
||||
// The return type on generative constructors is `void`, but we need
|
||||
// `dynamic` type to match the element model.
|
||||
returnType = DynamicType();
|
||||
returnType = types.dynamicType();
|
||||
} else {
|
||||
returnType = getDartType(node.returnType);
|
||||
}
|
||||
|
@ -908,10 +908,10 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
|
|||
typeVariables = new List<FunctionTypeVariable>.generate(
|
||||
node.typeParameters.length,
|
||||
(int index) =>
|
||||
new FunctionTypeVariable(index, types.defaultNullability));
|
||||
types.functionTypeVariable(index, types.defaultNullability));
|
||||
|
||||
DartType subst(DartType type) {
|
||||
return type.subst(typeVariables, typeParameters);
|
||||
return types.subst(typeVariables, typeParameters, type);
|
||||
}
|
||||
|
||||
returnType = subst(returnType);
|
||||
|
@ -926,7 +926,7 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
|
|||
typeVariables = const <FunctionTypeVariable>[];
|
||||
}
|
||||
|
||||
return new FunctionType(
|
||||
return types.functionType(
|
||||
returnType,
|
||||
parameterTypes,
|
||||
optionalParameterTypes,
|
||||
|
@ -938,8 +938,8 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
|
|||
|
||||
@override
|
||||
DartType substByContext(DartType type, InterfaceType context) {
|
||||
return type.subst(
|
||||
context.typeArguments, getThisType(context.element).typeArguments);
|
||||
return types.subst(context.typeArguments,
|
||||
getThisType(context.element).typeArguments, type);
|
||||
}
|
||||
|
||||
/// Returns the type of the `call` method on 'type'.
|
||||
|
@ -1756,7 +1756,7 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
|
|||
Map<String, IndexedMember> memberMap = <String, IndexedMember>{};
|
||||
JRecord container = new JRecord(member.library, box.name);
|
||||
BoxLocal boxLocal = new BoxLocal(container);
|
||||
InterfaceType thisType = new InterfaceType(
|
||||
InterfaceType thisType = types.interfaceType(
|
||||
container, const <DartType>[], types.defaultNullability);
|
||||
InterfaceType supertype = commonElements.objectType;
|
||||
JClassData containerData = new RecordClassData(
|
||||
|
@ -1820,7 +1820,7 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
|
|||
JClass classEntity = new JClosureClass(enclosingLibrary, name);
|
||||
// Create a classData and set up the interfaces and subclass
|
||||
// relationships that _ensureSupertypes and _ensureThisAndRawType are doing
|
||||
InterfaceType thisType = new InterfaceType(
|
||||
InterfaceType thisType = types.interfaceType(
|
||||
classEntity, const <DartType>[], types.defaultNullability);
|
||||
ClosureClassData closureData = new ClosureClassData(
|
||||
new ClosureClassDefinition(location),
|
||||
|
@ -2152,7 +2152,7 @@ class JsElementEnvironment extends ElementEnvironment
|
|||
JsElementEnvironment(this.elementMap);
|
||||
|
||||
@override
|
||||
DartType get dynamicType => DynamicType();
|
||||
DartType get dynamicType => elementMap.types.dynamicType();
|
||||
|
||||
@override
|
||||
LibraryEntity get mainLibrary => elementMap._mainLibrary;
|
||||
|
@ -2233,9 +2233,8 @@ class JsElementEnvironment extends ElementEnvironment
|
|||
|
||||
@override
|
||||
InterfaceType createInterfaceType(
|
||||
ClassEntity cls, List<DartType> typeArguments) {
|
||||
return new InterfaceType(
|
||||
cls, typeArguments, elementMap.types.defaultNullability);
|
||||
ClassEntity cls, List<DartType> typeArguments, Nullability nullability) {
|
||||
return elementMap.types.interfaceType(cls, typeArguments, nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -54,6 +54,7 @@ class JsClosedWorldBuilder {
|
|||
|
||||
ElementEnvironment get _elementEnvironment => _elementMap.elementEnvironment;
|
||||
CommonElements get _commonElements => _elementMap.commonElements;
|
||||
DartTypes get _dartTypes => _elementMap.types;
|
||||
|
||||
JsClosedWorld convertClosedWorld(
|
||||
KClosedWorld closedWorld,
|
||||
|
@ -427,7 +428,7 @@ class JsClosedWorldBuilder {
|
|||
boxedVariables,
|
||||
info,
|
||||
localsMap,
|
||||
new InterfaceType(
|
||||
_dartTypes.interfaceType(
|
||||
superclass, const [], _elementMap.types.defaultNullability),
|
||||
createSignatureMethod: createSignatureMethod);
|
||||
|
||||
|
@ -678,7 +679,8 @@ class JsToFrontendMapImpl extends JsToFrontendMap {
|
|||
DartType toBackendType(DartType type, {bool allowFreeVariables: false}) =>
|
||||
type == null
|
||||
? null
|
||||
: new _TypeConverter(allowFreeVariables: allowFreeVariables)
|
||||
: new _TypeConverter(_backend.types,
|
||||
allowFreeVariables: allowFreeVariables)
|
||||
.visit(type, toBackendEntity);
|
||||
|
||||
Entity toBackendEntity(Entity entity) {
|
||||
|
@ -733,12 +735,13 @@ class JsToFrontendMapImpl extends JsToFrontendMap {
|
|||
typedef Entity _EntityConverter(Entity cls);
|
||||
|
||||
class _TypeConverter implements DartTypeVisitor<DartType, _EntityConverter> {
|
||||
final DartTypes _dartTypes;
|
||||
final bool allowFreeVariables;
|
||||
|
||||
Map<FunctionTypeVariable, FunctionTypeVariable> _functionTypeVariables =
|
||||
<FunctionTypeVariable, FunctionTypeVariable>{};
|
||||
|
||||
_TypeConverter({this.allowFreeVariables: false});
|
||||
_TypeConverter(this._dartTypes, {this.allowFreeVariables: false});
|
||||
|
||||
List<DartType> convertTypes(
|
||||
List<DartType> types, _EntityConverter converter) =>
|
||||
|
@ -759,39 +762,39 @@ class _TypeConverter implements DartTypeVisitor<DartType, _EntityConverter> {
|
|||
|
||||
@override
|
||||
DartType visitNeverType(NeverType type, _EntityConverter converter) =>
|
||||
NeverType(type.nullability);
|
||||
_dartTypes.neverType(type.nullability);
|
||||
|
||||
@override
|
||||
DartType visitDynamicType(DynamicType type, _EntityConverter converter) {
|
||||
return DynamicType();
|
||||
}
|
||||
DartType visitDynamicType(DynamicType type, _EntityConverter converter) =>
|
||||
_dartTypes.dynamicType();
|
||||
|
||||
@override
|
||||
DartType visitErasedType(ErasedType type, _EntityConverter converter) =>
|
||||
ErasedType();
|
||||
_dartTypes.erasedType();
|
||||
|
||||
@override
|
||||
DartType visitAnyType(AnyType type, _EntityConverter converter) => AnyType();
|
||||
DartType visitAnyType(AnyType type, _EntityConverter converter) =>
|
||||
_dartTypes.anyType();
|
||||
|
||||
@override
|
||||
DartType visitInterfaceType(InterfaceType type, _EntityConverter converter) {
|
||||
return new InterfaceType(converter(type.element),
|
||||
return _dartTypes.interfaceType(converter(type.element),
|
||||
visitList(type.typeArguments, converter), type.nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
DartType visitTypeVariableType(
|
||||
TypeVariableType type, _EntityConverter converter) {
|
||||
return new TypeVariableType(converter(type.element), type.nullability);
|
||||
return _dartTypes.typeVariableType(
|
||||
converter(type.element), type.nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
DartType visitFunctionType(FunctionType type, _EntityConverter converter) {
|
||||
List<FunctionTypeVariable> typeVariables = <FunctionTypeVariable>[];
|
||||
for (FunctionTypeVariable typeVariable in type.typeVariables) {
|
||||
typeVariables.add(_functionTypeVariables[typeVariable] =
|
||||
new FunctionTypeVariable(
|
||||
typeVariable.index, typeVariable.nullability));
|
||||
typeVariables.add(_functionTypeVariables[typeVariable] = _dartTypes
|
||||
.functionTypeVariable(typeVariable.index, typeVariable.nullability));
|
||||
}
|
||||
for (FunctionTypeVariable typeVariable in type.typeVariables) {
|
||||
_functionTypeVariables[typeVariable].bound = typeVariable.bound != null
|
||||
|
@ -807,7 +810,7 @@ class _TypeConverter implements DartTypeVisitor<DartType, _EntityConverter> {
|
|||
for (FunctionTypeVariable typeVariable in type.typeVariables) {
|
||||
_functionTypeVariables.remove(typeVariable);
|
||||
}
|
||||
return new FunctionType(
|
||||
return _dartTypes.functionType(
|
||||
returnType,
|
||||
parameterTypes,
|
||||
optionalParameterTypes,
|
||||
|
@ -830,15 +833,13 @@ class _TypeConverter implements DartTypeVisitor<DartType, _EntityConverter> {
|
|||
}
|
||||
|
||||
@override
|
||||
DartType visitVoidType(VoidType type, _EntityConverter converter) {
|
||||
return VoidType();
|
||||
}
|
||||
DartType visitVoidType(VoidType type, _EntityConverter converter) =>
|
||||
_dartTypes.voidType();
|
||||
|
||||
@override
|
||||
DartType visitFutureOrType(FutureOrType type, _EntityConverter converter) {
|
||||
return new FutureOrType(
|
||||
visit(type.typeArgument, converter), type.nullability);
|
||||
}
|
||||
DartType visitFutureOrType(FutureOrType type, _EntityConverter converter) =>
|
||||
_dartTypes.futureOrType(
|
||||
visit(type.typeArgument, converter), type.nullability);
|
||||
}
|
||||
|
||||
class _ConstantConverter implements ConstantValueVisitor<ConstantValue, Null> {
|
||||
|
@ -847,7 +848,7 @@ class _ConstantConverter implements ConstantValueVisitor<ConstantValue, Null> {
|
|||
final _TypeConverter typeConverter;
|
||||
|
||||
_ConstantConverter(this._dartTypes, this.toBackendEntity)
|
||||
: typeConverter = new _TypeConverter();
|
||||
: typeConverter = new _TypeConverter(_dartTypes);
|
||||
|
||||
@override
|
||||
ConstantValue visitNull(NullConstantValue constant, _) => constant;
|
||||
|
|
|
@ -319,6 +319,10 @@ class FullTypeEnvironmentRecipe extends TypeEnvironmentRecipe {
|
|||
}
|
||||
|
||||
class TypeRecipeDomainImpl implements TypeRecipeDomain {
|
||||
final DartTypes _dartTypes;
|
||||
|
||||
const TypeRecipeDomainImpl(this._dartTypes);
|
||||
|
||||
@override
|
||||
bool isIdentity(TypeRecipe recipe, TypeEnvironmentStructure structure) {
|
||||
if (structure is SingletonTypeEnvironmentStructure &&
|
||||
|
@ -350,7 +354,7 @@ class TypeRecipeDomainImpl implements TypeRecipeDomain {
|
|||
if (environmentRecipe is TypeExpressionRecipe) {
|
||||
List<TypeVariableType> variables = [environmentStructure.variable];
|
||||
List<DartType> replacements = [environmentRecipe.type];
|
||||
return _Substitution(null, null, variables, replacements)
|
||||
return _Substitution(_dartTypes, null, null, variables, replacements)
|
||||
.substituteRecipe(recipe);
|
||||
}
|
||||
failedAt(CURRENT_ELEMENT_SPANNABLE,
|
||||
|
@ -362,7 +366,7 @@ class TypeRecipeDomainImpl implements TypeRecipeDomain {
|
|||
if (environmentStructure.classType != null) {
|
||||
if (environmentRecipe is TypeExpressionRecipe) {
|
||||
assert(environmentStructure.bindings.isEmpty);
|
||||
return _Substitution(environmentStructure.classType,
|
||||
return _Substitution(_dartTypes, environmentStructure.classType,
|
||||
environmentRecipe.type, null, null)
|
||||
.substituteRecipe(recipe);
|
||||
}
|
||||
|
@ -374,6 +378,7 @@ class TypeRecipeDomainImpl implements TypeRecipeDomain {
|
|||
}
|
||||
if (environmentRecipe is FullTypeEnvironmentRecipe) {
|
||||
return _Substitution(
|
||||
_dartTypes,
|
||||
environmentStructure.classType,
|
||||
environmentRecipe.classType,
|
||||
environmentStructure.bindings,
|
||||
|
@ -411,7 +416,7 @@ class TypeRecipeDomainImpl implements TypeRecipeDomain {
|
|||
List<TypeVariableType> replacedVariables = bindings.sublist(index);
|
||||
List<TypeVariableType> remainingVariables = bindings.sublist(0, index);
|
||||
TypeRecipe newRecipe =
|
||||
_Substitution(null, null, replacedVariables, replacements)
|
||||
_Substitution(_dartTypes, null, null, replacedVariables, replacements)
|
||||
.substituteRecipe(recipe);
|
||||
if (newRecipe == null) return null;
|
||||
TypeEnvironmentStructure newEnvironmentStructure =
|
||||
|
@ -436,8 +441,11 @@ class TypeRecipeDomainImpl implements TypeRecipeDomain {
|
|||
if (environmentStructure2 is SingletonTypeEnvironmentStructure &&
|
||||
recipe1 is TypeExpressionRecipe) {
|
||||
TypeRecipe newRecipe = _Substitution(
|
||||
null, null, [environmentStructure2.variable], [recipe1.type])
|
||||
.substituteRecipe(recipe2);
|
||||
_dartTypes,
|
||||
null,
|
||||
null,
|
||||
[environmentStructure2.variable],
|
||||
[recipe1.type]).substituteRecipe(recipe2);
|
||||
if (newRecipe == null) return null;
|
||||
return TypeRecipeAndEnvironmentStructure(
|
||||
newRecipe, environmentStructure1);
|
||||
|
@ -446,7 +454,7 @@ class TypeRecipeDomainImpl implements TypeRecipeDomain {
|
|||
if (environmentStructure2 is FullTypeEnvironmentStructure &&
|
||||
recipe1 is TypeExpressionRecipe) {
|
||||
assert(environmentStructure2.bindings.isEmpty);
|
||||
TypeRecipe newRecipe = _Substitution(
|
||||
TypeRecipe newRecipe = _Substitution(_dartTypes,
|
||||
environmentStructure2.classType, recipe1.type, null, null)
|
||||
.substituteRecipe(recipe2);
|
||||
if (newRecipe == null) return null;
|
||||
|
@ -456,8 +464,12 @@ class TypeRecipeDomainImpl implements TypeRecipeDomain {
|
|||
|
||||
if (environmentStructure2 is FullTypeEnvironmentStructure &&
|
||||
recipe1 is FullTypeEnvironmentRecipe) {
|
||||
TypeRecipe newRecipe = _Substitution(environmentStructure2.classType,
|
||||
recipe1.classType, environmentStructure2.bindings, recipe1.types)
|
||||
TypeRecipe newRecipe = _Substitution(
|
||||
_dartTypes,
|
||||
environmentStructure2.classType,
|
||||
recipe1.classType,
|
||||
environmentStructure2.bindings,
|
||||
recipe1.types)
|
||||
.substituteRecipe(recipe2);
|
||||
if (newRecipe == null) return null;
|
||||
return TypeRecipeAndEnvironmentStructure(
|
||||
|
@ -479,6 +491,8 @@ class TypeRecipeDomainImpl implements TypeRecipeDomain {
|
|||
/// A [_Substitution] contains the bindings and the state required to perform
|
||||
/// a single substitution.
|
||||
class _Substitution extends DartTypeSubstitutionVisitor<Null> {
|
||||
@override
|
||||
final DartTypes dartTypes;
|
||||
final Map<DartType, DartType> _lookupCache = {};
|
||||
final Map<DartType, int> _counts = {};
|
||||
bool _failed = false;
|
||||
|
@ -488,8 +502,8 @@ class _Substitution extends DartTypeSubstitutionVisitor<Null> {
|
|||
final List<TypeVariableType> _variables;
|
||||
final List<DartType> _replacements;
|
||||
|
||||
_Substitution(this._classEnvironment, this._classValue, this._variables,
|
||||
this._replacements)
|
||||
_Substitution(this.dartTypes, this._classEnvironment, this._classValue,
|
||||
this._variables, this._replacements)
|
||||
: assert(_variables?.length == _replacements?.length);
|
||||
|
||||
// Returns `null` if declined.
|
||||
|
|
|
@ -53,9 +53,9 @@ abstract class KernelToElementMap {
|
|||
FunctionType getFunctionType(ir.FunctionNode node);
|
||||
|
||||
/// Return the [InterfaceType] corresponding to the [cls] with the given
|
||||
/// [typeArguments].
|
||||
/// [typeArguments] and [nullability].
|
||||
InterfaceType createInterfaceType(
|
||||
ir.Class cls, List<ir.DartType> typeArguments);
|
||||
ir.Class cls, List<ir.DartType> typeArguments, Nullability nullability);
|
||||
|
||||
/// Returns the [CallStructure] corresponding to the [arguments].
|
||||
CallStructure getCallStructure(ir.Arguments arguments);
|
||||
|
|
|
@ -239,9 +239,9 @@ class KernelToElementMapImpl implements KernelToElementMap, IrToElementMap {
|
|||
|
||||
@override
|
||||
InterfaceType createInterfaceType(
|
||||
ir.Class cls, List<ir.DartType> typeArguments) {
|
||||
return new InterfaceType(
|
||||
getClass(cls), getDartTypes(typeArguments), types.defaultNullability);
|
||||
ir.Class cls, List<ir.DartType> typeArguments, Nullability nullability) {
|
||||
return types.interfaceType(
|
||||
getClass(cls), getDartTypes(typeArguments), nullability);
|
||||
}
|
||||
|
||||
LibraryEntity getLibrary(ir.Library node) => getLibraryInternal(node);
|
||||
|
@ -262,22 +262,22 @@ class KernelToElementMapImpl implements KernelToElementMap, IrToElementMap {
|
|||
if (data is KClassDataImpl && data.thisType == null) {
|
||||
ir.Class node = data.node;
|
||||
if (node.typeParameters.isEmpty) {
|
||||
data.thisType = data.rawType = new InterfaceType(
|
||||
data.thisType = data.rawType = types.interfaceType(
|
||||
cls, const <DartType>[], types.defaultNullability);
|
||||
} else {
|
||||
data.thisType = new InterfaceType(
|
||||
data.thisType = types.interfaceType(
|
||||
cls,
|
||||
new List<DartType>.generate(node.typeParameters.length,
|
||||
(int index) {
|
||||
return new TypeVariableType(
|
||||
return types.typeVariableType(
|
||||
getTypeVariableInternal(node.typeParameters[index]),
|
||||
types.defaultNullability);
|
||||
}),
|
||||
types.defaultNullability);
|
||||
data.rawType = new InterfaceType(
|
||||
data.rawType = types.interfaceType(
|
||||
cls,
|
||||
new List<DartType>.filled(
|
||||
node.typeParameters.length, DynamicType()),
|
||||
node.typeParameters.length, types.dynamicType()),
|
||||
types.defaultNullability);
|
||||
}
|
||||
}
|
||||
|
@ -291,9 +291,9 @@ class KernelToElementMapImpl implements KernelToElementMap, IrToElementMap {
|
|||
_ensureThisAndRawType(cls, data);
|
||||
data.jsInteropType = data.thisType;
|
||||
} else {
|
||||
data.jsInteropType = InterfaceType(
|
||||
data.jsInteropType = types.interfaceType(
|
||||
cls,
|
||||
List<DartType>.filled(node.typeParameters.length, AnyType()),
|
||||
List<DartType>.filled(node.typeParameters.length, types.anyType()),
|
||||
types.defaultNullability);
|
||||
}
|
||||
}
|
||||
|
@ -491,7 +491,7 @@ class KernelToElementMapImpl implements KernelToElementMap, IrToElementMap {
|
|||
if (node.parent is ir.Constructor) {
|
||||
// The return type on generative constructors is `void`, but we need
|
||||
// `dynamic` type to match the element model.
|
||||
returnType = DynamicType();
|
||||
returnType = types.dynamicType();
|
||||
} else {
|
||||
returnType = getDartType(node.returnType);
|
||||
}
|
||||
|
@ -531,10 +531,10 @@ class KernelToElementMapImpl implements KernelToElementMap, IrToElementMap {
|
|||
typeVariables = new List<FunctionTypeVariable>.generate(
|
||||
node.typeParameters.length,
|
||||
(int index) =>
|
||||
new FunctionTypeVariable(index, types.defaultNullability));
|
||||
types.functionTypeVariable(index, types.defaultNullability));
|
||||
|
||||
DartType subst(DartType type) {
|
||||
return type.subst(typeVariables, typeParameters);
|
||||
return types.subst(typeVariables, typeParameters, type);
|
||||
}
|
||||
|
||||
returnType = subst(returnType);
|
||||
|
@ -549,7 +549,7 @@ class KernelToElementMapImpl implements KernelToElementMap, IrToElementMap {
|
|||
typeVariables = const <FunctionTypeVariable>[];
|
||||
}
|
||||
|
||||
return new FunctionType(
|
||||
return types.functionType(
|
||||
returnType,
|
||||
parameterTypes,
|
||||
optionalParameterTypes,
|
||||
|
@ -561,8 +561,8 @@ class KernelToElementMapImpl implements KernelToElementMap, IrToElementMap {
|
|||
|
||||
@override
|
||||
DartType substByContext(DartType type, InterfaceType context) {
|
||||
return type.subst(
|
||||
context.typeArguments, getThisType(context.element).typeArguments);
|
||||
return types.subst(context.typeArguments,
|
||||
getThisType(context.element).typeArguments, type);
|
||||
}
|
||||
|
||||
/// Returns the type of the `call` method on 'type'.
|
||||
|
@ -1625,7 +1625,7 @@ class KernelElementEnvironment extends ElementEnvironment
|
|||
KernelElementEnvironment(this.elementMap);
|
||||
|
||||
@override
|
||||
DartType get dynamicType => DynamicType();
|
||||
DartType get dynamicType => elementMap.types.dynamicType();
|
||||
|
||||
@override
|
||||
LibraryEntity get mainLibrary => elementMap._mainLibrary;
|
||||
|
@ -1688,9 +1688,8 @@ class KernelElementEnvironment extends ElementEnvironment
|
|||
|
||||
@override
|
||||
InterfaceType createInterfaceType(
|
||||
ClassEntity cls, List<DartType> typeArguments) {
|
||||
return new InterfaceType(
|
||||
cls, typeArguments, elementMap.types.defaultNullability);
|
||||
ClassEntity cls, List<DartType> typeArguments, Nullability nullability) {
|
||||
return elementMap.types.interfaceType(cls, typeArguments, nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -285,7 +285,8 @@ abstract class KernelImpactRegistryMixin implements ImpactRegistry {
|
|||
void registerListLiteral(ir.DartType elementType,
|
||||
{bool isConst, bool isEmpty}) {
|
||||
impactBuilder.registerListLiteral(new ListLiteralUse(
|
||||
commonElements.listType(elementMap.getDartType(elementType)),
|
||||
commonElements.listType(
|
||||
Nullability.none, elementMap.getDartType(elementType)),
|
||||
isConstant: isConst,
|
||||
isEmpty: isEmpty));
|
||||
}
|
||||
|
@ -294,7 +295,8 @@ abstract class KernelImpactRegistryMixin implements ImpactRegistry {
|
|||
void registerSetLiteral(ir.DartType elementType,
|
||||
{bool isConst, bool isEmpty}) {
|
||||
impactBuilder.registerSetLiteral(new SetLiteralUse(
|
||||
commonElements.setType(elementMap.getDartType(elementType)),
|
||||
commonElements.setType(
|
||||
Nullability.none, elementMap.getDartType(elementType)),
|
||||
isConstant: isConst,
|
||||
isEmpty: isEmpty));
|
||||
}
|
||||
|
@ -303,7 +305,7 @@ abstract class KernelImpactRegistryMixin implements ImpactRegistry {
|
|||
void registerMapLiteral(ir.DartType keyType, ir.DartType valueType,
|
||||
{bool isConst, bool isEmpty}) {
|
||||
impactBuilder.registerMapLiteral(new MapLiteralUse(
|
||||
commonElements.mapType(
|
||||
commonElements.mapType(Nullability.none,
|
||||
elementMap.getDartType(keyType), elementMap.getDartType(valueType)),
|
||||
isConstant: isConst,
|
||||
isEmpty: isEmpty));
|
||||
|
@ -350,7 +352,8 @@ abstract class KernelImpactRegistryMixin implements ImpactRegistry {
|
|||
void registerConstInstantiation(ir.Class cls, List<ir.DartType> typeArguments,
|
||||
ir.LibraryDependency import) {
|
||||
ImportEntity deferredImport = elementMap.getImport(import);
|
||||
InterfaceType type = elementMap.createInterfaceType(cls, typeArguments);
|
||||
InterfaceType type =
|
||||
elementMap.createInterfaceType(cls, typeArguments, Nullability.none);
|
||||
impactBuilder
|
||||
.registerTypeUse(new TypeUse.constInstantiation(type, deferredImport));
|
||||
}
|
||||
|
|
|
@ -363,7 +363,7 @@ class NativeBehavior {
|
|||
/// [nullType] define the types for `Object` and `Null`, respectively. The
|
||||
/// latter is used for the type strings of the form '' and 'var'.
|
||||
/// [validTags] can be used to restrict which tags are accepted.
|
||||
static void processSpecString(
|
||||
static void processSpecString(DartTypes dartTypes,
|
||||
DiagnosticReporter reporter, Spannable spannable, String specString,
|
||||
{Iterable<String> validTags,
|
||||
void setSideEffects(SideEffects newEffects),
|
||||
|
@ -397,7 +397,7 @@ class NativeBehavior {
|
|||
/// * 'void' - in which case [onVoid] is called,
|
||||
/// * '' or 'var' - in which case [onVar] is called,
|
||||
/// * 'T1|...|Tn' - in which case [onType] is called for each resolved Ti.
|
||||
void resolveTypesString(String typesString,
|
||||
void resolveTypesString(DartTypes dartTypes, String typesString,
|
||||
{onVoid(), onVar(), onType(type)}) {
|
||||
// Various things that are not in fact types.
|
||||
if (typesString == 'void') {
|
||||
|
@ -413,13 +413,13 @@ class NativeBehavior {
|
|||
return;
|
||||
}
|
||||
for (final typeString in typesString.split('|')) {
|
||||
onType(_parseType(typeString.trim(), lookupType));
|
||||
onType(_parseType(dartTypes, typeString.trim(), lookupType));
|
||||
}
|
||||
}
|
||||
|
||||
if (!specString.contains(';') && !specString.contains(':')) {
|
||||
// Form (1), types or pseudo-types like 'void' and 'var'.
|
||||
resolveTypesString(specString.trim(), onVar: () {
|
||||
resolveTypesString(dartTypes, specString.trim(), onVar: () {
|
||||
typesReturned.add(objectType);
|
||||
typesReturned.add(nullType);
|
||||
}, onType: (type) {
|
||||
|
@ -478,7 +478,7 @@ class NativeBehavior {
|
|||
|
||||
String returns = values['returns'];
|
||||
if (returns != null) {
|
||||
resolveTypesString(returns, onVar: () {
|
||||
resolveTypesString(dartTypes, returns, onVar: () {
|
||||
typesReturned.add(objectType);
|
||||
typesReturned.add(nullType);
|
||||
}, onType: (type) {
|
||||
|
@ -488,13 +488,13 @@ class NativeBehavior {
|
|||
|
||||
String creates = values['creates'];
|
||||
if (creates != null) {
|
||||
resolveTypesString(creates, onVoid: () {
|
||||
resolveTypesString(dartTypes, creates, onVoid: () {
|
||||
reportError("Invalid type string 'creates:$creates'");
|
||||
}, onType: (type) {
|
||||
typesInstantiated.add(type);
|
||||
});
|
||||
} else if (returns != null) {
|
||||
resolveTypesString(returns, onType: (type) {
|
||||
resolveTypesString(dartTypes, returns, onType: (type) {
|
||||
typesInstantiated.add(type);
|
||||
});
|
||||
}
|
||||
|
@ -634,7 +634,7 @@ class NativeBehavior {
|
|||
behavior.useGvn = useGvn;
|
||||
}
|
||||
|
||||
processSpecString(reporter, spannable, specString,
|
||||
processSpecString(commonElements.dartTypes, reporter, spannable, specString,
|
||||
setSideEffects: setSideEffects,
|
||||
setThrows: setThrows,
|
||||
setIsAllocation: setIsAllocation,
|
||||
|
@ -669,7 +669,7 @@ class NativeBehavior {
|
|||
behavior.sideEffects.setTo(newEffects);
|
||||
}
|
||||
|
||||
processSpecString(reporter, spannable, specString,
|
||||
processSpecString(commonElements.dartTypes, reporter, spannable, specString,
|
||||
validTags: validTags,
|
||||
lookupType: lookupType,
|
||||
setSideEffects: setSideEffects,
|
||||
|
@ -711,10 +711,10 @@ class NativeBehavior {
|
|||
}
|
||||
|
||||
static dynamic /*DartType|SpecialType*/ _parseType(
|
||||
String typeString, TypeLookup lookupType) {
|
||||
DartTypes dartTypes, String typeString, TypeLookup lookupType) {
|
||||
if (typeString == '=Object') return SpecialType.JsObject;
|
||||
if (typeString == 'dynamic') {
|
||||
return DynamicType();
|
||||
return dartTypes.dynamicType();
|
||||
}
|
||||
int index = typeString.indexOf('<');
|
||||
var type = lookupType(typeString, required: index == -1);
|
||||
|
@ -727,7 +727,7 @@ class NativeBehavior {
|
|||
return type;
|
||||
}
|
||||
}
|
||||
return DynamicType();
|
||||
return dartTypes.dynamicType();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -766,7 +766,8 @@ abstract class BehaviorBuilder {
|
|||
List<dynamic> types = null;
|
||||
for (String specString in annotations) {
|
||||
for (final typeString in specString.split('|')) {
|
||||
var type = NativeBehavior._parseType(typeString, lookupType);
|
||||
var type = NativeBehavior._parseType(
|
||||
commonElements.dartTypes, typeString, lookupType);
|
||||
if (types == null) types = [];
|
||||
types.add(type);
|
||||
}
|
||||
|
|
|
@ -14,9 +14,6 @@ abstract class AbstractDataSink extends DataSinkMixin implements DataSink {
|
|||
/// and deserialization.
|
||||
final bool useDataKinds;
|
||||
|
||||
/// Visitor used for serializing [DartType]s.
|
||||
DartTypeWriter _dartTypeWriter;
|
||||
|
||||
/// Visitor used for serializing [ir.DartType]s.
|
||||
DartTypeNodeWriter _dartTypeNodeWriter;
|
||||
|
||||
|
@ -44,7 +41,6 @@ abstract class AbstractDataSink extends DataSinkMixin implements DataSink {
|
|||
_MemberData _currentMemberData;
|
||||
|
||||
AbstractDataSink({this.useDataKinds: false, this.tagFrequencyMap}) {
|
||||
_dartTypeWriter = new DartTypeWriter(this);
|
||||
_dartTypeNodeWriter = new DartTypeNodeWriter(this);
|
||||
_stringIndex = new IndexedSink<String>(this);
|
||||
_uriIndex = new IndexedSink<Uri>(this);
|
||||
|
@ -124,7 +120,7 @@ abstract class AbstractDataSink extends DataSinkMixin implements DataSink {
|
|||
}
|
||||
writeEnum(DartTypeKind.none);
|
||||
} else {
|
||||
_dartTypeWriter.visit(value, functionTypeVariables);
|
||||
value.writeToDataSink(this, functionTypeVariables);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -140,16 +140,6 @@ abstract class AbstractDataSource extends DataSourceMixin
|
|||
return _entityReader.readTypeVariableFromDataSource(this, entityLookup);
|
||||
}
|
||||
|
||||
List<DartType> _readDartTypes(
|
||||
List<FunctionTypeVariable> functionTypeVariables) {
|
||||
int count = readInt();
|
||||
List<DartType> types = new List<DartType>(count);
|
||||
for (int index = 0; index < count; index++) {
|
||||
types[index] = _readDartType(functionTypeVariables);
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
List<ir.DartType> _readDartTypeNodes(
|
||||
List<ir.TypeParameter> functionTypeVariables) {
|
||||
int count = readInt();
|
||||
|
@ -172,82 +162,11 @@ abstract class AbstractDataSource extends DataSourceMixin
|
|||
@override
|
||||
DartType readDartType({bool allowNull: false}) {
|
||||
_checkDataKind(DataKind.dartType);
|
||||
DartType type = _readDartType([]);
|
||||
DartType type = DartType.readFromDataSource(this, []);
|
||||
assert(type != null || allowNull);
|
||||
return type;
|
||||
}
|
||||
|
||||
DartType _readDartType(List<FunctionTypeVariable> functionTypeVariables) {
|
||||
DartTypeKind kind = readEnum(DartTypeKind.values);
|
||||
switch (kind) {
|
||||
case DartTypeKind.none:
|
||||
return null;
|
||||
case DartTypeKind.neverType:
|
||||
Nullability nullability = readEnum(Nullability.values);
|
||||
return NeverType(nullability);
|
||||
case DartTypeKind.voidType:
|
||||
return VoidType();
|
||||
case DartTypeKind.typeVariable:
|
||||
Nullability nullability = readEnum(Nullability.values);
|
||||
return new TypeVariableType(readTypeVariable(), nullability);
|
||||
case DartTypeKind.functionTypeVariable:
|
||||
int index = readInt();
|
||||
assert(0 <= index && index < functionTypeVariables.length);
|
||||
return functionTypeVariables[index];
|
||||
case DartTypeKind.functionType:
|
||||
int typeVariableCount = readInt();
|
||||
List<FunctionTypeVariable> typeVariables =
|
||||
new List<FunctionTypeVariable>.generate(typeVariableCount,
|
||||
(int index) {
|
||||
Nullability nullability = readEnum(Nullability.values);
|
||||
return new FunctionTypeVariable(index, nullability);
|
||||
});
|
||||
functionTypeVariables =
|
||||
new List<FunctionTypeVariable>.from(functionTypeVariables)
|
||||
..addAll(typeVariables);
|
||||
for (int index = 0; index < typeVariableCount; index++) {
|
||||
typeVariables[index].bound = _readDartType(functionTypeVariables);
|
||||
}
|
||||
DartType returnType = _readDartType(functionTypeVariables);
|
||||
List<DartType> parameterTypes = _readDartTypes(functionTypeVariables);
|
||||
List<DartType> optionalParameterTypes =
|
||||
_readDartTypes(functionTypeVariables);
|
||||
List<DartType> namedParameterTypes =
|
||||
_readDartTypes(functionTypeVariables);
|
||||
List<String> namedParameters =
|
||||
new List<String>(namedParameterTypes.length);
|
||||
for (int i = 0; i < namedParameters.length; i++) {
|
||||
namedParameters[i] = readString();
|
||||
}
|
||||
Nullability nullability = readEnum(Nullability.values);
|
||||
return new FunctionType(
|
||||
returnType,
|
||||
parameterTypes,
|
||||
optionalParameterTypes,
|
||||
namedParameters,
|
||||
namedParameterTypes,
|
||||
typeVariables,
|
||||
nullability);
|
||||
|
||||
case DartTypeKind.interfaceType:
|
||||
IndexedClass cls = readClass();
|
||||
List<DartType> typeArguments = _readDartTypes(functionTypeVariables);
|
||||
Nullability nullability = readEnum(Nullability.values);
|
||||
return new InterfaceType(cls, typeArguments, nullability);
|
||||
case DartTypeKind.dynamicType:
|
||||
return DynamicType();
|
||||
case DartTypeKind.erasedType:
|
||||
return ErasedType();
|
||||
case DartTypeKind.anyType:
|
||||
return AnyType();
|
||||
case DartTypeKind.futureOr:
|
||||
DartType typeArgument = _readDartType(functionTypeVariables);
|
||||
Nullability nullability = readEnum(Nullability.values);
|
||||
return new FutureOrType(typeArgument, nullability);
|
||||
}
|
||||
throw new UnsupportedError("Unexpected DartTypeKind $kind");
|
||||
}
|
||||
|
||||
@override
|
||||
ir.DartType readDartTypeNode({bool allowNull: false}) {
|
||||
_checkDataKind(DataKind.dartTypeNode);
|
||||
|
|
|
@ -101,121 +101,6 @@ enum DartTypeKind {
|
|||
futureOr,
|
||||
}
|
||||
|
||||
/// Visitor that serializes [DartType] object together with [AbstractDataSink].
|
||||
class DartTypeWriter
|
||||
implements DartTypeVisitor<void, List<FunctionTypeVariable>> {
|
||||
final AbstractDataSink _sink;
|
||||
|
||||
DartTypeWriter(this._sink);
|
||||
|
||||
@override
|
||||
void visit(covariant DartType type,
|
||||
List<FunctionTypeVariable> functionTypeVariables) =>
|
||||
type.accept(this, functionTypeVariables);
|
||||
|
||||
void visitTypes(
|
||||
List<DartType> types, List<FunctionTypeVariable> functionTypeVariables) {
|
||||
_sink.writeInt(types.length);
|
||||
for (DartType type in types) {
|
||||
_sink._writeDartType(type, functionTypeVariables);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void visitNeverType(covariant NeverType type,
|
||||
List<FunctionTypeVariable> functionTypeVariables) {
|
||||
_sink.writeEnum(DartTypeKind.neverType);
|
||||
_sink.writeEnum(type.nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitVoidType(covariant VoidType type,
|
||||
List<FunctionTypeVariable> functionTypeVariables) {
|
||||
_sink.writeEnum(DartTypeKind.voidType);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitTypeVariableType(covariant TypeVariableType type,
|
||||
List<FunctionTypeVariable> functionTypeVariables) {
|
||||
_sink.writeEnum(DartTypeKind.typeVariable);
|
||||
IndexedTypeVariable typeVariable = type.element;
|
||||
_sink.writeEnum(type.nullability);
|
||||
_sink.writeTypeVariable(typeVariable);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitFunctionTypeVariable(covariant FunctionTypeVariable type,
|
||||
List<FunctionTypeVariable> functionTypeVariables) {
|
||||
int index = functionTypeVariables.indexOf(type);
|
||||
if (index == -1) {
|
||||
// TODO(johnniwinther): Avoid free variables.
|
||||
_sink._writeDartType(DynamicType(), functionTypeVariables);
|
||||
} else {
|
||||
_sink.writeEnum(DartTypeKind.functionTypeVariable);
|
||||
_sink.writeInt(index);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void visitFunctionType(covariant FunctionType type,
|
||||
List<FunctionTypeVariable> functionTypeVariables) {
|
||||
_sink.writeEnum(DartTypeKind.functionType);
|
||||
functionTypeVariables =
|
||||
new List<FunctionTypeVariable>.from(functionTypeVariables)
|
||||
..addAll(type.typeVariables);
|
||||
_sink.writeInt(type.typeVariables.length);
|
||||
for (FunctionTypeVariable variable in type.typeVariables) {
|
||||
_sink.writeEnum(variable.nullability);
|
||||
}
|
||||
for (FunctionTypeVariable variable in type.typeVariables) {
|
||||
_sink._writeDartType(variable.bound, functionTypeVariables);
|
||||
}
|
||||
_sink._writeDartType(type.returnType, functionTypeVariables);
|
||||
visitTypes(type.parameterTypes, functionTypeVariables);
|
||||
visitTypes(type.optionalParameterTypes, functionTypeVariables);
|
||||
visitTypes(type.namedParameterTypes, functionTypeVariables);
|
||||
for (String namedParameter in type.namedParameters) {
|
||||
_sink.writeString(namedParameter);
|
||||
}
|
||||
_sink.writeEnum(type.nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitInterfaceType(covariant InterfaceType type,
|
||||
List<FunctionTypeVariable> functionTypeVariables) {
|
||||
_sink.writeEnum(DartTypeKind.interfaceType);
|
||||
_sink.writeClass(type.element);
|
||||
visitTypes(type.typeArguments, functionTypeVariables);
|
||||
_sink.writeEnum(type.nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitDynamicType(covariant DynamicType type,
|
||||
List<FunctionTypeVariable> functionTypeVariables) {
|
||||
_sink.writeEnum(DartTypeKind.dynamicType);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitErasedType(covariant ErasedType type,
|
||||
List<FunctionTypeVariable> functionTypeVariables) {
|
||||
_sink.writeEnum(DartTypeKind.erasedType);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitAnyType(covariant AnyType type,
|
||||
List<FunctionTypeVariable> functionTypeVariables) {
|
||||
_sink.writeEnum(DartTypeKind.anyType);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitFutureOrType(covariant FutureOrType type,
|
||||
List<FunctionTypeVariable> functionTypeVariables) {
|
||||
_sink.writeEnum(DartTypeKind.futureOr);
|
||||
_sink._writeDartType(type.typeArgument, functionTypeVariables);
|
||||
_sink.writeEnum(type.nullability);
|
||||
}
|
||||
}
|
||||
|
||||
/// Enum used for identifying [ir.DartType] subclasses in serialization.
|
||||
enum DartTypeNodeKind {
|
||||
none,
|
||||
|
|
|
@ -2123,8 +2123,9 @@ class KernelSsaGraphBuilder extends ir.Visitor {
|
|||
List<HInstruction> arguments = [pop()];
|
||||
ClassEntity cls = _commonElements.streamIterator;
|
||||
DartType typeArg = _elementMap.getDartType(node.variable.type);
|
||||
InterfaceType instanceType = localsHandler.substInContext(new InterfaceType(
|
||||
cls, [typeArg], closedWorld.dartTypes.defaultNullability));
|
||||
InterfaceType instanceType = localsHandler.substInContext(
|
||||
dartTypes.interfaceType(
|
||||
cls, [typeArg], closedWorld.dartTypes.defaultNullability));
|
||||
// TODO(johnniwinther): This should be the exact type.
|
||||
StaticType staticInstanceType =
|
||||
new StaticType(instanceType, ClassRelation.subtype);
|
||||
|
@ -3110,8 +3111,10 @@ class KernelSsaGraphBuilder extends ir.Visitor {
|
|||
}
|
||||
if (options.useNewRti) {
|
||||
// [type] could be `List<T>`, so ensure it is `JSArray<T>`.
|
||||
InterfaceType arrayType = InterfaceType(_commonElements.jsArrayClass,
|
||||
type.typeArguments, closedWorld.dartTypes.defaultNullability);
|
||||
InterfaceType arrayType = dartTypes.interfaceType(
|
||||
_commonElements.jsArrayClass,
|
||||
type.typeArguments,
|
||||
closedWorld.dartTypes.defaultNullability);
|
||||
HInstruction rti =
|
||||
_typeBuilder.analyzeTypeArgumentNewRti(arrayType, sourceElement);
|
||||
|
||||
|
@ -3146,7 +3149,8 @@ class KernelSsaGraphBuilder extends ir.Visitor {
|
|||
SourceInformation sourceInformation =
|
||||
_sourceInformationBuilder.buildListLiteral(node);
|
||||
InterfaceType type = localsHandler.substInContext(
|
||||
_commonElements.listType(_elementMap.getDartType(node.typeArgument)));
|
||||
_commonElements.listType(
|
||||
Nullability.none, _elementMap.getDartType(node.typeArgument)));
|
||||
listInstruction = _setListRuntimeTypeInfoIfNeeded(
|
||||
listInstruction, type, sourceInformation);
|
||||
}
|
||||
|
@ -3189,8 +3193,8 @@ class KernelSsaGraphBuilder extends ir.Visitor {
|
|||
assert(
|
||||
constructor is ConstructorEntity && constructor.isFactoryConstructor);
|
||||
|
||||
InterfaceType type = localsHandler.substInContext(
|
||||
_commonElements.setType(_elementMap.getDartType(node.typeArgument)));
|
||||
InterfaceType type = localsHandler.substInContext(_commonElements.setType(
|
||||
Nullability.none, _elementMap.getDartType(node.typeArgument)));
|
||||
ClassEntity cls = constructor.enclosingClass;
|
||||
|
||||
if (_rtiNeed.classNeedsTypeArguments(cls)) {
|
||||
|
@ -3271,6 +3275,7 @@ class KernelSsaGraphBuilder extends ir.Visitor {
|
|||
constructor is ConstructorEntity && constructor.isFactoryConstructor);
|
||||
|
||||
InterfaceType type = localsHandler.substInContext(_commonElements.mapType(
|
||||
Nullability.none,
|
||||
_elementMap.getDartType(node.keyType),
|
||||
_elementMap.getDartType(node.valueType)));
|
||||
ClassEntity cls = constructor.enclosingClass;
|
||||
|
@ -3883,7 +3888,9 @@ class KernelSsaGraphBuilder extends ir.Visitor {
|
|||
}
|
||||
|
||||
InterfaceType instanceType = _elementMap.createInterfaceType(
|
||||
invocation.target.enclosingClass, invocation.arguments.types);
|
||||
invocation.target.enclosingClass,
|
||||
invocation.arguments.types,
|
||||
Nullability.none);
|
||||
|
||||
AbstractValue resultType = typeMask;
|
||||
|
||||
|
@ -4008,7 +4015,9 @@ class KernelSsaGraphBuilder extends ir.Visitor {
|
|||
isGrowableListConstructorCall ||
|
||||
isJSArrayTypedConstructor)) {
|
||||
InterfaceType type = _elementMap.createInterfaceType(
|
||||
invocation.target.enclosingClass, invocation.arguments.types);
|
||||
invocation.target.enclosingClass,
|
||||
invocation.arguments.types,
|
||||
Nullability.none);
|
||||
stack
|
||||
.add(_setListRuntimeTypeInfoIfNeeded(pop(), type, sourceInformation));
|
||||
}
|
||||
|
@ -4715,8 +4724,10 @@ class KernelSsaGraphBuilder extends ir.Visitor {
|
|||
}
|
||||
// TODO(sra): This should be JSArray<any>, created via
|
||||
// _elementEnvironment.getJsInteropType(_elementEnvironment.jsArrayClass);
|
||||
InterfaceType interopType = InterfaceType(_commonElements.jsArrayClass,
|
||||
[DynamicType()], closedWorld.dartTypes.defaultNullability);
|
||||
InterfaceType interopType = dartTypes.interfaceType(
|
||||
_commonElements.jsArrayClass,
|
||||
[dartTypes.dynamicType()],
|
||||
closedWorld.dartTypes.defaultNullability);
|
||||
SourceInformation sourceInformation =
|
||||
_sourceInformationBuilder.buildCall(invocation, invocation);
|
||||
HInstruction rti =
|
||||
|
@ -5011,8 +5022,8 @@ class KernelSsaGraphBuilder extends ir.Visitor {
|
|||
// Native behavior effects here are similar to native/behavior.dart.
|
||||
// The return type is dynamic if we don't trust js-interop type
|
||||
// declarations.
|
||||
nativeBehavior.typesReturned
|
||||
.add(options.trustJSInteropTypeAnnotations ? type : DynamicType());
|
||||
nativeBehavior.typesReturned.add(
|
||||
options.trustJSInteropTypeAnnotations ? type : dartTypes.dynamicType());
|
||||
|
||||
// The allocation effects include the declared type if it is native (which
|
||||
// includes js interop types).
|
||||
|
@ -5372,7 +5383,7 @@ class KernelSsaGraphBuilder extends ir.Visitor {
|
|||
ClassEntity cls = constructor.enclosingClass;
|
||||
AbstractValue typeMask = _abstractValueDomain.createNonNullExact(cls);
|
||||
InterfaceType instanceType = _elementMap.createInterfaceType(
|
||||
target.enclosingClass, node.arguments.types);
|
||||
target.enclosingClass, node.arguments.types, Nullability.none);
|
||||
instanceType = localsHandler.substInContext(instanceType);
|
||||
|
||||
List<HInstruction> arguments = <HInstruction>[];
|
||||
|
|
|
@ -76,7 +76,8 @@ class SsaOptimizerTask extends CompilerTask {
|
|||
SsaCodeMotion codeMotion;
|
||||
SsaLoadElimination loadElimination;
|
||||
|
||||
TypeRecipeDomain typeRecipeDomain = TypeRecipeDomainImpl();
|
||||
TypeRecipeDomain typeRecipeDomain =
|
||||
TypeRecipeDomainImpl(closedWorld.dartTypes);
|
||||
|
||||
OptimizationTestLog log;
|
||||
if (retainDataForTesting) {
|
||||
|
@ -693,7 +694,9 @@ class SsaInstructionSimplifier extends HBaseVisitor
|
|||
if (_options.useNewRti) {
|
||||
typeInfo = HLoadType.type(
|
||||
_closedWorld.elementEnvironment.createInterfaceType(
|
||||
commonElements.jsArrayClass, [commonElements.stringType]),
|
||||
commonElements.jsArrayClass,
|
||||
[commonElements.stringType],
|
||||
Nullability.none),
|
||||
_abstractValueDomain.dynamicType);
|
||||
node.block.addBefore(node, typeInfo);
|
||||
} else {
|
||||
|
|
|
@ -66,6 +66,8 @@ main() {
|
|||
}
|
||||
"""));
|
||||
|
||||
var types = env.types;
|
||||
|
||||
testToString(FunctionType type, String expectedToString) {
|
||||
Expect.equals(expectedToString, type.toString());
|
||||
}
|
||||
|
@ -81,14 +83,14 @@ main() {
|
|||
|
||||
testInstantiate(FunctionType type, List<DartType> instantiation,
|
||||
String expectedToString) {
|
||||
DartType result = type.instantiate(instantiation);
|
||||
DartType result = types.instantiate(type, instantiation);
|
||||
Expect.equals(expectedToString, result.toString(),
|
||||
"Unexpected instantiation of $type with $instantiation: $result");
|
||||
}
|
||||
|
||||
void testSubst(List<DartType> arguments, List<DartType> parameters,
|
||||
DartType type1, String expectedToString) {
|
||||
DartType subst = type1.subst(arguments, parameters);
|
||||
DartType subst = types.subst(arguments, parameters, type1);
|
||||
Expect.equals(expectedToString, subst.toString(),
|
||||
"$type1.subst($arguments,$parameters)");
|
||||
}
|
||||
|
@ -117,10 +119,10 @@ main() {
|
|||
InterfaceType Object_ = env['Object'];
|
||||
InterfaceType num_ = env['num'];
|
||||
InterfaceType int_ = env['int'];
|
||||
InterfaceType C1 = instantiate(env.getClass('C1'), []);
|
||||
InterfaceType C2 = instantiate(env.getClass('C2'), []);
|
||||
InterfaceType C1 = instantiate(types, env.getClass('C1'), []);
|
||||
InterfaceType C2 = instantiate(types, env.getClass('C2'), []);
|
||||
ClassEntity C3 = env.getClass('C3');
|
||||
InterfaceType C4 = instantiate(env.getClass('C4'), []);
|
||||
InterfaceType C4 = instantiate(types, env.getClass('C4'), []);
|
||||
FunctionType F1 = env.getFieldType('F1');
|
||||
FunctionType F2 = env.getFieldType('F2');
|
||||
FunctionType F3 = env.getFieldType('F3');
|
||||
|
@ -203,10 +205,10 @@ main() {
|
|||
testBounds(F9, [F9.typeVariables.last, Object_]);
|
||||
testBounds(F10, [F10.typeVariables.last, Object_]);
|
||||
testBounds(F11, [
|
||||
instantiate(C3, [F11.typeVariables.last])
|
||||
instantiate(types, C3, [F11.typeVariables.last])
|
||||
]);
|
||||
testBounds(F12, [
|
||||
instantiate(C3, [F12.typeVariables.last])
|
||||
instantiate(types, C3, [F12.typeVariables.last])
|
||||
]);
|
||||
testBounds(F13, [Object_]);
|
||||
testBounds(F14, [Object_]);
|
||||
|
|
|
@ -17,8 +17,9 @@ import 'package:compiler/src/kernel/kernel_strategy.dart';
|
|||
import 'package:compiler/src/world.dart' show JClosedWorld, KClosedWorld;
|
||||
import 'memory_compiler.dart' as memory;
|
||||
|
||||
DartType instantiate(ClassEntity element, List<DartType> arguments) {
|
||||
return new InterfaceType(element, arguments, Nullability.none);
|
||||
DartType instantiate(
|
||||
DartTypes dartTypes, ClassEntity element, List<DartType> arguments) {
|
||||
return dartTypes.interfaceType(element, arguments, Nullability.none);
|
||||
}
|
||||
|
||||
class TypeEnvironment {
|
||||
|
@ -112,10 +113,10 @@ class TypeEnvironment {
|
|||
|
||||
DartType operator [](String name) {
|
||||
if (name == 'dynamic') {
|
||||
return DynamicType();
|
||||
return types.dynamicType();
|
||||
}
|
||||
if (name == 'void') {
|
||||
return VoidType();
|
||||
return types.voidType();
|
||||
}
|
||||
return getElementType(name);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,9 @@ import 'package:expect/expect.dart';
|
|||
import 'package:compiler/src/native/behavior.dart';
|
||||
import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
|
||||
import 'package:compiler/src/diagnostics/messages.dart';
|
||||
import 'package:compiler/src/elements/types.dart';
|
||||
import 'package:compiler/src/universe/side_effects.dart' show SideEffects;
|
||||
import '../helpers/type_test_helper.dart';
|
||||
|
||||
const OBJECT = 'Object';
|
||||
const NULL = 'Null';
|
||||
|
@ -39,7 +41,7 @@ class Listener extends DiagnosticReporter {
|
|||
noSuchMethod(_) => null;
|
||||
}
|
||||
|
||||
void test(String specString,
|
||||
void test(DartTypes dartTypes, String specString,
|
||||
{List returns,
|
||||
List creates,
|
||||
SideEffects expectedSideEffects,
|
||||
|
@ -55,7 +57,7 @@ void test(String specString,
|
|||
bool actualGvn;
|
||||
Listener listener = new Listener();
|
||||
try {
|
||||
NativeBehavior.processSpecString(listener, null, specString,
|
||||
NativeBehavior.processSpecString(dartTypes, listener, null, specString,
|
||||
setSideEffects: (effects) => actualSideEffects = effects,
|
||||
setThrows: (b) => actualThrows = b,
|
||||
setIsAllocation: (b) => actualNew = b,
|
||||
|
@ -84,11 +86,11 @@ void test(String specString,
|
|||
Expect.equals(expectedGvn, actualGvn);
|
||||
}
|
||||
|
||||
void testWithSideEffects(String specString,
|
||||
void testWithSideEffects(DartTypes dartTypes, String specString,
|
||||
{List returns, List creates, bool expectError: false}) {
|
||||
void sideEffectsTest(String newSpecString, SideEffects expectedSideEffects,
|
||||
{bool sideEffectsExpectError}) {
|
||||
test(newSpecString,
|
||||
test(dartTypes, newSpecString,
|
||||
returns: returns,
|
||||
creates: creates,
|
||||
expectedSideEffects: expectedSideEffects,
|
||||
|
@ -194,105 +196,117 @@ void testWithSideEffects(String specString,
|
|||
sideEffectsExpectError: true);
|
||||
}
|
||||
|
||||
void main() {
|
||||
test('void', returns: [], creates: []);
|
||||
test('', returns: [OBJECT, NULL], creates: []);
|
||||
test('var', returns: [OBJECT, NULL], creates: []);
|
||||
test('A', returns: ['A'], creates: ['A']);
|
||||
test('A|B', returns: ['A', 'B'], creates: ['A', 'B']);
|
||||
test('A|B|C', returns: ['A', 'B', 'C'], creates: ['A', 'B', 'C']);
|
||||
void main() async {
|
||||
var env = await TypeEnvironment.create('');
|
||||
var types = env.types;
|
||||
test(types, 'void', returns: [], creates: []);
|
||||
test(types, '', returns: [OBJECT, NULL], creates: []);
|
||||
test(types, 'var', returns: [OBJECT, NULL], creates: []);
|
||||
test(types, 'A', returns: ['A'], creates: ['A']);
|
||||
test(types, 'A|B', returns: ['A', 'B'], creates: ['A', 'B']);
|
||||
test(types, 'A|B|C', returns: ['A', 'B', 'C'], creates: ['A', 'B', 'C']);
|
||||
|
||||
test('returns:void;', returns: [], creates: []);
|
||||
test('returns:;', returns: [OBJECT, NULL], creates: []);
|
||||
test('returns:var;', returns: [OBJECT, NULL], creates: []);
|
||||
test('returns:A;', returns: ['A'], creates: ['A']);
|
||||
test('returns:A|B;', returns: ['A', 'B'], creates: ['A', 'B']);
|
||||
test('returns:A|B|C;', returns: ['A', 'B', 'C'], creates: ['A', 'B', 'C']);
|
||||
test(types, 'returns:void;', returns: [], creates: []);
|
||||
test(types, 'returns:;', returns: [OBJECT, NULL], creates: []);
|
||||
test(types, 'returns:var;', returns: [OBJECT, NULL], creates: []);
|
||||
test(types, 'returns:A;', returns: ['A'], creates: ['A']);
|
||||
test(types, 'returns:A|B;', returns: ['A', 'B'], creates: ['A', 'B']);
|
||||
test(types, 'returns:A|B|C;',
|
||||
returns: ['A', 'B', 'C'], creates: ['A', 'B', 'C']);
|
||||
|
||||
test('creates:void;', expectError: true);
|
||||
test('creates:;', creates: []);
|
||||
test('creates:var;', creates: []);
|
||||
test('creates:A;', returns: [], creates: ['A']);
|
||||
test('creates:A|B;', returns: [], creates: ['A', 'B']);
|
||||
test('creates:A|B|C;', returns: [], creates: ['A', 'B', 'C']);
|
||||
test(types, 'creates:void;', expectError: true);
|
||||
test(types, 'creates:;', creates: []);
|
||||
test(types, 'creates:var;', creates: []);
|
||||
test(types, 'creates:A;', returns: [], creates: ['A']);
|
||||
test(types, 'creates:A|B;', returns: [], creates: ['A', 'B']);
|
||||
test(types, 'creates:A|B|C;', returns: [], creates: ['A', 'B', 'C']);
|
||||
|
||||
test('returns:void;creates:', returns: [], creates: []);
|
||||
test('returns:;creates:', returns: [OBJECT, NULL], creates: []);
|
||||
test('returns:var;creates:', returns: [OBJECT, NULL], creates: []);
|
||||
test('returns:A;creates:', returns: ['A'], creates: []);
|
||||
test('returns:A|B;creates:;', returns: ['A', 'B'], creates: []);
|
||||
test('returns:A|B|C;creates:;', returns: ['A', 'B', 'C'], creates: []);
|
||||
test(types, 'returns:void;creates:', returns: [], creates: []);
|
||||
test(types, 'returns:;creates:', returns: [OBJECT, NULL], creates: []);
|
||||
test(types, 'returns:var;creates:', returns: [OBJECT, NULL], creates: []);
|
||||
test(types, 'returns:A;creates:', returns: ['A'], creates: []);
|
||||
test(types, 'returns:A|B;creates:;', returns: ['A', 'B'], creates: []);
|
||||
test(types, 'returns:A|B|C;creates:;', returns: ['A', 'B', 'C'], creates: []);
|
||||
|
||||
test('returns:void;creates:A;', returns: [], creates: ['A']);
|
||||
test('returns:;creates:A|B;', returns: [OBJECT, NULL], creates: ['A', 'B']);
|
||||
test('returns:var;creates:A|B|C;',
|
||||
test(types, 'returns:void;creates:A;', returns: [], creates: ['A']);
|
||||
test(types, 'returns:;creates:A|B;',
|
||||
returns: [OBJECT, NULL], creates: ['A', 'B']);
|
||||
test(types, 'returns:var;creates:A|B|C;',
|
||||
returns: [OBJECT, NULL], creates: ['A', 'B', 'C']);
|
||||
test('returns:A; creates:A|B|C; ', returns: ['A'], creates: ['A', 'B', 'C']);
|
||||
test(' returns:A|B; creates:A|C;', returns: ['A', 'B'], creates: ['A', 'C']);
|
||||
test(' returns:A|B|C; creates:A; ',
|
||||
test(types, 'returns:A; creates:A|B|C; ',
|
||||
returns: ['A'], creates: ['A', 'B', 'C']);
|
||||
test(types, ' returns:A|B; creates:A|C;',
|
||||
returns: ['A', 'B'], creates: ['A', 'C']);
|
||||
test(types, ' returns:A|B|C; creates:A; ',
|
||||
returns: ['A', 'B', 'C'], creates: ['A']);
|
||||
|
||||
testWithSideEffects('returns:void;', returns: [], creates: []);
|
||||
testWithSideEffects('returns:void;', returns: [], creates: []);
|
||||
testWithSideEffects('returns:;', returns: [OBJECT, NULL], creates: []);
|
||||
testWithSideEffects('returns:var;', returns: [OBJECT, NULL], creates: []);
|
||||
testWithSideEffects('returns:A;', returns: ['A'], creates: ['A']);
|
||||
testWithSideEffects('returns:A|B;', returns: ['A', 'B'], creates: ['A', 'B']);
|
||||
testWithSideEffects('returns:A|B|C;',
|
||||
testWithSideEffects(types, 'returns:void;', returns: [], creates: []);
|
||||
testWithSideEffects(types, 'returns:void;', returns: [], creates: []);
|
||||
testWithSideEffects(types, 'returns:;', returns: [OBJECT, NULL], creates: []);
|
||||
testWithSideEffects(types, 'returns:var;',
|
||||
returns: [OBJECT, NULL], creates: []);
|
||||
testWithSideEffects(types, 'returns:A;', returns: ['A'], creates: ['A']);
|
||||
testWithSideEffects(types, 'returns:A|B;',
|
||||
returns: ['A', 'B'], creates: ['A', 'B']);
|
||||
testWithSideEffects(types, 'returns:A|B|C;',
|
||||
returns: ['A', 'B', 'C'], creates: ['A', 'B', 'C']);
|
||||
testWithSideEffects('returns: A| B |C ;',
|
||||
testWithSideEffects(types, 'returns: A| B |C ;',
|
||||
returns: ['A', 'B', 'C'], creates: ['A', 'B', 'C']);
|
||||
|
||||
testWithSideEffects('creates:void;', expectError: true);
|
||||
testWithSideEffects('creates:;', creates: []);
|
||||
testWithSideEffects('creates:var;', creates: []);
|
||||
testWithSideEffects('creates:A;', returns: [], creates: ['A']);
|
||||
testWithSideEffects('creates:A|B;', returns: [], creates: ['A', 'B']);
|
||||
testWithSideEffects('creates:A|B|C;', returns: [], creates: ['A', 'B', 'C']);
|
||||
testWithSideEffects(types, 'creates:void;', expectError: true);
|
||||
testWithSideEffects(types, 'creates:;', creates: []);
|
||||
testWithSideEffects(types, 'creates:var;', creates: []);
|
||||
testWithSideEffects(types, 'creates:A;', returns: [], creates: ['A']);
|
||||
testWithSideEffects(types, 'creates:A|B;', returns: [], creates: ['A', 'B']);
|
||||
testWithSideEffects(types, 'creates:A|B|C;',
|
||||
returns: [], creates: ['A', 'B', 'C']);
|
||||
|
||||
testWithSideEffects('returns:void;creates:;', returns: [], creates: []);
|
||||
testWithSideEffects('returns:;creates:;',
|
||||
testWithSideEffects(types, 'returns:void;creates:;',
|
||||
returns: [], creates: []);
|
||||
testWithSideEffects(types, 'returns:;creates:;',
|
||||
returns: [OBJECT, NULL], creates: []);
|
||||
testWithSideEffects('returns:var;creates:;',
|
||||
testWithSideEffects(types, 'returns:var;creates:;',
|
||||
returns: [OBJECT, NULL], creates: []);
|
||||
testWithSideEffects('returns:A;creates:;', returns: ['A'], creates: []);
|
||||
testWithSideEffects('returns:A|B;creates:;',
|
||||
testWithSideEffects(types, 'returns:A;creates:;',
|
||||
returns: ['A'], creates: []);
|
||||
testWithSideEffects(types, 'returns:A|B;creates:;',
|
||||
returns: ['A', 'B'], creates: []);
|
||||
testWithSideEffects('returns:A|B|C;creates:;',
|
||||
testWithSideEffects(types, 'returns:A|B|C;creates:;',
|
||||
returns: ['A', 'B', 'C'], creates: []);
|
||||
|
||||
testWithSideEffects('returns:void;creates:A;', returns: [], creates: ['A']);
|
||||
testWithSideEffects('returns:;creates:A|B;',
|
||||
testWithSideEffects(types, 'returns:void;creates:A;',
|
||||
returns: [], creates: ['A']);
|
||||
testWithSideEffects(types, 'returns:;creates:A|B;',
|
||||
returns: [OBJECT, NULL], creates: ['A', 'B']);
|
||||
testWithSideEffects('returns:var;creates:A|B|C;',
|
||||
testWithSideEffects(types, 'returns:var;creates:A|B|C;',
|
||||
returns: [OBJECT, NULL], creates: ['A', 'B', 'C']);
|
||||
testWithSideEffects('returns:A; creates:A|B|C; ',
|
||||
testWithSideEffects(types, 'returns:A; creates:A|B|C; ',
|
||||
returns: ['A'], creates: ['A', 'B', 'C']);
|
||||
testWithSideEffects(' returns:A|B; creates:A|C;',
|
||||
testWithSideEffects(types, ' returns:A|B; creates:A|C;',
|
||||
returns: ['A', 'B'], creates: ['A', 'C']);
|
||||
testWithSideEffects(' returns:A|B|C; creates:A; ',
|
||||
testWithSideEffects(types, ' returns:A|B|C; creates:A; ',
|
||||
returns: ['A', 'B', 'C'], creates: ['A']);
|
||||
|
||||
test('throws:may', expectedThrows: NativeThrowBehavior.MAY);
|
||||
test('throws:never', expectedThrows: NativeThrowBehavior.NEVER);
|
||||
test('throws:null(1)', expectedThrows: NativeThrowBehavior.NULL_NSM);
|
||||
test('throws:null(1)+may',
|
||||
test(types, 'throws:may', expectedThrows: NativeThrowBehavior.MAY);
|
||||
test(types, 'throws:never', expectedThrows: NativeThrowBehavior.NEVER);
|
||||
test(types, 'throws:null(1)', expectedThrows: NativeThrowBehavior.NULL_NSM);
|
||||
test(types, 'throws:null(1)+may',
|
||||
expectedThrows: NativeThrowBehavior.NULL_NSM_THEN_MAY);
|
||||
|
||||
test('new:true', expectedNew: true);
|
||||
test('new:false', expectedNew: false);
|
||||
test('returns:A;new:true', returns: ['A'], expectedNew: true);
|
||||
test(' new : true ; returns:A;', returns: ['A'], expectedNew: true);
|
||||
test('new:true;returns:A;new:true', expectError: true);
|
||||
test(types, 'new:true', expectedNew: true);
|
||||
test(types, 'new:false', expectedNew: false);
|
||||
test(types, 'returns:A;new:true', returns: ['A'], expectedNew: true);
|
||||
test(types, ' new : true ; returns:A;', returns: ['A'], expectedNew: true);
|
||||
test(types, 'new:true;returns:A;new:true', expectError: true);
|
||||
|
||||
test('gvn:true', expectedGvn: true);
|
||||
test('gvn:false', expectedGvn: false);
|
||||
test('returns:A;gvn:true', returns: ['A'], expectedGvn: true);
|
||||
test(' gvn : true ; returns:A;', returns: ['A'], expectedGvn: true);
|
||||
test('gvn:true;returns:A;gvn:true', expectError: true);
|
||||
test(types, 'gvn:true', expectedGvn: true);
|
||||
test(types, 'gvn:false', expectedGvn: false);
|
||||
test(types, 'returns:A;gvn:true', returns: ['A'], expectedGvn: true);
|
||||
test(types, ' gvn : true ; returns:A;', returns: ['A'], expectedGvn: true);
|
||||
test(types, 'gvn:true;returns:A;gvn:true', expectError: true);
|
||||
|
||||
test('gvn: true; new: true', expectError: true);
|
||||
test('gvn: true; new: false', expectedGvn: true, expectedNew: false);
|
||||
test('gvn: false; new: true', expectedGvn: false, expectedNew: true);
|
||||
test('gvn: false; new: false', expectedGvn: false, expectedNew: false);
|
||||
test(types, 'gvn: true; new: true', expectError: true);
|
||||
test(types, 'gvn: true; new: false', expectedGvn: true, expectedNew: false);
|
||||
test(types, 'gvn: false; new: true', expectedGvn: false, expectedNew: true);
|
||||
test(types, 'gvn: false; new: false', expectedGvn: false, expectedNew: false);
|
||||
}
|
||||
|
|
|
@ -99,8 +99,8 @@ main() {
|
|||
getReturnType('futureOrFutureOrNum', 'FutureOr<FutureOr<num>>');
|
||||
|
||||
DartType futureNull = getReturnType('futureNull', 'Future<Null>');
|
||||
FutureOrType futureOrNull = getReturnType('futureOrNull', 'FutureOr<Null>');
|
||||
DartType Null_ = futureOrNull.typeArgument;
|
||||
InterfaceType futureOrNull = getReturnType('futureOrNull', 'Future<Null>');
|
||||
DartType Null_ = futureOrNull.typeArguments.single;
|
||||
|
||||
ClassEntity C = env.getClass('C');
|
||||
DartType futureT = getReturnType('futureT', 'Future<C.T>', C);
|
||||
|
@ -111,7 +111,7 @@ main() {
|
|||
|
||||
DartType returnVoid = getFunctionType('returnVoid', 'void Function()');
|
||||
DartType returnFutureNull =
|
||||
getFunctionType('futureOrNull', 'FutureOr<Null> Function()');
|
||||
getFunctionType('futureOrNull', 'Future<Null> Function()');
|
||||
|
||||
List<DartType> all = [
|
||||
Object_,
|
||||
|
|
|
@ -106,6 +106,7 @@ testNonTrivialSubstitutions() async {
|
|||
new F2();
|
||||
}
|
||||
""", expectNoWarningsOrErrors: true);
|
||||
var types = env.types;
|
||||
DartType _dynamic = env['dynamic'];
|
||||
DartType _ = env['_'];
|
||||
|
||||
|
@ -178,7 +179,7 @@ testNonTrivialSubstitutions() async {
|
|||
A: [D1_T],
|
||||
B: [
|
||||
D1_T,
|
||||
instantiate(A, [D1_T])
|
||||
instantiate(types, A, [D1_T])
|
||||
]
|
||||
});
|
||||
DartType D1_superclass_T = env.elementEnvironment
|
||||
|
@ -189,7 +190,7 @@ testNonTrivialSubstitutions() async {
|
|||
A: [D1_superclass_T],
|
||||
B: [
|
||||
D1_superclass_T,
|
||||
instantiate(A, [D1_superclass_T])
|
||||
instantiate(types, A, [D1_superclass_T])
|
||||
]
|
||||
});
|
||||
DartType D2_T = env.elementEnvironment.getThisType(D2).typeArguments.first;
|
||||
|
@ -197,7 +198,7 @@ testNonTrivialSubstitutions() async {
|
|||
A: [D2_T],
|
||||
B: [
|
||||
D2_T,
|
||||
instantiate(A, [D2_T])
|
||||
instantiate(types, A, [D2_T])
|
||||
]
|
||||
});
|
||||
|
||||
|
@ -205,21 +206,21 @@ testNonTrivialSubstitutions() async {
|
|||
A: [_],
|
||||
B: [
|
||||
_,
|
||||
instantiate(A, [_])
|
||||
instantiate(types, A, [_])
|
||||
]
|
||||
});
|
||||
testSupertypes(env.elementEnvironment.getSuperClass(E1), {
|
||||
A: [_],
|
||||
B: [
|
||||
_,
|
||||
instantiate(A, [_])
|
||||
instantiate(types, A, [_])
|
||||
]
|
||||
});
|
||||
testSupertypes(E2, {
|
||||
A: [_],
|
||||
B: [
|
||||
_,
|
||||
instantiate(A, [_])
|
||||
instantiate(types, A, [_])
|
||||
]
|
||||
});
|
||||
|
||||
|
@ -228,7 +229,7 @@ testNonTrivialSubstitutions() async {
|
|||
A: [_],
|
||||
B: [
|
||||
_,
|
||||
instantiate(B, [F1_T, _])
|
||||
instantiate(types, B, [F1_T, _])
|
||||
]
|
||||
});
|
||||
DartType F1_superclass_T = env.elementEnvironment
|
||||
|
@ -239,7 +240,7 @@ testNonTrivialSubstitutions() async {
|
|||
A: [_],
|
||||
B: [
|
||||
_,
|
||||
instantiate(B, [F1_superclass_T, _])
|
||||
instantiate(types, B, [F1_superclass_T, _])
|
||||
]
|
||||
});
|
||||
DartType F2_T = env.elementEnvironment.getThisType(F2).typeArguments.first;
|
||||
|
@ -247,7 +248,7 @@ testNonTrivialSubstitutions() async {
|
|||
A: [_],
|
||||
B: [
|
||||
_,
|
||||
instantiate(B, [F2_T, _])
|
||||
instantiate(types, B, [F2_T, _])
|
||||
]
|
||||
});
|
||||
}
|
||||
|
|
|
@ -63,6 +63,8 @@ Future testInterfaceSubtype() async {
|
|||
testTypes(env, T, S, expectSubtype);
|
||||
}
|
||||
|
||||
var types = env.types;
|
||||
|
||||
ClassEntity A = env.getClass('A');
|
||||
ClassEntity B = env.getClass('B');
|
||||
ClassEntity C = env.getClass('C');
|
||||
|
@ -124,12 +126,12 @@ Future testInterfaceSubtype() async {
|
|||
expect(false, dynamic_, Null_);
|
||||
expect(true, Null_, Null_);
|
||||
|
||||
DartType A_Object = instantiate(A, [Object_]);
|
||||
DartType A_num = instantiate(A, [num_]);
|
||||
DartType A_int = instantiate(A, [int_]);
|
||||
DartType A_String = instantiate(A, [String_]);
|
||||
DartType A_dynamic = instantiate(A, [dynamic_]);
|
||||
DartType A_Null = instantiate(A, [Null_]);
|
||||
DartType A_Object = instantiate(types, A, [Object_]);
|
||||
DartType A_num = instantiate(types, A, [num_]);
|
||||
DartType A_int = instantiate(types, A, [int_]);
|
||||
DartType A_String = instantiate(types, A, [String_]);
|
||||
DartType A_dynamic = instantiate(types, A, [dynamic_]);
|
||||
DartType A_Null = instantiate(types, A, [Null_]);
|
||||
|
||||
expect(true, A_Object, Object_);
|
||||
expect(false, A_Object, num_);
|
||||
|
@ -180,11 +182,11 @@ Future testInterfaceSubtype() async {
|
|||
expect(false, A_dynamic, A_Null);
|
||||
expect(true, A_Null, A_Null);
|
||||
|
||||
DartType B_Object_Object = instantiate(B, [Object_, Object_]);
|
||||
DartType B_num_num = instantiate(B, [num_, num_]);
|
||||
DartType B_int_num = instantiate(B, [int_, num_]);
|
||||
DartType B_dynamic_dynamic = instantiate(B, [dynamic_, dynamic_]);
|
||||
DartType B_String_dynamic = instantiate(B, [String_, dynamic_]);
|
||||
DartType B_Object_Object = instantiate(types, B, [Object_, Object_]);
|
||||
DartType B_num_num = instantiate(types, B, [num_, num_]);
|
||||
DartType B_int_num = instantiate(types, B, [int_, num_]);
|
||||
DartType B_dynamic_dynamic = instantiate(types, B, [dynamic_, dynamic_]);
|
||||
DartType B_String_dynamic = instantiate(types, B, [String_, dynamic_]);
|
||||
|
||||
expect(true, B_Object_Object, Object_);
|
||||
expect(true, B_Object_Object, A_Object);
|
||||
|
@ -251,10 +253,10 @@ Future testInterfaceSubtype() async {
|
|||
expect(false, B_dynamic_dynamic, B_String_dynamic);
|
||||
expect(true, B_String_dynamic, B_String_dynamic);
|
||||
|
||||
DartType C_Object_Object = instantiate(C, [Object_, Object_]);
|
||||
DartType C_num_num = instantiate(C, [num_, num_]);
|
||||
DartType C_int_String = instantiate(C, [int_, String_]);
|
||||
DartType C_dynamic_dynamic = instantiate(C, [dynamic_, dynamic_]);
|
||||
DartType C_Object_Object = instantiate(types, C, [Object_, Object_]);
|
||||
DartType C_num_num = instantiate(types, C, [num_, num_]);
|
||||
DartType C_int_String = instantiate(types, C, [int_, String_]);
|
||||
DartType C_dynamic_dynamic = instantiate(types, C, [dynamic_, dynamic_]);
|
||||
|
||||
expect(true, C_Object_Object, B_Object_Object);
|
||||
expect(false, C_Object_Object, B_num_num);
|
||||
|
@ -285,7 +287,7 @@ Future testInterfaceSubtype() async {
|
|||
// TODO(johnniwinther): Inheritance with different type arguments is
|
||||
// currently not supported by the implementation.
|
||||
//expect(true, C_int_String, instantiate(A, [A_int]));
|
||||
expect(false, C_int_String, instantiate(A, [A_String]));
|
||||
expect(false, C_int_String, instantiate(types, A, [A_String]));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -749,6 +751,8 @@ Future testStrongModeSubtyping() async {
|
|||
}
|
||||
}
|
||||
|
||||
var types = env.types;
|
||||
|
||||
InterfaceType ClassWithCall = env['ClassWithCall'];
|
||||
DartType Object_ = env['Object'];
|
||||
DartType dynamic_ = env['dynamic'];
|
||||
|
@ -758,11 +762,16 @@ Future testStrongModeSubtyping() async {
|
|||
DartType ClassWithCallType =
|
||||
env.getMemberType('call', ClassWithCall.element);
|
||||
|
||||
InterfaceType List_Object = env.commonElements.listType(Object_);
|
||||
InterfaceType List_dynamic = env.commonElements.listType(dynamic_);
|
||||
InterfaceType List_void = env.commonElements.listType(void_);
|
||||
InterfaceType List_Null = env.commonElements.listType(Null_);
|
||||
InterfaceType List_Function = env.commonElements.listType(Function_);
|
||||
InterfaceType List_Object =
|
||||
env.commonElements.listType(types.defaultNullability, Object_);
|
||||
InterfaceType List_dynamic =
|
||||
env.commonElements.listType(types.defaultNullability, dynamic_);
|
||||
InterfaceType List_void =
|
||||
env.commonElements.listType(types.defaultNullability, void_);
|
||||
InterfaceType List_Null =
|
||||
env.commonElements.listType(types.defaultNullability, Null_);
|
||||
InterfaceType List_Function =
|
||||
env.commonElements.listType(types.defaultNullability, Function_);
|
||||
|
||||
DartType returnNum = env.getMemberType('returnNum');
|
||||
DartType returnInt = env.getMemberType('returnInt');
|
||||
|
|
|
@ -58,6 +58,7 @@ testAsInstanceOf() async {
|
|||
new F();
|
||||
}
|
||||
''');
|
||||
var types = env.types;
|
||||
ClassEntity A = env.getElement("A");
|
||||
ClassEntity B = env.getElement("B");
|
||||
ClassEntity C = env.getElement("C");
|
||||
|
@ -68,34 +69,34 @@ testAsInstanceOf() async {
|
|||
DartType intType = env['int'];
|
||||
DartType stringType = env['String'];
|
||||
|
||||
InterfaceType C_int = instantiate(C, [intType]);
|
||||
Expect.equals(instantiate(C, [intType]), C_int);
|
||||
Expect.equals(instantiate(A, [intType]), env.types.asInstanceOf(C_int, A));
|
||||
InterfaceType C_int = instantiate(types, C, [intType]);
|
||||
Expect.equals(instantiate(types, C, [intType]), C_int);
|
||||
Expect.equals(instantiate(types, A, [intType]), types.asInstanceOf(C_int, A));
|
||||
|
||||
InterfaceType D_int = instantiate(D, [stringType]);
|
||||
Expect.equals(instantiate(A, [intType]), env.types.asInstanceOf(D_int, A));
|
||||
InterfaceType D_int = instantiate(types, D, [stringType]);
|
||||
Expect.equals(instantiate(types, A, [intType]), types.asInstanceOf(D_int, A));
|
||||
|
||||
InterfaceType E_int = instantiate(E, [intType]);
|
||||
InterfaceType E_int = instantiate(types, E, [intType]);
|
||||
Expect.equals(
|
||||
instantiate(A, [
|
||||
instantiate(A, [intType])
|
||||
instantiate(types, A, [
|
||||
instantiate(types, A, [intType])
|
||||
]),
|
||||
env.types.asInstanceOf(E_int, A));
|
||||
types.asInstanceOf(E_int, A));
|
||||
|
||||
InterfaceType F_int_string = instantiate(F, [intType, stringType]);
|
||||
InterfaceType F_int_string = instantiate(types, F, [intType, stringType]);
|
||||
Expect.equals(
|
||||
instantiate(B, [
|
||||
instantiate(F, [intType, stringType])
|
||||
instantiate(types, B, [
|
||||
instantiate(types, F, [intType, stringType])
|
||||
]),
|
||||
env.types.asInstanceOf(F_int_string, B));
|
||||
types.asInstanceOf(F_int_string, B));
|
||||
Expect.equals(
|
||||
instantiate(A, [
|
||||
instantiate(F, [
|
||||
instantiate(B, [stringType]),
|
||||
instantiate(types, A, [
|
||||
instantiate(types, F, [
|
||||
instantiate(types, B, [stringType]),
|
||||
intType
|
||||
])
|
||||
]),
|
||||
env.types.asInstanceOf(F_int_string, A));
|
||||
types.asInstanceOf(F_int_string, A));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -103,12 +104,13 @@ testAsInstanceOf() async {
|
|||
* through [name1] is the same as the type found through [name2].
|
||||
*/
|
||||
void testSubstitution(
|
||||
DartTypes dartTypes,
|
||||
ElementEnvironment elementEnvironment,
|
||||
List<DartType> arguments,
|
||||
List<DartType> parameters,
|
||||
DartType type1,
|
||||
DartType type2) {
|
||||
DartType subst = type1.subst(arguments, parameters);
|
||||
DartType subst = dartTypes.subst(arguments, parameters, type1);
|
||||
Expect.equals(
|
||||
type2, subst, "$type1.subst($arguments,$parameters)=$subst != $type2");
|
||||
}
|
||||
|
@ -119,6 +121,7 @@ testTypeSubstitution() async {
|
|||
|
||||
main() => new Class();
|
||||
""");
|
||||
var types = env.types;
|
||||
InterfaceType Class_T_S = env["Class"];
|
||||
Expect.isNotNull(Class_T_S);
|
||||
Expect.isTrue(Class_T_S is InterfaceType);
|
||||
|
@ -146,79 +149,103 @@ testTypeSubstitution() async {
|
|||
List<DartType> parameters = <DartType>[T, S];
|
||||
List<DartType> arguments = <DartType>[intType, StringType];
|
||||
|
||||
testSubstitution(types, env.elementEnvironment, arguments, parameters,
|
||||
types.voidType(), types.voidType());
|
||||
testSubstitution(types, env.elementEnvironment, arguments, parameters,
|
||||
types.dynamicType(), types.dynamicType());
|
||||
testSubstitution(
|
||||
env.elementEnvironment, arguments, parameters, VoidType(), VoidType());
|
||||
testSubstitution(env.elementEnvironment, arguments, parameters, DynamicType(),
|
||||
DynamicType());
|
||||
testSubstitution(
|
||||
env.elementEnvironment, arguments, parameters, intType, intType);
|
||||
testSubstitution(
|
||||
env.elementEnvironment, arguments, parameters, StringType, StringType);
|
||||
testSubstitution(env.elementEnvironment, arguments, parameters,
|
||||
instantiate(ListClass, [intType]), instantiate(ListClass, [intType]));
|
||||
testSubstitution(env.elementEnvironment, arguments, parameters,
|
||||
instantiate(ListClass, [T]), instantiate(ListClass, [intType]));
|
||||
testSubstitution(env.elementEnvironment, arguments, parameters,
|
||||
instantiate(ListClass, [S]), instantiate(ListClass, [StringType]));
|
||||
types, env.elementEnvironment, arguments, parameters, intType, intType);
|
||||
testSubstitution(types, env.elementEnvironment, arguments, parameters,
|
||||
StringType, StringType);
|
||||
testSubstitution(
|
||||
types,
|
||||
env.elementEnvironment,
|
||||
arguments,
|
||||
parameters,
|
||||
instantiate(ListClass, [
|
||||
instantiate(ListClass, [T])
|
||||
instantiate(types, ListClass, [intType]),
|
||||
instantiate(types, ListClass, [intType]));
|
||||
testSubstitution(
|
||||
types,
|
||||
env.elementEnvironment,
|
||||
arguments,
|
||||
parameters,
|
||||
instantiate(types, ListClass, [T]),
|
||||
instantiate(types, ListClass, [intType]));
|
||||
testSubstitution(
|
||||
types,
|
||||
env.elementEnvironment,
|
||||
arguments,
|
||||
parameters,
|
||||
instantiate(types, ListClass, [S]),
|
||||
instantiate(types, ListClass, [StringType]));
|
||||
testSubstitution(
|
||||
types,
|
||||
env.elementEnvironment,
|
||||
arguments,
|
||||
parameters,
|
||||
instantiate(types, ListClass, [
|
||||
instantiate(types, ListClass, [T])
|
||||
]),
|
||||
instantiate(ListClass, [
|
||||
instantiate(ListClass, [intType])
|
||||
instantiate(types, ListClass, [
|
||||
instantiate(types, ListClass, [intType])
|
||||
]));
|
||||
testSubstitution(
|
||||
types,
|
||||
env.elementEnvironment,
|
||||
arguments,
|
||||
parameters,
|
||||
instantiate(ListClass, [DynamicType()]),
|
||||
instantiate(ListClass, [DynamicType()]));
|
||||
instantiate(types, ListClass, [types.dynamicType()]),
|
||||
instantiate(types, ListClass, [types.dynamicType()]));
|
||||
testSubstitution(
|
||||
types,
|
||||
env.elementEnvironment,
|
||||
arguments,
|
||||
parameters,
|
||||
instantiate(MapClass, [intType, StringType]),
|
||||
instantiate(MapClass, [intType, StringType]));
|
||||
instantiate(types, MapClass, [intType, StringType]),
|
||||
instantiate(types, MapClass, [intType, StringType]));
|
||||
testSubstitution(
|
||||
types,
|
||||
env.elementEnvironment,
|
||||
arguments,
|
||||
parameters,
|
||||
instantiate(MapClass, [T, StringType]),
|
||||
instantiate(MapClass, [intType, StringType]));
|
||||
instantiate(types, MapClass, [T, StringType]),
|
||||
instantiate(types, MapClass, [intType, StringType]));
|
||||
testSubstitution(
|
||||
types,
|
||||
env.elementEnvironment,
|
||||
arguments,
|
||||
parameters,
|
||||
instantiate(MapClass, [DynamicType(), StringType]),
|
||||
instantiate(MapClass, [DynamicType(), StringType]));
|
||||
testSubstitution(env.elementEnvironment, arguments, parameters, T, intType);
|
||||
instantiate(types, MapClass, [types.dynamicType(), StringType]),
|
||||
instantiate(types, MapClass, [types.dynamicType(), StringType]));
|
||||
testSubstitution(
|
||||
env.elementEnvironment, arguments, parameters, S, StringType);
|
||||
types, env.elementEnvironment, arguments, parameters, T, intType);
|
||||
testSubstitution(
|
||||
types, env.elementEnvironment, arguments, parameters, S, StringType);
|
||||
testSubstitution(
|
||||
types,
|
||||
env.elementEnvironment,
|
||||
arguments,
|
||||
parameters,
|
||||
new FunctionType(
|
||||
intType, [StringType], [], [], [], [], env.types.defaultNullability),
|
||||
new FunctionType(
|
||||
intType, [StringType], [], [], [], [], env.types.defaultNullability));
|
||||
types.functionType(
|
||||
intType, [StringType], [], [], [], [], types.defaultNullability),
|
||||
types.functionType(
|
||||
intType, [StringType], [], [], [], [], types.defaultNullability));
|
||||
testSubstitution(
|
||||
types,
|
||||
env.elementEnvironment,
|
||||
arguments,
|
||||
parameters,
|
||||
new FunctionType(
|
||||
VoidType(), [T, S], [], [], [], [], env.types.defaultNullability),
|
||||
new FunctionType(VoidType(), [intType, StringType], [], [], [], [],
|
||||
env.types.defaultNullability));
|
||||
types.functionType(
|
||||
types.voidType(), [T, S], [], [], [], [], types.defaultNullability),
|
||||
types.functionType(types.voidType(), [intType, StringType], [], [], [],
|
||||
[], types.defaultNullability));
|
||||
testSubstitution(
|
||||
types,
|
||||
env.elementEnvironment,
|
||||
arguments,
|
||||
parameters,
|
||||
new FunctionType(VoidType(), [DynamicType()], [], [], [], [],
|
||||
env.types.defaultNullability),
|
||||
new FunctionType(VoidType(), [DynamicType()], [], [], [], [],
|
||||
env.types.defaultNullability));
|
||||
types.functionType(types.voidType(), [types.dynamicType()], [], [], [],
|
||||
[], types.defaultNullability),
|
||||
types.functionType(types.voidType(), [types.dynamicType()], [], [], [],
|
||||
[], types.defaultNullability));
|
||||
}
|
||||
|
|
|
@ -103,6 +103,7 @@ main() {
|
|||
}
|
||||
|
||||
JClosedWorld closedWorld = compiler.backendClosedWorldForTesting;
|
||||
DartTypes dartTypes = closedWorld.dartTypes;
|
||||
ElementEnvironment elementEnvironment = closedWorld.elementEnvironment;
|
||||
String func = rtiTags.functionTypeTag;
|
||||
String ret = rtiTags.functionTypeReturnTypeTag;
|
||||
|
@ -179,49 +180,51 @@ main() {
|
|||
// List
|
||||
expect(elementEnvironment.getRawType(List_), '[$List_rep,,]');
|
||||
// List<dynamic>
|
||||
expect(instantiate(List_, [dynamic_]), '[$List_rep,,]');
|
||||
expect(instantiate(dartTypes, List_, [dynamic_]), '[$List_rep,,]');
|
||||
// List<int>
|
||||
expect(instantiate(List_, [int_]), '[$List_rep, $int_rep]');
|
||||
expect(instantiate(dartTypes, List_, [int_]), '[$List_rep, $int_rep]');
|
||||
// List<Typedef1>
|
||||
expect(instantiate(List_, [Typedef1_]), '[$List_rep, {$func: 1, $retvoid}]',
|
||||
expect(
|
||||
instantiate(dartTypes, List_, [Typedef1_]),
|
||||
'[$List_rep, {$func: 1, $retvoid}]',
|
||||
'[$List_rep, {$func: 1, $retvoid$Typedef1_tag}]');
|
||||
expect(
|
||||
instantiate(List_, [Typedef2_]),
|
||||
instantiate(dartTypes, List_, [Typedef2_]),
|
||||
'[$List_rep, {$func: 1, $ret: $int_rep}]',
|
||||
'[$List_rep, {$func: 1, $ret: $int_rep$Typedef2_tag}]');
|
||||
expect(
|
||||
instantiate(List_, [Typedef3_]),
|
||||
instantiate(dartTypes, List_, [Typedef3_]),
|
||||
'[$List_rep, {$func: 1, $ret: [$List_rep, $int_rep]}]',
|
||||
'[$List_rep, {$func: 1, $ret: [$List_rep, $int_rep]$Typedef3_tag}]');
|
||||
expect(instantiate(List_, [Typedef4_]), '[$List_rep, {$func: 1}]',
|
||||
expect(instantiate(dartTypes, List_, [Typedef4_]), '[$List_rep, {$func: 1}]',
|
||||
'[$List_rep, {$func: 1$Typedef4_tag}]');
|
||||
expect(
|
||||
instantiate(List_, [Typedef5_]),
|
||||
instantiate(dartTypes, List_, [Typedef5_]),
|
||||
'[$List_rep, {$func: 1,'
|
||||
' $args: [$int_rep, $String_rep]}]',
|
||||
'[$List_rep, {$func: 1,'
|
||||
' $args: [$int_rep, $String_rep]$Typedef5_tag}]');
|
||||
expect(
|
||||
instantiate(List_, [Typedef6_]),
|
||||
instantiate(dartTypes, List_, [Typedef6_]),
|
||||
'[$List_rep, {$func: 1,'
|
||||
' $args: [$int_rep], $opt: [$String_rep]}]',
|
||||
'[$List_rep, {$func: 1,'
|
||||
' $args: [$int_rep], $opt: [$String_rep]$Typedef6_tag}]');
|
||||
expect(
|
||||
instantiate(List_, [Typedef7_]),
|
||||
instantiate(dartTypes, List_, [Typedef7_]),
|
||||
'[$List_rep, {$func: 1, $args: '
|
||||
'[$int_rep, $String_rep], $opt: [[$List_rep, $int_rep],,]}]',
|
||||
'[$List_rep, {$func: 1, $args: '
|
||||
'[$int_rep, $String_rep], $opt: [[$List_rep, $int_rep],,]'
|
||||
'$Typedef7_tag}]');
|
||||
expect(
|
||||
instantiate(List_, [Typedef8_]),
|
||||
instantiate(dartTypes, List_, [Typedef8_]),
|
||||
'[$List_rep, {$func: 1, $args: [$int_rep],'
|
||||
' $named: {b: $String_rep}}]',
|
||||
'[$List_rep, {$func: 1, $args: [$int_rep],'
|
||||
' $named: {b: $String_rep}$Typedef8_tag}]');
|
||||
expect(
|
||||
instantiate(List_, [Typedef9_]),
|
||||
instantiate(dartTypes, List_, [Typedef9_]),
|
||||
'[$List_rep, {$func: 1, '
|
||||
'$args: [$int_rep, $String_rep], $named: '
|
||||
'{c: [$List_rep, $int_rep], d: null}}]',
|
||||
|
@ -229,7 +232,7 @@ main() {
|
|||
'$args: [$int_rep, $String_rep], $named: {c: [$List_rep, $int_rep],'
|
||||
' d: null}$Typedef9_tag}]');
|
||||
expect(
|
||||
instantiate(List_, [Typedef10_]),
|
||||
instantiate(dartTypes, List_, [Typedef10_]),
|
||||
'[$List_rep, {$func: 1, '
|
||||
'$args: [{$func: 1, $retvoid, '
|
||||
'$args: [$int_rep], $opt: [,]}]}]',
|
||||
|
@ -238,7 +241,7 @@ main() {
|
|||
'$args: [$int_rep], $opt: [,]}]$Typedef10_tag}]');
|
||||
|
||||
expect(
|
||||
instantiate(List_, [Typedef11_]),
|
||||
instantiate(dartTypes, List_, [Typedef11_]),
|
||||
'[$List_rep, {$func: 1, $bounds: [$num_rep, $Object_rep], '
|
||||
'$ret: {$futureOr: 1, $futureOrType: $int_rep}, '
|
||||
'$args: [{$futureOr: 1, $futureOrType: 0}, 1, [$List_rep, -1]]}]');
|
||||
|
@ -249,10 +252,10 @@ main() {
|
|||
// Map
|
||||
expect(elementEnvironment.getRawType(Map_), '[$Map_rep,,,]');
|
||||
// Map<dynamic,dynamic>
|
||||
expect(instantiate(Map_, [dynamic_, dynamic_]), '[$Map_rep,,,]');
|
||||
expect(instantiate(dartTypes, Map_, [dynamic_, dynamic_]), '[$Map_rep,,,]');
|
||||
// Map<int,String>
|
||||
expect(
|
||||
instantiate(Map_, [int_, String_]), '[$Map_rep, $int_rep, $String_rep]');
|
||||
expect(instantiate(dartTypes, Map_, [int_, String_]),
|
||||
'[$Map_rep, $int_rep, $String_rep]');
|
||||
|
||||
// void m1() {}
|
||||
expect(findFunctionType(closedWorld, 'm1'), '{$func: 1, $retvoid}');
|
||||
|
|
Loading…
Reference in a new issue