mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
[cfe] Remove use of the AST-based class hierarchy from the inferrer
Change-Id: I636dd75b443a23dc531fbeddfbbf3cb76358e5f0 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/269780 Reviewed-by: Chloe Stefantsova <cstefantsova@google.com> Commit-Queue: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
parent
50e18b8160
commit
39c68314f2
|
@ -78,6 +78,7 @@ class ClassHierarchyBuilder implements ClassHierarchyBase {
|
|||
|
||||
@override
|
||||
Supertype? getClassAsInstanceOf(Class subclass, Class superclass) {
|
||||
if (identical(subclass, superclass)) return subclass.asThisSupertype;
|
||||
ClassHierarchyNode clsNode = getNodeFromClass(subclass);
|
||||
ClassHierarchyNode supertypeNode = getNodeFromClass(superclass);
|
||||
List<Supertype> superclasses = clsNode.superclasses;
|
||||
|
@ -114,6 +115,11 @@ class ClassHierarchyBuilder implements ClassHierarchyBase {
|
|||
return asSupertypeOf(type, superclass)?.typeArguments;
|
||||
}
|
||||
|
||||
@override
|
||||
bool isSubtypeOf(Class subtype, Class superclass) {
|
||||
return getClassAsInstanceOf(subtype, superclass) != null;
|
||||
}
|
||||
|
||||
@override
|
||||
InterfaceType getLegacyLeastUpperBound(
|
||||
InterfaceType type1, InterfaceType type2, Library clientLibrary) {
|
||||
|
|
|
@ -148,6 +148,18 @@ class ClassMembersBuilder implements ClassHierarchyMembers {
|
|||
return getNodeFromClass(cls).getInterfaceMember(name, setter);
|
||||
}
|
||||
|
||||
@override
|
||||
Member? getDispatchTarget(Class cls, Name name, {bool setter = false}) {
|
||||
return getNodeFromClass(cls)
|
||||
.getDispatchTarget(name, setter)
|
||||
?.getMember(this);
|
||||
}
|
||||
|
||||
ClassMember? getDispatchClassMember(Class cls, Name name,
|
||||
{bool setter = false}) {
|
||||
return getNodeFromClass(cls).getDispatchTarget(name, setter);
|
||||
}
|
||||
|
||||
static ClassMembersBuilder build(
|
||||
ClassHierarchyBuilder hierarchyBuilder, List<ClassBuilder> classes) {
|
||||
ClassMembersBuilder membersBuilder =
|
||||
|
|
|
@ -74,14 +74,6 @@ class ClassMembersNodeBuilder {
|
|||
bool get shouldModifyKernel =>
|
||||
classBuilder.libraryBuilder.loader == hierarchy.loader;
|
||||
|
||||
ClassMember? checkInheritanceConflict(ClassMember a, ClassMember b) {
|
||||
if (a.isStatic || a.isProperty != b.isProperty) {
|
||||
reportInheritanceConflict(a, b);
|
||||
return a;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static void inferMethodType(
|
||||
ClassHierarchyBuilder hierarchyBuilder,
|
||||
ClassMembersBuilder membersBuilder,
|
||||
|
@ -2311,6 +2303,7 @@ class ClassMembersNodeBuilder {
|
|||
|
||||
return new ClassMembersNode(
|
||||
classBuilder,
|
||||
supernode,
|
||||
classMemberMap,
|
||||
classSetterMap,
|
||||
interfaceMemberMap,
|
||||
|
@ -2360,6 +2353,8 @@ class ClassMembersNodeBuilder {
|
|||
class ClassMembersNode {
|
||||
final ClassBuilder classBuilder;
|
||||
|
||||
final ClassMembersNode? supernode;
|
||||
|
||||
/// All the members of this class including [classMembers] of its
|
||||
/// superclasses. The members are sorted by [compareDeclarations].
|
||||
final Map<Name, ClassMember> classMemberMap;
|
||||
|
@ -2387,6 +2382,7 @@ class ClassMembersNode {
|
|||
|
||||
ClassMembersNode(
|
||||
this.classBuilder,
|
||||
this.supernode,
|
||||
this.classMemberMap,
|
||||
this.classSetterMap,
|
||||
this.interfaceMemberMap,
|
||||
|
@ -2434,9 +2430,16 @@ class ClassMembersNode {
|
|||
}
|
||||
|
||||
ClassMember? getInterfaceMember(Name name, bool isSetter) {
|
||||
return isSetter
|
||||
ClassMember? result = isSetter
|
||||
? (interfaceSetterMap ?? classSetterMap)[name]
|
||||
: (interfaceMemberMap ?? classMemberMap)[name];
|
||||
if (result == null) {
|
||||
return null;
|
||||
}
|
||||
if (result.isStatic) {
|
||||
return null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ClassMember? findMember(Name name, List<ClassMember> declarations) {
|
||||
|
@ -2464,7 +2467,17 @@ class ClassMembersNode {
|
|||
}
|
||||
|
||||
ClassMember? getDispatchTarget(Name name, bool isSetter) {
|
||||
return isSetter ? classSetterMap[name] : classMemberMap[name];
|
||||
ClassMember? result =
|
||||
isSetter ? classSetterMap[name] : classMemberMap[name];
|
||||
if (result == null) {
|
||||
return null;
|
||||
}
|
||||
if (result.isStatic) {
|
||||
// TODO(johnniwinther): Can we avoid putting static members in the
|
||||
// [classMemberMap]/[classSetterMap] maps?
|
||||
return supernode?.getDispatchTarget(name, isSetter);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,8 @@ import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token;
|
|||
import 'package:_fe_analyzer_shared/src/util/resolve_relative_uri.dart'
|
||||
show resolveRelativeUri;
|
||||
import 'package:kernel/ast.dart' hide Combinator, MapLiteralEntry;
|
||||
import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
|
||||
import 'package:kernel/class_hierarchy.dart'
|
||||
show ClassHierarchy, ClassHierarchyBase, ClassHierarchyMembers;
|
||||
import 'package:kernel/clone.dart' show CloneVisitorNotMembers;
|
||||
import 'package:kernel/reference_from_index.dart'
|
||||
show IndexedClass, IndexedContainer, IndexedLibrary;
|
||||
|
@ -4416,7 +4417,8 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
|
|||
void checkBoundsInMethodInvocation(
|
||||
DartType receiverType,
|
||||
TypeEnvironment typeEnvironment,
|
||||
ClassHierarchy hierarchy,
|
||||
ClassHierarchyBase classHierarchy,
|
||||
ClassHierarchyMembers membersHierarchy,
|
||||
Name name,
|
||||
Member? interfaceTarget,
|
||||
Arguments arguments,
|
||||
|
@ -4437,14 +4439,14 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
|
|||
}
|
||||
// TODO(cstefantsova): Find a better way than relying on [interfaceTarget].
|
||||
Member? method =
|
||||
hierarchy.getDispatchTarget(klass, name) ?? interfaceTarget;
|
||||
membersHierarchy.getDispatchTarget(klass, name) ?? interfaceTarget;
|
||||
// ignore: unnecessary_null_comparison
|
||||
if (method == null || method is! Procedure) {
|
||||
return;
|
||||
}
|
||||
if (klass != method.enclosingClass) {
|
||||
Supertype parent =
|
||||
hierarchy.getClassAsInstanceOf(klass, method.enclosingClass!)!;
|
||||
classHierarchy.getClassAsInstanceOf(klass, method.enclosingClass!)!;
|
||||
klass = method.enclosingClass!;
|
||||
receiverTypeArguments = parent.typeArguments;
|
||||
Map<TypeParameter, DartType> instanceSubstitutionMap = substitutionMap;
|
||||
|
@ -4492,7 +4494,6 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
|
|||
|
||||
void checkBoundsInFunctionInvocation(
|
||||
TypeEnvironment typeEnvironment,
|
||||
ClassHierarchy hierarchy,
|
||||
FunctionType functionType,
|
||||
String? localName,
|
||||
Arguments arguments,
|
||||
|
@ -4526,7 +4527,6 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
|
|||
|
||||
void checkBoundsInInstantiation(
|
||||
TypeEnvironment typeEnvironment,
|
||||
ClassHierarchy hierarchy,
|
||||
FunctionType functionType,
|
||||
List<DartType> typeArguments,
|
||||
Uri fileUri,
|
||||
|
|
|
@ -2295,21 +2295,25 @@ severity: $severity
|
|||
Name name = restrictedMemberNames[i];
|
||||
Class? declarer = restrictedMemberDeclarers[i];
|
||||
|
||||
Member? member = hierarchy.getDispatchTarget(classBuilder.cls, name);
|
||||
if (member?.enclosingClass != declarer &&
|
||||
member?.enclosingClass != classBuilder.cls &&
|
||||
member?.isAbstract == false) {
|
||||
classBuilder.libraryBuilder.addProblem(
|
||||
templateEnumInheritsRestricted.withArguments(name.text),
|
||||
classBuilder.charOffset,
|
||||
classBuilder.name.length,
|
||||
classBuilder.fileUri,
|
||||
context: <LocatedMessage>[
|
||||
messageEnumInheritsRestrictedMember.withLocation(
|
||||
member!.fileUri,
|
||||
member.fileOffset,
|
||||
member.name.text.length)
|
||||
]);
|
||||
ClassMember? classMember =
|
||||
membersBuilder.getDispatchClassMember(classBuilder.cls, name);
|
||||
if (classMember != null) {
|
||||
Member member = classMember.getMember(membersBuilder);
|
||||
if (member.enclosingClass != declarer &&
|
||||
member.enclosingClass != classBuilder.cls &&
|
||||
member.isAbstract == false) {
|
||||
classBuilder.libraryBuilder.addProblem(
|
||||
templateEnumInheritsRestricted.withArguments(name.text),
|
||||
classBuilder.charOffset,
|
||||
classBuilder.name.length,
|
||||
classBuilder.fileUri,
|
||||
context: <LocatedMessage>[
|
||||
messageEnumInheritsRestrictedMember.withLocation(
|
||||
classMember.fileUri,
|
||||
classMember.charOffset,
|
||||
member.name.text.length)
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1407,7 +1407,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
|||
if (inferredExpressionType is InterfaceType) {
|
||||
// TODO(johnniwinther): Should we use the type of
|
||||
// `iterable.iterator.current` instead?
|
||||
List<DartType>? supertypeArguments = classHierarchy
|
||||
List<DartType>? supertypeArguments = hierarchyBuilder
|
||||
.getTypeArgumentsAsInstanceOf(inferredExpressionType, iterableClass);
|
||||
if (supertypeArguments != null) {
|
||||
inferredType = supertypeArguments[0];
|
||||
|
@ -1636,7 +1636,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
|||
InitializerInferenceResult visitInvalidSuperInitializerJudgment(
|
||||
InvalidSuperInitializerJudgment node) {
|
||||
Substitution substitution = Substitution.fromSupertype(
|
||||
classHierarchy.getClassAsInstanceOf(
|
||||
hierarchyBuilder.getClassAsInstanceOf(
|
||||
thisType!.classNode, node.target.enclosingClass)!);
|
||||
FunctionType functionType = replaceReturnType(
|
||||
substitution.substituteType(node.target.function
|
||||
|
@ -2843,10 +2843,10 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
|||
// Ambiguous set/map literal
|
||||
if (unfuturedTypeContext is InterfaceType) {
|
||||
typeContextIsMap = typeContextIsMap ||
|
||||
classHierarchy.isSubtypeOf(
|
||||
hierarchyBuilder.isSubtypeOf(
|
||||
unfuturedTypeContext.classNode, coreTypes.mapClass);
|
||||
typeContextIsIterable = typeContextIsIterable ||
|
||||
classHierarchy.isSubtypeOf(
|
||||
hierarchyBuilder.isSubtypeOf(
|
||||
unfuturedTypeContext.classNode, coreTypes.iterableClass);
|
||||
if (node.entries.isEmpty && typeContextIsIterable && !typeContextIsMap) {
|
||||
// Set literal
|
||||
|
@ -3086,7 +3086,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
|||
result.inferredType, result.applyResult(invocation));
|
||||
} else {
|
||||
// TODO(johnniwinther): Handle augmentation of field with inferred types.
|
||||
TypeInferenceEngine.resolveInferenceNode(member, classHierarchy);
|
||||
TypeInferenceEngine.resolveInferenceNode(member, hierarchyBuilder);
|
||||
Link<NullAwareGuard> nullAwareGuards = const Link<NullAwareGuard>();
|
||||
DartType receiverType = member.getterType;
|
||||
Expression receiver = new StaticGet(member)..fileOffset = node.fileOffset;
|
||||
|
@ -5892,7 +5892,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
|||
return new ExpressionInferenceResult(replacementType, replacement);
|
||||
} else {
|
||||
// TODO(johnniwinther): Handle augmentation of field with inferred types.
|
||||
TypeInferenceEngine.resolveInferenceNode(member, classHierarchy);
|
||||
TypeInferenceEngine.resolveInferenceNode(member, hierarchyBuilder);
|
||||
DartType writeContext = member.setterType;
|
||||
ExpressionInferenceResult rhsResult =
|
||||
inferExpression(node.value, writeContext, isVoidAllowed: true);
|
||||
|
@ -6153,7 +6153,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
|||
readResult.inferredType, readResult.expression);
|
||||
} else {
|
||||
// TODO(johnniwinther): Handle augmentation of field with inferred types.
|
||||
TypeInferenceEngine.resolveInferenceNode(member, classHierarchy);
|
||||
TypeInferenceEngine.resolveInferenceNode(member, hierarchyBuilder);
|
||||
DartType type = member.getterType;
|
||||
|
||||
if (member is Procedure && member.kind == ProcedureKind.Method) {
|
||||
|
@ -6302,7 +6302,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
|||
ExpressionInferenceResult visitStaticSet(
|
||||
StaticSet node, DartType typeContext) {
|
||||
Member writeMember = node.target;
|
||||
TypeInferenceEngine.resolveInferenceNode(writeMember, classHierarchy);
|
||||
TypeInferenceEngine.resolveInferenceNode(writeMember, hierarchyBuilder);
|
||||
DartType writeContext = writeMember.setterType;
|
||||
ExpressionInferenceResult rhsResult =
|
||||
inferExpression(node.value, writeContext, isVoidAllowed: true);
|
||||
|
@ -6318,7 +6318,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
|||
ExpressionInferenceResult visitStaticGet(
|
||||
StaticGet node, DartType typeContext) {
|
||||
Member target = node.target;
|
||||
TypeInferenceEngine.resolveInferenceNode(target, classHierarchy);
|
||||
TypeInferenceEngine.resolveInferenceNode(target, hierarchyBuilder);
|
||||
DartType type = target.getterType;
|
||||
|
||||
if (!isNonNullableByDefault) {
|
||||
|
@ -6378,7 +6378,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
|||
InitializerInferenceResult visitSuperInitializer(SuperInitializer node) {
|
||||
ensureMemberType(node.target);
|
||||
Substitution substitution = Substitution.fromSupertype(
|
||||
classHierarchy.getClassAsInstanceOf(
|
||||
hierarchyBuilder.getClassAsInstanceOf(
|
||||
thisType!.classNode, node.target.enclosingClass)!);
|
||||
FunctionType functionType = replaceReturnType(
|
||||
substitution.substituteType(node.target.function
|
||||
|
|
|
@ -9,7 +9,8 @@ import 'package:_fe_analyzer_shared/src/testing/id.dart';
|
|||
import 'package:_fe_analyzer_shared/src/util/link.dart';
|
||||
import 'package:kernel/ast.dart';
|
||||
import 'package:kernel/canonical_name.dart' as kernel;
|
||||
import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
|
||||
import 'package:kernel/class_hierarchy.dart'
|
||||
show ClassHierarchyBase, ClassHierarchyMembers;
|
||||
import 'package:kernel/core_types.dart' show CoreTypes;
|
||||
import 'package:kernel/src/bounds_checks.dart'
|
||||
show calculateBounds, isGenericFunctionTypeOrAlias;
|
||||
|
@ -32,7 +33,6 @@ import '../builder/extension_builder.dart';
|
|||
import '../builder/member_builder.dart';
|
||||
import '../fasta_codes.dart';
|
||||
import '../kernel/constructor_tearoff_lowering.dart';
|
||||
import '../kernel/hierarchy/class_member.dart' show ClassMember;
|
||||
import '../kernel/internal_ast.dart';
|
||||
import '../kernel/kernel_helper.dart';
|
||||
import '../kernel/type_algorithms.dart' show hasAnyTypeVariables;
|
||||
|
@ -171,7 +171,9 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
|
|||
|
||||
Instrumentation? get instrumentation => _inferrer.instrumentation;
|
||||
|
||||
ClassHierarchy get classHierarchy => _inferrer.classHierarchy;
|
||||
ClassHierarchyBase get hierarchyBuilder => _inferrer.engine.hierarchyBuilder;
|
||||
|
||||
ClassHierarchyMembers get membersBuilder => _inferrer.engine.membersBuilder;
|
||||
|
||||
InferenceDataForTesting? get dataForTesting => _inferrer.dataForTesting;
|
||||
|
||||
|
@ -366,7 +368,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
|
|||
} else if ((constructor = engine.toBeInferred[target]) != null) {
|
||||
engine.toBeInferred.remove(target);
|
||||
engine.beingInferred[target] = constructor!;
|
||||
constructor.inferFormalTypes(classHierarchy);
|
||||
constructor.inferFormalTypes(hierarchyBuilder);
|
||||
engine.beingInferred.remove(target);
|
||||
}
|
||||
}
|
||||
|
@ -669,7 +671,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
|
|||
TypedTearoff _tearOffCall(
|
||||
Expression expression, InterfaceType expressionType, int fileOffset) {
|
||||
Class classNode = expressionType.classNode;
|
||||
Member callMember = classHierarchy.getInterfaceMember(classNode, callName)!;
|
||||
Member callMember = membersBuilder.getInterfaceMember(classNode, callName)!;
|
||||
assert(callMember is Procedure && callMember.kind == ProcedureKind.Method);
|
||||
|
||||
// Replace expression with:
|
||||
|
@ -719,7 +721,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
|
|||
if (coerceExpression && expressionType is InterfaceType) {
|
||||
Class classNode = expressionType.classNode;
|
||||
Member? callMember =
|
||||
classHierarchy.getInterfaceMember(classNode, callName);
|
||||
membersBuilder.getInterfaceMember(classNode, callName);
|
||||
if (callMember is Procedure && callMember.kind == ProcedureKind.Method) {
|
||||
if (_shouldTearOffCall(contextType, expressionType)) {
|
||||
needsTearoff = true;
|
||||
|
@ -851,7 +853,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
|
|||
if (showHideClause == null) return defaultTarget;
|
||||
|
||||
kernel.Reference? reference = showHideClause.findShownReference(
|
||||
name, callSiteAccessKind, classHierarchy);
|
||||
name, callSiteAccessKind, membersBuilder);
|
||||
if (reference != null) {
|
||||
return new ObjectAccessTarget.interfaceMember(
|
||||
receiverType, reference.asMember,
|
||||
|
@ -1314,7 +1316,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
|
|||
if (memberClass.typeParameters.isNotEmpty) {
|
||||
receiverType = resolveTypeParameter(receiverType);
|
||||
if (receiverType is InterfaceType) {
|
||||
List<DartType> castedTypeArguments = classHierarchy
|
||||
List<DartType> castedTypeArguments = hierarchyBuilder
|
||||
.getTypeArgumentsAsInstanceOf(receiverType, memberClass)!;
|
||||
calleeType = Substitution.fromPairs(
|
||||
memberClass.typeParameters, castedTypeArguments)
|
||||
|
@ -1367,7 +1369,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
|
|||
DartType? getDerivedTypeArgumentOf(DartType type, Class class_) {
|
||||
if (type is InterfaceType) {
|
||||
List<DartType>? typeArgumentsAsInstanceOfClass =
|
||||
classHierarchy.getTypeArgumentsAsInstanceOf(type, class_);
|
||||
hierarchyBuilder.getTypeArgumentsAsInstanceOf(type, class_);
|
||||
if (typeArgumentsAsInstanceOfClass != null) {
|
||||
return typeArgumentsAsInstanceOfClass[0];
|
||||
}
|
||||
|
@ -3299,7 +3301,8 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
|
|||
libraryBuilder.checkBoundsInMethodInvocation(
|
||||
actualReceiverType,
|
||||
typeSchemaEnvironment,
|
||||
classHierarchy,
|
||||
hierarchyBuilder,
|
||||
membersBuilder,
|
||||
actualMethodName,
|
||||
interfaceTarget,
|
||||
arguments,
|
||||
|
@ -3314,22 +3317,16 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
|
|||
assert(inferred != null);
|
||||
// If [arguments] were inferred, check them.
|
||||
|
||||
libraryBuilder.checkBoundsInInstantiation(typeSchemaEnvironment,
|
||||
classHierarchy, functionType, arguments, helper.uri, fileOffset,
|
||||
libraryBuilder.checkBoundsInInstantiation(
|
||||
typeSchemaEnvironment, functionType, arguments, helper.uri, fileOffset,
|
||||
inferred: inferred);
|
||||
}
|
||||
|
||||
void _checkBoundsInFunctionInvocation(FunctionType functionType,
|
||||
String? localName, Arguments arguments, int fileOffset) {
|
||||
// If [arguments] were inferred, check them.
|
||||
libraryBuilder.checkBoundsInFunctionInvocation(
|
||||
typeSchemaEnvironment,
|
||||
classHierarchy,
|
||||
functionType,
|
||||
localName,
|
||||
arguments,
|
||||
helper.uri,
|
||||
fileOffset);
|
||||
libraryBuilder.checkBoundsInFunctionInvocation(typeSchemaEnvironment,
|
||||
functionType, localName, arguments, helper.uri, fileOffset);
|
||||
}
|
||||
|
||||
/// Performs the core type inference algorithm for super method invocations.
|
||||
|
@ -3635,22 +3632,9 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
|
|||
|
||||
Member? _getInterfaceMember(
|
||||
Class class_, Name name, bool setter, int charOffset) {
|
||||
ClassMember? classMember = engine.membersBuilder
|
||||
.getInterfaceClassMember(class_, name, setter: setter);
|
||||
if (classMember != null) {
|
||||
if (classMember.isStatic) {
|
||||
classMember = null;
|
||||
} else if (classMember.isDuplicate) {
|
||||
libraryBuilder.addProblem(
|
||||
templateDuplicatedDeclarationUse.withArguments(name.text),
|
||||
charOffset,
|
||||
name.text.length,
|
||||
helper.uri);
|
||||
classMember = null;
|
||||
}
|
||||
}
|
||||
Member? member = classMember?.getMember(engine.membersBuilder);
|
||||
return TypeInferenceEngine.resolveInferenceNode(member, classHierarchy);
|
||||
Member? member =
|
||||
engine.membersBuilder.getInterfaceMember(class_, name, setter: setter);
|
||||
return TypeInferenceEngine.resolveInferenceNode(member, hierarchyBuilder);
|
||||
}
|
||||
|
||||
/// Determines if the given [expression]'s type is precisely known at compile
|
||||
|
|
|
@ -419,7 +419,7 @@ class InstanceAccessTarget extends ObjectAccessTarget {
|
|||
if (resolvedReceiverType is InterfaceType) {
|
||||
setterType = Substitution.fromPairs(
|
||||
memberClass.typeParameters,
|
||||
base.classHierarchy.getTypeArgumentsAsInstanceOf(
|
||||
base.hierarchyBuilder.getTypeArgumentsAsInstanceOf(
|
||||
resolvedReceiverType, memberClass)!)
|
||||
.substituteType(setterType);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,8 @@ import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
|
|||
import 'package:_fe_analyzer_shared/src/type_inference/assigned_variables.dart';
|
||||
import 'package:_fe_analyzer_shared/src/type_inference/type_operations.dart';
|
||||
import 'package:kernel/ast.dart';
|
||||
import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
|
||||
import 'package:kernel/class_hierarchy.dart'
|
||||
show ClassHierarchy, ClassHierarchyBase;
|
||||
import 'package:kernel/core_types.dart' show CoreTypes;
|
||||
import 'package:kernel/type_environment.dart';
|
||||
|
||||
|
@ -133,8 +134,6 @@ class IncludesTypeParametersNonCovariantly implements DartTypeVisitor<bool> {
|
|||
/// (e.g. DietListener). Derived classes should derive from
|
||||
/// [TypeInferenceEngineImpl].
|
||||
abstract class TypeInferenceEngine {
|
||||
late ClassHierarchy classHierarchy;
|
||||
|
||||
late ClassHierarchyBuilder hierarchyBuilder;
|
||||
|
||||
late ClassMembersBuilder membersBuilder;
|
||||
|
@ -187,7 +186,7 @@ abstract class TypeInferenceEngine {
|
|||
// Field types have all been inferred so we don't need to guard against
|
||||
// cyclic dependency.
|
||||
for (SourceConstructorBuilder builder in toBeInferred.values) {
|
||||
builder.inferFormalTypes(classHierarchy);
|
||||
builder.inferFormalTypes(hierarchyBuilder);
|
||||
}
|
||||
toBeInferred.clear();
|
||||
for (TypeDependency typeDependency in typeDependencies.values) {
|
||||
|
@ -200,13 +199,12 @@ abstract class TypeInferenceEngine {
|
|||
/// given [hierarchy], using the given [coreTypes].
|
||||
void prepareTopLevel(CoreTypes coreTypes, ClassHierarchy hierarchy) {
|
||||
this.coreTypes = coreTypes;
|
||||
this.classHierarchy = hierarchy;
|
||||
this.typeSchemaEnvironment =
|
||||
new TypeSchemaEnvironment(coreTypes, hierarchy);
|
||||
}
|
||||
|
||||
static Member? resolveInferenceNode(
|
||||
Member? member, ClassHierarchy hierarchy) {
|
||||
Member? member, ClassHierarchyBase hierarchy) {
|
||||
if (member is Field) {
|
||||
DartType type = member.type;
|
||||
if (type is InferredType) {
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
|
||||
import 'package:_fe_analyzer_shared/src/type_inference/assigned_variables.dart';
|
||||
import 'package:kernel/ast.dart';
|
||||
import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
|
||||
|
||||
import '../../base/instrumentation.dart' show Instrumentation;
|
||||
import '../kernel/benchmarker.dart' show BenchmarkSubdivides, Benchmarker;
|
||||
|
@ -116,8 +115,6 @@ class TypeInferrerImpl implements TypeInferrer {
|
|||
@override
|
||||
final bool isTopLevel;
|
||||
|
||||
final ClassHierarchy classHierarchy;
|
||||
|
||||
final Instrumentation? instrumentation;
|
||||
|
||||
@override
|
||||
|
@ -140,7 +137,6 @@ class TypeInferrerImpl implements TypeInferrer {
|
|||
: assert(libraryBuilder != null),
|
||||
unknownFunction = new FunctionType(
|
||||
const [], const DynamicType(), libraryBuilder.nonNullable),
|
||||
classHierarchy = engine.classHierarchy,
|
||||
instrumentation = isTopLevel ? null : engine.instrumentation,
|
||||
typeSchemaEnvironment = engine.typeSchemaEnvironment,
|
||||
operations = new OperationsCfe(engine.typeSchemaEnvironment,
|
||||
|
|
|
@ -1880,7 +1880,7 @@ class ExtensionTypeShowHideClause {
|
|||
final List<Reference> hiddenOperators = <Reference>[];
|
||||
|
||||
Reference? findShownReference(Name name,
|
||||
CallSiteAccessKind callSiteAccessKind, ClassHierarchy hierarchy) {
|
||||
CallSiteAccessKind callSiteAccessKind, ClassHierarchyMembers hierarchy) {
|
||||
List<Reference> shownReferences;
|
||||
List<Reference> hiddenReferences;
|
||||
switch (callSiteAccessKind) {
|
||||
|
@ -1918,7 +1918,7 @@ class ExtensionTypeShowHideClause {
|
|||
Name name,
|
||||
List<Reference> references,
|
||||
List<Supertype> interfaces,
|
||||
ClassHierarchy hierarchy,
|
||||
ClassHierarchyMembers hierarchy,
|
||||
CallSiteAccessKind callSiteAccessKind) {
|
||||
for (Reference reference in references) {
|
||||
if (reference.asMember.name == name) {
|
||||
|
|
|
@ -42,6 +42,10 @@ abstract class ClassHierarchyBase {
|
|||
List<DartType>? getTypeArgumentsAsInstanceOf(
|
||||
InterfaceType type, Class superclass);
|
||||
|
||||
/// True if [subtype] inherits from [superclass] though zero or more
|
||||
/// `extends`, `with`, and `implements` relationships.
|
||||
bool isSubtypeOf(Class subtype, Class superclass);
|
||||
|
||||
/// Returns the least upper bound of two interface types, as defined by Dart
|
||||
/// 1.0.
|
||||
///
|
||||
|
@ -62,6 +66,21 @@ abstract class ClassHierarchyBase {
|
|||
}
|
||||
|
||||
abstract class ClassHierarchyMembers {
|
||||
/// Returns the instance member that would respond to a dynamic dispatch of
|
||||
/// [name] to an instance of [class_], or `null` if no such member exists.
|
||||
///
|
||||
/// If [setter] is `false`, the name is dispatched as a getter or call,
|
||||
/// and will return a field, getter, method, or operator (or null).
|
||||
///
|
||||
/// If [setter] is `true`, the name is dispatched as a setter, roughly
|
||||
/// corresponding to `name=` in the Dart specification, but note that the
|
||||
/// returned member will not have a name ending with `=`. In this case,
|
||||
/// a non-final field or setter (or null) will be returned.
|
||||
///
|
||||
/// If the class is abstract, abstract members are ignored and the dispatch
|
||||
/// is resolved if the class was not abstract.
|
||||
Member? getDispatchTarget(Class class_, Name name, {bool setter = false});
|
||||
|
||||
/// Returns the possibly abstract interface member of [class_] with the given
|
||||
/// [name].
|
||||
///
|
||||
|
@ -111,21 +130,6 @@ abstract class ClassHierarchy
|
|||
/// be a generic class.
|
||||
Supertype? asInstantiationOf(Supertype type, Class superclass);
|
||||
|
||||
/// Returns the instance member that would respond to a dynamic dispatch of
|
||||
/// [name] to an instance of [class_], or `null` if no such member exists.
|
||||
///
|
||||
/// If [setter] is `false`, the name is dispatched as a getter or call,
|
||||
/// and will return a field, getter, method, or operator (or null).
|
||||
///
|
||||
/// If [setter] is `true`, the name is dispatched as a setter, roughly
|
||||
/// corresponding to `name=` in the Dart specification, but note that the
|
||||
/// returned member will not have a name ending with `=`. In this case,
|
||||
/// a non-final field or setter (or null) will be returned.
|
||||
///
|
||||
/// If the class is abstract, abstract members are ignored and the dispatch
|
||||
/// is resolved if the class was not abstract.
|
||||
Member? getDispatchTarget(Class class_, Name name, {bool setter = false});
|
||||
|
||||
/// Returns the list of potential targets of dynamic dispatch to an instance
|
||||
/// of [class_].
|
||||
///
|
||||
|
@ -159,10 +163,6 @@ abstract class ClassHierarchy
|
|||
/// `extends` relationships.
|
||||
bool isSubclassOf(Class subclass, Class superclass);
|
||||
|
||||
/// True if [subtype] inherits from [superclass] though zero or more
|
||||
/// `extends`, `with`, and `implements` relationships.
|
||||
bool isSubtypeOf(Class subtype, Class superclass);
|
||||
|
||||
/// True if the given class is used as the right-hand operand to a
|
||||
/// mixin application (i.e. [Class.mixedInType]).
|
||||
bool isUsedAsMixin(Class class_);
|
||||
|
|
Loading…
Reference in a new issue