mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
[dart2js] Represent nullability as a field.
Change-Id: I12f4c7acfa294b0e92d3f94f7099ffa2aa9cc0a1 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/134792 Reviewed-by: Sigmund Cherem <sigmund@google.com>
This commit is contained in:
parent
fcf88fe6fa
commit
573f470615
|
@ -1652,16 +1652,6 @@ class TypeDependencyVisitor implements DartTypeVisitor<void, Null> {
|
|||
types.forEach(visit);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitLegacyType(LegacyType type, Null argument) {
|
||||
visit(type.baseType);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitNullableType(NullableType type, Null argument) {
|
||||
visit(type.baseType);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitFutureOrType(FutureOrType type, Null argument) {
|
||||
_dependencies.addClass(_commonElements.futureClass);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -5,6 +5,7 @@
|
|||
import '../common_elements.dart';
|
||||
import '../elements/entities.dart';
|
||||
import '../elements/types.dart';
|
||||
import '../options.dart';
|
||||
import '../ordered_typeset.dart';
|
||||
import 'element_map.dart';
|
||||
|
||||
|
@ -12,9 +13,13 @@ import 'element_map.dart';
|
|||
class KernelDartTypes extends DartTypes {
|
||||
final IrToElementMap elementMap;
|
||||
@override
|
||||
final bool useNullSafety;
|
||||
@override
|
||||
final bool useLegacySubtyping;
|
||||
|
||||
KernelDartTypes(this.elementMap, this.useLegacySubtyping);
|
||||
KernelDartTypes(this.elementMap, CompilerOptions options)
|
||||
: useNullSafety = options.useNullSafety,
|
||||
useLegacySubtyping = options.useLegacySubtyping;
|
||||
|
||||
@override
|
||||
InterfaceType getThisType(ClassEntity cls) {
|
||||
|
|
|
@ -50,6 +50,8 @@ class DartTypeConverter extends ir.DartTypeVisitor<DartType> {
|
|||
|
||||
DartTypeConverter(this.elementMap);
|
||||
|
||||
DartTypes get _dartTypes => elementMap.commonElements.dartTypes;
|
||||
|
||||
DartType convert(ir.DartType type) {
|
||||
topLevel = true;
|
||||
return type.accept(this);
|
||||
|
@ -63,7 +65,8 @@ class DartTypeConverter extends ir.DartTypeVisitor<DartType> {
|
|||
|
||||
InterfaceType visitSupertype(ir.Supertype node) {
|
||||
ClassEntity cls = elementMap.getClass(node.classNode);
|
||||
return new InterfaceType(cls, visitTypes(node.typeArguments));
|
||||
return new InterfaceType(
|
||||
cls, visitTypes(node.typeArguments), _dartTypes.defaultNullability);
|
||||
}
|
||||
|
||||
List<DartType> visitTypes(List<ir.DartType> types) {
|
||||
|
@ -83,7 +86,8 @@ class DartTypeConverter extends ir.DartTypeVisitor<DartType> {
|
|||
// variables.
|
||||
return DynamicType();
|
||||
}
|
||||
return new TypeVariableType(elementMap.getTypeVariable(node.parameter));
|
||||
return new TypeVariableType(elementMap.getTypeVariable(node.parameter),
|
||||
_dartTypes.defaultNullability);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -91,7 +95,8 @@ class DartTypeConverter extends ir.DartTypeVisitor<DartType> {
|
|||
int index = 0;
|
||||
List<FunctionTypeVariable> typeVariables;
|
||||
for (ir.TypeParameter typeParameter in node.typeParameters) {
|
||||
FunctionTypeVariable typeVariable = new FunctionTypeVariable(index);
|
||||
FunctionTypeVariable typeVariable =
|
||||
new FunctionTypeVariable(index, _dartTypes.defaultNullability);
|
||||
currentFunctionTypeParameters[typeParameter] = typeVariable;
|
||||
typeVariables ??= <FunctionTypeVariable>[];
|
||||
typeVariables.add(typeVariable);
|
||||
|
@ -114,7 +119,8 @@ class DartTypeConverter extends ir.DartTypeVisitor<DartType> {
|
|||
.toList()),
|
||||
node.namedParameters.map((n) => n.name).toList(),
|
||||
node.namedParameters.map((n) => visitType(n.type)).toList(),
|
||||
typeVariables ?? const <FunctionTypeVariable>[]);
|
||||
typeVariables ?? const <FunctionTypeVariable>[],
|
||||
_dartTypes.defaultNullability);
|
||||
for (ir.TypeParameter typeParameter in node.typeParameters) {
|
||||
currentFunctionTypeParameters.remove(typeParameter);
|
||||
}
|
||||
|
@ -126,9 +132,11 @@ class DartTypeConverter extends ir.DartTypeVisitor<DartType> {
|
|||
ClassEntity cls = elementMap.getClass(node.classNode);
|
||||
if (cls.name == 'FutureOr' &&
|
||||
cls.library == elementMap.commonElements.asyncLibrary) {
|
||||
return new FutureOrType(visitTypes(node.typeArguments).single);
|
||||
return new FutureOrType(
|
||||
visitTypes(node.typeArguments).single, _dartTypes.defaultNullability);
|
||||
}
|
||||
return new InterfaceType(cls, visitTypes(node.typeArguments));
|
||||
return new InterfaceType(
|
||||
cls, visitTypes(node.typeArguments), _dartTypes.defaultNullability);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -447,8 +447,8 @@ class ConstantEmitter extends ModularConstantEmitter {
|
|||
_constantReferenceGenerator(constant.function)
|
||||
];
|
||||
if (_options.useNewRti) {
|
||||
fields
|
||||
.add(_reifiedTypeNewRti(InterfaceType(cls, constant.typeArguments)));
|
||||
fields.add(_reifiedTypeNewRti(InterfaceType(cls, constant.typeArguments,
|
||||
_commonElements.dartTypes.defaultNullability)));
|
||||
} else {
|
||||
fields.add(_reifiedTypeArguments(constant, constant.typeArguments));
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ jsAst.Statement buildJsInteropBootstrap(
|
|||
return new jsAst.Block(statements);
|
||||
}
|
||||
|
||||
FunctionType buildJsFunctionType() {
|
||||
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.
|
||||
|
@ -50,5 +50,6 @@ FunctionType buildJsFunctionType() {
|
|||
new List<DartType>.filled(16, DynamicType()),
|
||||
const <String>[],
|
||||
const <DartType>[],
|
||||
const <FunctionTypeVariable>[]);
|
||||
const <FunctionTypeVariable>[],
|
||||
dartTypes.defaultNullability);
|
||||
}
|
||||
|
|
|
@ -1004,17 +1004,6 @@ class TypeRepresentationGenerator
|
|||
return onVariable(type);
|
||||
}
|
||||
|
||||
@override
|
||||
jsAst.Expression visitLegacyType(LegacyType type, ModularEmitter emitter) {
|
||||
throw UnsupportedError('Legacy RTI does not support legacy types');
|
||||
}
|
||||
|
||||
@override
|
||||
jsAst.Expression visitNullableType(
|
||||
NullableType type, ModularEmitter emitter) {
|
||||
throw UnsupportedError('Legacy RTI does not support nullable types');
|
||||
}
|
||||
|
||||
@override
|
||||
jsAst.Expression visitNeverType(NeverType type, ModularEmitter emitter) {
|
||||
throw UnsupportedError('Legacy RTI does not support the Never type');
|
||||
|
@ -1248,16 +1237,6 @@ class ArgumentCollector extends DartTypeVisitor<void, void> {
|
|||
/// InterfaceType.
|
||||
void collectAll(List<DartType> types) => types.forEach(collect);
|
||||
|
||||
@override
|
||||
void visitLegacyType(LegacyType type, _) {
|
||||
collect(type.baseType);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitNullableType(NullableType type, _) {
|
||||
collect(type.baseType);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitFutureOrType(FutureOrType type, _) {
|
||||
collect(type.typeArgument);
|
||||
|
@ -1334,14 +1313,6 @@ class TypeVisitor extends DartTypeVisitor<void, TypeVisitorState> {
|
|||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void visitLegacyType(LegacyType type, TypeVisitorState state) =>
|
||||
visitType(type.baseType, state);
|
||||
|
||||
@override
|
||||
void visitNullableType(NullableType type, TypeVisitorState state) =>
|
||||
visitType(type.baseType, state);
|
||||
|
||||
@override
|
||||
void visitFutureOrType(FutureOrType type, TypeVisitorState state) =>
|
||||
visitType(type.typeArgument, state);
|
||||
|
|
|
@ -222,32 +222,35 @@ class _RecipeGenerator implements DartTypeVisitor<void, void> {
|
|||
_emitCode(Recipe.extensionOp);
|
||||
}
|
||||
|
||||
void _emitNullability(Nullability nullability) {
|
||||
switch (nullability) {
|
||||
case Nullability.none:
|
||||
return;
|
||||
case Nullability.question:
|
||||
_emitCode(Recipe.wrapQuestion);
|
||||
return;
|
||||
case Nullability.star:
|
||||
_emitCode(Recipe.wrapStar);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void visit(DartType type, _) => type.accept(this, _);
|
||||
|
||||
@override
|
||||
void visitLegacyType(LegacyType type, _) {
|
||||
visit(type.baseType, _);
|
||||
_emitCode(Recipe.wrapStar);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitNullableType(NullableType type, _) {
|
||||
visit(type.baseType, _);
|
||||
_emitCode(Recipe.wrapQuestion);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitNeverType(NeverType type, _) {
|
||||
_emitExtensionOp(Recipe.pushNeverExtension);
|
||||
_emitNullability(type.nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitTypeVariableType(TypeVariableType type, _) {
|
||||
TypeEnvironmentStructure environment = _environment;
|
||||
if (environment is SingletonTypeEnvironmentStructure) {
|
||||
if (type == environment.variable) {
|
||||
if (type.element == environment.variable.element) {
|
||||
_emitInteger(0);
|
||||
_emitNullability(type.nullability);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -257,11 +260,13 @@ class _RecipeGenerator implements DartTypeVisitor<void, void> {
|
|||
metadata: metadata);
|
||||
if (index != null) {
|
||||
_emitInteger(index);
|
||||
_emitNullability(type.nullability);
|
||||
return;
|
||||
}
|
||||
|
||||
jsAst.Name name = _emitter.typeVariableAccessNewRti(type.element);
|
||||
_emitName(name);
|
||||
_emitNullability(type.nullability);
|
||||
typeVariables.add(type);
|
||||
return;
|
||||
}
|
||||
|
@ -277,6 +282,7 @@ class _RecipeGenerator implements DartTypeVisitor<void, void> {
|
|||
// See [visitFunctionType] for explanation.
|
||||
_emitInteger(functionTypeVariables.length - position - 1);
|
||||
_emitCode(Recipe.genericFunctionTypeParameterIndex);
|
||||
_emitNullability(type.nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -301,6 +307,7 @@ class _RecipeGenerator implements DartTypeVisitor<void, void> {
|
|||
// Push the name, which is later converted by an implicit toType
|
||||
// operation.
|
||||
_emitName(name);
|
||||
_emitNullability(type.nullability);
|
||||
} else {
|
||||
_emitName(name);
|
||||
_emitCode(Recipe.startTypeArguments);
|
||||
|
@ -318,6 +325,7 @@ class _RecipeGenerator implements DartTypeVisitor<void, void> {
|
|||
first = false;
|
||||
}
|
||||
_emitCode(Recipe.endTypeArguments);
|
||||
_emitNullability(type.nullability);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -412,6 +420,8 @@ class _RecipeGenerator implements DartTypeVisitor<void, void> {
|
|||
// Exit generic function scope. Remove the type variables pushed at entry.
|
||||
functionTypeVariables.length -= type.typeVariables.length;
|
||||
}
|
||||
|
||||
_emitNullability(type.nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -423,6 +433,7 @@ class _RecipeGenerator implements DartTypeVisitor<void, void> {
|
|||
void visitFutureOrType(FutureOrType type, _) {
|
||||
visit(type.typeArgument, _);
|
||||
_emitCode(Recipe.wrapFutureOr);
|
||||
_emitNullability(type.nullability);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -615,24 +615,26 @@ class _RecipeToIdentifier extends DartTypeVisitor<void, DartType> {
|
|||
return true;
|
||||
}
|
||||
|
||||
void _handleNullability(Nullability nullability) {
|
||||
switch (nullability) {
|
||||
case Nullability.none:
|
||||
return;
|
||||
case Nullability.star:
|
||||
_add('legacy');
|
||||
return;
|
||||
case Nullability.question:
|
||||
_add('nullable');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void _visit(DartType type, DartType parent) {
|
||||
type.accept(this, parent);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitLegacyType(covariant LegacyType type, _) {
|
||||
_add('legacy');
|
||||
_visit(type.baseType, type);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitNullableType(covariant NullableType type, _) {
|
||||
_add('nullable');
|
||||
_visit(type.baseType, type);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitNeverType(covariant NeverType type, _) {
|
||||
_handleNullability(type.nullability);
|
||||
_add('Never');
|
||||
}
|
||||
|
||||
|
@ -646,6 +648,11 @@ class _RecipeToIdentifier extends DartTypeVisitor<void, DartType> {
|
|||
_add('dynamic');
|
||||
}
|
||||
|
||||
@override
|
||||
void visitErasedType(covariant ErasedType type, _) {
|
||||
_add('erased');
|
||||
}
|
||||
|
||||
@override
|
||||
void visitAnyType(covariant AnyType type, _) {
|
||||
_add('any');
|
||||
|
@ -653,6 +660,7 @@ class _RecipeToIdentifier extends DartTypeVisitor<void, DartType> {
|
|||
|
||||
@override
|
||||
void visitTypeVariableType(covariant TypeVariableType type, DartType parent) {
|
||||
_handleNullability(type.nullability);
|
||||
if (parent != type.element.typeDeclaration) {
|
||||
_identifier(type.element.typeDeclaration.name);
|
||||
}
|
||||
|
@ -661,6 +669,7 @@ class _RecipeToIdentifier extends DartTypeVisitor<void, DartType> {
|
|||
|
||||
@override
|
||||
void visitFunctionTypeVariable(covariant FunctionTypeVariable type, _) {
|
||||
_handleNullability(type.nullability);
|
||||
int index = type.index;
|
||||
String name = index < 26 ? String.fromCharCode($A + index) : 'v\$${index}';
|
||||
_add(name);
|
||||
|
@ -671,6 +680,7 @@ class _RecipeToIdentifier extends DartTypeVisitor<void, DartType> {
|
|||
if (_dagCheck(type)) return;
|
||||
|
||||
_visit(type.returnType, type);
|
||||
_handleNullability(type.nullability);
|
||||
_add('Function');
|
||||
var typeVariables = type.typeVariables;
|
||||
if (typeVariables.isNotEmpty) {
|
||||
|
@ -734,6 +744,7 @@ class _RecipeToIdentifier extends DartTypeVisitor<void, DartType> {
|
|||
// types which 'print' as a single identifier.
|
||||
if (arguments.isNotEmpty && _dagCheck(type)) return;
|
||||
|
||||
_handleNullability(type.nullability);
|
||||
_identifier(type.element.name);
|
||||
|
||||
if (arguments.isEmpty) return;
|
||||
|
@ -782,6 +793,7 @@ class _RecipeToIdentifier extends DartTypeVisitor<void, DartType> {
|
|||
|
||||
@override
|
||||
void visitFutureOrType(covariant FutureOrType type, _) {
|
||||
_handleNullability(type.nullability);
|
||||
_identifier('FutureOr');
|
||||
_visit(type.typeArgument, type);
|
||||
}
|
||||
|
|
|
@ -218,11 +218,7 @@ class _DartTypeKindVisitor implements DartTypeVisitor<int, Null> {
|
|||
@override
|
||||
int visitErasedType(ErasedType type, _) => 8;
|
||||
@override
|
||||
int visitLegacyType(LegacyType type, _) => 9;
|
||||
@override
|
||||
int visitNullableType(NullableType type, _) => 10;
|
||||
@override
|
||||
int visitFutureOrType(FutureOrType type, _) => 11;
|
||||
int visitFutureOrType(FutureOrType type, _) => 9;
|
||||
}
|
||||
|
||||
class _DartTypeOrdering extends DartTypeVisitor<int, DartType> {
|
||||
|
@ -243,19 +239,16 @@ class _DartTypeOrdering extends DartTypeVisitor<int, DartType> {
|
|||
return r;
|
||||
}
|
||||
|
||||
@override
|
||||
int visitLegacyType(covariant LegacyType type, covariant LegacyType other) =>
|
||||
compare(type.baseType, other.baseType);
|
||||
|
||||
@override
|
||||
int visitNullableType(
|
||||
covariant NullableType type, covariant NullableType other) =>
|
||||
visit(type.baseType, other.baseType);
|
||||
int _compareNullability(DartType a, DartType b) =>
|
||||
a.nullability.compareTo(b.nullability);
|
||||
|
||||
@override
|
||||
int visitFutureOrType(
|
||||
covariant FutureOrType type, covariant FutureOrType other) =>
|
||||
visit(type.typeArgument, other.typeArgument);
|
||||
covariant FutureOrType type, covariant FutureOrType other) {
|
||||
int r = _compareNullability(type, other);
|
||||
if (r != 0) return r;
|
||||
return visit(type.typeArgument, other.typeArgument);
|
||||
}
|
||||
|
||||
@override
|
||||
int visitNeverType(covariant NeverType type, covariant NeverType other) {
|
||||
|
@ -277,11 +270,13 @@ class _DartTypeOrdering extends DartTypeVisitor<int, DartType> {
|
|||
@override
|
||||
int visitFunctionTypeVariable(covariant FunctionTypeVariable type,
|
||||
covariant FunctionTypeVariable other) {
|
||||
int r = _compareNullability(type, other);
|
||||
if (r != 0) return r;
|
||||
int leftIndex = _leftFunctionTypeVariables.indexOf(type);
|
||||
int rightIndex = _rightFunctionTypeVariables.indexOf(other);
|
||||
assert(leftIndex != -1);
|
||||
assert(rightIndex != -1);
|
||||
int r = leftIndex.compareTo(rightIndex);
|
||||
r = leftIndex.compareTo(rightIndex);
|
||||
if (r != 0) return r;
|
||||
return compare(type.bound, other.bound);
|
||||
}
|
||||
|
@ -289,37 +284,39 @@ class _DartTypeOrdering extends DartTypeVisitor<int, DartType> {
|
|||
@override
|
||||
int visitFunctionType(
|
||||
covariant FunctionType type, covariant FunctionType other) {
|
||||
int leftLength = _leftFunctionTypeVariables.length;
|
||||
int rightLength = _rightFunctionTypeVariables.length;
|
||||
int r = _compareNullability(type, other);
|
||||
if (r != 0) return r;
|
||||
int oldLeftLength = _leftFunctionTypeVariables.length;
|
||||
int oldRightLength = _rightFunctionTypeVariables.length;
|
||||
_leftFunctionTypeVariables.addAll(type.typeVariables);
|
||||
_rightFunctionTypeVariables.addAll(other.typeVariables);
|
||||
int r = _compareTypeArguments(type.parameterTypes, other.parameterTypes);
|
||||
if (r == 0) {
|
||||
try {
|
||||
r = _compareTypeArguments(type.parameterTypes, other.parameterTypes);
|
||||
if (r != 0) return r;
|
||||
r = _compareTypeArguments(
|
||||
type.optionalParameterTypes, other.optionalParameterTypes);
|
||||
}
|
||||
if (r == 0) {
|
||||
if (r != 0) return r;
|
||||
r = _ConstantOrdering.compareLists((String a, String b) => a.compareTo(b),
|
||||
type.namedParameters, other.namedParameters);
|
||||
}
|
||||
if (r == 0) {
|
||||
if (r != 0) return r;
|
||||
r = _compareTypeArguments(
|
||||
type.namedParameterTypes, other.namedParameterTypes);
|
||||
if (r != 0) return r;
|
||||
return compare(type.returnType, other.returnType);
|
||||
} finally {
|
||||
_leftFunctionTypeVariables.removeRange(
|
||||
oldLeftLength, _leftFunctionTypeVariables.length);
|
||||
_rightFunctionTypeVariables.removeRange(
|
||||
oldRightLength, _rightFunctionTypeVariables.length);
|
||||
}
|
||||
if (r == 0) {
|
||||
r = compare(type.returnType, other.returnType);
|
||||
}
|
||||
_leftFunctionTypeVariables.removeRange(
|
||||
leftLength, _leftFunctionTypeVariables.length);
|
||||
_rightFunctionTypeVariables.removeRange(
|
||||
rightLength, _rightFunctionTypeVariables.length);
|
||||
return r;
|
||||
}
|
||||
|
||||
@override
|
||||
int visitInterfaceType(
|
||||
covariant InterfaceType type, covariant InterfaceType other) {
|
||||
int r = _constantOrdering.compareClasses(type.element, other.element);
|
||||
int r = _compareNullability(type, other);
|
||||
if (r != 0) return r;
|
||||
r = _constantOrdering.compareClasses(type.element, other.element);
|
||||
if (r != 0) return r;
|
||||
return _compareTypeArguments(type.typeArguments, other.typeArguments);
|
||||
}
|
||||
|
|
|
@ -196,7 +196,8 @@ class RuntimeTypeGenerator {
|
|||
classElement, generateFunctionTypeSignature, generateTypeCheck);
|
||||
|
||||
if (classElement == _commonElements.jsJavaScriptFunctionClass) {
|
||||
var type = jsInteropAnalysis.buildJsFunctionType();
|
||||
var type =
|
||||
jsInteropAnalysis.buildJsFunctionType(_commonElements.dartTypes);
|
||||
if (type != null) {
|
||||
jsAst.Expression thisAccess = new jsAst.This();
|
||||
jsAst.Expression encoding = _rtiEncoder.getSignatureEncoding(
|
||||
|
@ -322,14 +323,6 @@ class _TypeContainedInOutputUnitVisitor
|
|||
return true;
|
||||
}
|
||||
|
||||
@override
|
||||
bool visitLegacyType(LegacyType type, OutputUnit argument) =>
|
||||
visit(type.baseType, argument);
|
||||
|
||||
@override
|
||||
bool visitNullableType(NullableType type, OutputUnit argument) =>
|
||||
visit(type.baseType, argument);
|
||||
|
||||
@override
|
||||
bool visitNeverType(NeverType type, OutputUnit argument) => true;
|
||||
|
||||
|
|
|
@ -137,7 +137,7 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
|
|||
: this.options = _elementMap.options {
|
||||
_elementEnvironment = new JsElementEnvironment(this);
|
||||
_typeConverter = new DartTypeConverter(this);
|
||||
_types = new KernelDartTypes(this, options.useLegacySubtyping);
|
||||
_types = new KernelDartTypes(this, options);
|
||||
_commonElements = new CommonElementsImpl(
|
||||
_types, _elementEnvironment, _elementMap.options);
|
||||
_constantValuefier = new ConstantValuefier(this);
|
||||
|
@ -298,7 +298,7 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
|
|||
this._environment, ir.Component component, DataSource source) {
|
||||
_elementEnvironment = new JsElementEnvironment(this);
|
||||
_typeConverter = new DartTypeConverter(this);
|
||||
_types = new KernelDartTypes(this, options.useLegacySubtyping);
|
||||
_types = new KernelDartTypes(this, options);
|
||||
_commonElements =
|
||||
new CommonElementsImpl(_types, _elementEnvironment, options);
|
||||
_constantValuefier = new ConstantValuefier(this);
|
||||
|
@ -619,7 +619,8 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
|
|||
@override
|
||||
InterfaceType createInterfaceType(
|
||||
ir.Class cls, List<ir.DartType> typeArguments) {
|
||||
return new InterfaceType(getClass(cls), getDartTypes(typeArguments));
|
||||
return new InterfaceType(
|
||||
getClass(cls), getDartTypes(typeArguments), types.defaultNullability);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -641,20 +642,23 @@ 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(cls, const <DartType>[]);
|
||||
data.thisType = data.rawType = new InterfaceType(
|
||||
cls, const <DartType>[], types.defaultNullability);
|
||||
} else {
|
||||
data.thisType = new InterfaceType(
|
||||
cls,
|
||||
new List<DartType>.generate(node.typeParameters.length,
|
||||
(int index) {
|
||||
return new TypeVariableType(
|
||||
getTypeVariableInternal(node.typeParameters[index]));
|
||||
}));
|
||||
getTypeVariableInternal(node.typeParameters[index]),
|
||||
types.defaultNullability);
|
||||
}),
|
||||
types.defaultNullability);
|
||||
data.rawType = new InterfaceType(
|
||||
cls,
|
||||
new List<DartType>.filled(
|
||||
node.typeParameters.length, DynamicType()));
|
||||
node.typeParameters.length, DynamicType()),
|
||||
types.defaultNullability);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -668,7 +672,9 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
|
|||
data.jsInteropType = data.thisType;
|
||||
} else {
|
||||
data.jsInteropType = InterfaceType(
|
||||
cls, List<DartType>.filled(node.typeParameters.length, AnyType()));
|
||||
cls,
|
||||
List<DartType>.filled(node.typeParameters.length, AnyType()),
|
||||
types.defaultNullability);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -901,7 +907,8 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
|
|||
}
|
||||
typeVariables = new List<FunctionTypeVariable>.generate(
|
||||
node.typeParameters.length,
|
||||
(int index) => new FunctionTypeVariable(index));
|
||||
(int index) =>
|
||||
new FunctionTypeVariable(index, types.defaultNullability));
|
||||
|
||||
DartType subst(DartType type) {
|
||||
return type.subst(typeVariables, typeParameters);
|
||||
|
@ -919,8 +926,14 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
|
|||
typeVariables = const <FunctionTypeVariable>[];
|
||||
}
|
||||
|
||||
return new FunctionType(returnType, parameterTypes, optionalParameterTypes,
|
||||
namedParameters, namedParameterTypes, typeVariables);
|
||||
return new FunctionType(
|
||||
returnType,
|
||||
parameterTypes,
|
||||
optionalParameterTypes,
|
||||
namedParameters,
|
||||
namedParameterTypes,
|
||||
typeVariables,
|
||||
types.defaultNullability);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1743,13 +1756,14 @@ 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(container, const <DartType>[]);
|
||||
InterfaceType thisType = new InterfaceType(
|
||||
container, const <DartType>[], types.defaultNullability);
|
||||
InterfaceType supertype = commonElements.objectType;
|
||||
JClassData containerData = new RecordClassData(
|
||||
new RecordContainerDefinition(getMemberDefinition(member).location),
|
||||
thisType,
|
||||
supertype,
|
||||
getOrderedTypeSet(supertype.element).extendClass(_types, thisType));
|
||||
getOrderedTypeSet(supertype.element).extendClass(types, thisType));
|
||||
classes.register(container, containerData, new RecordEnv(memberMap));
|
||||
|
||||
InterfaceType memberThisType = member.enclosingClass != null
|
||||
|
@ -1806,12 +1820,13 @@ 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(classEntity, const <DartType>[]);
|
||||
InterfaceType thisType = new InterfaceType(
|
||||
classEntity, const <DartType>[], types.defaultNullability);
|
||||
ClosureClassData closureData = new ClosureClassData(
|
||||
new ClosureClassDefinition(location),
|
||||
thisType,
|
||||
supertype,
|
||||
getOrderedTypeSet(supertype.element).extendClass(_types, thisType));
|
||||
getOrderedTypeSet(supertype.element).extendClass(types, thisType));
|
||||
classes.register(classEntity, closureData, new ClosureClassEnv(memberMap));
|
||||
|
||||
Local closureEntity;
|
||||
|
@ -2219,7 +2234,8 @@ class JsElementEnvironment extends ElementEnvironment
|
|||
@override
|
||||
InterfaceType createInterfaceType(
|
||||
ClassEntity cls, List<DartType> typeArguments) {
|
||||
return new InterfaceType(cls, typeArguments);
|
||||
return new InterfaceType(
|
||||
cls, typeArguments, elementMap.types.defaultNullability);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -427,7 +427,8 @@ class JsClosedWorldBuilder {
|
|||
boxedVariables,
|
||||
info,
|
||||
localsMap,
|
||||
new InterfaceType(superclass, const []),
|
||||
new InterfaceType(
|
||||
superclass, const [], _elementMap.types.defaultNullability),
|
||||
createSignatureMethod: createSignatureMethod);
|
||||
|
||||
// Tell the hierarchy that this is the super class. then we can use
|
||||
|
@ -756,17 +757,9 @@ class _TypeConverter implements DartTypeVisitor<DartType, _EntityConverter> {
|
|||
return list;
|
||||
}
|
||||
|
||||
@override
|
||||
DartType visitLegacyType(LegacyType type, _EntityConverter converter) =>
|
||||
LegacyType(visit(type.baseType, converter));
|
||||
|
||||
@override
|
||||
DartType visitNullableType(NullableType type, _EntityConverter converter) =>
|
||||
NullableType(visit(type.baseType, converter));
|
||||
|
||||
@override
|
||||
DartType visitNeverType(NeverType type, _EntityConverter converter) =>
|
||||
NeverType();
|
||||
NeverType(type.nullability);
|
||||
|
||||
@override
|
||||
DartType visitDynamicType(DynamicType type, _EntityConverter converter) {
|
||||
|
@ -782,14 +775,14 @@ class _TypeConverter implements DartTypeVisitor<DartType, _EntityConverter> {
|
|||
|
||||
@override
|
||||
DartType visitInterfaceType(InterfaceType type, _EntityConverter converter) {
|
||||
return new InterfaceType(
|
||||
converter(type.element), visitList(type.typeArguments, converter));
|
||||
return new InterfaceType(converter(type.element),
|
||||
visitList(type.typeArguments, converter), type.nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
DartType visitTypeVariableType(
|
||||
TypeVariableType type, _EntityConverter converter) {
|
||||
return new TypeVariableType(converter(type.element));
|
||||
return new TypeVariableType(converter(type.element), type.nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -797,7 +790,8 @@ class _TypeConverter implements DartTypeVisitor<DartType, _EntityConverter> {
|
|||
List<FunctionTypeVariable> typeVariables = <FunctionTypeVariable>[];
|
||||
for (FunctionTypeVariable typeVariable in type.typeVariables) {
|
||||
typeVariables.add(_functionTypeVariables[typeVariable] =
|
||||
new FunctionTypeVariable(typeVariable.index));
|
||||
new FunctionTypeVariable(
|
||||
typeVariable.index, typeVariable.nullability));
|
||||
}
|
||||
for (FunctionTypeVariable typeVariable in type.typeVariables) {
|
||||
_functionTypeVariables[typeVariable].bound = typeVariable.bound != null
|
||||
|
@ -813,8 +807,14 @@ class _TypeConverter implements DartTypeVisitor<DartType, _EntityConverter> {
|
|||
for (FunctionTypeVariable typeVariable in type.typeVariables) {
|
||||
_functionTypeVariables.remove(typeVariable);
|
||||
}
|
||||
return new FunctionType(returnType, parameterTypes, optionalParameterTypes,
|
||||
type.namedParameters, namedParameterTypes, typeVariables);
|
||||
return new FunctionType(
|
||||
returnType,
|
||||
parameterTypes,
|
||||
optionalParameterTypes,
|
||||
type.namedParameters,
|
||||
namedParameterTypes,
|
||||
typeVariables,
|
||||
type.nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -836,7 +836,8 @@ class _TypeConverter implements DartTypeVisitor<DartType, _EntityConverter> {
|
|||
|
||||
@override
|
||||
DartType visitFutureOrType(FutureOrType type, _EntityConverter converter) {
|
||||
return new FutureOrType(visit(type.typeArgument, converter));
|
||||
return new FutureOrType(
|
||||
visit(type.typeArgument, converter), type.nullability);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -117,7 +117,7 @@ class KernelToElementMapImpl implements KernelToElementMap, IrToElementMap {
|
|||
this.reporter, this._environment, this._frontendStrategy, this.options) {
|
||||
_elementEnvironment = new KernelElementEnvironment(this);
|
||||
_typeConverter = new DartTypeConverter(this);
|
||||
_types = new KernelDartTypes(this, options.useLegacySubtyping);
|
||||
_types = new KernelDartTypes(this, options);
|
||||
_commonElements =
|
||||
new CommonElementsImpl(_types, _elementEnvironment, options);
|
||||
_constantValuefier = new ConstantValuefier(this);
|
||||
|
@ -240,7 +240,8 @@ class KernelToElementMapImpl implements KernelToElementMap, IrToElementMap {
|
|||
@override
|
||||
InterfaceType createInterfaceType(
|
||||
ir.Class cls, List<ir.DartType> typeArguments) {
|
||||
return new InterfaceType(getClass(cls), getDartTypes(typeArguments));
|
||||
return new InterfaceType(
|
||||
getClass(cls), getDartTypes(typeArguments), types.defaultNullability);
|
||||
}
|
||||
|
||||
LibraryEntity getLibrary(ir.Library node) => getLibraryInternal(node);
|
||||
|
@ -261,20 +262,23 @@ 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(cls, const <DartType>[]);
|
||||
data.thisType = data.rawType = new InterfaceType(
|
||||
cls, const <DartType>[], types.defaultNullability);
|
||||
} else {
|
||||
data.thisType = new InterfaceType(
|
||||
cls,
|
||||
new List<DartType>.generate(node.typeParameters.length,
|
||||
(int index) {
|
||||
return new TypeVariableType(
|
||||
getTypeVariableInternal(node.typeParameters[index]));
|
||||
}));
|
||||
getTypeVariableInternal(node.typeParameters[index]),
|
||||
types.defaultNullability);
|
||||
}),
|
||||
types.defaultNullability);
|
||||
data.rawType = new InterfaceType(
|
||||
cls,
|
||||
new List<DartType>.filled(
|
||||
node.typeParameters.length, DynamicType()));
|
||||
node.typeParameters.length, DynamicType()),
|
||||
types.defaultNullability);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -288,7 +292,9 @@ class KernelToElementMapImpl implements KernelToElementMap, IrToElementMap {
|
|||
data.jsInteropType = data.thisType;
|
||||
} else {
|
||||
data.jsInteropType = InterfaceType(
|
||||
cls, List<DartType>.filled(node.typeParameters.length, AnyType()));
|
||||
cls,
|
||||
List<DartType>.filled(node.typeParameters.length, AnyType()),
|
||||
types.defaultNullability);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -524,7 +530,8 @@ class KernelToElementMapImpl implements KernelToElementMap, IrToElementMap {
|
|||
}
|
||||
typeVariables = new List<FunctionTypeVariable>.generate(
|
||||
node.typeParameters.length,
|
||||
(int index) => new FunctionTypeVariable(index));
|
||||
(int index) =>
|
||||
new FunctionTypeVariable(index, types.defaultNullability));
|
||||
|
||||
DartType subst(DartType type) {
|
||||
return type.subst(typeVariables, typeParameters);
|
||||
|
@ -542,8 +549,14 @@ class KernelToElementMapImpl implements KernelToElementMap, IrToElementMap {
|
|||
typeVariables = const <FunctionTypeVariable>[];
|
||||
}
|
||||
|
||||
return new FunctionType(returnType, parameterTypes, optionalParameterTypes,
|
||||
namedParameters, namedParameterTypes, typeVariables);
|
||||
return new FunctionType(
|
||||
returnType,
|
||||
parameterTypes,
|
||||
optionalParameterTypes,
|
||||
namedParameters,
|
||||
namedParameterTypes,
|
||||
typeVariables,
|
||||
types.defaultNullability);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1676,7 +1689,8 @@ class KernelElementEnvironment extends ElementEnvironment
|
|||
@override
|
||||
InterfaceType createInterfaceType(
|
||||
ClassEntity cls, List<DartType> typeArguments) {
|
||||
return new InterfaceType(cls, typeArguments);
|
||||
return new InterfaceType(
|
||||
cls, typeArguments, elementMap.types.defaultNullability);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -182,16 +182,14 @@ abstract class AbstractDataSource extends DataSourceMixin
|
|||
switch (kind) {
|
||||
case DartTypeKind.none:
|
||||
return null;
|
||||
case DartTypeKind.legacyType:
|
||||
return LegacyType(_readDartType(functionTypeVariables));
|
||||
case DartTypeKind.nullableType:
|
||||
return NullableType(_readDartType(functionTypeVariables));
|
||||
case DartTypeKind.neverType:
|
||||
return NeverType();
|
||||
Nullability nullability = readEnum(Nullability.values);
|
||||
return NeverType(nullability);
|
||||
case DartTypeKind.voidType:
|
||||
return VoidType();
|
||||
case DartTypeKind.typeVariable:
|
||||
return new TypeVariableType(readTypeVariable());
|
||||
Nullability nullability = readEnum(Nullability.values);
|
||||
return new TypeVariableType(readTypeVariable(), nullability);
|
||||
case DartTypeKind.functionTypeVariable:
|
||||
int index = readInt();
|
||||
assert(0 <= index && index < functionTypeVariables.length);
|
||||
|
@ -200,7 +198,10 @@ abstract class AbstractDataSource extends DataSourceMixin
|
|||
int typeVariableCount = readInt();
|
||||
List<FunctionTypeVariable> typeVariables =
|
||||
new List<FunctionTypeVariable>.generate(typeVariableCount,
|
||||
(int index) => new FunctionTypeVariable(index));
|
||||
(int index) {
|
||||
Nullability nullability = readEnum(Nullability.values);
|
||||
return new FunctionTypeVariable(index, nullability);
|
||||
});
|
||||
functionTypeVariables =
|
||||
new List<FunctionTypeVariable>.from(functionTypeVariables)
|
||||
..addAll(typeVariables);
|
||||
|
@ -218,18 +219,21 @@ abstract class AbstractDataSource extends DataSourceMixin
|
|||
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);
|
||||
typeVariables,
|
||||
nullability);
|
||||
|
||||
case DartTypeKind.interfaceType:
|
||||
IndexedClass cls = readClass();
|
||||
List<DartType> typeArguments = _readDartTypes(functionTypeVariables);
|
||||
return new InterfaceType(cls, typeArguments);
|
||||
Nullability nullability = readEnum(Nullability.values);
|
||||
return new InterfaceType(cls, typeArguments, nullability);
|
||||
case DartTypeKind.dynamicType:
|
||||
return DynamicType();
|
||||
case DartTypeKind.erasedType:
|
||||
|
@ -238,7 +242,8 @@ abstract class AbstractDataSource extends DataSourceMixin
|
|||
return AnyType();
|
||||
case DartTypeKind.futureOr:
|
||||
DartType typeArgument = _readDartType(functionTypeVariables);
|
||||
return new FutureOrType(typeArgument);
|
||||
Nullability nullability = readEnum(Nullability.values);
|
||||
return new FutureOrType(typeArgument, nullability);
|
||||
}
|
||||
throw new UnsupportedError("Unexpected DartTypeKind $kind");
|
||||
}
|
||||
|
|
|
@ -89,8 +89,6 @@ class Tag {
|
|||
/// Enum used for identifying [DartType] subclasses in serialization.
|
||||
enum DartTypeKind {
|
||||
none,
|
||||
legacyType,
|
||||
nullableType,
|
||||
neverType,
|
||||
voidType,
|
||||
typeVariable,
|
||||
|
@ -123,24 +121,11 @@ class DartTypeWriter
|
|||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void visitLegacyType(covariant LegacyType type,
|
||||
List<FunctionTypeVariable> functionTypeVariables) {
|
||||
_sink.writeEnum(DartTypeKind.legacyType);
|
||||
_sink._writeDartType(type.baseType, functionTypeVariables);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitNullableType(covariant NullableType type,
|
||||
List<FunctionTypeVariable> functionTypeVariables) {
|
||||
_sink.writeEnum(DartTypeKind.nullableType);
|
||||
_sink._writeDartType(type.baseType, functionTypeVariables);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitNeverType(covariant NeverType type,
|
||||
List<FunctionTypeVariable> functionTypeVariables) {
|
||||
_sink.writeEnum(DartTypeKind.neverType);
|
||||
_sink.writeEnum(type.nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -154,6 +139,7 @@ class DartTypeWriter
|
|||
List<FunctionTypeVariable> functionTypeVariables) {
|
||||
_sink.writeEnum(DartTypeKind.typeVariable);
|
||||
IndexedTypeVariable typeVariable = type.element;
|
||||
_sink.writeEnum(type.nullability);
|
||||
_sink.writeTypeVariable(typeVariable);
|
||||
}
|
||||
|
||||
|
@ -178,6 +164,9 @@ class DartTypeWriter
|
|||
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);
|
||||
}
|
||||
|
@ -188,6 +177,7 @@ class DartTypeWriter
|
|||
for (String namedParameter in type.namedParameters) {
|
||||
_sink.writeString(namedParameter);
|
||||
}
|
||||
_sink.writeEnum(type.nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -196,6 +186,7 @@ class DartTypeWriter
|
|||
_sink.writeEnum(DartTypeKind.interfaceType);
|
||||
_sink.writeClass(type.element);
|
||||
visitTypes(type.typeArguments, functionTypeVariables);
|
||||
_sink.writeEnum(type.nullability);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -221,6 +212,7 @@ class DartTypeWriter
|
|||
List<FunctionTypeVariable> functionTypeVariables) {
|
||||
_sink.writeEnum(DartTypeKind.futureOr);
|
||||
_sink._writeDartType(type.typeArgument, functionTypeVariables);
|
||||
_sink.writeEnum(type.nullability);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -387,6 +387,8 @@ class KernelSsaGraphBuilder extends ir.Visitor {
|
|||
return options.useNewRti;
|
||||
case 'VARIANCE':
|
||||
return options.enableVariance;
|
||||
case 'NNBD':
|
||||
return options.useNullSafety;
|
||||
case 'LEGACY':
|
||||
return options.useLegacySubtyping;
|
||||
default:
|
||||
|
@ -2121,8 +2123,8 @@ 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]));
|
||||
InterfaceType instanceType = localsHandler.substInContext(new InterfaceType(
|
||||
cls, [typeArg], closedWorld.dartTypes.defaultNullability));
|
||||
// TODO(johnniwinther): This should be the exact type.
|
||||
StaticType staticInstanceType =
|
||||
new StaticType(instanceType, ClassRelation.subtype);
|
||||
|
@ -3108,8 +3110,8 @@ 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);
|
||||
InterfaceType arrayType = InterfaceType(_commonElements.jsArrayClass,
|
||||
type.typeArguments, closedWorld.dartTypes.defaultNullability);
|
||||
HInstruction rti =
|
||||
_typeBuilder.analyzeTypeArgumentNewRti(arrayType, sourceElement);
|
||||
|
||||
|
@ -4713,8 +4715,8 @@ class KernelSsaGraphBuilder extends ir.Visitor {
|
|||
}
|
||||
// TODO(sra): This should be JSArray<any>, created via
|
||||
// _elementEnvironment.getJsInteropType(_elementEnvironment.jsArrayClass);
|
||||
InterfaceType interopType =
|
||||
InterfaceType(_commonElements.jsArrayClass, [DynamicType()]);
|
||||
InterfaceType interopType = InterfaceType(_commonElements.jsArrayClass,
|
||||
[DynamicType()], closedWorld.dartTypes.defaultNullability);
|
||||
SourceInformation sourceInformation =
|
||||
_sourceInformationBuilder.buildCall(invocation, invocation);
|
||||
HInstruction rti =
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
name: compiler
|
||||
publish_to: none
|
||||
environment:
|
||||
sdk: '>=2.3.0 <3.0.0'
|
||||
sdk: '>=2.6.0 <3.0.0'
|
||||
|
||||
# NOTE: `pub get / pub upgrade` are generally not needed when working on this
|
||||
# package. The `.packages` file in the repository root will be used by default.
|
||||
|
|
|
@ -2372,7 +2372,7 @@ bool _isSubtype(universe, Rti s, sEnv, Rti t, tEnv) {
|
|||
if (sKind == Rti.kindAny) return true;
|
||||
|
||||
// Left Top:
|
||||
if (isTopType(s)) return false;
|
||||
if (isStrongTopType(s)) return false;
|
||||
|
||||
// Left Bottom:
|
||||
if (isLegacy) {
|
||||
|
@ -2489,6 +2489,10 @@ bool _isSubtype(universe, Rti s, sEnv, Rti t, tEnv) {
|
|||
int sLength = _Utils.arrayLength(sBounds);
|
||||
int tLength = _Utils.arrayLength(tBounds);
|
||||
if (sLength != tLength) return false;
|
||||
|
||||
sEnv = sEnv == null ? sBounds : _Utils.arrayConcat(sBounds, sEnv);
|
||||
tEnv = tEnv == null ? tBounds : _Utils.arrayConcat(tBounds, tEnv);
|
||||
|
||||
for (int i = 0; i < sLength; i++) {
|
||||
var sBound = _Utils.arrayAt(sBounds, i);
|
||||
var tBound = _Utils.arrayAt(tBounds, i);
|
||||
|
@ -2498,9 +2502,6 @@ bool _isSubtype(universe, Rti s, sEnv, Rti t, tEnv) {
|
|||
}
|
||||
}
|
||||
|
||||
sEnv = sEnv == null ? sBounds : _Utils.arrayConcat(sBounds, sEnv);
|
||||
tEnv = tEnv == null ? tBounds : _Utils.arrayConcat(tBounds, tEnv);
|
||||
|
||||
return _isFunctionSubtype(universe, Rti._getGenericFunctionBase(s), sEnv,
|
||||
Rti._getGenericFunctionBase(t), tEnv);
|
||||
}
|
||||
|
@ -2685,21 +2686,23 @@ bool _isInterfaceSubtype(universe, Rti s, sEnv, Rti t, tEnv) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool isTopType(Rti t) {
|
||||
if (JS_GET_FLAG('LEGACY')) {
|
||||
if (isObjectType(t)) return true;
|
||||
} else {
|
||||
if (isNullableObjectType(t)) return true;
|
||||
}
|
||||
bool isTopType(Rti t) => isStrongTopType(t) || isLegacyObjectType(t);
|
||||
|
||||
bool isStrongTopType(Rti t) {
|
||||
int kind = Rti._getKind(t);
|
||||
return kind == Rti.kindDynamic ||
|
||||
kind == Rti.kindVoid ||
|
||||
kind == Rti.kindAny ||
|
||||
kind == Rti.kindErased ||
|
||||
kind == Rti.kindFutureOr && isTopType(Rti._getFutureOrArgument(t));
|
||||
!JS_GET_FLAG('NNBD') && isObjectType(t) ||
|
||||
isNullableObjectType(t);
|
||||
}
|
||||
|
||||
bool isObjectType(Rti t) => _Utils.isIdentical(t, TYPE_REF<Object>());
|
||||
// TODO(fishythefish): Use `LEGACY_TYPE_REF<Object?>()`.
|
||||
bool isLegacyObjectType(Rti t) =>
|
||||
Rti._getKind(t) == Rti.kindQuestion &&
|
||||
isObjectType(Rti._getStarArgument(t));
|
||||
// TODO(fishythefish): Use `TYPE_REF<Object?>()`.
|
||||
bool isNullableObjectType(Rti t) =>
|
||||
Rti._getKind(t) == Rti.kindQuestion &&
|
||||
|
|
|
@ -2372,7 +2372,7 @@ bool _isSubtype(universe, Rti s, sEnv, Rti t, tEnv) {
|
|||
if (sKind == Rti.kindAny) return true;
|
||||
|
||||
// Left Top:
|
||||
if (isTopType(s)) return false;
|
||||
if (isStrongTopType(s)) return false;
|
||||
|
||||
// Left Bottom:
|
||||
if (isLegacy) {
|
||||
|
@ -2489,6 +2489,10 @@ bool _isSubtype(universe, Rti s, sEnv, Rti t, tEnv) {
|
|||
int sLength = _Utils.arrayLength(sBounds);
|
||||
int tLength = _Utils.arrayLength(tBounds);
|
||||
if (sLength != tLength) return false;
|
||||
|
||||
sEnv = sEnv == null ? sBounds : _Utils.arrayConcat(sBounds, sEnv);
|
||||
tEnv = tEnv == null ? tBounds : _Utils.arrayConcat(tBounds, tEnv);
|
||||
|
||||
for (int i = 0; i < sLength; i++) {
|
||||
var sBound = _Utils.arrayAt(sBounds, i);
|
||||
var tBound = _Utils.arrayAt(tBounds, i);
|
||||
|
@ -2498,9 +2502,6 @@ bool _isSubtype(universe, Rti s, sEnv, Rti t, tEnv) {
|
|||
}
|
||||
}
|
||||
|
||||
sEnv = sEnv == null ? sBounds : _Utils.arrayConcat(sBounds, sEnv);
|
||||
tEnv = tEnv == null ? tBounds : _Utils.arrayConcat(tBounds, tEnv);
|
||||
|
||||
return _isFunctionSubtype(universe, Rti._getGenericFunctionBase(s), sEnv,
|
||||
Rti._getGenericFunctionBase(t), tEnv);
|
||||
}
|
||||
|
@ -2685,21 +2686,23 @@ bool _isInterfaceSubtype(universe, Rti s, sEnv, Rti t, tEnv) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool isTopType(Rti t) {
|
||||
if (JS_GET_FLAG('LEGACY')) {
|
||||
if (isObjectType(t)) return true;
|
||||
} else {
|
||||
if (isNullableObjectType(t)) return true;
|
||||
}
|
||||
bool isTopType(Rti t) => isStrongTopType(t) || isLegacyObjectType(t);
|
||||
|
||||
bool isStrongTopType(Rti t) {
|
||||
int kind = Rti._getKind(t);
|
||||
return kind == Rti.kindDynamic ||
|
||||
kind == Rti.kindVoid ||
|
||||
kind == Rti.kindAny ||
|
||||
kind == Rti.kindErased ||
|
||||
kind == Rti.kindFutureOr && isTopType(Rti._getFutureOrArgument(t));
|
||||
!JS_GET_FLAG('NNBD') && isObjectType(t) ||
|
||||
isNullableObjectType(t);
|
||||
}
|
||||
|
||||
bool isObjectType(Rti t) => _Utils.isIdentical(t, TYPE_REF<Object>());
|
||||
// TODO(fishythefish): Use `LEGACY_TYPE_REF<Object?>()`.
|
||||
bool isLegacyObjectType(Rti t) =>
|
||||
Rti._getKind(t) == Rti.kindQuestion &&
|
||||
isObjectType(Rti._getStarArgument(t));
|
||||
// TODO(fishythefish): Use `TYPE_REF<Object?>()`.
|
||||
bool isNullableObjectType(Rti t) =>
|
||||
Rti._getKind(t) == Rti.kindQuestion &&
|
||||
|
|
|
@ -440,21 +440,28 @@ class DartTypePrinter implements DartTypeVisitor {
|
|||
return comma;
|
||||
}
|
||||
|
||||
@override
|
||||
visitLegacyType(LegacyType type, _) {
|
||||
visit(type.baseType);
|
||||
sb.write('*');
|
||||
}
|
||||
|
||||
@override
|
||||
visitNullableType(NullableType type, _) {
|
||||
visit(type.baseType);
|
||||
sb.write('?');
|
||||
void _writeNullability(Nullability nullability, StringBuffer sb) {
|
||||
switch (nullability) {
|
||||
case Nullability.none:
|
||||
return;
|
||||
case Nullability.question:
|
||||
sb.write('?');
|
||||
return;
|
||||
case Nullability.star:
|
||||
sb.write('*');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
visitNeverType(NeverType type, _) {
|
||||
sb.write('Never');
|
||||
_writeNullability(type.nullability, sb);
|
||||
}
|
||||
|
||||
@override
|
||||
visitVoidType(VoidType type, _) {
|
||||
sb.write('void');
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -480,6 +487,7 @@ class DartTypePrinter implements DartTypeVisitor {
|
|||
visitTypes(type.typeArguments);
|
||||
sb.write('>');
|
||||
}
|
||||
_writeNullability(type.nullability, sb);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -512,21 +520,19 @@ class DartTypePrinter implements DartTypeVisitor {
|
|||
sb.write('}');
|
||||
}
|
||||
sb.write(')');
|
||||
_writeNullability(type.nullability, sb);
|
||||
}
|
||||
|
||||
@override
|
||||
visitFunctionTypeVariable(FunctionTypeVariable type, _) {
|
||||
sb.write(type);
|
||||
_writeNullability(type.nullability, sb);
|
||||
}
|
||||
|
||||
@override
|
||||
visitTypeVariableType(TypeVariableType type, _) {
|
||||
sb.write(type);
|
||||
}
|
||||
|
||||
@override
|
||||
visitVoidType(VoidType type, _) {
|
||||
sb.write('void');
|
||||
_writeNullability(type.nullability, sb);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -534,6 +540,7 @@ class DartTypePrinter implements DartTypeVisitor {
|
|||
sb.write('FutureOr<');
|
||||
visit(type.typeArgument);
|
||||
sb.write('>');
|
||||
_writeNullability(type.nullability, sb);
|
||||
}
|
||||
|
||||
String getText() => sb.toString();
|
||||
|
|
|
@ -23,21 +23,23 @@ class DartTypeToTextVisitor extends DartTypeVisitor<void, StringBuffer> {
|
|||
return comma;
|
||||
}
|
||||
|
||||
@override
|
||||
void visitLegacyType(LegacyType type, StringBuffer sb) {
|
||||
visit(type.baseType, sb);
|
||||
sb.write('*');
|
||||
}
|
||||
|
||||
@override
|
||||
void visitNullableType(NullableType type, StringBuffer sb) {
|
||||
visit(type.baseType, sb);
|
||||
sb.write('?');
|
||||
void _writeNullability(Nullability nullability, StringBuffer sb) {
|
||||
switch (nullability) {
|
||||
case Nullability.none:
|
||||
return;
|
||||
case Nullability.question:
|
||||
sb.write('?');
|
||||
return;
|
||||
case Nullability.star:
|
||||
sb.write('*');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void visitNeverType(NeverType type, StringBuffer sb) {
|
||||
sb.write('Never');
|
||||
_writeNullability(type.nullability, sb);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -45,18 +47,36 @@ class DartTypeToTextVisitor extends DartTypeVisitor<void, StringBuffer> {
|
|||
sb.write('void');
|
||||
}
|
||||
|
||||
@override
|
||||
void visitDynamicType(DynamicType type, StringBuffer sb) {
|
||||
sb.write('dynamic');
|
||||
}
|
||||
|
||||
@override
|
||||
void visitErasedType(ErasedType type, StringBuffer sb) {
|
||||
sb.write('erased');
|
||||
}
|
||||
|
||||
@override
|
||||
void visitAnyType(AnyType type, StringBuffer sb) {
|
||||
sb.write('any');
|
||||
}
|
||||
|
||||
@override
|
||||
void visitTypeVariableType(TypeVariableType type, StringBuffer sb) {
|
||||
sb.write(type.element.name);
|
||||
_writeNullability(type.nullability, sb);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitFunctionTypeVariable(FunctionTypeVariable type, StringBuffer sb) {
|
||||
sb.write(type.index);
|
||||
_writeNullability(type.nullability, sb);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitFunctionType(FunctionType type, StringBuffer sb) {
|
||||
if (!type.nullability.isNone) sb.write('(');
|
||||
sb.write('(');
|
||||
String comma = visitList(type.parameterTypes, sb);
|
||||
if (type.optionalParameterTypes.isNotEmpty) {
|
||||
|
@ -81,6 +101,8 @@ class DartTypeToTextVisitor extends DartTypeVisitor<void, StringBuffer> {
|
|||
}
|
||||
sb.write(')->');
|
||||
visit(type.returnType, sb);
|
||||
if (!type.nullability.isNone) sb.write(')');
|
||||
_writeNullability(type.nullability, sb);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -91,11 +113,7 @@ class DartTypeToTextVisitor extends DartTypeVisitor<void, StringBuffer> {
|
|||
visitList(type.typeArguments, sb);
|
||||
sb.write('>');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void visitDynamicType(DynamicType type, StringBuffer sb) {
|
||||
sb.write('dynamic');
|
||||
_writeNullability(type.nullability, sb);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -103,6 +121,7 @@ class DartTypeToTextVisitor extends DartTypeVisitor<void, StringBuffer> {
|
|||
sb.write('FutureOr<');
|
||||
visit(type.typeArgument, sb);
|
||||
sb.write('>');
|
||||
_writeNullability(type.nullability, sb);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ 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);
|
||||
return new InterfaceType(element, arguments, Nullability.none);
|
||||
}
|
||||
|
||||
class TypeEnvironment {
|
||||
|
|
|
@ -201,18 +201,24 @@ testTypeSubstitution() async {
|
|||
env.elementEnvironment,
|
||||
arguments,
|
||||
parameters,
|
||||
new FunctionType(intType, [StringType], [], [], [], []),
|
||||
new FunctionType(intType, [StringType], [], [], [], []));
|
||||
new FunctionType(
|
||||
intType, [StringType], [], [], [], [], env.types.defaultNullability),
|
||||
new FunctionType(
|
||||
intType, [StringType], [], [], [], [], env.types.defaultNullability));
|
||||
testSubstitution(
|
||||
env.elementEnvironment,
|
||||
arguments,
|
||||
parameters,
|
||||
new FunctionType(VoidType(), [T, S], [], [], [], []),
|
||||
new FunctionType(VoidType(), [intType, StringType], [], [], [], []));
|
||||
new FunctionType(
|
||||
VoidType(), [T, S], [], [], [], [], env.types.defaultNullability),
|
||||
new FunctionType(VoidType(), [intType, StringType], [], [], [], [],
|
||||
env.types.defaultNullability));
|
||||
testSubstitution(
|
||||
env.elementEnvironment,
|
||||
arguments,
|
||||
parameters,
|
||||
new FunctionType(VoidType(), [DynamicType()], [], [], [], []),
|
||||
new FunctionType(VoidType(), [DynamicType()], [], [], [], []));
|
||||
new FunctionType(VoidType(), [DynamicType()], [], [], [], [],
|
||||
env.types.defaultNullability),
|
||||
new FunctionType(VoidType(), [DynamicType()], [], [], [], [],
|
||||
env.types.defaultNullability));
|
||||
}
|
||||
|
|
|
@ -39,13 +39,13 @@ class Class4 {}
|
|||
method10<T extends Class4>() => null;
|
||||
|
||||
main() {
|
||||
/*strong.needsArgs,needsSignature,selectors=[Selector(call, call, arity=0, types=1)]*/
|
||||
/*omit.needsSignature*/method7<T extends Class1a>() => null;
|
||||
/*strong.needsArgs,selectors=[Selector(call, call, arity=0, types=1)]*/
|
||||
/*omit.*/method7<T extends Class1a>() => null;
|
||||
|
||||
/*strong.needsArgs,needsSignature,selectors=[Selector(call, call, arity=0, types=1)]*/
|
||||
/*omit.needsSignature*/method8<T extends Class2a<num>>() => null;
|
||||
/*strong.needsArgs,selectors=[Selector(call, call, arity=0, types=1)]*/
|
||||
/*omit.*/method8<T extends Class2a<num>>() => null;
|
||||
|
||||
/*needsSignature*/
|
||||
/**/
|
||||
method9<T>() => null;
|
||||
|
||||
dynamic f1 = method1;
|
||||
|
|
|
@ -6,7 +6,7 @@ import 'package:expect/expect.dart';
|
|||
|
||||
class Class1 {
|
||||
method1() {
|
||||
/*needsSignature*/
|
||||
/**/
|
||||
num local<T>(num n) => null;
|
||||
return local;
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ class Class1 {
|
|||
}
|
||||
|
||||
method3() {
|
||||
/*needsSignature*/
|
||||
/**/
|
||||
int local<T>(num n) => null;
|
||||
return local;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ class Class1 {
|
|||
}
|
||||
|
||||
class Class2 {
|
||||
/*strong.member: Class2.method4:direct,explicit=[method4.T],needsArgs,needsInst=[<num>,<num>]*/
|
||||
/*strong.member: Class2.method4:direct,explicit=[method4.T],needsArgs,needsInst=[<num>,<num>,<num>,<num>]*/
|
||||
/*omit.member: Class2.method4:*/
|
||||
num method4<T>(T n) => null;
|
||||
}
|
||||
|
@ -27,19 +27,19 @@ class Class3 {
|
|||
}
|
||||
|
||||
class Class4 {
|
||||
/*strong.member: Class4.method6:direct,explicit=[method6.T],needsArgs,needsInst=[<num>,<num>]*/
|
||||
/*strong.member: Class4.method6:direct,explicit=[method6.T],needsArgs,needsInst=[<num>,<num>,<num>,<num>]*/
|
||||
/*omit.member: Class4.method6:*/
|
||||
num method6<T>(num n, T t) => null;
|
||||
}
|
||||
|
||||
/*strong.member: method7:direct,explicit=[method7.T],needsArgs,needsInst=[<num>,<num>]*/
|
||||
/*strong.member: method7:direct,explicit=[method7.T],needsArgs,needsInst=[<num>,<num>,<num>,<num>]*/
|
||||
/*omit.member: method7:*/
|
||||
num method7<T>(T n) => null;
|
||||
|
||||
/*member: method8:*/
|
||||
T method8<T>(num n) => null;
|
||||
|
||||
/*strong.member: method9:direct,explicit=[method9.T],needsArgs,needsInst=[<num>,<num>]*/
|
||||
/*strong.member: method9:direct,explicit=[method9.T],needsArgs,needsInst=[<num>,<num>,<num>,<num>]*/
|
||||
/*omit.member: method9:*/
|
||||
num method9<T>(num n, T t) => null;
|
||||
|
||||
|
|
|
@ -203,12 +203,6 @@ class FindTypeVisitor extends BaseDartTypeVisitor<bool, Null> {
|
|||
@override
|
||||
bool visitType(DartType type, _) => false;
|
||||
|
||||
@override
|
||||
bool visitLegacyType(LegacyType type, _) => visit(type.baseType, _);
|
||||
|
||||
@override
|
||||
bool visitNullableType(NullableType type, _) => visit(type.baseType, _);
|
||||
|
||||
@override
|
||||
bool visitInterfaceType(InterfaceType type, _) {
|
||||
if (type.element == entity) return true;
|
||||
|
|
Loading…
Reference in a new issue