diff --git a/DEPS b/DEPS index c20695c69908a..d079b714f9e2c 100644 --- a/DEPS +++ b/DEPS @@ -51,7 +51,7 @@ vars = { # co19 is a cipd package. Use update.sh in tests/co19[_2] to update these # hashes. - "co19_rev": "36cc25de009198a8516be7f12ac5b61069656d09", + "co19_rev": "19439c0d58a0df422c4acc4ae97a3deeb98d0f67", # This line prevents conflicts when both packages are rolled simultaneously. "co19_2_rev": "cdab7e4e26f3dd534bcb297ff3f9e9aa5c7a04fb", diff --git a/pkg/front_end/lib/src/fasta/kernel/hierarchy/hierarchy_builder.dart b/pkg/front_end/lib/src/fasta/kernel/hierarchy/hierarchy_builder.dart index d1cdc2cece3c9..43ef32fd8c3c2 100644 --- a/pkg/front_end/lib/src/fasta/kernel/hierarchy/hierarchy_builder.dart +++ b/pkg/front_end/lib/src/fasta/kernel/hierarchy/hierarchy_builder.dart @@ -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 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) { diff --git a/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_builder.dart b/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_builder.dart index 6207ebb790b73..bc9b9f65a2869 100644 --- a/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_builder.dart +++ b/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_builder.dart @@ -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 classes) { ClassMembersBuilder membersBuilder = diff --git a/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_node.dart b/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_node.dart index b7a0054d16d7c..7007cb9344628 100644 --- a/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_node.dart +++ b/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_node.dart @@ -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 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 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; } } diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart index aec10b0fc8f54..c4fa265a3de2a 100644 --- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart +++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart @@ -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 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 typeArguments, Uri fileUri, diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart index 6d7a964b0aa1a..87af9ee880f82 100644 --- a/pkg/front_end/lib/src/fasta/source/source_loader.dart +++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart @@ -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: [ - 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: [ + messageEnumInheritsRestrictedMember.withLocation( + classMember.fileUri, + classMember.charOffset, + member.name.text.length) + ]); + } } } } diff --git a/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart index 68fe759403f63..a5164ee3a341d 100644 --- a/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart +++ b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart @@ -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? supertypeArguments = classHierarchy + List? 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 nullAwareGuards = const Link(); 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 diff --git a/pkg/front_end/lib/src/fasta/type_inference/inference_visitor_base.dart b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor_base.dart index 8042d2e657085..58236a5a68099 100644 --- a/pkg/front_end/lib/src/fasta/type_inference/inference_visitor_base.dart +++ b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor_base.dart @@ -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 castedTypeArguments = classHierarchy + List 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? 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. @@ -3390,8 +3387,9 @@ abstract class InferenceVisitorBase implements InferenceVisitor { if (member is Procedure && member.kind == ProcedureKind.Method) { return instantiateTearOff(inferredType, typeContext, expression); } - flowAnalysis.thisOrSuperPropertyGet( - expression, name.text, member, inferredType); + inferredType = flowAnalysis.thisOrSuperPropertyGet( + expression, name.text, member, inferredType) ?? + inferredType; return new ExpressionInferenceResult(inferredType, expression); } @@ -3635,22 +3633,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 diff --git a/pkg/front_end/lib/src/fasta/type_inference/object_access_target.dart b/pkg/front_end/lib/src/fasta/type_inference/object_access_target.dart index 8f3d3ed3b1a8d..35f035f7cf164 100644 --- a/pkg/front_end/lib/src/fasta/type_inference/object_access_target.dart +++ b/pkg/front_end/lib/src/fasta/type_inference/object_access_target.dart @@ -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); } diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart index 802dffd9b3711..7703b0c3fd85d 100644 --- a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart +++ b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart @@ -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 { /// (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) { diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart index 13b0ea5299d0b..802bad84624f8 100644 --- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart +++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart @@ -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, diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart index 35b86f95d1f19..92c7e3a712eb3 100644 --- a/pkg/kernel/lib/ast.dart +++ b/pkg/kernel/lib/ast.dart @@ -1880,7 +1880,7 @@ class ExtensionTypeShowHideClause { final List hiddenOperators = []; Reference? findShownReference(Name name, - CallSiteAccessKind callSiteAccessKind, ClassHierarchy hierarchy) { + CallSiteAccessKind callSiteAccessKind, ClassHierarchyMembers hierarchy) { List shownReferences; List hiddenReferences; switch (callSiteAccessKind) { @@ -1918,7 +1918,7 @@ class ExtensionTypeShowHideClause { Name name, List references, List interfaces, - ClassHierarchy hierarchy, + ClassHierarchyMembers hierarchy, CallSiteAccessKind callSiteAccessKind) { for (Reference reference in references) { if (reference.asMember.name == name) { diff --git a/pkg/kernel/lib/class_hierarchy.dart b/pkg/kernel/lib/class_hierarchy.dart index e460042fd42a8..7b2b12e148d60 100644 --- a/pkg/kernel/lib/class_hierarchy.dart +++ b/pkg/kernel/lib/class_hierarchy.dart @@ -42,6 +42,10 @@ abstract class ClassHierarchyBase { List? 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_); diff --git a/runtime/include/dart_api_dl.h b/runtime/include/dart_api_dl.h index 804b2811cd6d1..39b97b6828250 100644 --- a/runtime/include/dart_api_dl.h +++ b/runtime/include/dart_api_dl.h @@ -97,7 +97,9 @@ typedef void (*Dart_NativeMessageHandler_DL)(Dart_Port_DL dest_port_id, (Dart_Handle port, Dart_Port_DL * port_id)) \ /* Scopes */ \ F(Dart_EnterScope, void, (void)) \ - F(Dart_ExitScope, void, (void)) + F(Dart_ExitScope, void, (void)) \ + /* Objects */ \ + F(Dart_IsNull, bool, (Dart_Handle)) #define DART_API_ALL_DL_SYMBOLS(F) \ DART_NATIVE_API_DL_SYMBOLS(F) \ diff --git a/runtime/include/dart_version.h b/runtime/include/dart_version.h index b3b4924392e04..a9b902e3b3e4a 100644 --- a/runtime/include/dart_version.h +++ b/runtime/include/dart_version.h @@ -11,6 +11,6 @@ // On backwards compatible changes the minor version is increased. // The versioning covers the symbols exposed in dart_api_dl.h #define DART_API_DL_MAJOR_VERSION 2 -#define DART_API_DL_MINOR_VERSION 0 +#define DART_API_DL_MINOR_VERSION 1 #endif /* RUNTIME_INCLUDE_DART_VERSION_H_ */ /* NOLINT */ diff --git a/samples/ffi/async/sample_async_callback.dart b/samples/ffi/async/sample_async_callback.dart index 4901c550296dc..e9d300fc4a1eb 100644 --- a/samples/ffi/async/sample_async_callback.dart +++ b/samples/ffi/async/sample_async_callback.dart @@ -27,7 +27,7 @@ main() async { print("C = C T1 or C T2."); print("Dart: Setup."); Expect.isTrue(NativeApi.majorVersion == 2); - Expect.isTrue(NativeApi.minorVersion >= 0); + Expect.isTrue(NativeApi.minorVersion >= 1); final initializeApi = dl.lookupFunction), int Function(Pointer)>("InitDartApiDL"); Expect.isTrue(initializeApi(NativeApi.initializeApiDLData) == 0); diff --git a/samples/ffi/async/sample_native_port_call.dart b/samples/ffi/async/sample_native_port_call.dart index 302a50fca3f98..fd5fefc72c2ed 100644 --- a/samples/ffi/async/sample_native_port_call.dart +++ b/samples/ffi/async/sample_native_port_call.dart @@ -36,7 +36,7 @@ main() async { print("C = C T1 or C T2."); print("Dart: Setup."); Expect.isTrue(NativeApi.majorVersion == 2); - Expect.isTrue(NativeApi.minorVersion >= 0); + Expect.isTrue(NativeApi.minorVersion >= 1); final initializeApi = dl.lookupFunction), int Function(Pointer)>("InitDartApiDL"); Expect.isTrue(initializeApi(NativeApi.initializeApiDLData) == 0); diff --git a/samples/ffi/sample_ffi_functions_callbacks_closures.dart b/samples/ffi/sample_ffi_functions_callbacks_closures.dart index 1d08340517f31..5fb0b7ac7b0e4 100644 --- a/samples/ffi/sample_ffi_functions_callbacks_closures.dart +++ b/samples/ffi/sample_ffi_functions_callbacks_closures.dart @@ -54,7 +54,7 @@ final closureCallbackPointer = void doDynamicLinking() { Expect.isTrue(NativeApi.majorVersion == 2); - Expect.isTrue(NativeApi.minorVersion >= 0); + Expect.isTrue(NativeApi.minorVersion >= 1); final initializeApi = testLibrary.lookupFunction< IntPtr Function(Pointer), int Function(Pointer)>("InitDartApiDL"); diff --git a/tests/ffi/vmspecific_handle_dynamically_linked_test.dart b/tests/ffi/vmspecific_handle_dynamically_linked_test.dart index 2b6e834ffdbd9..54535077cbb3a 100644 --- a/tests/ffi/vmspecific_handle_dynamically_linked_test.dart +++ b/tests/ffi/vmspecific_handle_dynamically_linked_test.dart @@ -13,11 +13,12 @@ import 'dylib_utils.dart'; void main() { doDynamicLinking(); testHandle(); + testNativeAPIs(); } void doDynamicLinking() { Expect.isTrue(NativeApi.majorVersion == 2); - Expect.isTrue(NativeApi.minorVersion >= 0); + Expect.isTrue(NativeApi.minorVersion >= 1); final initializeApi = testLibrary.lookupFunction< IntPtr Function(Pointer), int Function(Pointer)>("InitDartApiDL"); @@ -32,6 +33,13 @@ void testHandle() { Expect.isTrue(identical(s, result)); } +void testNativeAPIs() { + // No need to expect here, `lookupFunction` throws an argument error if lookup fails. + testLibrary.lookupFunction< + Bool Function(Handle), + bool Function(Object)>("Dart_IsNull_DL"); +} + class SomeClass { // We use this getter in the native api, don't tree shake it. @pragma("vm:entry-point") diff --git a/tests/ffi_2/vmspecific_handle_dynamically_linked_test.dart b/tests/ffi_2/vmspecific_handle_dynamically_linked_test.dart index 318be21f65476..1f3c9499fcee4 100644 --- a/tests/ffi_2/vmspecific_handle_dynamically_linked_test.dart +++ b/tests/ffi_2/vmspecific_handle_dynamically_linked_test.dart @@ -15,11 +15,12 @@ import 'dylib_utils.dart'; void main() { doDynamicLinking(); testHandle(); + testNativeAPIs(); } void doDynamicLinking() { Expect.isTrue(NativeApi.majorVersion == 2); - Expect.isTrue(NativeApi.minorVersion >= 0); + Expect.isTrue(NativeApi.minorVersion >= 1); final initializeApi = testLibrary.lookupFunction< IntPtr Function(Pointer), int Function(Pointer)>("InitDartApiDL"); @@ -34,6 +35,13 @@ void testHandle() { Expect.isTrue(identical(s, result)); } +void testNativeAPIs() { + // No need to expect here, `lookupFunction` throws an argument error if lookup fails. + testLibrary.lookupFunction< + Bool Function(Handle), + bool Function(Object)>("Dart_IsNull_DL"); +} + class SomeClass { // We use this getter in the native api, don't tree shake it. @pragma("vm:entry-point") diff --git a/tools/VERSION b/tools/VERSION index bcc40948dbcc1..6da3ab7dcf741 100644 --- a/tools/VERSION +++ b/tools/VERSION @@ -27,5 +27,5 @@ CHANNEL dev MAJOR 2 MINOR 19 PATCH 0 -PRERELEASE 402 +PRERELEASE 403 PRERELEASE_PATCH 0 diff --git a/utils/analysis_server/BUILD.gn b/utils/analysis_server/BUILD.gn index d8d0cea8e8433..8d2be9f47ae55 100644 --- a/utils/analysis_server/BUILD.gn +++ b/utils/analysis_server/BUILD.gn @@ -7,9 +7,7 @@ import("../application_snapshot.gni") application_snapshot("analysis_server") { main_dart = "../../pkg/analysis_server/bin/server.dart" training_args = [ - "--help", - # TODO(34616): This is broken on Fuchsia. - # "--sdk=" + rebase_path("../../sdk/"), - # "--train-using=" + rebase_path("../../pkg/analyzer_cli") + "--sdk=" + rebase_path("../../sdk/"), + "--train-using=" + rebase_path("../../pkg/compiler/lib"), ] }