mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 10:49:00 +00:00
[dart2js] migrate runtime_types.dart
Change-Id: Ide7ac30296612be3b4208267dc9135f3361b5cf2 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/264344 Reviewed-by: Nate Biggs <natebiggs@google.com>
This commit is contained in:
parent
77a480ca49
commit
04239b784f
2 changed files with 44 additions and 71 deletions
|
@ -2,8 +2,6 @@
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
// for details. All rights reserved. Use of this source code is governed by a
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// @dart = 2.10
|
|
||||||
|
|
||||||
library js_backend.runtime_types;
|
library js_backend.runtime_types;
|
||||||
|
|
||||||
import '../common.dart';
|
import '../common.dart';
|
||||||
|
@ -96,8 +94,7 @@ class TrivialRuntimeTypesChecksBuilder implements RuntimeTypesChecksBuilder {
|
||||||
..functionType = _computeFunctionType(_elementEnvironment, cls);
|
..functionType = _computeFunctionType(_elementEnvironment, cls);
|
||||||
classUseMap[cls] = classUse;
|
classUseMap[cls] = classUse;
|
||||||
}
|
}
|
||||||
TypeChecks typeChecks = _substitutions._requiredChecks =
|
TypeChecks typeChecks = _substitutions._computeChecks(classUseMap);
|
||||||
_substitutions._computeChecks(classUseMap);
|
|
||||||
return TrivialTypesChecks(typeChecks);
|
return TrivialTypesChecks(typeChecks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +115,6 @@ class TrivialRuntimeTypesChecksBuilder implements RuntimeTypesChecksBuilder {
|
||||||
abstract class RuntimeTypesSubstitutionsMixin
|
abstract class RuntimeTypesSubstitutionsMixin
|
||||||
implements RuntimeTypesSubstitutions {
|
implements RuntimeTypesSubstitutions {
|
||||||
JClosedWorld get _closedWorld;
|
JClosedWorld get _closedWorld;
|
||||||
TypeChecks get _requiredChecks;
|
|
||||||
|
|
||||||
JElementEnvironment get _elementEnvironment =>
|
JElementEnvironment get _elementEnvironment =>
|
||||||
_closedWorld.elementEnvironment;
|
_closedWorld.elementEnvironment;
|
||||||
|
@ -148,9 +144,9 @@ abstract class RuntimeTypesSubstitutionsMixin
|
||||||
result[cls] = checks;
|
result[cls] = checks;
|
||||||
|
|
||||||
// Find the superclass from which [cls] inherits checks.
|
// Find the superclass from which [cls] inherits checks.
|
||||||
ClassEntity superClass = _elementEnvironment.getSuperClass(cls,
|
ClassEntity? superClass = _elementEnvironment.getSuperClass(cls,
|
||||||
skipUnnamedMixinApplications: true);
|
skipUnnamedMixinApplications: true);
|
||||||
ClassChecks superChecks;
|
ClassChecks? superChecks;
|
||||||
bool extendsSuperClassTrivially = false;
|
bool extendsSuperClassTrivially = false;
|
||||||
if (superClass != null) {
|
if (superClass != null) {
|
||||||
// Compute the checks inherited from [superClass].
|
// Compute the checks inherited from [superClass].
|
||||||
|
@ -173,7 +169,7 @@ abstract class RuntimeTypesSubstitutionsMixin
|
||||||
if (classUse.typeArgument ||
|
if (classUse.typeArgument ||
|
||||||
classUse.typeLiteral ||
|
classUse.typeLiteral ||
|
||||||
(isNativeClass && classUse.checkedInstance)) {
|
(isNativeClass && classUse.checkedInstance)) {
|
||||||
Substitution substitution = computeSubstitution(cls, cls);
|
Substitution? substitution = computeSubstitution(cls, cls);
|
||||||
// We need [cls] at runtime - even if [cls] is not instantiated. Either
|
// We need [cls] at runtime - even if [cls] is not instantiated. Either
|
||||||
// as a type argument, for a type literal or for an is-test if [cls] is
|
// as a type argument, for a type literal or for an is-test if [cls] is
|
||||||
// native.
|
// native.
|
||||||
|
@ -185,7 +181,7 @@ abstract class RuntimeTypesSubstitutionsMixin
|
||||||
// This set reflects the emitted class hierarchy and therefore uses
|
// This set reflects the emitted class hierarchy and therefore uses
|
||||||
// `getEffectiveMixinClass` to find the inherited mixins.
|
// `getEffectiveMixinClass` to find the inherited mixins.
|
||||||
Set<ClassEntity> inheritedClasses = {};
|
Set<ClassEntity> inheritedClasses = {};
|
||||||
ClassEntity other = cls;
|
ClassEntity? other = cls;
|
||||||
while (other != null) {
|
while (other != null) {
|
||||||
inheritedClasses.add(other);
|
inheritedClasses.add(other);
|
||||||
if (classUse.instance &&
|
if (classUse.instance &&
|
||||||
|
@ -193,7 +189,7 @@ abstract class RuntimeTypesSubstitutionsMixin
|
||||||
// We don't mixin [other] if [cls] isn't instantiated, directly or
|
// We don't mixin [other] if [cls] isn't instantiated, directly or
|
||||||
// indirectly.
|
// indirectly.
|
||||||
inheritedClasses
|
inheritedClasses
|
||||||
.add(_elementEnvironment.getEffectiveMixinClass(other));
|
.add(_elementEnvironment.getEffectiveMixinClass(other)!);
|
||||||
}
|
}
|
||||||
other = _elementEnvironment.getSuperClass(other);
|
other = _elementEnvironment.getSuperClass(other);
|
||||||
}
|
}
|
||||||
|
@ -263,7 +259,7 @@ abstract class RuntimeTypesSubstitutionsMixin
|
||||||
_elementEnvironment.isGenericClass(checkedClass);
|
_elementEnvironment.isGenericClass(checkedClass);
|
||||||
|
|
||||||
// The checks for [checkedClass] inherited for [superClass].
|
// The checks for [checkedClass] inherited for [superClass].
|
||||||
TypeCheck checkFromSuperClass =
|
TypeCheck? checkFromSuperClass =
|
||||||
superChecks != null ? superChecks[checkedClass] : null;
|
superChecks != null ? superChecks[checkedClass] : null;
|
||||||
|
|
||||||
// Whether [cls] need an explicit $isX property for [checkedClass].
|
// Whether [cls] need an explicit $isX property for [checkedClass].
|
||||||
|
@ -294,11 +290,10 @@ abstract class RuntimeTypesSubstitutionsMixin
|
||||||
// We need a non-trivial substitution function for
|
// We need a non-trivial substitution function for
|
||||||
// [checkedClass].
|
// [checkedClass].
|
||||||
Substitution substitution =
|
Substitution substitution =
|
||||||
computeSubstitution(cls, checkedClass);
|
computeSubstitution(cls, checkedClass)!;
|
||||||
checks
|
checks
|
||||||
.add(TypeCheck(checkedClass, substitution, needsIs: false));
|
.add(TypeCheck(checkedClass, substitution, needsIs: false));
|
||||||
|
|
||||||
assert(substitution != null);
|
|
||||||
for (DartType argument in substitution.arguments) {
|
for (DartType argument in substitution.arguments) {
|
||||||
argument = argument.withoutNullability;
|
argument = argument.withoutNullability;
|
||||||
if (argument is InterfaceType) {
|
if (argument is InterfaceType) {
|
||||||
|
@ -318,11 +313,10 @@ abstract class RuntimeTypesSubstitutionsMixin
|
||||||
// We need a non-trivial substitution function for
|
// We need a non-trivial substitution function for
|
||||||
// [checkedClass].
|
// [checkedClass].
|
||||||
Substitution substitution =
|
Substitution substitution =
|
||||||
computeSubstitution(cls, checkedClass);
|
computeSubstitution(cls, checkedClass)!;
|
||||||
checks
|
checks
|
||||||
.add(TypeCheck(checkedClass, substitution, needsIs: needsIs));
|
.add(TypeCheck(checkedClass, substitution, needsIs: needsIs));
|
||||||
|
|
||||||
assert(substitution != null);
|
|
||||||
for (DartType argument in substitution.arguments) {
|
for (DartType argument in substitution.arguments) {
|
||||||
argument = argument.withoutNullability;
|
argument = argument.withoutNullability;
|
||||||
if (argument is InterfaceType) {
|
if (argument is InterfaceType) {
|
||||||
|
@ -361,7 +355,7 @@ abstract class RuntimeTypesSubstitutionsMixin
|
||||||
for (ClassEntity target in checks.classes) {
|
for (ClassEntity target in checks.classes) {
|
||||||
ClassChecks classChecks = checks[target];
|
ClassChecks classChecks = checks[target];
|
||||||
for (TypeCheck check in classChecks.checks) {
|
for (TypeCheck check in classChecks.checks) {
|
||||||
Substitution substitution = check.substitution;
|
Substitution? substitution = check.substitution;
|
||||||
if (substitution != null) {
|
if (substitution != null) {
|
||||||
collector.collectAll(substitution.arguments);
|
collector.collectAll(substitution.arguments);
|
||||||
}
|
}
|
||||||
|
@ -398,7 +392,7 @@ abstract class RuntimeTypesSubstitutionsMixin
|
||||||
}
|
}
|
||||||
|
|
||||||
InterfaceType originalType = _elementEnvironment.getThisType(cls);
|
InterfaceType originalType = _elementEnvironment.getThisType(cls);
|
||||||
InterfaceType type = _types.asInstanceOf(originalType, check);
|
InterfaceType? type = _types.asInstanceOf(originalType, check);
|
||||||
// [type] is not a subtype of [check]. we do not generate a check and do not
|
// [type] is not a subtype of [check]. we do not generate a check and do not
|
||||||
// need a substitution.
|
// need a substitution.
|
||||||
if (type == null) return true;
|
if (type == null) return true;
|
||||||
|
@ -419,20 +413,12 @@ abstract class RuntimeTypesSubstitutionsMixin
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
// TODO(sigmund): consider using the existing required checks returned by
|
||||||
Substitution getSubstitution(ClassEntity cls, ClassEntity other) {
|
// `_substitutions.computeChecks` to cache existing substitutions. Before the
|
||||||
// Look for a precomputed check.
|
// null-safety migration this library had logic to retrieve substitutions from
|
||||||
for (TypeCheck check in _requiredChecks[cls].checks) {
|
// such a cache, but the algorithm never used it. Because of that we deleted
|
||||||
if (check.cls == other) {
|
// the caching mechanism altogether.
|
||||||
return check.substitution;
|
Substitution? computeSubstitution(ClassEntity cls, ClassEntity check,
|
||||||
}
|
|
||||||
}
|
|
||||||
// There is no precomputed check for this pair (because the check is not
|
|
||||||
// done on type arguments only. Compute a new substitution.
|
|
||||||
return computeSubstitution(cls, other);
|
|
||||||
}
|
|
||||||
|
|
||||||
Substitution computeSubstitution(ClassEntity cls, ClassEntity check,
|
|
||||||
{bool alwaysGenerateFunction = false}) {
|
{bool alwaysGenerateFunction = false}) {
|
||||||
if (isTrivialSubstitution(cls, check)) return null;
|
if (isTrivialSubstitution(cls, check)) return null;
|
||||||
|
|
||||||
|
@ -440,7 +426,7 @@ abstract class RuntimeTypesSubstitutionsMixin
|
||||||
// are never instantiated and their checks are overwritten by the class that
|
// are never instantiated and their checks are overwritten by the class that
|
||||||
// they are mixed into.
|
// they are mixed into.
|
||||||
InterfaceType type = _elementEnvironment.getThisType(cls);
|
InterfaceType type = _elementEnvironment.getThisType(cls);
|
||||||
InterfaceType target = _types.asInstanceOf(type, check);
|
InterfaceType target = _types.asInstanceOf(type, check)!;
|
||||||
List<DartType> typeVariables = type.typeArguments;
|
List<DartType> typeVariables = type.typeArguments;
|
||||||
if (_closedWorld.nativeData.isJsInteropClass(cls)) {
|
if (_closedWorld.nativeData.isJsInteropClass(cls)) {
|
||||||
int typeArguments = target.typeArguments.length;
|
int typeArguments = target.typeArguments.length;
|
||||||
|
@ -458,8 +444,6 @@ abstract class RuntimeTypesSubstitutionsMixin
|
||||||
class TrivialRuntimeTypesSubstitutions extends RuntimeTypesSubstitutionsMixin {
|
class TrivialRuntimeTypesSubstitutions extends RuntimeTypesSubstitutionsMixin {
|
||||||
@override
|
@override
|
||||||
final JClosedWorld _closedWorld;
|
final JClosedWorld _closedWorld;
|
||||||
@override
|
|
||||||
TypeChecks _requiredChecks;
|
|
||||||
|
|
||||||
TrivialRuntimeTypesSubstitutions(this._closedWorld);
|
TrivialRuntimeTypesSubstitutions(this._closedWorld);
|
||||||
}
|
}
|
||||||
|
@ -495,8 +479,6 @@ class RuntimeTypesImpl
|
||||||
// The set of tested type variable bounds.
|
// The set of tested type variable bounds.
|
||||||
final Set<DartType> checkedBounds = {};
|
final Set<DartType> checkedBounds = {};
|
||||||
|
|
||||||
TypeChecks cachedRequiredChecks;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool rtiChecksBuilderClosed = false;
|
bool rtiChecksBuilderClosed = false;
|
||||||
|
|
||||||
|
@ -509,10 +491,7 @@ class RuntimeTypesImpl
|
||||||
@override
|
@override
|
||||||
RuntimeTypesNeed get _rtiNeed => _closedWorld.rtiNeed;
|
RuntimeTypesNeed get _rtiNeed => _closedWorld.rtiNeed;
|
||||||
|
|
||||||
@override
|
Map<ClassEntity, ClassUse>? classUseMapForTesting;
|
||||||
TypeChecks get _requiredChecks => cachedRequiredChecks;
|
|
||||||
|
|
||||||
Map<ClassEntity, ClassUse> classUseMapForTesting;
|
|
||||||
|
|
||||||
final Set<GenericInstantiation> _genericInstantiations = {};
|
final Set<GenericInstantiation> _genericInstantiations = {};
|
||||||
|
|
||||||
|
@ -547,14 +526,14 @@ class RuntimeTypesImpl
|
||||||
Set<ClassEntity> typeArguments = {};
|
Set<ClassEntity> typeArguments = {};
|
||||||
|
|
||||||
Iterable<DartType> instantiateTypeVariable(TypeVariableEntity variable) {
|
Iterable<DartType> instantiateTypeVariable(TypeVariableEntity variable) {
|
||||||
Entity declaration = variable.typeDeclaration;
|
Entity? declaration = variable.typeDeclaration;
|
||||||
int index = variable.index;
|
int index = variable.index;
|
||||||
if (declaration is ClassEntity) {
|
if (declaration is ClassEntity) {
|
||||||
return typeVariableTests
|
return typeVariableTests
|
||||||
.classInstantiationsOf(declaration)
|
.classInstantiationsOf(declaration)
|
||||||
.map((InterfaceType interface) => interface.typeArguments[index]);
|
.map((InterfaceType interface) => interface.typeArguments[index]);
|
||||||
} else {
|
} else {
|
||||||
return typeVariableTests.instantiationsOf(declaration).map(
|
return typeVariableTests.instantiationsOf(declaration!).map(
|
||||||
(GenericInstantiation instantiation) =>
|
(GenericInstantiation instantiation) =>
|
||||||
instantiation.typeArguments[index]);
|
instantiation.typeArguments[index]);
|
||||||
}
|
}
|
||||||
|
@ -573,8 +552,8 @@ class RuntimeTypesImpl
|
||||||
// new A<B Function(C)>();
|
// new A<B Function(C)>();
|
||||||
//
|
//
|
||||||
// makes A and B live but C tested.
|
// makes A and B live but C tested.
|
||||||
TypeVisitor liveTypeVisitor = TypeVisitor(
|
_TypeVisitor liveTypeVisitor = _TypeVisitor(
|
||||||
onClass: (ClassEntity cls, {TypeVisitorState state}) {
|
onClass: (ClassEntity cls, {required TypeVisitorState state}) {
|
||||||
ClassUse classUse = classUseMap.putIfAbsent(cls, () => ClassUse());
|
ClassUse classUse = classUseMap.putIfAbsent(cls, () => ClassUse());
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case TypeVisitorState.covariantTypeArgument:
|
case TypeVisitorState.covariantTypeArgument:
|
||||||
|
@ -608,8 +587,8 @@ class RuntimeTypesImpl
|
||||||
// o is A<B Function(C)>;
|
// o is A<B Function(C)>;
|
||||||
//
|
//
|
||||||
// makes A and B tested but C live.
|
// makes A and B tested but C live.
|
||||||
TypeVisitor testedTypeVisitor = TypeVisitor(
|
_TypeVisitor testedTypeVisitor = _TypeVisitor(
|
||||||
onClass: (ClassEntity cls, {TypeVisitorState state}) {
|
onClass: (ClassEntity cls, {required TypeVisitorState state}) {
|
||||||
ClassUse classUse = classUseMap.putIfAbsent(cls, () => ClassUse());
|
ClassUse classUse = classUseMap.putIfAbsent(cls, () => ClassUse());
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case TypeVisitorState.covariantTypeArgument:
|
case TypeVisitorState.covariantTypeArgument:
|
||||||
|
@ -641,7 +620,7 @@ class RuntimeTypesImpl
|
||||||
ClassUse classUse =
|
ClassUse classUse =
|
||||||
classUseMap.putIfAbsent(type.element, () => ClassUse());
|
classUseMap.putIfAbsent(type.element, () => ClassUse());
|
||||||
classUse.directInstance = true;
|
classUse.directInstance = true;
|
||||||
FunctionType callType = _types.getCallType(type);
|
FunctionType? callType = _types.getCallType(type);
|
||||||
if (callType != null) {
|
if (callType != null) {
|
||||||
liveTypeVisitor.visitType(callType, TypeVisitorState.direct);
|
liveTypeVisitor.visitType(callType, TypeVisitorState.direct);
|
||||||
}
|
}
|
||||||
|
@ -717,7 +696,7 @@ class RuntimeTypesImpl
|
||||||
// closures have a signature method iff they need it and should have a
|
// closures have a signature method iff they need it and should have a
|
||||||
// function type iff they have a signature, we process all classes.
|
// function type iff they have a signature, we process all classes.
|
||||||
void processClass(ClassEntity cls) {
|
void processClass(ClassEntity cls) {
|
||||||
ClassFunctionType functionType =
|
ClassFunctionType? functionType =
|
||||||
_computeFunctionType(_elementEnvironment, cls);
|
_computeFunctionType(_elementEnvironment, cls);
|
||||||
if (functionType != null) {
|
if (functionType != null) {
|
||||||
ClassUse classUse = classUseMap.putIfAbsent(cls, () => ClassUse());
|
ClassUse classUse = classUseMap.putIfAbsent(cls, () => ClassUse());
|
||||||
|
@ -752,10 +731,9 @@ class RuntimeTypesImpl
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
cachedRequiredChecks = _computeChecks(classUseMap);
|
final checks = _computeChecks(classUseMap);
|
||||||
rtiChecksBuilderClosed = true;
|
rtiChecksBuilderClosed = true;
|
||||||
return _RuntimeTypesChecks(
|
return _RuntimeTypesChecks(this, checks, typeArguments, typeLiterals);
|
||||||
this, cachedRequiredChecks, typeArguments, typeLiterals);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -763,13 +741,13 @@ class RuntimeTypesImpl
|
||||||
///
|
///
|
||||||
/// In Dart 1, any class with a `call` method has a function type, in Dart 2
|
/// In Dart 1, any class with a `call` method has a function type, in Dart 2
|
||||||
/// only closure classes have a function type.
|
/// only closure classes have a function type.
|
||||||
ClassFunctionType _computeFunctionType(
|
ClassFunctionType? _computeFunctionType(
|
||||||
ElementEnvironment elementEnvironment, ClassEntity cls) {
|
ElementEnvironment elementEnvironment, ClassEntity cls) {
|
||||||
FunctionEntity signatureFunction;
|
FunctionEntity? signatureFunction;
|
||||||
if (cls.isClosure) {
|
if (cls.isClosure) {
|
||||||
// Use signature function if available.
|
// Use signature function if available.
|
||||||
signatureFunction =
|
signatureFunction = elementEnvironment.lookupLocalClassMember(
|
||||||
elementEnvironment.lookupLocalClassMember(cls, Names.signature);
|
cls, Names.signature) as FunctionEntity?;
|
||||||
if (signatureFunction == null) {
|
if (signatureFunction == null) {
|
||||||
// In Dart 2, a closure only needs its function type if it has a
|
// In Dart 2, a closure only needs its function type if it has a
|
||||||
// signature function.
|
// signature function.
|
||||||
|
@ -779,10 +757,10 @@ ClassFunctionType _computeFunctionType(
|
||||||
// Only closures have function type in Dart 2.
|
// Only closures have function type in Dart 2.
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
MemberEntity call =
|
MemberEntity? call =
|
||||||
elementEnvironment.lookupLocalClassMember(cls, Names.call);
|
elementEnvironment.lookupLocalClassMember(cls, Names.call);
|
||||||
if (call != null && call.isFunction) {
|
if (call != null && call.isFunction) {
|
||||||
FunctionEntity callFunction = call;
|
FunctionEntity callFunction = call as FunctionEntity;
|
||||||
FunctionType callType = elementEnvironment.getFunctionType(callFunction);
|
FunctionType callType = elementEnvironment.getFunctionType(callFunction);
|
||||||
return ClassFunctionType(callFunction, callType, signatureFunction);
|
return ClassFunctionType(callFunction, callType, signatureFunction);
|
||||||
}
|
}
|
||||||
|
@ -794,7 +772,7 @@ class TypeCheckMapping implements TypeChecks {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ClassChecks operator [](ClassEntity element) {
|
ClassChecks operator [](ClassEntity element) {
|
||||||
ClassChecks result = map[element];
|
ClassChecks? result = map[element];
|
||||||
return result ?? const ClassChecks.empty();
|
return result ?? const ClassChecks.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -895,15 +873,16 @@ enum TypeVisitorState {
|
||||||
typeLiteral,
|
typeLiteral,
|
||||||
}
|
}
|
||||||
|
|
||||||
class TypeVisitor extends DartTypeVisitor<void, TypeVisitorState> {
|
class _TypeVisitor extends DartTypeVisitor<void, TypeVisitorState> {
|
||||||
final Set<TypeVariableType> _visitedTypeVariables = {};
|
final Set<TypeVariableType> _visitedTypeVariables = {};
|
||||||
final Set<FunctionTypeVariable> _visitedFunctionTypeVariables = {};
|
final Set<FunctionTypeVariable> _visitedFunctionTypeVariables = {};
|
||||||
|
|
||||||
final void Function(ClassEntity entity, {TypeVisitorState state}) onClass;
|
final void Function(ClassEntity entity, {required TypeVisitorState state})
|
||||||
|
onClass;
|
||||||
final Iterable<DartType> Function(TypeVariableEntity entity)
|
final Iterable<DartType> Function(TypeVariableEntity entity)
|
||||||
instantiateTypeVariable;
|
instantiateTypeVariable;
|
||||||
|
|
||||||
TypeVisitor({this.onClass, this.instantiateTypeVariable});
|
_TypeVisitor({required this.onClass, required this.instantiateTypeVariable});
|
||||||
|
|
||||||
void visitType(DartType type, TypeVisitorState state) =>
|
void visitType(DartType type, TypeVisitorState state) =>
|
||||||
type.accept(this, state);
|
type.accept(this, state);
|
||||||
|
@ -919,7 +898,6 @@ class TypeVisitor extends DartTypeVisitor<void, TypeVisitorState> {
|
||||||
case TypeVisitorState.typeLiteral:
|
case TypeVisitorState.typeLiteral:
|
||||||
return TypeVisitorState.typeLiteral;
|
return TypeVisitorState.typeLiteral;
|
||||||
}
|
}
|
||||||
throw UnsupportedError("Unexpected TypeVisitorState $state");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeVisitorState contravariantArgument(TypeVisitorState state) {
|
TypeVisitorState contravariantArgument(TypeVisitorState state) {
|
||||||
|
@ -933,7 +911,6 @@ class TypeVisitor extends DartTypeVisitor<void, TypeVisitorState> {
|
||||||
case TypeVisitorState.typeLiteral:
|
case TypeVisitorState.typeLiteral:
|
||||||
return TypeVisitorState.typeLiteral;
|
return TypeVisitorState.typeLiteral;
|
||||||
}
|
}
|
||||||
throw UnsupportedError("Unexpected TypeVisitorState $state");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitTypes(List<DartType> types, TypeVisitorState state) {
|
void visitTypes(List<DartType> types, TypeVisitorState state) {
|
||||||
|
@ -958,7 +935,7 @@ class TypeVisitor extends DartTypeVisitor<void, TypeVisitorState> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void visitTypeVariableType(TypeVariableType type, TypeVisitorState state) {
|
void visitTypeVariableType(TypeVariableType type, TypeVisitorState state) {
|
||||||
if (_visitedTypeVariables.add(type) && instantiateTypeVariable != null) {
|
if (_visitedTypeVariables.add(type)) {
|
||||||
for (DartType instantiation in instantiateTypeVariable(type.element)) {
|
for (DartType instantiation in instantiateTypeVariable(type.element)) {
|
||||||
visitType(instantiation, state);
|
visitType(instantiation, state);
|
||||||
}
|
}
|
||||||
|
@ -985,9 +962,7 @@ class TypeVisitor extends DartTypeVisitor<void, TypeVisitorState> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void visitInterfaceType(InterfaceType type, TypeVisitorState state) {
|
void visitInterfaceType(InterfaceType type, TypeVisitorState state) {
|
||||||
if (onClass != null) {
|
onClass(type.element, state: state);
|
||||||
onClass(type.element, state: state);
|
|
||||||
}
|
|
||||||
visitTypes(type.typeArguments, covariantArgument(state));
|
visitTypes(type.typeArguments, covariantArgument(state));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1076,7 +1051,7 @@ class ClassUse {
|
||||||
///
|
///
|
||||||
/// Furthermore optimization might also omit function type that are known not
|
/// Furthermore optimization might also omit function type that are known not
|
||||||
/// to be valid in any subtype test.
|
/// to be valid in any subtype test.
|
||||||
ClassFunctionType functionType;
|
ClassFunctionType? functionType;
|
||||||
|
|
||||||
/// `true` if the class is 'live' either through instantiation or use in
|
/// `true` if the class is 'live' either through instantiation or use in
|
||||||
/// type arguments.
|
/// type arguments.
|
||||||
|
|
|
@ -29,7 +29,7 @@ class ClassFunctionType {
|
||||||
class TypeCheck {
|
class TypeCheck {
|
||||||
final ClassEntity cls;
|
final ClassEntity cls;
|
||||||
final bool needsIs;
|
final bool needsIs;
|
||||||
final Substitution substitution;
|
final Substitution? substitution;
|
||||||
@override
|
@override
|
||||||
final int hashCode = _nextHash = (_nextHash + 100003).toUnsigned(30);
|
final int hashCode = _nextHash = (_nextHash + 100003).toUnsigned(30);
|
||||||
static int _nextHash = 0;
|
static int _nextHash = 0;
|
||||||
|
@ -130,8 +130,6 @@ class Substitution {
|
||||||
abstract class RuntimeTypesSubstitutions {
|
abstract class RuntimeTypesSubstitutions {
|
||||||
bool isTrivialSubstitution(ClassEntity cls, ClassEntity check);
|
bool isTrivialSubstitution(ClassEntity cls, ClassEntity check);
|
||||||
|
|
||||||
Substitution getSubstitution(ClassEntity cls, ClassEntity other);
|
|
||||||
|
|
||||||
Set<ClassEntity> getClassesUsedInSubstitutions(TypeChecks checks);
|
Set<ClassEntity> getClassesUsedInSubstitutions(TypeChecks checks);
|
||||||
|
|
||||||
static bool hasTypeArguments(DartTypes dartTypes, DartType type) {
|
static bool hasTypeArguments(DartTypes dartTypes, DartType type) {
|
||||||
|
|
Loading…
Reference in a new issue