diff --git a/pkg/compiler/lib/src/ir/static_type.dart b/pkg/compiler/lib/src/ir/static_type.dart index 716567a703f1..8e6bc4b7e36d 100644 --- a/pkg/compiler/lib/src/ir/static_type.dart +++ b/pkg/compiler/lib/src/ir/static_type.dart @@ -54,6 +54,7 @@ abstract class StaticTypeVisitor extends StaticTypeBase { final ir.ClassHierarchy hierarchy; ThisInterfaceType _thisType; + ir.Library _currentLibrary; StaticTypeVisitor(ir.TypeEnvironment typeEnvironment, this.hierarchy) : super(typeEnvironment); @@ -83,6 +84,16 @@ abstract class StaticTypeVisitor extends StaticTypeBase { _thisType = value; } + ir.Library get currentLibrary { + assert(_currentLibrary != null); + return _currentLibrary; + } + + void set currentLibrary(ir.Library value) { + assert(value == null || _currentLibrary == null); + _currentLibrary = value; + } + bool completes(ir.DartType type) => type != const DoesNotCompleteType(); Set _currentVariables; @@ -173,7 +184,8 @@ abstract class StaticTypeVisitor extends StaticTypeBase { /// If this is not the case the raw type of [superclass] is returned. /// /// This method is derived from `ir.Expression.getStaticTypeAsInstanceOf`. - ir.InterfaceType getTypeAsInstanceOf(ir.DartType type, ir.Class superclass) { + ir.InterfaceType getTypeAsInstanceOf( + ir.DartType type, ir.Class superclass, ir.Library clientLibrary) { // This method assumes the program is correctly typed, so if the superclass // is not generic, we can just return its raw type without computing the // type of this expression. It also ensures that all types are considered @@ -186,14 +198,16 @@ abstract class StaticTypeVisitor extends StaticTypeBase { type = (type as ir.TypeParameterType).parameter.bound; } if (type == typeEnvironment.nullType) { - return superclass.bottomType; + return typeEnvironment.coreTypes + .bottomInterfaceType(superclass, ir.Nullability.legacy); } if (type is ir.InterfaceType) { - ir.InterfaceType upcastType = - typeEnvironment.getTypeAsInstanceOf(type, superclass); + ir.InterfaceType upcastType = typeEnvironment.getTypeAsInstanceOf( + type, superclass, clientLibrary, typeEnvironment.coreTypes); if (upcastType != null) return upcastType; } else if (type is ir.BottomType) { - return superclass.bottomType; + return typeEnvironment.coreTypes + .bottomInterfaceType(superclass, ir.Nullability.legacy); } // TODO(johnniwinther): Should we assert that this doesn't happen? return typeEnvironment.coreTypes.legacyRawType(superclass); @@ -213,7 +227,8 @@ abstract class StaticTypeVisitor extends StaticTypeBase { } if (interfaceTarget != null) { ir.Class superclass = interfaceTarget.enclosingClass; - receiverType = getTypeAsInstanceOf(receiverType, superclass); + receiverType = + getTypeAsInstanceOf(receiverType, superclass, currentLibrary); return ir.Substitution.fromInterfaceType(receiverType) .substituteType(interfaceTarget.getterType); } @@ -283,7 +298,7 @@ abstract class StaticTypeVisitor extends StaticTypeBase { ir.Class superclass = interfaceTarget.enclosingClass; ir.Substitution receiverSubstitution = ir.Substitution.fromInterfaceType( - getTypeAsInstanceOf(receiverType, superclass)); + getTypeAsInstanceOf(receiverType, superclass, currentLibrary)); ir.DartType setterType = receiverSubstitution.substituteType(interfaceTarget.setterType); if (!typeEnvironment.isSubtypeOf( @@ -316,7 +331,8 @@ abstract class StaticTypeVisitor extends StaticTypeBase { ir.DartType visitDirectPropertyGet(ir.DirectPropertyGet node) { ir.DartType receiverType = visitNode(node.receiver); ir.Class superclass = node.target.enclosingClass; - receiverType = getTypeAsInstanceOf(receiverType, superclass); + receiverType = + getTypeAsInstanceOf(receiverType, superclass, currentLibrary); ir.DartType resultType = ir.Substitution.fromInterfaceType(receiverType) .substituteType(node.target.getterType); _expressionTypeCache[node] = resultType; @@ -341,7 +357,8 @@ abstract class StaticTypeVisitor extends StaticTypeBase { receiverType, argumentType); } else { ir.Class superclass = node.target.enclosingClass; - receiverType = getTypeAsInstanceOf(receiverType, superclass); + receiverType = + getTypeAsInstanceOf(receiverType, superclass, currentLibrary); ir.DartType returnType = ir.Substitution.fromInterfaceType(receiverType) .substituteType(node.target.function.returnType); returnType = ir.Substitution.fromPairs( @@ -597,7 +614,7 @@ abstract class StaticTypeVisitor extends StaticTypeBase { if (interfaceTarget != null) { ir.Class superclass = interfaceTarget.enclosingClass; ir.Substitution receiverSubstitution = ir.Substitution.fromInterfaceType( - getTypeAsInstanceOf(receiverType, superclass)); + getTypeAsInstanceOf(receiverType, superclass, currentLibrary)); ir.DartType getterType = receiverSubstitution.substituteType(interfaceTarget.getterType); if (getterType is ir.FunctionType) { @@ -810,8 +827,8 @@ abstract class StaticTypeVisitor extends StaticTypeBase { if (declaringClass.typeParameters.isEmpty) { resultType = node.interfaceTarget.getterType; } else { - ir.DartType receiver = - typeEnvironment.getTypeAsInstanceOf(thisType, declaringClass); + ir.DartType receiver = typeEnvironment.getTypeAsInstanceOf(thisType, + declaringClass, currentLibrary, typeEnvironment.coreTypes); resultType = ir.Substitution.fromInterfaceType(receiver) .substituteType(node.interfaceTarget.getterType); } @@ -843,8 +860,8 @@ abstract class StaticTypeVisitor extends StaticTypeBase { returnType = const ir.DynamicType(); } else { ir.Class superclass = node.interfaceTarget.enclosingClass; - ir.InterfaceType receiverType = - typeEnvironment.getTypeAsInstanceOf(thisType, superclass); + ir.InterfaceType receiverType = typeEnvironment.getTypeAsInstanceOf( + thisType, superclass, currentLibrary, typeEnvironment.coreTypes); returnType = ir.Substitution.fromInterfaceType(receiverType) .substituteType(node.interfaceTarget.function.returnType); returnType = ir.Substitution.fromPairs( @@ -1216,7 +1233,10 @@ abstract class StaticTypeVisitor extends StaticTypeBase { if (node.isAsync) { ir.InterfaceType streamInterfaceType = getInterfaceTypeOf(iterableType); ir.InterfaceType streamType = typeEnvironment.getTypeAsInstanceOf( - streamInterfaceType, typeEnvironment.coreTypes.streamClass); + streamInterfaceType, + typeEnvironment.coreTypes.streamClass, + currentLibrary, + typeEnvironment.coreTypes); if (streamType != null) { iteratorType = new ir.InterfaceType( typeEnvironment.coreTypes.streamIteratorClass, @@ -1230,7 +1250,10 @@ abstract class StaticTypeVisitor extends StaticTypeBase { if (member != null) { iteratorType = ir.Substitution.fromInterfaceType( typeEnvironment.getTypeAsInstanceOf( - iterableInterfaceType, member.enclosingClass)) + iterableInterfaceType, + member.enclosingClass, + currentLibrary, + typeEnvironment.coreTypes)) .substituteType(member.getterType); } } @@ -1382,12 +1405,14 @@ abstract class StaticTypeVisitor extends StaticTypeBase { thisType = new ThisInterfaceType.from(node.enclosingClass?.getThisType( typeEnvironment.coreTypes, node.enclosingLibrary.nonNullable)); _currentVariables = {}; + currentLibrary = node.enclosingLibrary; visitSignature(node.function); visitNode(node.function.body); handleProcedure(node); _invalidatedVariables.removeAll(_currentVariables); _currentVariables = null; thisType = null; + currentLibrary = null; } void handleConstructor(ir.Constructor node) {} @@ -1397,6 +1422,7 @@ abstract class StaticTypeVisitor extends StaticTypeBase { thisType = new ThisInterfaceType.from(node.enclosingClass.getThisType( typeEnvironment.coreTypes, node.enclosingLibrary.nonNullable)); _currentVariables = {}; + currentLibrary = node.enclosingLibrary; visitSignature(node.function); visitNodes(node.initializers); visitNode(node.function.body); @@ -1404,6 +1430,7 @@ abstract class StaticTypeVisitor extends StaticTypeBase { _invalidatedVariables.removeAll(_currentVariables); _currentVariables = null; thisType = null; + currentLibrary = null; } void handleField(ir.Field node) {} @@ -1413,11 +1440,13 @@ abstract class StaticTypeVisitor extends StaticTypeBase { thisType = new ThisInterfaceType.from(node.enclosingClass?.getThisType( typeEnvironment.coreTypes, node.enclosingLibrary.nonNullable)); _currentVariables = {}; + currentLibrary = node.enclosingLibrary; visitNode(node.initializer); handleField(node); _invalidatedVariables.removeAll(_currentVariables); _currentVariables = null; thisType = null; + currentLibrary = null; } void handleVariableDeclaration(ir.VariableDeclaration node) {} diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart index 6357defb905b..a0903b2dd50f 100644 --- a/pkg/dev_compiler/lib/src/kernel/compiler.dart +++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart @@ -2987,8 +2987,9 @@ class ProgramCompiler extends ComputeOnceConstantVisitor DartType _expectedReturnType(FunctionNode f, Class expected) { var type = f.thisFunctionType.returnType; if (type is InterfaceType) { - var match = _hierarchy.getTypeAsInstanceOf(type, expected); - if (match != null) return match.typeArguments[0]; + var matchArguments = + _hierarchy.getTypeArgumentsAsInstanceOf(type, expected); + if (matchArguments != null) return matchArguments[0]; } return const DynamicType(); } diff --git a/pkg/front_end/lib/src/fasta/builder/class_builder.dart b/pkg/front_end/lib/src/fasta/builder/class_builder.dart index da424d928902..3bfa5c78bdc5 100644 --- a/pkg/front_end/lib/src/fasta/builder/class_builder.dart +++ b/pkg/front_end/lib/src/fasta/builder/class_builder.dart @@ -274,7 +274,7 @@ abstract class ClassBuilder implements DeclarationBuilder { Message message, int fileOffset, int length, {List context}); - void checkMixinApplication(ClassHierarchy hierarchy); + void checkMixinApplication(ClassHierarchy hierarchy, CoreTypes coreTypes); // Computes the function type of a given redirection target. Returns [null] if // the type of the target could not be computed. @@ -1094,8 +1094,11 @@ abstract class ClassBuilderImpl extends DeclarationBuilderImpl bool isInterfaceCheck) { Substitution interfaceSubstitution = Substitution.empty; if (interfaceMember.enclosingClass.typeParameters.isNotEmpty) { - interfaceSubstitution = Substitution.fromInterfaceType(types.hierarchy - .getKernelTypeAsInstanceOf(thisType, interfaceMember.enclosingClass)); + Class enclosingClass = interfaceMember.enclosingClass; + interfaceSubstitution = Substitution.fromPairs( + enclosingClass.typeParameters, + types.hierarchy + .getKernelTypeArgumentsAsInstanceOf(thisType, enclosingClass)); } if (declaredFunction?.typeParameters?.length != interfaceFunction?.typeParameters?.length) { @@ -1166,8 +1169,11 @@ abstract class ClassBuilderImpl extends DeclarationBuilderImpl Types types, Member declaredMember) { Substitution declaredSubstitution = Substitution.empty; if (declaredMember.enclosingClass.typeParameters.isNotEmpty) { - declaredSubstitution = Substitution.fromInterfaceType(types.hierarchy - .getKernelTypeAsInstanceOf(thisType, declaredMember.enclosingClass)); + Class enclosingClass = declaredMember.enclosingClass; + declaredSubstitution = Substitution.fromPairs( + enclosingClass.typeParameters, + types.hierarchy + .getKernelTypeArgumentsAsInstanceOf(thisType, enclosingClass)); } return declaredSubstitution; } @@ -1534,7 +1540,7 @@ abstract class ClassBuilderImpl extends DeclarationBuilderImpl } @override - void checkMixinApplication(ClassHierarchy hierarchy) { + void checkMixinApplication(ClassHierarchy hierarchy, CoreTypes coreTypes) { // A mixin declaration can only be applied to a class that implements all // the declaration's superclass constraints. InterfaceType supertype = cls.supertype.asInterfaceType; @@ -1542,7 +1548,8 @@ abstract class ClassBuilderImpl extends DeclarationBuilderImpl for (Supertype constraint in cls.mixedInClass.superclassConstraints()) { InterfaceType interface = substitution.substituteSupertype(constraint).asInterfaceType; - if (hierarchy.getTypeAsInstanceOf(supertype, interface.classNode) != + if (hierarchy.getTypeAsInstanceOf( + supertype, interface.classNode, library.library, coreTypes) != interface) { library.addProblem( templateMixinApplicationIncompatibleSupertype.withArguments( diff --git a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart index a1798c49bad9..764c8ee79177 100644 --- a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart +++ b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart @@ -30,6 +30,8 @@ import 'package:kernel/core_types.dart' show CoreTypes; import 'package:kernel/type_algebra.dart' show Substitution; import 'package:kernel/type_environment.dart'; +import 'package:kernel/src/future_or.dart'; + import '../builder/builder.dart'; import '../builder/class_builder.dart'; import '../builder/field_builder.dart'; @@ -290,18 +292,18 @@ class ClassHierarchyBuilder { } InterfaceType getKernelTypeAsInstanceOf( - InterfaceType type, Class superclass) { + InterfaceType type, Class superclass, Library clientLibrary) { Class kernelClass = type.classNode; if (kernelClass == superclass) return type; if (kernelClass == nullClass) { if (superclass.typeParameters.isEmpty) { - return coreTypes.legacyRawType(superclass); + return coreTypes.rawType(superclass, clientLibrary.nullable); } else { // This is a safe fall-back for dealing with `Null`. It will likely be // faster to check for `Null` before calling this method. return new InterfaceType( superclass, - Nullability.legacy, + clientLibrary.nullable, new List.filled( superclass.typeParameters.length, coreTypes.nullType)); } @@ -309,15 +311,49 @@ class ClassHierarchyBuilder { NamedTypeBuilder supertype = asSupertypeOf(kernelClass, superclass); if (supertype == null) return null; if (supertype.arguments == null && superclass.typeParameters.isEmpty) { - return coreTypes.legacyRawType(superclass); + return coreTypes.rawType(superclass, type.nullability); } return Substitution.fromInterfaceType(type) - .substituteType(supertype.build(null)); + .substituteType(supertype.build(null)) + .withNullability(type.nullability); + } + + List getKernelTypeArgumentsAsInstanceOf( + InterfaceType type, Class superclass) { + Class kernelClass = type.classNode; + if (kernelClass == superclass) return type.typeArguments; + if (kernelClass == nullClass) { + if (superclass.typeParameters.isEmpty) return const []; + return new List.filled( + superclass.typeParameters.length, coreTypes.nullType); + } + NamedTypeBuilder supertype = asSupertypeOf(kernelClass, superclass); + if (supertype == null) return null; + if (supertype.arguments == null && superclass.typeParameters.isEmpty) { + return const []; + } + return (Substitution.fromInterfaceType(type) + .substituteType(supertype.build(null)) as InterfaceType) + .typeArguments; } InterfaceType getKernelLegacyLeastUpperBound( - InterfaceType type1, InterfaceType type2) { + InterfaceType type1, InterfaceType type2, Library clientLibrary) { if (type1 == type2) return type1; + + // LLUB(Null, List*) works differently for opt-in and opt-out + // libraries. In opt-out libraries the legacy behavior is preserved, so + // LLUB(Null, List*) = List*. In opt-out libraries the + // rules imply that LLUB(Null, List*) = List?. + if (!clientLibrary.isNonNullableByDefault) { + if (type1 is InterfaceType && type1.classNode == nullClass) { + return type2; + } + if (type2 is InterfaceType && type2.classNode == nullClass) { + return type1; + } + } + ClassHierarchyNode node1 = getNodeFromKernelClass(type1.classNode); ClassHierarchyNode node2 = getNodeFromKernelClass(type2.classNode); Set nodes1 = node1.computeAllSuperNodes(this).toSet(); @@ -328,30 +364,37 @@ class ClassHierarchyBuilder { ClassHierarchyNode node = nodes2[i]; if (node == null) continue; if (nodes1.contains(node)) { - DartType candidate1 = - getKernelTypeAsInstanceOf(type1, node.classBuilder.cls); - DartType candidate2 = - getKernelTypeAsInstanceOf(type2, node.classBuilder.cls); + DartType candidate1 = getKernelTypeAsInstanceOf( + type1, node.classBuilder.cls, clientLibrary); + DartType candidate2 = getKernelTypeAsInstanceOf( + type2, node.classBuilder.cls, clientLibrary); if (candidate1 == candidate2) { common.add(node); } } } - if (common.length == 1) return coreTypes.objectLegacyRawType; + if (common.length == 1) { + return coreTypes.objectRawType( + uniteNullabilities(type1.nullability, type2.nullability)); + } common.sort(ClassHierarchyNode.compareMaxInheritancePath); for (int i = 0; i < common.length - 1; i++) { ClassHierarchyNode node = common[i]; if (node.maxInheritancePath != common[i + 1].maxInheritancePath) { - return getKernelTypeAsInstanceOf(type1, node.classBuilder.cls); + return getKernelTypeAsInstanceOf( + type1, node.classBuilder.cls, clientLibrary) + .withNullability( + uniteNullabilities(type1.nullability, type2.nullability)); } else { do { i++; } while (node.maxInheritancePath == common[i + 1].maxInheritancePath); } } - return coreTypes.objectLegacyRawType; + return coreTypes.objectRawType( + uniteNullabilities(type1.nullability, type2.nullability)); } Member getInterfaceMemberKernel(Class cls, Name name, bool isSetter) { @@ -1964,10 +2007,10 @@ class BuilderMixinInferrer extends MixinInferrer { : super(coreTypes, gatherer); Supertype asInstantiationOf(Supertype type, Class superclass) { - InterfaceType interfaceType = - gatherer.getTypeAsInstanceOf(type.asInterfaceType, superclass); - if (interfaceType == null) return null; - return new Supertype(interfaceType.classNode, interfaceType.typeArguments); + List arguments = + gatherer.getTypeArgumentsAsInstanceOf(type.asInterfaceType, superclass); + if (arguments == null) return null; + return new Supertype(superclass, arguments); } void reportProblem(Message message, Class kernelClass) { @@ -2003,21 +2046,27 @@ class TypeBuilderConstraintGatherer extends TypeConstraintGatherer InterfaceType get nullType => hierarchy.coreTypes.nullType; @override - InterfaceType get objectLegacyRawType => - hierarchy.coreTypes.objectLegacyRawType; + InterfaceType get objectLegacyRawType { + return hierarchy.coreTypes.objectLegacyRawType; + } @override - InterfaceType get functionLegacyRawType => - hierarchy.coreTypes.functionLegacyRawType; + InterfaceType get functionLegacyRawType { + return hierarchy.coreTypes.functionLegacyRawType; + } @override - void addLowerBound(TypeConstraint constraint, DartType lower) { - constraint.lower = getStandardUpperBound(constraint.lower, lower); + void addLowerBound( + TypeConstraint constraint, DartType lower, Library clientLibrary) { + constraint.lower = + getStandardUpperBound(constraint.lower, lower, clientLibrary); } @override - void addUpperBound(TypeConstraint constraint, DartType upper) { - constraint.upper = getStandardLowerBound(constraint.upper, upper); + void addUpperBound( + TypeConstraint constraint, DartType upper, Library clientLibrary) { + constraint.upper = + getStandardLowerBound(constraint.upper, upper, clientLibrary); } @override @@ -2026,8 +2075,15 @@ class TypeBuilderConstraintGatherer extends TypeConstraintGatherer } @override - InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass) { - return hierarchy.getKernelTypeAsInstanceOf(type, superclass); + InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass, + Library clientLibrary, CoreTypes coreTypes) { + return hierarchy.getKernelTypeAsInstanceOf(type, superclass, clientLibrary); + } + + @override + List getTypeArgumentsAsInstanceOf( + InterfaceType type, Class superclass) { + return hierarchy.getKernelTypeArgumentsAsInstanceOf(type, superclass); } @override @@ -2044,8 +2100,9 @@ class TypeBuilderConstraintGatherer extends TypeConstraintGatherer @override InterfaceType getLegacyLeastUpperBound( - InterfaceType type1, InterfaceType type2) { - return hierarchy.getKernelLegacyLeastUpperBound(type1, type2); + InterfaceType type1, InterfaceType type2, Library clientLibrary) { + return hierarchy.getKernelLegacyLeastUpperBound( + type1, type2, clientLibrary); } } @@ -2086,7 +2143,8 @@ class DelayedOverrideCheck { hierarchy.getKernelTypeAsInstanceOf( hierarchy.coreTypes.thisInterfaceType( classBuilder.cls, classBuilder.library.nonNullable), - b.member.enclosingClass)) + b.member.enclosingClass, + classBuilder.library.library)) .substituteType(type); if (!a.hadTypesInferred || !b.isSetter) { inferReturnType( @@ -2110,7 +2168,8 @@ class DelayedOverrideCheck { hierarchy.getKernelTypeAsInstanceOf( hierarchy.coreTypes.thisInterfaceType( classBuilder.cls, classBuilder.library.nonNullable), - b.member.enclosingClass)) + b.member.enclosingClass, + classBuilder.library.library)) .substituteType(type); if (!a.hadTypesInferred || !b.isGetter) { inferParameterType(classBuilder, a, a.formals.single, type, @@ -2136,7 +2195,8 @@ class DelayedOverrideCheck { hierarchy.getKernelTypeAsInstanceOf( hierarchy.coreTypes.thisInterfaceType( classBuilder.cls, classBuilder.library.nonNullable), - b.member.enclosingClass)) + b.member.enclosingClass, + classBuilder.library.library)) .substituteType(type); if (type != a.fieldType) { if (a.hadTypesInferred) { @@ -2317,7 +2377,7 @@ class InterfaceConflict extends DelayedMember { classBuilder.fileUri); } return Substitution.fromInterfaceType(hierarchy.getKernelTypeAsInstanceOf( - thisType, member.enclosingClass)) + thisType, member.enclosingClass, classBuilder.library.library)) .substituteType(type); } diff --git a/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart b/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart index 4e1e2a5c63b6..55ee9ab67ae6 100644 --- a/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart +++ b/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart @@ -384,7 +384,8 @@ class ForwardingNode { return Substitution.fromInterfaceType(hierarchy.getKernelTypeAsInstanceOf( hierarchy.coreTypes .thisInterfaceType(class_, class_.enclosingLibrary.nonNullable), - candidate.enclosingClass)); + candidate.enclosingClass, + class_.enclosingLibrary)); } List getPositionalParameters(Member member) { diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart index 710fcd66f49f..9c6a0bbe3197 100644 --- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart +++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart @@ -415,8 +415,8 @@ class InferenceVisitor isReachable: isOtherwiseReachable); inferrer.flowAnalysis.conditional_end(node.condition, node.otherwise); DartType inferredType = inferrer.typeSchemaEnvironment - .getStandardUpperBound( - thenResult.inferredType, otherwiseResult.inferredType); + .getStandardUpperBound(thenResult.inferredType, + otherwiseResult.inferredType, inferrer.library.library); node.staticType = inferredType; return new ExpressionInferenceResult(inferredType, node); } @@ -817,10 +817,11 @@ class InferenceVisitor if (inferredExpressionType is InterfaceType) { // TODO(johnniwinther): Should we use the type of // `iterable.iterator.current` instead? - InterfaceType supertype = inferrer.classHierarchy - .getTypeAsInstanceOf(inferredExpressionType, iterableClass); - if (supertype != null) { - inferredType = supertype.typeArguments[0]; + List supertypeArguments = inferrer.classHierarchy + .getTypeArgumentsAsInstanceOf( + inferredExpressionType, iterableClass); + if (supertypeArguments != null) { + inferredType = supertypeArguments[0]; } } } @@ -1147,7 +1148,8 @@ class InferenceVisitor // UP(t0, t1) // - Then the inferred type is T. DartType inferredType = inferrer.typeSchemaEnvironment - .getStandardUpperBound(lhsResult.inferredType, rhsResult.inferredType); + .getStandardUpperBound(lhsResult.inferredType, rhsResult.inferredType, + inferrer.library.library); VariableDeclaration variable = createVariable(lhsResult.expression, lhsResult.inferredType); MethodInvocation equalsNull = createEqualsNull( @@ -1279,9 +1281,10 @@ class InferenceVisitor DartType getSpreadElementType(DartType spreadType, bool isNullAware) { if (spreadType is InterfaceType) { - InterfaceType supertype = inferrer.typeSchemaEnvironment - .getTypeAsInstanceOf(spreadType, inferrer.coreTypes.iterableClass); - if (supertype != null) return supertype.typeArguments[0]; + List supertypeArguments = inferrer.typeSchemaEnvironment + .getTypeArgumentsAsInstanceOf( + spreadType, inferrer.coreTypes.iterableClass); + if (supertypeArguments != null) return supertypeArguments[0]; if (spreadType.classNode == inferrer.coreTypes.nullClass && isNullAware) { return spreadType; } @@ -1378,7 +1381,9 @@ class InferenceVisitor otherwiseResult == null ? thenResult.inferredType : inferrer.typeSchemaEnvironment.getStandardUpperBound( - thenResult.inferredType, otherwiseResult.inferredType), + thenResult.inferredType, + otherwiseResult.inferredType, + inferrer.library.library), element); } else if (element is ForElement) { // TODO(johnniwinther): Use _visitStatements instead. @@ -1662,11 +1667,12 @@ class InferenceVisitor void storeSpreadMapEntryElementTypes(DartType spreadMapEntryType, bool isNullAware, List output, int offset) { if (spreadMapEntryType is InterfaceType) { - InterfaceType supertype = inferrer.typeSchemaEnvironment - .getTypeAsInstanceOf(spreadMapEntryType, inferrer.coreTypes.mapClass); - if (supertype != null) { - output[offset] = supertype.typeArguments[0]; - output[offset + 1] = supertype.typeArguments[1]; + List supertypeArguments = inferrer.typeSchemaEnvironment + .getTypeArgumentsAsInstanceOf( + spreadMapEntryType, inferrer.coreTypes.mapClass); + if (supertypeArguments != null) { + output[offset] = supertypeArguments[0]; + output[offset + 1] = supertypeArguments[1]; } else if (spreadMapEntryType.classNode == inferrer.coreTypes.nullClass && isNullAware) { output[offset] = output[offset + 1] = spreadMapEntryType; @@ -1845,13 +1851,15 @@ class InferenceVisitor typeChecksNeeded); int length = actualTypes.length; actualTypes[length - 2] = inferrer.typeSchemaEnvironment - .getStandardUpperBound(actualKeyType, actualTypes[length - 2]); + .getStandardUpperBound(actualKeyType, actualTypes[length - 2], + inferrer.library.library); actualTypes[length - 1] = inferrer.typeSchemaEnvironment - .getStandardUpperBound(actualValueType, actualTypes[length - 1]); + .getStandardUpperBound(actualValueType, actualTypes[length - 1], + inferrer.library.library); int lengthForSet = actualTypesForSet.length; actualTypesForSet[lengthForSet - 1] = inferrer.typeSchemaEnvironment - .getStandardUpperBound( - actualTypeForSet, actualTypesForSet[lengthForSet - 1]); + .getStandardUpperBound(actualTypeForSet, + actualTypesForSet[lengthForSet - 1], inferrer.library.library); entry.otherwise = otherwise..parent = entry; } return entry; @@ -2132,8 +2140,11 @@ class InferenceVisitor iterableSpreadType = null; DartType spreadTypeContext = const UnknownType(); if (typeContextIsIterable && !typeContextIsMap) { - spreadTypeContext = inferrer.typeSchemaEnvironment - .getTypeAsInstanceOf(typeContext, inferrer.coreTypes.iterableClass); + spreadTypeContext = inferrer.typeSchemaEnvironment.getTypeAsInstanceOf( + typeContext, + inferrer.coreTypes.iterableClass, + inferrer.library.library, + inferrer.coreTypes); } else if (!typeContextIsIterable && typeContextIsMap) { spreadTypeContext = new InterfaceType( inferrer.coreTypes.mapClass, @@ -2517,7 +2528,8 @@ class InferenceVisitor .member; DartType inferredType = inferrer.typeSchemaEnvironment - .getStandardUpperBound(readType, writeResult.inferredType); + .getStandardUpperBound( + readType, writeResult.inferredType, inferrer.library.library); Expression replacement; if (node.forEffect) { @@ -2577,8 +2589,8 @@ class InferenceVisitor .member; DartType inferredType = inferrer.typeSchemaEnvironment - .getStandardUpperBound( - readResult.inferredType, writeResult.inferredType); + .getStandardUpperBound(readResult.inferredType, + writeResult.inferredType, inferrer.library.library); Expression replacement; if (node.forEffect) { @@ -2923,7 +2935,8 @@ class InferenceVisitor inferrer.flowAnalysis.ifNullExpression_end(); DartType inferredType = inferrer.typeSchemaEnvironment - .getStandardUpperBound(readType, valueResult.inferredType); + .getStandardUpperBound( + readType, valueResult.inferredType, inferrer.library.library); VariableDeclaration valueVariable; if (node.forEffect) { @@ -3074,7 +3087,8 @@ class InferenceVisitor inferrer.flowAnalysis.ifNullExpression_end(); DartType inferredType = inferrer.typeSchemaEnvironment - .getStandardUpperBound(readType, valueResult.inferredType); + .getStandardUpperBound( + readType, valueResult.inferredType, inferrer.library.library); VariableDeclaration valueVariable; if (node.forEffect) { @@ -3228,7 +3242,8 @@ class InferenceVisitor inferrer.flowAnalysis.ifNullExpression_end(); DartType inferredType = inferrer.typeSchemaEnvironment - .getStandardUpperBound(readType, valueResult.inferredType); + .getStandardUpperBound( + readType, valueResult.inferredType, inferrer.library.library); VariableDeclaration valueVariable; if (node.forEffect) { @@ -4451,7 +4466,8 @@ class InferenceVisitor inferrer.flowAnalysis.ifNullExpression_end(); DartType inferredType = inferrer.typeSchemaEnvironment - .getStandardUpperBound(readType, valueResult.inferredType); + .getStandardUpperBound( + readType, valueResult.inferredType, inferrer.library.library); Expression replacement; if (node.forEffect) { @@ -4778,7 +4794,10 @@ class InferenceVisitor ExpressionInferenceResult visitSuperPropertySet( SuperPropertySet node, DartType typeContext) { DartType receiverType = inferrer.classHierarchy.getTypeAsInstanceOf( - inferrer.thisType, inferrer.thisType.classNode.supertype.classNode); + inferrer.thisType, + inferrer.thisType.classNode.supertype.classNode, + inferrer.library.library, + inferrer.coreTypes); ObjectAccessTarget writeTarget = inferrer.findInterfaceMember( receiverType, node.name, node.fileOffset, diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart index 49e0a85c9042..a5e8d91c1b5e 100644 --- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart +++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart @@ -25,7 +25,6 @@ import 'package:kernel/ast.dart' Library, Name, NamedExpression, - Nullability, NullLiteral, Procedure, RedirectingInitializer, @@ -568,8 +567,8 @@ class KernelTarget extends TargetImplementation { new TypeParameterType.withDefaultNullabilityForLibrary( typeParameter, enclosingClass.enclosingLibrary)); } - return new InterfaceType( - enclosingClass, Nullability.legacy, typeParameterTypes); + return new InterfaceType(enclosingClass, + enclosingClass.enclosingLibrary.nonNullable, typeParameterTypes); } void setupTopAndBottomTypes() { diff --git a/pkg/front_end/lib/src/fasta/kernel/load_library_builder.dart b/pkg/front_end/lib/src/fasta/kernel/load_library_builder.dart index e209c0b973de..b5d38d7303e3 100644 --- a/pkg/front_end/lib/src/fasta/kernel/load_library_builder.dart +++ b/pkg/front_end/lib/src/fasta/kernel/load_library_builder.dart @@ -13,7 +13,6 @@ import 'package:kernel/ast.dart' LoadLibrary, Member, Name, - Nullability, Procedure, ProcedureKind, ReturnStatement; @@ -55,7 +54,7 @@ class LoadLibraryBuilder extends BuilderImpl { ProcedureKind.Method, new FunctionNode(new ReturnStatement(expression), returnType: new InterfaceType(parent.loader.coreTypes.futureClass, - Nullability.legacy, [const DynamicType()])), + parent.nonNullable, [const DynamicType()])), fileUri: parent.library.fileUri, isStatic: true) ..startFileOffset = charOffset diff --git a/pkg/front_end/lib/src/fasta/kernel/types.dart b/pkg/front_end/lib/src/fasta/kernel/types.dart index 5f75c6d30ebb..8f443ff3dc25 100644 --- a/pkg/front_end/lib/src/fasta/kernel/types.dart +++ b/pkg/front_end/lib/src/fasta/kernel/types.dart @@ -13,6 +13,7 @@ import 'package:kernel/ast.dart' FunctionType, InterfaceType, InvalidType, + Library, NamedType, NeverType, Nullability, @@ -22,6 +23,8 @@ import 'package:kernel/ast.dart' Variance, VoidType; +import 'package:kernel/core_types.dart'; + import 'package:kernel/type_algebra.dart' show Substitution, combineNullabilitiesForSubstitution; @@ -282,8 +285,15 @@ class Types implements SubtypeTester { } @override - InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass) { - return hierarchy.getKernelTypeAsInstanceOf(type, superclass); + InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass, + Library clientLibrary, CoreTypes coreTypes) { + return hierarchy.getKernelTypeAsInstanceOf(type, superclass, clientLibrary); + } + + @override + List getTypeArgumentsAsInstanceOf( + InterfaceType type, Class superclass) { + return hierarchy.getKernelTypeArgumentsAsInstanceOf(type, superclass); } @override @@ -349,14 +359,14 @@ class IsInterfaceSubtypeOf extends TypeRelation { // arguments in getKernelTypeAsInstanceOf. return new IsSubtypeOf.basedSolelyOnNullabilities(s, t); } - InterfaceType asSupertype = - types.hierarchy.getKernelTypeAsInstanceOf(s, t.classNode); - if (asSupertype == null) { + List asSupertypeArguments = + types.hierarchy.getKernelTypeArgumentsAsInstanceOf(s, t.classNode); + if (asSupertypeArguments == null) { return const IsSubtypeOf.never(); } return types - .areTypeArgumentsOfSubtypeKernel(asSupertype.typeArguments, - t.typeArguments, t.classNode.typeParameters) + .areTypeArgumentsOfSubtypeKernel( + asSupertypeArguments, t.typeArguments, t.classNode.typeParameters) .and(new IsSubtypeOf.basedSolelyOnNullabilities(s, t)); } 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 4f723e8d3608..5ae202463bfa 100644 --- a/pkg/front_end/lib/src/fasta/source/source_loader.dart +++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart @@ -142,12 +142,23 @@ class SourceLoader extends Loader { ClassHierarchyBuilder builderHierarchy; - // Used when building directly to kernel. + /// Used when building directly to kernel. ClassHierarchy hierarchy; CoreTypes _coreTypes; - // Used when checking whether a return type of an async function is valid. + + /// Used when checking whether a return type of an async function is valid. + /// + /// The said return type is valid if it's a subtype of [futureOfBottom]. DartType futureOfBottom; + + /// Used when checking whether a return type of a sync* function is valid. + /// + /// The said return type is valid if it's a subtype of [iterableOfBottom]. DartType iterableOfBottom; + + /// Used when checking whether a return type of an async* function is valid. + /// + /// The said return type is valid if it's a subtype of [streamOfBottom]. DartType streamOfBottom; TypeInferenceEngineImpl typeInferenceEngine; @@ -888,12 +899,16 @@ class SourceLoader extends Loader { assert(_coreTypes == null, "CoreTypes has already been computed"); _coreTypes = new CoreTypes(component); + // These types are used on the left-hand side of the is-subtype-of relation + // to check if the return types of functions with async, sync*, and async* + // bodies are correct. It's valid to use the non-nullable types on the + // left-hand side in both opt-in and opt-out code. futureOfBottom = new InterfaceType(coreTypes.futureClass, - Nullability.legacy, [const BottomType()]); + Nullability.nonNullable, [const BottomType()]); iterableOfBottom = new InterfaceType(coreTypes.iterableClass, - Nullability.legacy, [const BottomType()]); + Nullability.nonNullable, [const BottomType()]); streamOfBottom = new InterfaceType(coreTypes.streamClass, - Nullability.legacy, [const BottomType()]); + Nullability.nonNullable, [const BottomType()]); ticker.logMs("Computed core types"); } @@ -981,7 +996,7 @@ class SourceLoader extends Loader { if (builder.library.loader == this && !builder.isPatch) { Class mixedInClass = builder.cls.mixedInClass; if (mixedInClass != null && mixedInClass.isMixinDeclaration) { - builder.checkMixinApplication(hierarchy); + builder.checkMixinApplication(hierarchy, coreTypes); } } } diff --git a/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart b/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart index 67147c8884c1..7a4451f7dc02 100644 --- a/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart +++ b/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart @@ -13,6 +13,7 @@ import 'package:kernel/ast.dart' FunctionType, InterfaceType, InvalidType, + Library, NamedType, TypeParameter, TypeParameterType, @@ -38,14 +39,15 @@ abstract class StandardBounds { bool isSubtypeOf(DartType subtype, DartType supertype, SubtypeCheckMode mode); InterfaceType getLegacyLeastUpperBound( - InterfaceType type1, InterfaceType type2); + InterfaceType type1, InterfaceType type2, Library clientLibrary); /// Computes the standard lower bound of [type1] and [type2]. /// /// Standard lower bound is a lower bound function that imposes an /// ordering on the top types `void`, `dynamic`, and `object`. This function /// additionally handles the unknown type that appears during type inference. - DartType getStandardLowerBound(DartType type1, DartType type2) { + DartType getStandardLowerBound( + DartType type1, DartType type2, Library clientLibrary) { // For all types T, SLB(T,T) = T. Note that we don't test for equality // because we don't want to make the algorithm quadratic. This is ok // because the check is not needed for correctness; it's just a speed @@ -94,7 +96,7 @@ abstract class StandardBounds { // Function types have structural lower bounds. if (type1 is FunctionType && type2 is FunctionType) { - return _functionStandardLowerBound(type1, type2); + return _functionStandardLowerBound(type1, type2, clientLibrary); } // Otherwise, the lower bounds of two types is one of them it if it is a @@ -113,7 +115,7 @@ abstract class StandardBounds { if (type2.classNode == futureOrClass) { // GLB(FutureOr, FutureOr) == FutureOr DartType argument = getStandardLowerBound( - type1.typeArguments[0], type2.typeArguments[0]); + type1.typeArguments[0], type2.typeArguments[0], clientLibrary); return new InterfaceType( futureOrClass, argument.nullability, [argument]); } @@ -125,13 +127,14 @@ abstract class StandardBounds { computeNullabilityOfFutureOr(type1, futureOrClass), type2.nullability), [ - getStandardLowerBound( - type1.typeArguments[0], type2.typeArguments[0]) + getStandardLowerBound(type1.typeArguments[0], + type2.typeArguments[0], clientLibrary) ]); } } // GLB(FutureOr, B) == GLB(A, B) - return getStandardLowerBound(type1.typeArguments[0], type2); + return getStandardLowerBound( + type1.typeArguments[0], type2, clientLibrary); } // The if-statement below handles the following rule: // GLB(A, FutureOr) == GLB(FutureOr, A) @@ -147,11 +150,12 @@ abstract class StandardBounds { computeNullabilityOfFutureOr(type2, futureOrClass)), [ getStandardLowerBound( - type2.typeArguments[0], type1.typeArguments[0]) + type2.typeArguments[0], type1.typeArguments[0], clientLibrary) ]); } // GLB(A, FutureOr) == GLB(B, A) - return getStandardLowerBound(type2.typeArguments[0], type1); + return getStandardLowerBound( + type2.typeArguments[0], type1, clientLibrary); } // No subtype relation, so the lower bound is bottom. @@ -163,7 +167,8 @@ abstract class StandardBounds { /// Standard upper bound is an upper bound function that imposes an ordering /// on the top types 'void', 'dynamic', and `object`. This function /// additionally handles the unknown type that appears during type inference. - DartType getStandardUpperBound(DartType type1, DartType type2) { + DartType getStandardUpperBound( + DartType type1, DartType type2, Library clientLibrary) { // For all types T, SUB(T,T) = T. Note that we don't test for equality // because we don't want to make the algorithm quadratic. This is ok // because the check is not needed for correctness; it's just a speed @@ -211,7 +216,7 @@ abstract class StandardBounds { if (type2 == nullType) return type1; if (type1 is TypeParameterType || type2 is TypeParameterType) { - return _typeParameterStandardUpperBound(type1, type2); + return _typeParameterStandardUpperBound(type1, type2, clientLibrary); } // The standard upper bound of a function type and an interface type T is @@ -226,11 +231,11 @@ abstract class StandardBounds { // At this point type1 and type2 should both either be interface types or // function types. if (type1 is InterfaceType && type2 is InterfaceType) { - return _interfaceStandardUpperBound(type1, type2); + return _interfaceStandardUpperBound(type1, type2, clientLibrary); } if (type1 is FunctionType && type2 is FunctionType) { - return _functionStandardUpperBound(type1, type2); + return _functionStandardUpperBound(type1, type2, clientLibrary); } if (type1 is InvalidType || type2 is InvalidType) { @@ -259,7 +264,8 @@ abstract class StandardBounds { /// the resulting parameter type. /// /// - Use the SLB of their return types. - DartType _functionStandardLowerBound(FunctionType f, FunctionType g) { + DartType _functionStandardLowerBound( + FunctionType f, FunctionType g, Library clientLibrary) { // TODO(rnystrom,paulberry): Right now, this assumes f and g do not have any // type parameters. Revisit that in the presence of generic methods. @@ -272,7 +278,8 @@ abstract class StandardBounds { DartType fType = f.positionalParameters[i]; if (i < g.positionalParameters.length) { DartType gType = g.positionalParameters[i]; - positionalParameters[i] = getStandardUpperBound(fType, gType); + positionalParameters[i] = + getStandardUpperBound(fType, gType, clientLibrary); } else { positionalParameters[i] = fType; } @@ -307,7 +314,7 @@ abstract class StandardBounds { namedParameters.add(new NamedType( fName, getStandardUpperBound(f.namedParameters[i++].type, - g.namedParameters[j++].type))); + g.namedParameters[j++].type, clientLibrary))); } } else { namedParameters.addAll(f.namedParameters.skip(i)); @@ -326,7 +333,8 @@ abstract class StandardBounds { if (hasPositional && hasNamed) return const BottomType(); // Calculate the SLB of the return type. - DartType returnType = getStandardLowerBound(f.returnType, g.returnType); + DartType returnType = + getStandardLowerBound(f.returnType, g.returnType, clientLibrary); return new FunctionType(positionalParameters, returnType, intersectNullabilities(f.nullability, g.nullability), namedParameters: namedParameters, @@ -345,7 +353,8 @@ abstract class StandardBounds { /// /// - Compute the SLB of each corresponding pair of parameter types, and the /// SUB of the return types. Return a function type with those types. - DartType _functionStandardUpperBound(FunctionType f, FunctionType g) { + DartType _functionStandardUpperBound( + FunctionType f, FunctionType g, Library clientLibrary) { // TODO(rnystrom): Right now, this assumes f and g do not have any type // parameters. Revisit that in the presence of generic methods. @@ -369,7 +378,7 @@ abstract class StandardBounds { List positionalParameters = new List(totalPositional); for (int i = 0; i < totalPositional; i++) { positionalParameters[i] = getStandardLowerBound( - f.positionalParameters[i], g.positionalParameters[i]); + f.positionalParameters[i], g.positionalParameters[i], clientLibrary); } // Intersect the named parameters. @@ -391,7 +400,7 @@ abstract class StandardBounds { namedParameters.add(new NamedType( fName, getStandardLowerBound(f.namedParameters[i++].type, - g.namedParameters[j++].type))); + g.namedParameters[j++].type, clientLibrary))); } } else { break; @@ -403,7 +412,8 @@ abstract class StandardBounds { } // Calculate the SUB of the return type. - DartType returnType = getStandardUpperBound(f.returnType, g.returnType); + DartType returnType = + getStandardUpperBound(f.returnType, g.returnType, clientLibrary); return new FunctionType(positionalParameters, returnType, uniteNullabilities(f.nullability, g.nullability), namedParameters: namedParameters, @@ -411,7 +421,7 @@ abstract class StandardBounds { } DartType _interfaceStandardUpperBound( - InterfaceType type1, InterfaceType type2) { + InterfaceType type1, InterfaceType type2, Library clientLibrary) { // This currently does not implement a very complete standard upper bound // algorithm, but handles a couple of the very common cases that are // causing pain in real code. The current algorithm is: @@ -449,29 +459,30 @@ abstract class StandardBounds { List tArgs = new List(tArgs1.length); for (int i = 0; i < tArgs1.length; i++) { if (tParams[i].variance == Variance.contravariant) { - tArgs[i] = getStandardLowerBound(tArgs1[i], tArgs2[i]); + tArgs[i] = getStandardLowerBound(tArgs1[i], tArgs2[i], clientLibrary); } else if (tParams[i].variance == Variance.invariant) { if (!isSubtypeOf(tArgs1[i], tArgs2[i], SubtypeCheckMode.ignoringNullabilities) || !isSubtypeOf(tArgs2[i], tArgs1[i], SubtypeCheckMode.ignoringNullabilities)) { // No bound will be valid, find bound at the interface level. - return getLegacyLeastUpperBound(type1, type2); + return getLegacyLeastUpperBound(type1, type2, clientLibrary); } // TODO (kallentu) : Fix asymmetric bounds behavior for invariant type // parameters. tArgs[i] = tArgs1[i]; } else { - tArgs[i] = getStandardUpperBound(tArgs1[i], tArgs2[i]); + tArgs[i] = getStandardUpperBound(tArgs1[i], tArgs2[i], clientLibrary); } } return new InterfaceType(type1.classNode, uniteNullabilities(type1.nullability, type2.nullability), tArgs); } - return getLegacyLeastUpperBound(type1, type2); + return getLegacyLeastUpperBound(type1, type2, clientLibrary); } - DartType _typeParameterStandardUpperBound(DartType type1, DartType type2) { + DartType _typeParameterStandardUpperBound( + DartType type1, DartType type2, Library clientLibrary) { // This currently just implements a simple standard upper bound to // handle some common cases. It also avoids some termination issues // with the naive spec algorithm. The standard upper bound of two types @@ -517,12 +528,14 @@ abstract class StandardBounds { return getStandardUpperBound( Substitution.fromMap({type1.parameter: objectLegacyRawType}) .substituteType(type1.parameter.bound), - type2); + type2, + clientLibrary); } else if (type2 is TypeParameterType) { return getStandardUpperBound( type1, Substitution.fromMap({type2.parameter: objectLegacyRawType}) - .substituteType(type2.parameter.bound)); + .substituteType(type2.parameter.bound), + clientLibrary); } else { // We should only be called when at least one of the types is a // TypeParameterType diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart index c71249a7d87c..861ef3497080 100644 --- a/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart +++ b/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart @@ -20,6 +20,8 @@ import 'package:kernel/ast.dart' Variance, VoidType; +import 'package:kernel/core_types.dart'; + import 'package:kernel/type_algebra.dart' show substitute, Substitution; import 'package:kernel/type_environment.dart'; @@ -63,18 +65,24 @@ abstract class TypeConstraintGatherer { Class get nullClass; - void addUpperBound(TypeConstraint constraint, DartType upper); + void addUpperBound( + TypeConstraint constraint, DartType upper, Library clientLibrary); - void addLowerBound(TypeConstraint constraint, DartType lower); + void addLowerBound( + TypeConstraint constraint, DartType lower, Library clientLibrary); Member getInterfaceMember(Class class_, Name name, {bool setter: false}); - InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass); + InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass, + Library clientLibrary, CoreTypes coreTypes); + + List getTypeArgumentsAsInstanceOf( + InterfaceType type, Class superclass); InterfaceType futureType(DartType type, Nullability nullability); /// Returns the set of type constraints that was gathered. - Map computeConstraints() { + Map computeConstraints(Library clientLibrary) { Map result = {}; for (TypeParameter parameter in _parametersToConstrain) { @@ -82,9 +90,11 @@ abstract class TypeConstraintGatherer { } for (_ProtoConstraint protoConstraint in _protoConstraints) { if (protoConstraint.isUpper) { - addUpperBound(result[protoConstraint.parameter], protoConstraint.bound); + addUpperBound(result[protoConstraint.parameter], protoConstraint.bound, + clientLibrary); } else { - addLowerBound(result[protoConstraint.parameter], protoConstraint.bound); + addLowerBound(result[protoConstraint.parameter], protoConstraint.bound, + clientLibrary); } } return result; @@ -212,26 +222,26 @@ abstract class TypeConstraintGatherer { // of supertypes of a given type more than once, the order of the checks // above is irrelevant; we just need to find the matched superclass, // substitute, and then iterate through type variables. - InterfaceType matchingSupertypeOfSubtype = - getTypeAsInstanceOf(subtype, supertype.classNode); - if (matchingSupertypeOfSubtype == null) return false; + List matchingSupertypeOfSubtypeArguments = + getTypeArgumentsAsInstanceOf(subtype, supertype.classNode); + if (matchingSupertypeOfSubtypeArguments == null) return false; for (int i = 0; i < supertype.classNode.typeParameters.length; i++) { // Generate constraints and subtype match with respect to variance. int parameterVariance = supertype.classNode.typeParameters[i].variance; if (parameterVariance == Variance.contravariant) { if (!_isSubtypeMatch(supertype.typeArguments[i], - matchingSupertypeOfSubtype.typeArguments[i])) { + matchingSupertypeOfSubtypeArguments[i])) { return false; } } else if (parameterVariance == Variance.invariant) { if (!_isSubtypeMatch(supertype.typeArguments[i], - matchingSupertypeOfSubtype.typeArguments[i]) || - !_isSubtypeMatch(matchingSupertypeOfSubtype.typeArguments[i], + matchingSupertypeOfSubtypeArguments[i]) || + !_isSubtypeMatch(matchingSupertypeOfSubtypeArguments[i], supertype.typeArguments[i])) { return false; } } else { - if (!_isSubtypeMatch(matchingSupertypeOfSubtype.typeArguments[i], + if (!_isSubtypeMatch(matchingSupertypeOfSubtypeArguments[i], supertype.typeArguments[i])) { return false; } @@ -476,13 +486,15 @@ class TypeSchemaConstraintGatherer extends TypeConstraintGatherer { Class get nullClass => environment.coreTypes.nullClass; @override - void addUpperBound(TypeConstraint constraint, DartType upper) { - environment.addUpperBound(constraint, upper); + void addUpperBound( + TypeConstraint constraint, DartType upper, Library clientLibrary) { + environment.addUpperBound(constraint, upper, clientLibrary); } @override - void addLowerBound(TypeConstraint constraint, DartType lower) { - environment.addLowerBound(constraint, lower); + void addLowerBound( + TypeConstraint constraint, DartType lower, Library clientLibrary) { + environment.addLowerBound(constraint, lower, clientLibrary); } @override @@ -492,8 +504,16 @@ class TypeSchemaConstraintGatherer extends TypeConstraintGatherer { } @override - InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass) { - return environment.getTypeAsInstanceOf(type, superclass); + InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass, + Library clientLibrary, CoreTypes coreTypes) { + return environment.getTypeAsInstanceOf( + type, superclass, clientLibrary, coreTypes); + } + + @override + List getTypeArgumentsAsInstanceOf( + InterfaceType type, Class superclass) { + return environment.getTypeArgumentsAsInstanceOf(type, superclass); } @override 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 c3a46182c307..4633040a5cba 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 @@ -281,8 +281,8 @@ class ClosureContext { _inferredUnwrappedReturnOrYieldType = unwrappedType; } else { _inferredUnwrappedReturnOrYieldType = inferrer.typeSchemaEnvironment - .getStandardUpperBound( - _inferredUnwrappedReturnOrYieldType, unwrappedType); + .getStandardUpperBound(_inferredUnwrappedReturnOrYieldType, + unwrappedType, inferrer.library.library); } return; } @@ -332,8 +332,8 @@ class ClosureContext { _inferredUnwrappedReturnOrYieldType = unwrappedType; } else { _inferredUnwrappedReturnOrYieldType = inferrer.typeSchemaEnvironment - .getStandardUpperBound( - _inferredUnwrappedReturnOrYieldType, unwrappedType); + .getStandardUpperBound(_inferredUnwrappedReturnOrYieldType, + unwrappedType, inferrer.library.library); } } } @@ -452,8 +452,7 @@ abstract class TypeInferrer { class TypeInferrerImpl implements TypeInferrer { /// Marker object to indicate that a function takes an unknown number /// of arguments. - static final FunctionType unknownFunction = - new FunctionType(const [], const DynamicType(), Nullability.legacy); + final FunctionType unknownFunction; final TypeInferenceEngine engine; @@ -503,6 +502,8 @@ class TypeInferrerImpl implements TypeInferrer { TypeInferrerImpl(this.engine, this.uriForInstrumentation, bool topLevel, this.thisType, this.library, this.assignedVariables, this.dataForTesting) : assert(library != null), + unknownFunction = new FunctionType( + const [], const DynamicType(), library.nonNullable), classHierarchy = engine.classHierarchy, instrumentation = topLevel ? null : engine.instrumentation, typeSchemaEnvironment = engine.typeSchemaEnvironment, @@ -1055,9 +1056,10 @@ class TypeInferrerImpl implements TypeInferrer { if (memberClass.typeParameters.isNotEmpty) { receiverType = resolveTypeParameter(receiverType); if (receiverType is InterfaceType) { - InterfaceType castedType = - classHierarchy.getTypeAsInstanceOf(receiverType, memberClass); - calleeType = Substitution.fromInterfaceType(castedType) + List castedTypeArguments = classHierarchy + .getTypeArgumentsAsInstanceOf(receiverType, memberClass); + calleeType = Substitution.fromPairs( + memberClass.typeParameters, castedTypeArguments) .substituteType(calleeType); } } @@ -1323,10 +1325,10 @@ class TypeInferrerImpl implements TypeInferrer { DartType getDerivedTypeArgumentOf(DartType type, Class class_) { if (type is InterfaceType) { - InterfaceType typeAsInstanceOfClass = - classHierarchy.getTypeAsInstanceOf(type, class_); - if (typeAsInstanceOfClass != null) { - return typeAsInstanceOfClass.typeArguments[0]; + List typeArgumentsAsInstanceOfClass = + classHierarchy.getTypeArgumentsAsInstanceOf(type, class_); + if (typeArgumentsAsInstanceOfClass != null) { + return typeArgumentsAsInstanceOfClass[0]; } } return null; @@ -1368,9 +1370,10 @@ class TypeInferrerImpl implements TypeInferrer { if (memberClass.typeParameters.isNotEmpty) { receiverType = resolveTypeParameter(receiverType); if (receiverType is InterfaceType) { - InterfaceType castedType = - classHierarchy.getTypeAsInstanceOf(receiverType, memberClass); - setterType = Substitution.fromInterfaceType(castedType) + setterType = Substitution.fromPairs( + memberClass.typeParameters, + classHierarchy.getTypeArgumentsAsInstanceOf( + receiverType, memberClass)) .substituteType(setterType); } } @@ -3184,7 +3187,8 @@ abstract class MixinInferrer { generateConstraints(mixinClass, baseType, mixinSupertype); // Solve them to get a map from type parameters to upper and lower // bounds. - Map result = gatherer.computeConstraints(); + Map result = + gatherer.computeConstraints(classNode.enclosingLibrary); // Generate new type parameters with the solution as bounds. List parameters = mixinClass.typeParameters.map((p) { TypeConstraint constraint = result[p]; diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart b/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart index 16f0ff7a7a4f..6a42d91461a9 100644 --- a/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart +++ b/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart @@ -110,18 +110,23 @@ class TypeSchemaEnvironment extends HierarchyBasedTypeEnvironment Class get objectClass => coreTypes.objectClass; InterfaceType getLegacyLeastUpperBound( - InterfaceType type1, InterfaceType type2) { - return hierarchy.getLegacyLeastUpperBound(type1, type2, this.coreTypes); + InterfaceType type1, InterfaceType type2, Library clientLibrary) { + return hierarchy.getLegacyLeastUpperBound( + type1, type2, clientLibrary, this.coreTypes); } /// Modify the given [constraint]'s lower bound to include [lower]. - void addLowerBound(TypeConstraint constraint, DartType lower) { - constraint.lower = getStandardUpperBound(constraint.lower, lower); + void addLowerBound( + TypeConstraint constraint, DartType lower, Library clientLibrary) { + constraint.lower = + getStandardUpperBound(constraint.lower, lower, clientLibrary); } /// Modify the given [constraint]'s upper bound to include [upper]. - void addUpperBound(TypeConstraint constraint, DartType upper) { - constraint.upper = getStandardLowerBound(constraint.upper, upper); + void addUpperBound( + TypeConstraint constraint, DartType upper, Library clientLibrary) { + constraint.upper = + getStandardLowerBound(constraint.upper, upper, clientLibrary); } @override @@ -170,7 +175,7 @@ class TypeSchemaEnvironment extends HierarchyBasedTypeEnvironment List actualTypes, DartType returnContextType, List inferredTypes, - Library currentLibrary, + Library clientLibrary, {bool isConst: false}) { if (typeParametersToInfer.isEmpty) { return; @@ -181,7 +186,7 @@ class TypeSchemaEnvironment extends HierarchyBasedTypeEnvironment // be subtypes (or supertypes) as necessary, and track the constraints that // are implied by this. TypeConstraintGatherer gatherer = - new TypeConstraintGatherer(this, typeParametersToInfer, currentLibrary); + new TypeConstraintGatherer(this, typeParametersToInfer, clientLibrary); if (!isEmptyContext(returnContextType)) { if (isConst) { @@ -199,8 +204,8 @@ class TypeSchemaEnvironment extends HierarchyBasedTypeEnvironment } } - inferTypeFromConstraints( - gatherer.computeConstraints(), typeParametersToInfer, inferredTypes, + inferTypeFromConstraints(gatherer.computeConstraints(clientLibrary), + typeParametersToInfer, inferredTypes, clientLibrary, downwardsInferPhase: formalTypes == null); for (int i = 0; i < inferredTypes.length; i++) { @@ -238,8 +243,11 @@ class TypeSchemaEnvironment extends HierarchyBasedTypeEnvironment /// inference, and must not conclude `?` for any type formal. In this pass, /// [inferredTypes] should contain the values from the first pass. They will /// be replaced with the final inferred types. - void inferTypeFromConstraints(Map constraints, - List typeParametersToInfer, List inferredTypes, + void inferTypeFromConstraints( + Map constraints, + List typeParametersToInfer, + List inferredTypes, + Library clientLibrary, {bool downwardsInferPhase: false}) { List typesFromDownwardsInference = downwardsInferPhase ? null : inferredTypes.toList(growable: false); @@ -258,11 +266,14 @@ class TypeSchemaEnvironment extends HierarchyBasedTypeEnvironment TypeConstraint constraint = constraints[typeParam]; if (downwardsInferPhase || !typeParam.isLegacyCovariant) { inferredTypes[i] = _inferTypeParameterFromContext( - constraint, extendsConstraint, + constraint, extendsConstraint, clientLibrary, isContravariant: typeParam.variance == Variance.contravariant); } else { inferredTypes[i] = _inferTypeParameterFromAll( - typesFromDownwardsInference[i], constraint, extendsConstraint); + typesFromDownwardsInference[i], + constraint, + extendsConstraint, + clientLibrary); } } @@ -409,8 +420,11 @@ class TypeSchemaEnvironment extends HierarchyBasedTypeEnvironment type, constraint.upper, SubtypeCheckMode.ignoringNullabilities); } - DartType _inferTypeParameterFromAll(DartType typeFromContextInference, - TypeConstraint constraint, DartType extendsConstraint) { + DartType _inferTypeParameterFromAll( + DartType typeFromContextInference, + TypeConstraint constraint, + DartType extendsConstraint, + Library clientLibrary) { // See if we already fixed this type from downwards inference. // If so, then we aren't allowed to change it based on argument types. if (isKnown(typeFromContextInference)) { @@ -419,14 +433,14 @@ class TypeSchemaEnvironment extends HierarchyBasedTypeEnvironment if (extendsConstraint != null) { constraint = constraint.clone(); - addUpperBound(constraint, extendsConstraint); + addUpperBound(constraint, extendsConstraint, clientLibrary); } return solveTypeConstraint(constraint, grounded: true); } - DartType _inferTypeParameterFromContext( - TypeConstraint constraint, DartType extendsConstraint, + DartType _inferTypeParameterFromContext(TypeConstraint constraint, + DartType extendsConstraint, Library clientLibrary, {bool isContravariant: false}) { DartType t = solveTypeConstraint(constraint, isContravariant: isContravariant); @@ -443,7 +457,7 @@ class TypeSchemaEnvironment extends HierarchyBasedTypeEnvironment // If we consider the `T extends num` we conclude ``, which works. if (extendsConstraint != null) { constraint = constraint.clone(); - addUpperBound(constraint, extendsConstraint); + addUpperBound(constraint, extendsConstraint, clientLibrary); return solveTypeConstraint(constraint); } return t; diff --git a/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_test.dart b/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_test.dart index 4e948dea0cb9..a661a3e4ded9 100644 --- a/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_test.dart +++ b/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_test.dart @@ -74,27 +74,27 @@ class TypeConstraintGathererTest { InterfaceType get Q => coreTypes.legacyRawType(classQ); void test_any_subtype_parameter() { - _checkConstraints(Q, T1, ['lib::Q* <: T1']); + _checkConstraints(Q, T1, testLib, ['lib::Q* <: T1']); } void test_any_subtype_top() { - _checkConstraints(P, dynamicType, []); - _checkConstraints(P, objectType, []); - _checkConstraints(P, voidType, []); + _checkConstraints(P, dynamicType, testLib, []); + _checkConstraints(P, objectType, testLib, []); + _checkConstraints(P, voidType, testLib, []); } void test_any_subtype_unknown() { - _checkConstraints(P, unknownType, []); - _checkConstraints(T1, unknownType, []); + _checkConstraints(P, unknownType, testLib, []); + _checkConstraints(T1, unknownType, testLib, []); } void test_different_classes() { - _checkConstraints(_list(T1), _iterable(Q), ['T1 <: lib::Q*']); - _checkConstraints(_iterable(T1), _list(Q), null); + _checkConstraints(_list(T1), _iterable(Q), testLib, ['T1 <: lib::Q*']); + _checkConstraints(_iterable(T1), _list(Q), testLib, null); } void test_equal_types() { - _checkConstraints(P, P, []); + _checkConstraints(P, P, testLib, []); } void test_function_generic() { @@ -107,12 +107,14 @@ class TypeConstraintGathererTest { new FunctionType([], dynamicType, Nullability.legacy, typeParameters: [T.parameter]), new FunctionType([], dynamicType, Nullability.legacy), + testLib, null); // () -> dynamic <: () -> dynamic, never _checkConstraints( new FunctionType([], dynamicType, Nullability.legacy), new FunctionType([], dynamicType, Nullability.legacy, typeParameters: [T.parameter]), + testLib, null); // (T) -> T <: (U) -> U, always _checkConstraints( @@ -120,39 +122,44 @@ class TypeConstraintGathererTest { typeParameters: [T.parameter]), new FunctionType([U], U, Nullability.legacy, typeParameters: [U.parameter]), + testLib, []); } void test_function_parameter_mismatch() { // (P) -> dynamic <: () -> dynamic, never _checkConstraints(new FunctionType([P], dynamicType, Nullability.legacy), - new FunctionType([], dynamicType, Nullability.legacy), null); + new FunctionType([], dynamicType, Nullability.legacy), testLib, null); // () -> dynamic <: (P) -> dynamic, never _checkConstraints(new FunctionType([], dynamicType, Nullability.legacy), - new FunctionType([P], dynamicType, Nullability.legacy), null); + new FunctionType([P], dynamicType, Nullability.legacy), testLib, null); // ([P]) -> dynamic <: () -> dynamic, always _checkConstraints( new FunctionType([P], dynamicType, Nullability.legacy, requiredParameterCount: 0), new FunctionType([], dynamicType, Nullability.legacy), + testLib, []); // () -> dynamic <: ([P]) -> dynamic, never _checkConstraints( new FunctionType([], dynamicType, Nullability.legacy), new FunctionType([P], dynamicType, Nullability.legacy, requiredParameterCount: 0), + testLib, null); // ({x: P}) -> dynamic <: () -> dynamic, always _checkConstraints( new FunctionType([], dynamicType, Nullability.legacy, namedParameters: [new NamedType('x', P)]), new FunctionType([], dynamicType, Nullability.legacy), + testLib, []); // () -> dynamic !<: ({x: P}) -> dynamic, never _checkConstraints( new FunctionType([], dynamicType, Nullability.legacy), new FunctionType([], dynamicType, Nullability.legacy, namedParameters: [new NamedType('x', P)]), + testLib, null); } @@ -161,6 +168,7 @@ class TypeConstraintGathererTest { _checkConstraints( new FunctionType([T1], dynamicType, Nullability.legacy), new FunctionType([Q], dynamicType, Nullability.legacy), + testLib, ['lib::Q* <: T1']); // ({x: T1}) -> dynamic <: ({x: Q}) -> dynamic, under constraint Q <: T1 _checkConstraints( @@ -168,58 +176,62 @@ class TypeConstraintGathererTest { namedParameters: [new NamedType('x', T1)]), new FunctionType([], dynamicType, Nullability.legacy, namedParameters: [new NamedType('x', Q)]), + testLib, ['lib::Q* <: T1']); } void test_function_return_type() { // () -> T1 <: () -> Q, under constraint T1 <: Q - _checkConstraints(new FunctionType([], T1, Nullability.legacy), - new FunctionType([], Q, Nullability.legacy), ['T1 <: lib::Q*']); + _checkConstraints( + new FunctionType([], T1, Nullability.legacy), + new FunctionType([], Q, Nullability.legacy), + testLib, + ['T1 <: lib::Q*']); // () -> P <: () -> void, always _checkConstraints(new FunctionType([], P, Nullability.legacy), - new FunctionType([], voidType, Nullability.legacy), []); + new FunctionType([], voidType, Nullability.legacy), testLib, []); // () -> void <: () -> P, never _checkConstraints(new FunctionType([], voidType, Nullability.legacy), - new FunctionType([], P, Nullability.legacy), null); + new FunctionType([], P, Nullability.legacy), testLib, null); } void test_function_trivial_cases() { var F = new FunctionType([], dynamicType, Nullability.legacy); // () -> dynamic <: dynamic, always - _checkConstraints(F, dynamicType, []); + _checkConstraints(F, dynamicType, testLib, []); // () -> dynamic <: Function, always - _checkConstraints(F, functionType, []); + _checkConstraints(F, functionType, testLib, []); // () -> dynamic <: Object, always - _checkConstraints(F, objectType, []); + _checkConstraints(F, objectType, testLib, []); } void test_nonInferredParameter_subtype_any() { var U = new TypeParameterType( new TypeParameter('U', _list(P)), Nullability.legacy); - _checkConstraints(U, _list(T1), ['lib::P* <: T1']); + _checkConstraints(U, _list(T1), testLib, ['lib::P* <: T1']); } void test_null_subtype_any() { - _checkConstraints(nullType, T1, ['dart.core::Null? <: T1']); - _checkConstraints(nullType, Q, []); + _checkConstraints(nullType, T1, testLib, ['dart.core::Null? <: T1']); + _checkConstraints(nullType, Q, testLib, []); } void test_parameter_subtype_any() { - _checkConstraints(T1, Q, ['T1 <: lib::Q*']); + _checkConstraints(T1, Q, testLib, ['T1 <: lib::Q*']); } void test_same_classes() { - _checkConstraints(_list(T1), _list(Q), ['T1 <: lib::Q*']); + _checkConstraints(_list(T1), _list(Q), testLib, ['T1 <: lib::Q*']); } void test_typeParameters() { _checkConstraints( - _map(T1, T2), _map(P, Q), ['T1 <: lib::P*', 'T2 <: lib::Q*']); + _map(T1, T2), _map(P, Q), testLib, ['T1 <: lib::P*', 'T2 <: lib::Q*']); } void test_unknown_subtype_any() { - _checkConstraints(unknownType, Q, []); - _checkConstraints(unknownType, T1, []); + _checkConstraints(unknownType, Q, testLib, []); + _checkConstraints(unknownType, T1, testLib, []); } Class _addClass(Class c) { @@ -227,14 +239,14 @@ class TypeConstraintGathererTest { return c; } - void _checkConstraints( - DartType a, DartType b, List expectedConstraints) { + void _checkConstraints(DartType a, DartType b, Library clientLibrary, + List expectedConstraints) { var typeSchemaEnvironment = new TypeSchemaEnvironment(coreTypes, new ClassHierarchy(component)); var typeConstraintGatherer = new TypeConstraintGatherer( typeSchemaEnvironment, [T1.parameter, T2.parameter], testLib); var constraints = typeConstraintGatherer.trySubtypeMatch(a, b) - ? typeConstraintGatherer.computeConstraints() + ? typeConstraintGatherer.computeConstraints(clientLibrary) : null; if (expectedConstraints == null) { expect(constraints, isNull); diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart b/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart index fb49702f0cb2..22c5dc0b2535 100644 --- a/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart +++ b/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart @@ -69,9 +69,9 @@ class TypeSchemaEnvironmentTest { var env = _makeEnv(); var typeConstraint = new TypeConstraint(); expect(typeConstraint.lower, same(unknownType)); - env.addLowerBound(typeConstraint, B); + env.addLowerBound(typeConstraint, B, testLib); expect(typeConstraint.lower, same(B)); - env.addLowerBound(typeConstraint, C); + env.addLowerBound(typeConstraint, C, testLib); expect(typeConstraint.lower, same(A)); } @@ -86,19 +86,19 @@ class TypeSchemaEnvironmentTest { var env = _makeEnv(); var typeConstraint = new TypeConstraint(); expect(typeConstraint.upper, same(unknownType)); - env.addUpperBound(typeConstraint, A); + env.addUpperBound(typeConstraint, A, testLib); expect(typeConstraint.upper, same(A)); - env.addUpperBound(typeConstraint, B); + env.addUpperBound(typeConstraint, B, testLib); expect(typeConstraint.upper, same(B)); - env.addUpperBound(typeConstraint, C); + env.addUpperBound(typeConstraint, C, testLib); expect(typeConstraint.upper, same(bottomType)); } void test_glb_bottom() { var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy); var env = _makeEnv(); - expect(env.getStandardLowerBound(bottomType, A), same(bottomType)); - expect(env.getStandardLowerBound(A, bottomType), same(bottomType)); + expect(env.getStandardLowerBound(bottomType, A, testLib), same(bottomType)); + expect(env.getStandardLowerBound(A, bottomType, testLib), same(bottomType)); } void test_glb_function() { @@ -110,31 +110,35 @@ class TypeSchemaEnvironmentTest { // GLB(() -> A, () -> B) = () -> B expect( env.getStandardLowerBound(new FunctionType([], A, Nullability.legacy), - new FunctionType([], B, Nullability.legacy)), + new FunctionType([], B, Nullability.legacy), testLib), new FunctionType([], B, Nullability.legacy)); // GLB(() -> void, (A, B) -> void) = ([A, B]) -> void expect( env.getStandardLowerBound( new FunctionType([], voidType, Nullability.legacy), - new FunctionType([A, B], voidType, Nullability.legacy)), + new FunctionType([A, B], voidType, Nullability.legacy), + testLib), new FunctionType([A, B], voidType, Nullability.legacy, requiredParameterCount: 0)); expect( env.getStandardLowerBound( new FunctionType([A, B], voidType, Nullability.legacy), - new FunctionType([], voidType, Nullability.legacy)), + new FunctionType([], voidType, Nullability.legacy), + testLib), new FunctionType([A, B], voidType, Nullability.legacy, requiredParameterCount: 0)); // GLB((A) -> void, (B) -> void) = (A) -> void expect( env.getStandardLowerBound( new FunctionType([A], voidType, Nullability.legacy), - new FunctionType([B], voidType, Nullability.legacy)), + new FunctionType([B], voidType, Nullability.legacy), + testLib), new FunctionType([A], voidType, Nullability.legacy)); expect( env.getStandardLowerBound( new FunctionType([B], voidType, Nullability.legacy), - new FunctionType([A], voidType, Nullability.legacy)), + new FunctionType([A], voidType, Nullability.legacy), + testLib), new FunctionType([A], voidType, Nullability.legacy)); // GLB(({a: A}) -> void, ({b: B}) -> void) = ({a: A, b: B}) -> void expect( @@ -142,7 +146,8 @@ class TypeSchemaEnvironmentTest { new FunctionType([], voidType, Nullability.legacy, namedParameters: [new NamedType('a', A)]), new FunctionType([], voidType, Nullability.legacy, - namedParameters: [new NamedType('b', B)])), + namedParameters: [new NamedType('b', B)]), + testLib), new FunctionType([], voidType, Nullability.legacy, namedParameters: [new NamedType('a', A), new NamedType('b', B)])); expect( @@ -150,7 +155,8 @@ class TypeSchemaEnvironmentTest { new FunctionType([], voidType, Nullability.legacy, namedParameters: [new NamedType('b', B)]), new FunctionType([], voidType, Nullability.legacy, - namedParameters: [new NamedType('a', A)])), + namedParameters: [new NamedType('a', A)]), + testLib), new FunctionType([], voidType, Nullability.legacy, namedParameters: [new NamedType('a', A), new NamedType('b', B)])); // GLB(({a: A, c: A}) -> void, ({b: B, d: B}) -> void) @@ -166,7 +172,8 @@ class TypeSchemaEnvironmentTest { namedParameters: [ new NamedType('b', B), new NamedType('d', B) - ])), + ]), + testLib), new FunctionType([], voidType, Nullability.legacy, namedParameters: [ new NamedType('a', A), @@ -187,7 +194,8 @@ class TypeSchemaEnvironmentTest { namedParameters: [ new NamedType('a', B), new NamedType('b', A) - ])), + ]), + testLib), new FunctionType([], voidType, Nullability.legacy, namedParameters: [new NamedType('a', A), new NamedType('b', A)])); expect( @@ -201,7 +209,8 @@ class TypeSchemaEnvironmentTest { namedParameters: [ new NamedType('a', A), new NamedType('b', B) - ])), + ]), + testLib), new FunctionType([], voidType, Nullability.legacy, namedParameters: [new NamedType('a', A), new NamedType('b', A)])); // GLB((B, {a: A}) -> void, (B) -> void) = (B, {a: A}) -> void @@ -209,7 +218,8 @@ class TypeSchemaEnvironmentTest { env.getStandardLowerBound( new FunctionType([B], voidType, Nullability.legacy, namedParameters: [new NamedType('a', A)]), - new FunctionType([B], voidType, Nullability.legacy)), + new FunctionType([B], voidType, Nullability.legacy), + testLib), new FunctionType([B], voidType, Nullability.legacy, namedParameters: [new NamedType('a', A)])); // GLB(({a: A}) -> void, (B) -> void) = bottom @@ -217,7 +227,8 @@ class TypeSchemaEnvironmentTest { env.getStandardLowerBound( new FunctionType([], voidType, Nullability.legacy, namedParameters: [new NamedType('a', A)]), - new FunctionType([B], voidType, Nullability.legacy)), + new FunctionType([B], voidType, Nullability.legacy), + testLib), same(bottomType)); // GLB(({a: A}) -> void, ([B]) -> void) = bottom expect( @@ -225,17 +236,18 @@ class TypeSchemaEnvironmentTest { new FunctionType([], voidType, Nullability.legacy, namedParameters: [new NamedType('a', A)]), new FunctionType([B], voidType, Nullability.legacy, - requiredParameterCount: 0)), + requiredParameterCount: 0), + testLib), same(bottomType)); } void test_glb_identical() { var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy); var env = _makeEnv(); - expect(env.getStandardLowerBound(A, A), same(A)); + expect(env.getStandardLowerBound(A, A, testLib), same(A)); expect( env.getStandardLowerBound( - new InterfaceType(A.classNode, Nullability.legacy), A), + new InterfaceType(A.classNode, Nullability.legacy), A, testLib), A); } @@ -245,33 +257,33 @@ class TypeSchemaEnvironmentTest { _addClass(_class('B', supertype: A.classNode.asThisSupertype)), Nullability.legacy); var env = _makeEnv(); - expect(env.getStandardLowerBound(A, B), same(B)); - expect(env.getStandardLowerBound(B, A), same(B)); + expect(env.getStandardLowerBound(A, B, testLib), same(B)); + expect(env.getStandardLowerBound(B, A, testLib), same(B)); } void test_glb_top() { var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy); var env = _makeEnv(); - expect(env.getStandardLowerBound(dynamicType, A), same(A)); - expect(env.getStandardLowerBound(A, dynamicType), same(A)); - expect(env.getStandardLowerBound(objectType, A), same(A)); - expect(env.getStandardLowerBound(A, objectType), same(A)); - expect(env.getStandardLowerBound(voidType, A), same(A)); - expect(env.getStandardLowerBound(A, voidType), same(A)); + expect(env.getStandardLowerBound(dynamicType, A, testLib), same(A)); + expect(env.getStandardLowerBound(A, dynamicType, testLib), same(A)); + expect(env.getStandardLowerBound(objectType, A, testLib), same(A)); + expect(env.getStandardLowerBound(A, objectType, testLib), same(A)); + expect(env.getStandardLowerBound(voidType, A, testLib), same(A)); + expect(env.getStandardLowerBound(A, voidType, testLib), same(A)); } void test_glb_unknown() { var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy); var env = _makeEnv(); - expect(env.getStandardLowerBound(A, unknownType), same(A)); - expect(env.getStandardLowerBound(unknownType, A), same(A)); + expect(env.getStandardLowerBound(A, unknownType, testLib), same(A)); + expect(env.getStandardLowerBound(unknownType, A, testLib), same(A)); } void test_glb_unrelated() { var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy); var B = coreTypes.rawType(_addClass(_class('B')), Nullability.legacy); var env = _makeEnv(); - expect(env.getStandardLowerBound(A, B), same(bottomType)); + expect(env.getStandardLowerBound(A, B, testLib), same(bottomType)); } void test_inferGenericFunctionOrType() { @@ -317,11 +329,11 @@ class TypeSchemaEnvironmentTest { var constraints = {T: new TypeConstraint()}; // Downward inference should infer A var inferredTypes = [unknownType]; - env.inferTypeFromConstraints(constraints, [T], inferredTypes, + env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib, downwardsInferPhase: true); expect(inferredTypes[0], unknownType); // Upward inference should infer A - env.inferTypeFromConstraints(constraints, [T], inferredTypes); + env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib); expect(inferredTypes[0], numType); } { @@ -329,16 +341,16 @@ class TypeSchemaEnvironmentTest { var constraints = {T: _makeConstraint(upper: objectType)}; // Downward inference should infer A var inferredTypes = [unknownType]; - env.inferTypeFromConstraints(constraints, [T], inferredTypes, + env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib, downwardsInferPhase: true); expect(inferredTypes[0], numType); // Upward inference should infer A - env.inferTypeFromConstraints(constraints, [T], inferredTypes); + env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib); expect(inferredTypes[0], numType); // Upward inference should still infer A even if there are more // constraints now, because num was finalized during downward inference. constraints = {T: _makeConstraint(lower: intType, upper: intType)}; - env.inferTypeFromConstraints(constraints, [T], inferredTypes); + env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib); expect(inferredTypes[0], numType); } } @@ -350,11 +362,11 @@ class TypeSchemaEnvironmentTest { var constraints = {T: _makeConstraint(upper: _list(unknownType))}; // Downwards inference should infer List> var inferredTypes = [unknownType]; - env.inferTypeFromConstraints(constraints, [T], inferredTypes, + env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib, downwardsInferPhase: true); expect(inferredTypes[0], _list(unknownType)); // Upwards inference should refine that to List> - env.inferTypeFromConstraints(constraints, [T], inferredTypes); + env.inferTypeFromConstraints(constraints, [T], inferredTypes, testLib); expect(inferredTypes[0], _list(dynamicType)); } @@ -388,12 +400,13 @@ class TypeSchemaEnvironmentTest { ])), Nullability.legacy); var env = _makeEnv(); - expect(env.getStandardUpperBound(D, E), A); + expect(env.getStandardUpperBound(D, E, testLib), A); } void test_lub_commonClass() { var env = _makeEnv(); - expect(env.getStandardUpperBound(_list(intType), _list(doubleType)), + expect( + env.getStandardUpperBound(_list(intType), _list(doubleType), testLib), _list(numType)); } @@ -406,36 +419,41 @@ class TypeSchemaEnvironmentTest { // LUB(() -> A, () -> B) = () -> A expect( env.getStandardUpperBound(new FunctionType([], A, Nullability.legacy), - new FunctionType([], B, Nullability.legacy)), + new FunctionType([], B, Nullability.legacy), testLib), new FunctionType([], A, Nullability.legacy)); // LUB(([A]) -> void, (A) -> void) = Function expect( env.getStandardUpperBound( new FunctionType([A], voidType, Nullability.legacy, requiredParameterCount: 0), - new FunctionType([A], voidType, Nullability.legacy)), + new FunctionType([A], voidType, Nullability.legacy), + testLib), functionType); // LUB(() -> void, (A, B) -> void) = Function expect( env.getStandardUpperBound( new FunctionType([], voidType, Nullability.legacy), - new FunctionType([A, B], voidType, Nullability.legacy)), + new FunctionType([A, B], voidType, Nullability.legacy), + testLib), functionType); expect( env.getStandardUpperBound( new FunctionType([A, B], voidType, Nullability.legacy), - new FunctionType([], voidType, Nullability.legacy)), + new FunctionType([], voidType, Nullability.legacy), + testLib), functionType); // LUB((A) -> void, (B) -> void) = (B) -> void expect( env.getStandardUpperBound( new FunctionType([A], voidType, Nullability.legacy), - new FunctionType([B], voidType, Nullability.legacy)), + new FunctionType([B], voidType, Nullability.legacy), + testLib), new FunctionType([B], voidType, Nullability.legacy)); expect( env.getStandardUpperBound( new FunctionType([B], voidType, Nullability.legacy), - new FunctionType([A], voidType, Nullability.legacy)), + new FunctionType([A], voidType, Nullability.legacy), + testLib), new FunctionType([B], voidType, Nullability.legacy)); // LUB(({a: A}) -> void, ({b: B}) -> void) = () -> void expect( @@ -443,14 +461,16 @@ class TypeSchemaEnvironmentTest { new FunctionType([], voidType, Nullability.legacy, namedParameters: [new NamedType('a', A)]), new FunctionType([], voidType, Nullability.legacy, - namedParameters: [new NamedType('b', B)])), + namedParameters: [new NamedType('b', B)]), + testLib), new FunctionType([], voidType, Nullability.legacy)); expect( env.getStandardUpperBound( new FunctionType([], voidType, Nullability.legacy, namedParameters: [new NamedType('b', B)]), new FunctionType([], voidType, Nullability.legacy, - namedParameters: [new NamedType('a', A)])), + namedParameters: [new NamedType('a', A)]), + testLib), new FunctionType([], voidType, Nullability.legacy)); // LUB(({a: A, c: A}) -> void, ({b: B, d: B}) -> void) = () -> void expect( @@ -464,7 +484,8 @@ class TypeSchemaEnvironmentTest { namedParameters: [ new NamedType('b', B), new NamedType('d', B) - ])), + ]), + testLib), new FunctionType([], voidType, Nullability.legacy)); // LUB(({a: A, b: B}) -> void, ({a: B, b: A}) -> void) // = ({a: B, b: B}) -> void @@ -479,7 +500,8 @@ class TypeSchemaEnvironmentTest { namedParameters: [ new NamedType('a', B), new NamedType('b', A) - ])), + ]), + testLib), new FunctionType([], voidType, Nullability.legacy, namedParameters: [new NamedType('a', B), new NamedType('b', B)])); expect( @@ -493,7 +515,8 @@ class TypeSchemaEnvironmentTest { namedParameters: [ new NamedType('a', A), new NamedType('b', B) - ])), + ]), + testLib), new FunctionType([], voidType, Nullability.legacy, namedParameters: [new NamedType('a', B), new NamedType('b', B)])); // LUB((B, {a: A}) -> void, (B) -> void) = (B) -> void @@ -501,14 +524,16 @@ class TypeSchemaEnvironmentTest { env.getStandardUpperBound( new FunctionType([B], voidType, Nullability.legacy, namedParameters: [new NamedType('a', A)]), - new FunctionType([B], voidType, Nullability.legacy)), + new FunctionType([B], voidType, Nullability.legacy), + testLib), new FunctionType([B], voidType, Nullability.legacy)); // LUB(({a: A}) -> void, (B) -> void) = Function expect( env.getStandardUpperBound( new FunctionType([], voidType, Nullability.legacy, namedParameters: [new NamedType('a', A)]), - new FunctionType([B], voidType, Nullability.legacy)), + new FunctionType([B], voidType, Nullability.legacy), + testLib), functionType); // GLB(({a: A}) -> void, ([B]) -> void) = () -> void expect( @@ -516,17 +541,18 @@ class TypeSchemaEnvironmentTest { new FunctionType([], voidType, Nullability.legacy, namedParameters: [new NamedType('a', A)]), new FunctionType([B], voidType, Nullability.legacy, - requiredParameterCount: 0)), + requiredParameterCount: 0), + testLib), new FunctionType([], voidType, Nullability.legacy)); } void test_lub_identical() { var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy); var env = _makeEnv(); - expect(env.getStandardUpperBound(A, A), same(A)); + expect(env.getStandardUpperBound(A, A, testLib), same(A)); expect( env.getStandardUpperBound( - new InterfaceType(A.classNode, Nullability.legacy), A), + new InterfaceType(A.classNode, Nullability.legacy), A, testLib), A); } @@ -536,34 +562,43 @@ class TypeSchemaEnvironmentTest { _addClass(_class('B', supertype: A.classNode.asThisSupertype)), Nullability.legacy); var env = _makeEnv(); - expect(env.getStandardUpperBound(_map(A, B), _map(B, A)), _map(A, A)); + expect( + env.getStandardUpperBound(_map(A, B), _map(B, A), testLib), _map(A, A)); } void test_lub_subtype() { var env = _makeEnv(); - expect(env.getStandardUpperBound(_list(intType), _iterable(numType)), + expect( + env.getStandardUpperBound(_list(intType), _iterable(numType), testLib), _iterable(numType)); - expect(env.getStandardUpperBound(_iterable(numType), _list(intType)), + expect( + env.getStandardUpperBound(_iterable(numType), _list(intType), testLib), _iterable(numType)); } void test_lub_top() { var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy); var env = _makeEnv(); - expect(env.getStandardUpperBound(dynamicType, A), same(dynamicType)); - expect(env.getStandardUpperBound(A, dynamicType), same(dynamicType)); - expect(env.getStandardUpperBound(objectType, A), same(objectType)); - expect(env.getStandardUpperBound(A, objectType), same(objectType)); - expect(env.getStandardUpperBound(voidType, A), same(voidType)); - expect(env.getStandardUpperBound(A, voidType), same(voidType)); - expect( - env.getStandardUpperBound(dynamicType, objectType), same(dynamicType)); - expect( - env.getStandardUpperBound(objectType, dynamicType), same(dynamicType)); - expect(env.getStandardUpperBound(dynamicType, voidType), same(voidType)); - expect(env.getStandardUpperBound(voidType, dynamicType), same(voidType)); - expect(env.getStandardUpperBound(objectType, voidType), same(voidType)); - expect(env.getStandardUpperBound(voidType, objectType), same(voidType)); + expect( + env.getStandardUpperBound(dynamicType, A, testLib), same(dynamicType)); + expect( + env.getStandardUpperBound(A, dynamicType, testLib), same(dynamicType)); + expect(env.getStandardUpperBound(objectType, A, testLib), same(objectType)); + expect(env.getStandardUpperBound(A, objectType, testLib), same(objectType)); + expect(env.getStandardUpperBound(voidType, A, testLib), same(voidType)); + expect(env.getStandardUpperBound(A, voidType, testLib), same(voidType)); + expect(env.getStandardUpperBound(dynamicType, objectType, testLib), + same(dynamicType)); + expect(env.getStandardUpperBound(objectType, dynamicType, testLib), + same(dynamicType)); + expect(env.getStandardUpperBound(dynamicType, voidType, testLib), + same(voidType)); + expect(env.getStandardUpperBound(voidType, dynamicType, testLib), + same(voidType)); + expect(env.getStandardUpperBound(objectType, voidType, testLib), + same(voidType)); + expect(env.getStandardUpperBound(voidType, objectType, testLib), + same(voidType)); } void test_lub_typeParameter() { @@ -573,21 +608,23 @@ class TypeSchemaEnvironmentTest { U.parameter.bound = _list(bottomType); var env = _makeEnv(); // LUB(T, T) = T - expect(env.getStandardUpperBound(T, T), same(T)); + expect(env.getStandardUpperBound(T, T, testLib), same(T)); // LUB(T, List) = LUB(List, List) = List - expect(env.getStandardUpperBound(T, _list(bottomType)), _list(objectType)); - expect(env.getStandardUpperBound(_list(bottomType), T), _list(objectType)); + expect(env.getStandardUpperBound(T, _list(bottomType), testLib), + _list(objectType)); + expect(env.getStandardUpperBound(_list(bottomType), T, testLib), + _list(objectType)); // LUB(T, U) = LUB(List, U) = LUB(List, List) // = List - expect(env.getStandardUpperBound(T, U), _list(objectType)); - expect(env.getStandardUpperBound(U, T), _list(objectType)); + expect(env.getStandardUpperBound(T, U, testLib), _list(objectType)); + expect(env.getStandardUpperBound(U, T, testLib), _list(objectType)); } void test_lub_unknown() { var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy); var env = _makeEnv(); - expect(env.getStandardLowerBound(A, unknownType), same(A)); - expect(env.getStandardLowerBound(unknownType, A), same(A)); + expect(env.getStandardLowerBound(A, unknownType, testLib), same(A)); + expect(env.getStandardLowerBound(unknownType, A, testLib), same(A)); } void test_solveTypeConstraint() { diff --git a/pkg/front_end/test/fasta/types/fasta_legacy_upper_bound_test.dart b/pkg/front_end/test/fasta/types/fasta_legacy_upper_bound_test.dart index 1a5e9af6a35e..ebfcd28c7e7f 100644 --- a/pkg/front_end/test/fasta/types/fasta_legacy_upper_bound_test.dart +++ b/pkg/front_end/test/fasta/types/fasta_legacy_upper_bound_test.dart @@ -2,7 +2,7 @@ // 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. -import "package:kernel/ast.dart" show DartType; +import "package:kernel/ast.dart" show DartType, Library; import "package:kernel/core_types.dart" show CoreTypes; @@ -55,8 +55,8 @@ class FastaLegacyUpperBoundTest extends LegacyUpperBoundTest { @override DartType getLegacyLeastUpperBound( - DartType a, DartType b, CoreTypes coreTypes) { - return hierarchy.getKernelLegacyLeastUpperBound(a, b); + DartType a, DartType b, Library clientLibrary, CoreTypes coreTypes) { + return hierarchy.getKernelLegacyLeastUpperBound(a, b, clientLibrary); } } diff --git a/pkg/front_end/test/fasta/types/kernel_legacy_upper_bound_test.dart b/pkg/front_end/test/fasta/types/kernel_legacy_upper_bound_test.dart index da6a0ad09d5b..256e582e9c2f 100644 --- a/pkg/front_end/test/fasta/types/kernel_legacy_upper_bound_test.dart +++ b/pkg/front_end/test/fasta/types/kernel_legacy_upper_bound_test.dart @@ -4,7 +4,7 @@ import "legacy_upper_bound_helper.dart" show LegacyUpperBoundTest; -import "package:kernel/ast.dart" show DartType; +import "package:kernel/ast.dart" show DartType, Library; import "package:kernel/class_hierarchy.dart" show ClassHierarchy; @@ -22,8 +22,8 @@ class KernelLegacyUpperBoundTest extends LegacyUpperBoundTest { @override DartType getLegacyLeastUpperBound( - DartType a, DartType b, CoreTypes coreTypes) { - return hierarchy.getLegacyLeastUpperBound(a, b, coreTypes); + DartType a, DartType b, Library clientLibrary, CoreTypes coreTypes) { + return hierarchy.getLegacyLeastUpperBound(a, b, clientLibrary, coreTypes); } } diff --git a/pkg/front_end/test/fasta/types/legacy_upper_bound_helper.dart b/pkg/front_end/test/fasta/types/legacy_upper_bound_helper.dart index d95d0340ffdf..06847dc3daba 100644 --- a/pkg/front_end/test/fasta/types/legacy_upper_bound_helper.dart +++ b/pkg/front_end/test/fasta/types/legacy_upper_bound_helper.dart @@ -7,7 +7,7 @@ import "package:async_helper/async_helper.dart" show asyncTest; import "package:expect/expect.dart" show Expect; import "package:kernel/ast.dart" - show Class, Component, DartType, InterfaceType, Nullability; + show Class, Component, DartType, InterfaceType, Library, Nullability; import "package:kernel/core_types.dart"; @@ -49,11 +49,11 @@ abstract class LegacyUpperBoundTest { } DartType getLegacyLeastUpperBound( - DartType a, DartType b, CoreTypes coreTypes); + DartType a, DartType b, Library clientLibrary, CoreTypes coreTypes); void checkGetLegacyLeastUpperBound( - DartType a, DartType b, DartType expected) { - DartType actual = getLegacyLeastUpperBound(a, b, coreTypes); + DartType a, DartType b, Library clientLibrary, DartType expected) { + DartType actual = getLegacyLeastUpperBound(a, b, clientLibrary, coreTypes); Expect.equals(expected, actual); } @@ -76,6 +76,7 @@ class C2 extends N*>*>*>*>; Class N = getClass("N"); Class C1 = getClass("C1"); Class C2 = getClass("C2"); + Library testLib = N.enclosingLibrary; // The least upper bound of C1 and N> is Object since the // supertypes are @@ -87,6 +88,7 @@ class C2 extends N*>*>*>*>; new InterfaceType(N, Nullability.legacy, [ new InterfaceType(C1, Nullability.legacy, [stringType]) ]), + testLib, objectType); // The least upper bound of C2 and N> is Object since the @@ -99,6 +101,7 @@ class C2 extends N*>*>*>*>; new InterfaceType(N, Nullability.legacy, [ new InterfaceType(C2, Nullability.legacy, [stringType]) ]), + testLib, objectType); } @@ -118,26 +121,32 @@ class F implements D; Class d = getClass("D"); Class e = getClass("E"); Class f = getClass("F"); + Library testLib = a.enclosingLibrary; checkGetLegacyLeastUpperBound( new InterfaceType(d, Nullability.legacy, [intType, doubleType]), new InterfaceType(d, Nullability.legacy, [intType, doubleType]), + testLib, new InterfaceType(d, Nullability.legacy, [intType, doubleType])); checkGetLegacyLeastUpperBound( new InterfaceType(d, Nullability.legacy, [intType, doubleType]), new InterfaceType(d, Nullability.legacy, [intType, boolType]), + testLib, new InterfaceType(b, Nullability.legacy, [intType])); checkGetLegacyLeastUpperBound( new InterfaceType(d, Nullability.legacy, [intType, doubleType]), new InterfaceType(d, Nullability.legacy, [boolType, doubleType]), + testLib, new InterfaceType(c, Nullability.legacy, [doubleType])); checkGetLegacyLeastUpperBound( new InterfaceType(d, Nullability.legacy, [intType, doubleType]), new InterfaceType(d, Nullability.legacy, [boolType, intType]), + testLib, coreTypes.legacyRawType(a)); checkGetLegacyLeastUpperBound( coreTypes.legacyRawType(e), coreTypes.legacyRawType(f), + testLib, new InterfaceType(b, Nullability.legacy, [intType])); } @@ -162,22 +171,23 @@ class I implements C, D, E; Class g = getClass("G"); Class h = getClass("H"); Class i = getClass("I"); + Library testLib = a.enclosingLibrary; + checkGetLegacyLeastUpperBound(coreTypes.legacyRawType(a), + coreTypes.legacyRawType(b), testLib, objectType); checkGetLegacyLeastUpperBound( - coreTypes.legacyRawType(a), coreTypes.legacyRawType(b), objectType); - checkGetLegacyLeastUpperBound( - coreTypes.legacyRawType(a), objectType, objectType); + coreTypes.legacyRawType(a), objectType, testLib, objectType); checkGetLegacyLeastUpperBound( - objectType, coreTypes.legacyRawType(b), objectType); + objectType, coreTypes.legacyRawType(b), testLib, objectType); checkGetLegacyLeastUpperBound(coreTypes.legacyRawType(c), - coreTypes.legacyRawType(d), coreTypes.legacyRawType(a)); + coreTypes.legacyRawType(d), testLib, coreTypes.legacyRawType(a)); checkGetLegacyLeastUpperBound(coreTypes.legacyRawType(c), - coreTypes.legacyRawType(a), coreTypes.legacyRawType(a)); + coreTypes.legacyRawType(a), testLib, coreTypes.legacyRawType(a)); checkGetLegacyLeastUpperBound(coreTypes.legacyRawType(a), - coreTypes.legacyRawType(d), coreTypes.legacyRawType(a)); + coreTypes.legacyRawType(d), testLib, coreTypes.legacyRawType(a)); checkGetLegacyLeastUpperBound(coreTypes.legacyRawType(f), - coreTypes.legacyRawType(g), coreTypes.legacyRawType(a)); + coreTypes.legacyRawType(g), testLib, coreTypes.legacyRawType(a)); checkGetLegacyLeastUpperBound(coreTypes.legacyRawType(h), - coreTypes.legacyRawType(i), coreTypes.legacyRawType(a)); + coreTypes.legacyRawType(i), testLib, coreTypes.legacyRawType(a)); } } diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt index e94a456e4802..b596f151dadf 100644 --- a/pkg/front_end/test/spell_checking_list_code.txt +++ b/pkg/front_end/test/spell_checking_list_code.txt @@ -463,7 +463,6 @@ json juxtaposition juxtapositions k -k’s kallentu kernel's kernel2kernel @@ -471,6 +470,7 @@ klass kmillikin kustermann kv +k’s l lacks lang @@ -491,6 +491,7 @@ lifted lifter linearized lives +llub lm locationd lots @@ -648,13 +649,13 @@ queries quick quoted r +r'$creation r'\f r'\r r'\s r'\t r'\u r'\v -r'$creation ra radix raises diff --git a/pkg/front_end/test/static_types/data/list_literals.dart b/pkg/front_end/test/static_types/data/list_literals.dart index 8cb149c78387..08a166748d59 100644 --- a/pkg/front_end/test/static_types/data/list_literals.dart +++ b/pkg/front_end/test/static_types/data/list_literals.dart @@ -15,14 +15,14 @@ main() { [/*cfe|dart2js.int*/ /*cfe:nnbd.int!*/ 0]; /*cfe|dart2js.List*/ - /*cfe:nnbd.List!*/ + /*cfe:nnbd.List!*/ [ /*cfe|dart2js.int*/ /*cfe:nnbd.int!*/ 0, /*cfe|dart2js.double*/ /*cfe:nnbd.double!*/ 0.5 ]; /*cfe|dart2js.List*/ - /*cfe:nnbd.List!*/ + /*cfe:nnbd.List!*/ [ /*cfe|dart2js.int*/ /*cfe:nnbd.int!*/ 0, /*cfe|dart2js.String*/ /*cfe:nnbd.String!*/ '' diff --git a/pkg/front_end/test/static_types/data/map_literals.dart b/pkg/front_end/test/static_types/data/map_literals.dart index c83e20c632be..0bd189204357 100644 --- a/pkg/front_end/test/static_types/data/map_literals.dart +++ b/pkg/front_end/test/static_types/data/map_literals.dart @@ -41,7 +41,7 @@ main() { // ignore: unused_local_variable var a3 = /*cfe|dart2js.Map*/ - /*cfe:nnbd.Map!*/ + /*cfe:nnbd.Map!*/ { /*cfe|dart2js.int*/ /*cfe:nnbd.int!*/ @@ -60,7 +60,7 @@ main() { // ignore: unused_local_variable var a4 = /*cfe|dart2js.Map*/ - /*cfe:nnbd.Map!*/ + /*cfe:nnbd.Map!*/ { /*cfe|dart2js.int*/ /*cfe:nnbd.int!*/ @@ -79,7 +79,7 @@ main() { // ignore: unused_local_variable var a5 = /*cfe|dart2js.Map*/ - /*cfe:nnbd.Map!*/ + /*cfe:nnbd.Map!*/ { /*cfe|dart2js.int*/ /*cfe:nnbd.int!*/ @@ -98,7 +98,7 @@ main() { // ignore: unused_local_variable var a6 = /*cfe|dart2js.Map*/ - /*cfe:nnbd.Map!*/ + /*cfe:nnbd.Map!*/ { /*cfe|dart2js.int*/ /*cfe:nnbd.int!*/ @@ -117,7 +117,7 @@ main() { // ignore: unused_local_variable var a7 = /*cfe|dart2js.Map*/ - /*cfe:nnbd.Map!*/ + /*cfe:nnbd.Map!*/ { /*cfe|dart2js.int*/ /*cfe:nnbd.int!*/ @@ -136,7 +136,7 @@ main() { // ignore: unused_local_variable var a8 = /*cfe|dart2js.Map*/ - /*cfe:nnbd.Map!*/ + /*cfe:nnbd.Map!*/ { /*cfe|dart2js.int*/ /*cfe:nnbd.int!*/ diff --git a/pkg/front_end/test/static_types/data/set_literals.dart b/pkg/front_end/test/static_types/data/set_literals.dart index 0a253e2bbf21..4cb20228c066 100644 --- a/pkg/front_end/test/static_types/data/set_literals.dart +++ b/pkg/front_end/test/static_types/data/set_literals.dart @@ -25,7 +25,7 @@ main() { // ignore: unused_local_variable var a2 = /*cfe|dart2js.Set*/ - /*cfe:nnbd.Set!*/ + /*cfe:nnbd.Set!*/ { /*cfe|dart2js.int*/ /*cfe:nnbd.int!*/ @@ -38,7 +38,7 @@ main() { // ignore: unused_local_variable var a3 = /*cfe|dart2js.Set*/ - /*cfe:nnbd.Set!*/ + /*cfe:nnbd.Set!*/ { /*cfe|dart2js.int*/ /*cfe:nnbd.int!*/ diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/experiments_enabled_1.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/experiments_enabled_1.yaml.world.1.expect index ce0d68aec831..26a90cf8c8df 100644 --- a/pkg/front_end/testcases/incremental_initialize_from_dill/experiments_enabled_1.yaml.world.1.expect +++ b/pkg/front_end/testcases/incremental_initialize_from_dill/experiments_enabled_1.yaml.world.1.expect @@ -2,7 +2,7 @@ main = ; library from "org-dartlang-test:///main.dart" as main { class Class extends dart.core::Object { - synthetic constructor •() → main::Class* + synthetic constructor •() → main::Class : super dart.core::Object::•() ; } diff --git a/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.outline.expect b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.outline.expect index dff738636bca..e28ea8cd561a 100644 --- a/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.outline.expect +++ b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.outline.expect @@ -6,7 +6,7 @@ class Class extends core::Object { static field core::int? _#lateStaticField1; static field core::int? _#lateStaticField2; field core::int? _#lateInstanceField; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class ; static get lateStaticField1() → core::int; static set lateStaticField1(core::int #t1) → void; diff --git a/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.strong.expect index f873e75054b0..41775a201f99 100644 --- a/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.strong.expect +++ b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.strong.expect @@ -6,7 +6,7 @@ class Class extends core::Object { static field core::int? _#lateStaticField1 = null; static field core::int? _#lateStaticField2 = null; field core::int? _#lateInstanceField = null; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class : super core::Object::•() ; static get lateStaticField1() → core::int diff --git a/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.strong.transformed.expect index f873e75054b0..41775a201f99 100644 --- a/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/late_lowering/late_field_with_initializer.dart.strong.transformed.expect @@ -6,7 +6,7 @@ class Class extends core::Object { static field core::int? _#lateStaticField1 = null; static field core::int? _#lateStaticField2 = null; field core::int? _#lateInstanceField = null; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class : super core::Object::•() ; static get lateStaticField1() → core::int diff --git a/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.outline.expect b/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.outline.expect index 553fa899256d..e7e3cc124330 100644 --- a/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.outline.expect +++ b/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.outline.expect @@ -6,7 +6,7 @@ class Class extends core::Object { static field core::int? _#lateStaticField1; static field core::int? _#lateStaticField2; field core::int? _#lateInstanceField; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class ; static get lateStaticField1() → core::int; static set lateStaticField1(core::int #t1) → void; diff --git a/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.strong.expect index 996aa3ac6583..299a7218f550 100644 --- a/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.strong.expect +++ b/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.strong.expect @@ -7,7 +7,7 @@ class Class extends core::Object { static field core::int? _#lateStaticField1 = null; static field core::int? _#lateStaticField2 = null; field core::int? _#lateInstanceField = null; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class : super core::Object::•() ; static get lateStaticField1() → core::int diff --git a/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.strong.transformed.expect index 996aa3ac6583..299a7218f550 100644 --- a/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/late_lowering/late_field_without_initializer.dart.strong.transformed.expect @@ -7,7 +7,7 @@ class Class extends core::Object { static field core::int? _#lateStaticField1 = null; static field core::int? _#lateStaticField2 = null; field core::int? _#lateInstanceField = null; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class : super core::Object::•() ; static get lateStaticField1() → core::int diff --git a/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.outline.expect b/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.outline.expect index 42bc15e63c42..5b6009ab6f62 100644 --- a/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.outline.expect +++ b/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.outline.expect @@ -9,7 +9,7 @@ class Class extends core::Object { static field core::int? _#lateStaticField2; field core::int? lateInstanceFieldInit; field core::int? _#lateInstanceField; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class ; static method initLateStaticField1(core::int value) → core::int ; diff --git a/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.strong.expect index 69ddb3cb9a17..dcc2bf20a25d 100644 --- a/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.strong.expect +++ b/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.strong.expect @@ -9,7 +9,7 @@ class Class extends core::Object { static field core::int? _#lateStaticField2 = null; field core::int? lateInstanceFieldInit = null; field core::int? _#lateInstanceField = null; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class : super core::Object::•() ; static method initLateStaticField1(core::int value) → core::int { diff --git a/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.strong.transformed.expect index 69ddb3cb9a17..dcc2bf20a25d 100644 --- a/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/late_lowering/late_final_field_with_initializer.dart.strong.transformed.expect @@ -9,7 +9,7 @@ class Class extends core::Object { static field core::int? _#lateStaticField2 = null; field core::int? lateInstanceFieldInit = null; field core::int? _#lateInstanceField = null; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class : super core::Object::•() ; static method initLateStaticField1(core::int value) → core::int { diff --git a/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.outline.expect b/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.outline.expect index 553fa899256d..e7e3cc124330 100644 --- a/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.outline.expect +++ b/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.outline.expect @@ -6,7 +6,7 @@ class Class extends core::Object { static field core::int? _#lateStaticField1; static field core::int? _#lateStaticField2; field core::int? _#lateInstanceField; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class ; static get lateStaticField1() → core::int; static set lateStaticField1(core::int #t1) → void; diff --git a/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.strong.expect index afecc9ec3193..9034ca30a772 100644 --- a/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.strong.expect +++ b/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.strong.expect @@ -7,7 +7,7 @@ class Class extends core::Object { static field core::int? _#lateStaticField1 = null; static field core::int? _#lateStaticField2 = null; field core::int? _#lateInstanceField = null; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class : super core::Object::•() ; static get lateStaticField1() → core::int diff --git a/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.strong.transformed.expect index afecc9ec3193..9034ca30a772 100644 --- a/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/late_lowering/late_final_field_without_initializer.dart.strong.transformed.expect @@ -7,7 +7,7 @@ class Class extends core::Object { static field core::int? _#lateStaticField1 = null; static field core::int? _#lateStaticField2 = null; field core::int? _#lateInstanceField = null; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class : super core::Object::•() ; static get lateStaticField1() → core::int diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.outline.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.outline.expect index 2a29aef91ddf..64c696d35771 100644 --- a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.outline.expect +++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.outline.expect @@ -12,7 +12,7 @@ class Class extends core::Object { field core::int? lateInstanceFieldInit; field core::int? _#lateInstanceField; field core::bool _#lateInstanceField#isSet; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class ; static method initLateStaticField1(core::int value) → core::int? ; diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.strong.expect index eed63edb264d..69fa89d2afcc 100644 --- a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.strong.expect +++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.strong.expect @@ -12,7 +12,7 @@ class Class extends core::Object { field core::int? lateInstanceFieldInit = null; field core::int? _#lateInstanceField = null; field core::bool _#lateInstanceField#isSet = false; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class : super core::Object::•() ; static method initLateStaticField1(core::int value) → core::int? { diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.strong.transformed.expect index eed63edb264d..69fa89d2afcc 100644 --- a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_with_initializer.dart.strong.transformed.expect @@ -12,7 +12,7 @@ class Class extends core::Object { field core::int? lateInstanceFieldInit = null; field core::int? _#lateInstanceField = null; field core::bool _#lateInstanceField#isSet = false; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class : super core::Object::•() ; static method initLateStaticField1(core::int value) → core::int? { diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.outline.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.outline.expect index c3faac63d23d..cb84a8b51e67 100644 --- a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.outline.expect +++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.outline.expect @@ -9,7 +9,7 @@ class Class extends core::Object { static field core::bool _#lateStaticField2#isSet; field core::int? _#lateInstanceField; field core::bool _#lateInstanceField#isSet; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class ; static get lateStaticField1() → core::int?; static set lateStaticField1(core::int? #t1) → void; diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.strong.expect index 7d4b81639d43..7af514e9c6ef 100644 --- a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.strong.expect +++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.strong.expect @@ -10,7 +10,7 @@ class Class extends core::Object { static field core::bool _#lateStaticField2#isSet = false; field core::int? _#lateInstanceField = null; field core::bool _#lateInstanceField#isSet = false; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class : super core::Object::•() ; static get lateStaticField1() → core::int? diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.strong.transformed.expect index 7d4b81639d43..7af514e9c6ef 100644 --- a/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_field_without_initializer.dart.strong.transformed.expect @@ -10,7 +10,7 @@ class Class extends core::Object { static field core::bool _#lateStaticField2#isSet = false; field core::int? _#lateInstanceField = null; field core::bool _#lateInstanceField#isSet = false; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class : super core::Object::•() ; static get lateStaticField1() → core::int? diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.outline.expect b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.outline.expect index d089b3485b1f..b98c8ed6b897 100644 --- a/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.outline.expect +++ b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.outline.expect @@ -9,7 +9,7 @@ class Class extends core::Object { static field core::bool _#lateStaticField2#isSet; field core::int? _#lateInstanceField; field core::bool _#lateInstanceField#isSet; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class ; static method lateStaticField1Init() → core::int? ; diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.strong.expect index 573be76de7a2..8ae398ac65db 100644 --- a/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.strong.expect +++ b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.strong.expect @@ -9,7 +9,7 @@ class Class extends core::Object { static field core::bool _#lateStaticField2#isSet = false; field core::int? _#lateInstanceField = null; field core::bool _#lateInstanceField#isSet = false; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class : super core::Object::•() ; static method lateStaticField1Init() → core::int? diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.strong.transformed.expect index 573be76de7a2..8ae398ac65db 100644 --- a/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/late_lowering/late_nullable_field_with_initializer.dart.strong.transformed.expect @@ -9,7 +9,7 @@ class Class extends core::Object { static field core::bool _#lateStaticField2#isSet = false; field core::int? _#lateInstanceField = null; field core::bool _#lateInstanceField#isSet = false; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class : super core::Object::•() ; static method lateStaticField1Init() → core::int? diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.outline.expect b/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.outline.expect index c3faac63d23d..cb84a8b51e67 100644 --- a/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.outline.expect +++ b/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.outline.expect @@ -9,7 +9,7 @@ class Class extends core::Object { static field core::bool _#lateStaticField2#isSet; field core::int? _#lateInstanceField; field core::bool _#lateInstanceField#isSet; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class ; static get lateStaticField1() → core::int?; static set lateStaticField1(core::int? #t1) → void; diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.strong.expect index eff23df81c3b..d5c374c18fc5 100644 --- a/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.strong.expect +++ b/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.strong.expect @@ -10,7 +10,7 @@ class Class extends core::Object { static field core::bool _#lateStaticField2#isSet = false; field core::int? _#lateInstanceField = null; field core::bool _#lateInstanceField#isSet = false; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class : super core::Object::•() ; static get lateStaticField1() → core::int? diff --git a/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.strong.transformed.expect index eff23df81c3b..d5c374c18fc5 100644 --- a/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/late_lowering/late_nullable_field_without_initializer.dart.strong.transformed.expect @@ -10,7 +10,7 @@ class Class extends core::Object { static field core::bool _#lateStaticField2#isSet = false; field core::int? _#lateInstanceField = null; field core::bool _#lateInstanceField#isSet = false; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class : super core::Object::•() ; static get lateStaticField1() → core::int? diff --git a/pkg/front_end/testcases/nnbd/function_types.dart.outline.expect b/pkg/front_end/testcases/nnbd/function_types.dart.outline.expect index 9ebda3843da6..56f50791f5fe 100644 --- a/pkg/front_end/testcases/nnbd/function_types.dart.outline.expect +++ b/pkg/front_end/testcases/nnbd/function_types.dart.outline.expect @@ -4,11 +4,11 @@ import "dart:core" as core; typedef F = () → void; class A extends core::Object { - synthetic constructor •() → self::A* + synthetic constructor •() → self::A ; } class B extends self::A<() →? dynamic> { - synthetic constructor •() → self::B* + synthetic constructor •() → self::B ; method method(() →? dynamic x) → () →? dynamic ; diff --git a/pkg/front_end/testcases/nnbd/function_types.dart.strong.expect b/pkg/front_end/testcases/nnbd/function_types.dart.strong.expect index 8aab3014930c..75317809439d 100644 --- a/pkg/front_end/testcases/nnbd/function_types.dart.strong.expect +++ b/pkg/front_end/testcases/nnbd/function_types.dart.strong.expect @@ -4,12 +4,12 @@ import "dart:core" as core; typedef F = () → void; class A extends core::Object { - synthetic constructor •() → self::A* + synthetic constructor •() → self::A : super core::Object::•() ; } class B extends self::A<() →? dynamic> { - synthetic constructor •() → self::B* + synthetic constructor •() → self::B : super self::A::•() ; method method(() →? dynamic x) → () →? dynamic diff --git a/pkg/front_end/testcases/nnbd/function_types.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/function_types.dart.strong.transformed.expect index 8aab3014930c..75317809439d 100644 --- a/pkg/front_end/testcases/nnbd/function_types.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/nnbd/function_types.dart.strong.transformed.expect @@ -4,12 +4,12 @@ import "dart:core" as core; typedef F = () → void; class A extends core::Object { - synthetic constructor •() → self::A* + synthetic constructor •() → self::A : super core::Object::•() ; } class B extends self::A<() →? dynamic> { - synthetic constructor •() → self::B* + synthetic constructor •() → self::B : super self::A::•() ; method method(() →? dynamic x) → () →? dynamic diff --git a/pkg/front_end/testcases/nnbd/inheritance_from_opt_out.dart.outline.expect b/pkg/front_end/testcases/nnbd/inheritance_from_opt_out.dart.outline.expect index 8d725343e148..0fd58432a174 100644 --- a/pkg/front_end/testcases/nnbd/inheritance_from_opt_out.dart.outline.expect +++ b/pkg/front_end/testcases/nnbd/inheritance_from_opt_out.dart.outline.expect @@ -19,35 +19,35 @@ import "dart:core" as core; import "org-dartlang-testcase:///inheritance_from_opt_out_lib.dart"; class Class1 extends inh::LegacyClass1 { - synthetic constructor •() → self::Class1* + synthetic constructor •() → self::Class1 ; } class Class2 extends inh::LegacyClass2 { - synthetic constructor •() → self::Class2* + synthetic constructor •() → self::Class2 ; } class Class3a extends inh::LegacyClass3 { - synthetic constructor •() → self::Class3a* + synthetic constructor •() → self::Class3a ; } class Class3b extends inh::LegacyClass3 implements inh::GenericInterface { - synthetic constructor •() → self::Class3b* + synthetic constructor •() → self::Class3b ; } class Class4a extends inh::LegacyClass4 { - synthetic constructor •() → self::Class4a* + synthetic constructor •() → self::Class4a ; } class Class4b extends core::Object implements inh::GenericInterface { - synthetic constructor •() → self::Class4b* + synthetic constructor •() → self::Class4b ; } class Class4c extends core::Object implements inh::GenericInterface { - synthetic constructor •() → self::Class4c* + synthetic constructor •() → self::Class4c ; } class Class4d extends inh::LegacyClass4 implements inh::GenericInterface { - synthetic constructor •() → self::Class4d* + synthetic constructor •() → self::Class4d ; } static method main() → dynamic diff --git a/pkg/front_end/testcases/nnbd/inheritance_from_opt_out.dart.strong.expect b/pkg/front_end/testcases/nnbd/inheritance_from_opt_out.dart.strong.expect index 3b75a329605a..5c9ceb3aade1 100644 --- a/pkg/front_end/testcases/nnbd/inheritance_from_opt_out.dart.strong.expect +++ b/pkg/front_end/testcases/nnbd/inheritance_from_opt_out.dart.strong.expect @@ -19,42 +19,42 @@ import "dart:core" as core; import "org-dartlang-testcase:///inheritance_from_opt_out_lib.dart"; class Class1 extends inh::LegacyClass1 { - synthetic constructor •() → self::Class1* + synthetic constructor •() → self::Class1 : super inh::LegacyClass1::•() ; } class Class2 extends inh::LegacyClass2 { - synthetic constructor •() → self::Class2* + synthetic constructor •() → self::Class2 : super inh::LegacyClass2::•() ; } class Class3a extends inh::LegacyClass3 { - synthetic constructor •() → self::Class3a* + synthetic constructor •() → self::Class3a : super inh::LegacyClass3::•() ; } class Class3b extends inh::LegacyClass3 implements inh::GenericInterface { - synthetic constructor •() → self::Class3b* + synthetic constructor •() → self::Class3b : super inh::LegacyClass3::•() ; } class Class4a extends inh::LegacyClass4 { - synthetic constructor •() → self::Class4a* + synthetic constructor •() → self::Class4a : super inh::LegacyClass4::•() ; } class Class4b extends core::Object implements inh::GenericInterface { - synthetic constructor •() → self::Class4b* + synthetic constructor •() → self::Class4b : super core::Object::•() ; } class Class4c extends core::Object implements inh::GenericInterface { - synthetic constructor •() → self::Class4c* + synthetic constructor •() → self::Class4c : super core::Object::•() ; } class Class4d extends inh::LegacyClass4 implements inh::GenericInterface { - synthetic constructor •() → self::Class4d* + synthetic constructor •() → self::Class4d : super inh::LegacyClass4::•() ; } diff --git a/pkg/front_end/testcases/nnbd/intersection_types.dart.outline.expect b/pkg/front_end/testcases/nnbd/intersection_types.dart.outline.expect index a1b7bfba0865..d27719dd2c90 100644 --- a/pkg/front_end/testcases/nnbd/intersection_types.dart.outline.expect +++ b/pkg/front_end/testcases/nnbd/intersection_types.dart.outline.expect @@ -3,19 +3,19 @@ import self as self; import "dart:core" as core; class A extends core::Object { - synthetic constructor •() → self::A* + synthetic constructor •() → self::A ; } class B extends self::A { - synthetic constructor •() → self::B* + synthetic constructor •() → self::B ; } class C extends self::B { - synthetic constructor •() → self::C* + synthetic constructor •() → self::C ; } class Foo extends core::Object { - synthetic constructor •() → self::Foo* + synthetic constructor •() → self::Foo ; method doPromotionsToNullable(generic-covariant-impl self::Foo::T% t) → dynamic ; diff --git a/pkg/front_end/testcases/nnbd/intersection_types.dart.strong.expect b/pkg/front_end/testcases/nnbd/intersection_types.dart.strong.expect index 4f137d34b386..7facb01927e2 100644 --- a/pkg/front_end/testcases/nnbd/intersection_types.dart.strong.expect +++ b/pkg/front_end/testcases/nnbd/intersection_types.dart.strong.expect @@ -3,22 +3,22 @@ import self as self; import "dart:core" as core; class A extends core::Object { - synthetic constructor •() → self::A* + synthetic constructor •() → self::A : super core::Object::•() ; } class B extends self::A { - synthetic constructor •() → self::B* + synthetic constructor •() → self::B : super self::A::•() ; } class C extends self::B { - synthetic constructor •() → self::C* + synthetic constructor •() → self::C : super self::B::•() ; } class Foo extends core::Object { - synthetic constructor •() → self::Foo* + synthetic constructor •() → self::Foo : super core::Object::•() ; method doPromotionsToNullable(generic-covariant-impl self::Foo::T% t) → dynamic { diff --git a/pkg/front_end/testcases/nnbd/intersection_types.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/intersection_types.dart.strong.transformed.expect index 4f137d34b386..7facb01927e2 100644 --- a/pkg/front_end/testcases/nnbd/intersection_types.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/nnbd/intersection_types.dart.strong.transformed.expect @@ -3,22 +3,22 @@ import self as self; import "dart:core" as core; class A extends core::Object { - synthetic constructor •() → self::A* + synthetic constructor •() → self::A : super core::Object::•() ; } class B extends self::A { - synthetic constructor •() → self::B* + synthetic constructor •() → self::B : super self::A::•() ; } class C extends self::B { - synthetic constructor •() → self::C* + synthetic constructor •() → self::C : super self::B::•() ; } class Foo extends core::Object { - synthetic constructor •() → self::Foo* + synthetic constructor •() → self::Foo : super core::Object::•() ; method doPromotionsToNullable(generic-covariant-impl self::Foo::T% t) → dynamic { diff --git a/pkg/front_end/testcases/nnbd/issue_39286.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue_39286.dart.outline.expect index acfeb300a445..28744137d3f2 100644 --- a/pkg/front_end/testcases/nnbd/issue_39286.dart.outline.expect +++ b/pkg/front_end/testcases/nnbd/issue_39286.dart.outline.expect @@ -3,7 +3,7 @@ import self as self; import "dart:core" as core; class C extends core::Object { - synthetic constructor •() → self::C* + synthetic constructor •() → self::C ; method f() → self::D? ; @@ -11,7 +11,7 @@ class C extends core::Object { ; } class D extends core::Object { - synthetic constructor •() → self::D* + synthetic constructor •() → self::D ; method g() → void ; diff --git a/pkg/front_end/testcases/nnbd/issue_39286.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue_39286.dart.strong.expect index 108244e5b4c3..ae125e8d8d28 100644 --- a/pkg/front_end/testcases/nnbd/issue_39286.dart.strong.expect +++ b/pkg/front_end/testcases/nnbd/issue_39286.dart.strong.expect @@ -3,7 +3,7 @@ import self as self; import "dart:core" as core; class C extends core::Object { - synthetic constructor •() → self::C* + synthetic constructor •() → self::C : super core::Object::•() ; method f() → self::D? @@ -11,7 +11,7 @@ class C extends core::Object { method h() → void {} } class D extends core::Object { - synthetic constructor •() → self::D* + synthetic constructor •() → self::D : super core::Object::•() ; method g() → void {} diff --git a/pkg/front_end/testcases/nnbd/issue_39286.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue_39286.dart.strong.transformed.expect index 108244e5b4c3..ae125e8d8d28 100644 --- a/pkg/front_end/testcases/nnbd/issue_39286.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/nnbd/issue_39286.dart.strong.transformed.expect @@ -3,7 +3,7 @@ import self as self; import "dart:core" as core; class C extends core::Object { - synthetic constructor •() → self::C* + synthetic constructor •() → self::C : super core::Object::•() ; method f() → self::D? @@ -11,7 +11,7 @@ class C extends core::Object { method h() → void {} } class D extends core::Object { - synthetic constructor •() → self::D* + synthetic constructor •() → self::D : super core::Object::•() ; method g() → void {} diff --git a/pkg/front_end/testcases/nnbd/issue_39286_2.dart.outline.expect b/pkg/front_end/testcases/nnbd/issue_39286_2.dart.outline.expect index f2c2b39a9c2d..8872e99a03ec 100644 --- a/pkg/front_end/testcases/nnbd/issue_39286_2.dart.outline.expect +++ b/pkg/front_end/testcases/nnbd/issue_39286_2.dart.outline.expect @@ -4,7 +4,7 @@ import "dart:core" as core; class C extends core::Object { field core::int y; - synthetic constructor •() → self::C* + synthetic constructor •() → self::C ; method f() → self::D? ; @@ -12,7 +12,7 @@ class C extends core::Object { ; } class D extends core::Object { - synthetic constructor •() → self::D* + synthetic constructor •() → self::D ; method g() → self::D ; diff --git a/pkg/front_end/testcases/nnbd/issue_39286_2.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue_39286_2.dart.strong.expect index 37e9149ff7a9..32274dd34c0d 100644 --- a/pkg/front_end/testcases/nnbd/issue_39286_2.dart.strong.expect +++ b/pkg/front_end/testcases/nnbd/issue_39286_2.dart.strong.expect @@ -4,7 +4,7 @@ import "dart:core" as core; class C extends core::Object { field core::int y = null; - synthetic constructor •() → self::C* + synthetic constructor •() → self::C : super core::Object::•() ; method f() → self::D? @@ -13,7 +13,7 @@ class C extends core::Object { return this; } class D extends core::Object { - synthetic constructor •() → self::D* + synthetic constructor •() → self::D : super core::Object::•() ; method g() → self::D diff --git a/pkg/front_end/testcases/nnbd/issue_39286_2.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue_39286_2.dart.strong.transformed.expect index 37e9149ff7a9..32274dd34c0d 100644 --- a/pkg/front_end/testcases/nnbd/issue_39286_2.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/nnbd/issue_39286_2.dart.strong.transformed.expect @@ -4,7 +4,7 @@ import "dart:core" as core; class C extends core::Object { field core::int y = null; - synthetic constructor •() → self::C* + synthetic constructor •() → self::C : super core::Object::•() ; method f() → self::D? @@ -13,7 +13,7 @@ class C extends core::Object { return this; } class D extends core::Object { - synthetic constructor •() → self::D* + synthetic constructor •() → self::D : super core::Object::•() ; method g() → self::D diff --git a/pkg/front_end/testcases/nnbd/late.dart.outline.expect b/pkg/front_end/testcases/nnbd/late.dart.outline.expect index ab02fd7ab2a3..88ea1d537528 100644 --- a/pkg/front_end/testcases/nnbd/late.dart.outline.expect +++ b/pkg/front_end/testcases/nnbd/late.dart.outline.expect @@ -13,7 +13,7 @@ class Class extends core::Object { late static final field core::int lateFinalStaticField1; late static final field core::int lateFinalStaticField2; late static final field core::int lateFinalStaticFieldWithInit; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class ; method method() → dynamic ; diff --git a/pkg/front_end/testcases/nnbd/late.dart.strong.expect b/pkg/front_end/testcases/nnbd/late.dart.strong.expect index f22251a8ca01..854f872c3960 100644 --- a/pkg/front_end/testcases/nnbd/late.dart.strong.expect +++ b/pkg/front_end/testcases/nnbd/late.dart.strong.expect @@ -44,7 +44,7 @@ class Class extends core::Object { late static final field core::int lateFinalStaticField1; late static final field core::int lateFinalStaticField2; late static final field core::int lateFinalStaticFieldWithInit = 0; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class : super core::Object::•() ; method method() → dynamic { diff --git a/pkg/front_end/testcases/nnbd/late.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/late.dart.strong.transformed.expect index f22251a8ca01..854f872c3960 100644 --- a/pkg/front_end/testcases/nnbd/late.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/nnbd/late.dart.strong.transformed.expect @@ -44,7 +44,7 @@ class Class extends core::Object { late static final field core::int lateFinalStaticField1; late static final field core::int lateFinalStaticField2; late static final field core::int lateFinalStaticFieldWithInit = 0; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class : super core::Object::•() ; method method() → dynamic { diff --git a/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.outline.expect b/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.outline.expect index 655c6c714e71..83a9a175a4e4 100644 --- a/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.outline.expect +++ b/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.outline.expect @@ -55,7 +55,7 @@ import "messages_with_types_opt_out.dart" as mes; import "org-dartlang-testcase:///messages_with_types_opt_out.dart"; class SuperIn extends core::Object { - synthetic constructor •() → self::SuperIn* + synthetic constructor •() → self::SuperIn ; method nullableSame() → core::String? ; @@ -67,7 +67,7 @@ class SuperIn extends core::Object { ; } class SubInIn extends self::SuperIn { - synthetic constructor •() → self::SubInIn* + synthetic constructor •() → self::SubInIn ; method nullableSame() → core::String? ; @@ -79,7 +79,7 @@ class SubInIn extends self::SuperIn { ; } class SubOutIn extends mes::SuperOut { - synthetic constructor •() → self::SubOutIn* + synthetic constructor •() → self::SubOutIn ; method nullableSame() → core::String? ; diff --git a/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.strong.expect b/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.strong.expect index 0a3c6ef8595c..050c5f834121 100644 --- a/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.strong.expect +++ b/pkg/front_end/testcases/nnbd/messages_with_types_opt_in.dart.strong.expect @@ -79,7 +79,7 @@ import "messages_with_types_opt_out.dart" as mes; import "org-dartlang-testcase:///messages_with_types_opt_out.dart"; class SuperIn extends core::Object { - synthetic constructor •() → self::SuperIn* + synthetic constructor •() → self::SuperIn : super core::Object::•() ; method nullableSame() → core::String? @@ -92,7 +92,7 @@ class SuperIn extends core::Object { return 2; } class SubInIn extends self::SuperIn { - synthetic constructor •() → self::SubInIn* + synthetic constructor •() → self::SubInIn : super self::SuperIn::•() ; method nullableSame() → core::String? @@ -105,7 +105,7 @@ class SubInIn extends self::SuperIn { return t; } class SubOutIn extends mes::SuperOut { - synthetic constructor •() → self::SubOutIn* + synthetic constructor •() → self::SubOutIn : super mes::SuperOut::•() ; method nullableSame() → core::String? diff --git a/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.outline.expect b/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.outline.expect index 049cf57aa224..51f5591df0f4 100644 --- a/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.outline.expect +++ b/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.outline.expect @@ -151,7 +151,7 @@ import "messages_with_types_opt_out.dart" as self; import "org-dartlang-testcase:///messages_with_types_opt_out.dart"; class SuperIn extends core::Object { - synthetic constructor •() → mes::SuperIn* + synthetic constructor •() → mes::SuperIn ; method nullableSame() → core::String? ; @@ -163,7 +163,7 @@ class SuperIn extends core::Object { ; } class SubInIn extends mes::SuperIn { - synthetic constructor •() → mes::SubInIn* + synthetic constructor •() → mes::SubInIn ; method nullableSame() → core::String? ; @@ -175,7 +175,7 @@ class SubInIn extends mes::SuperIn { ; } class SubOutIn extends self::SuperOut { - synthetic constructor •() → mes::SubOutIn* + synthetic constructor •() → mes::SubOutIn ; method nullableSame() → core::String? ; diff --git a/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.strong.expect b/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.strong.expect index 72243c645d81..fe57a7bfaccb 100644 --- a/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.strong.expect +++ b/pkg/front_end/testcases/nnbd/messages_with_types_opt_out.dart.strong.expect @@ -220,7 +220,7 @@ import "messages_with_types_opt_out.dart" as self; import "org-dartlang-testcase:///messages_with_types_opt_out.dart"; class SuperIn extends core::Object { - synthetic constructor •() → mes::SuperIn* + synthetic constructor •() → mes::SuperIn : super core::Object::•() ; method nullableSame() → core::String? @@ -233,7 +233,7 @@ class SuperIn extends core::Object { return 2; } class SubInIn extends mes::SuperIn { - synthetic constructor •() → mes::SubInIn* + synthetic constructor •() → mes::SubInIn : super mes::SuperIn::•() ; method nullableSame() → core::String? @@ -246,7 +246,7 @@ class SubInIn extends mes::SuperIn { return t; } class SubOutIn extends self::SuperOut { - synthetic constructor •() → mes::SubOutIn* + synthetic constructor •() → mes::SubOutIn : super self::SuperOut::•() ; method nullableSame() → core::String? diff --git a/pkg/front_end/testcases/nnbd/null_check.dart.outline.expect b/pkg/front_end/testcases/nnbd/null_check.dart.outline.expect index 5dd134e08c45..aa7235a13600 100644 --- a/pkg/front_end/testcases/nnbd/null_check.dart.outline.expect +++ b/pkg/front_end/testcases/nnbd/null_check.dart.outline.expect @@ -4,7 +4,7 @@ import "dart:core" as core; class Class extends core::Object { field core::int? field; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class ; method method() → core::int? ; diff --git a/pkg/front_end/testcases/nnbd/null_check.dart.strong.expect b/pkg/front_end/testcases/nnbd/null_check.dart.strong.expect index 8e7b90eb17aa..bffb6cef1820 100644 --- a/pkg/front_end/testcases/nnbd/null_check.dart.strong.expect +++ b/pkg/front_end/testcases/nnbd/null_check.dart.strong.expect @@ -4,7 +4,7 @@ import "dart:core" as core; class Class extends core::Object { field core::int? field = null; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class : super core::Object::•() ; method method() → core::int? diff --git a/pkg/front_end/testcases/nnbd/null_check.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/null_check.dart.strong.transformed.expect index 8e7b90eb17aa..bffb6cef1820 100644 --- a/pkg/front_end/testcases/nnbd/null_check.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/nnbd/null_check.dart.strong.transformed.expect @@ -4,7 +4,7 @@ import "dart:core" as core; class Class extends core::Object { field core::int? field = null; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class : super core::Object::•() ; method method() → core::int? diff --git a/pkg/front_end/testcases/nnbd/null_shorting.dart.outline.expect b/pkg/front_end/testcases/nnbd/null_shorting.dart.outline.expect index 4e95ca9dfb0d..c6e03e11d235 100644 --- a/pkg/front_end/testcases/nnbd/null_shorting.dart.outline.expect +++ b/pkg/front_end/testcases/nnbd/null_shorting.dart.outline.expect @@ -4,7 +4,7 @@ import "dart:core" as core; class Class extends core::Object { field self::Class? field; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class ; method method() → self::Class? ; diff --git a/pkg/front_end/testcases/nnbd/null_shorting.dart.strong.expect b/pkg/front_end/testcases/nnbd/null_shorting.dart.strong.expect index e46753bee1aa..7ce23d4c79f5 100644 --- a/pkg/front_end/testcases/nnbd/null_shorting.dart.strong.expect +++ b/pkg/front_end/testcases/nnbd/null_shorting.dart.strong.expect @@ -4,7 +4,7 @@ import "dart:core" as core; class Class extends core::Object { field self::Class? field = null; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class : super core::Object::•() ; method method() → self::Class? diff --git a/pkg/front_end/testcases/nnbd/null_shorting.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/null_shorting.dart.strong.transformed.expect index e46753bee1aa..7ce23d4c79f5 100644 --- a/pkg/front_end/testcases/nnbd/null_shorting.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/nnbd/null_shorting.dart.strong.transformed.expect @@ -4,7 +4,7 @@ import "dart:core" as core; class Class extends core::Object { field self::Class? field = null; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class : super core::Object::•() ; method method() → self::Class? diff --git a/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.outline.expect b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.outline.expect index 3538ffe9ed7c..99caa3137cad 100644 --- a/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.outline.expect +++ b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.outline.expect @@ -3,7 +3,7 @@ import self as self; import "dart:core" as core; class Class extends core::Object { - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class ; method method() → self::Class ; diff --git a/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.strong.expect b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.strong.expect index db9cb33a50e3..f45240b8ef20 100644 --- a/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.strong.expect +++ b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.strong.expect @@ -3,7 +3,7 @@ import self as self; import "dart:core" as core; class Class extends core::Object { - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class : super core::Object::•() ; method method() → self::Class diff --git a/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.strong.transformed.expect index db9cb33a50e3..f45240b8ef20 100644 --- a/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/nnbd/null_shorting_cascade.dart.strong.transformed.expect @@ -3,7 +3,7 @@ import self as self; import "dart:core" as core; class Class extends core::Object { - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class : super core::Object::•() ; method method() → self::Class diff --git a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.outline.expect b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.outline.expect index 8a55652761ea..226223270374 100644 --- a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.outline.expect +++ b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.outline.expect @@ -4,7 +4,7 @@ import "dart:core" as core; class Class extends core::Object { field self::Class? _field; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class ; } extension Extension on self::Class { diff --git a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.strong.expect b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.strong.expect index 5f6ede8879af..c57069c19ebd 100644 --- a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.strong.expect +++ b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.strong.expect @@ -4,7 +4,7 @@ import "dart:core" as core; class Class extends core::Object { field self::Class? _field = null; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class : super core::Object::•() ; } diff --git a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.strong.transformed.expect index 5f6ede8879af..c57069c19ebd 100644 --- a/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/nnbd/null_shorting_explicit_extension.dart.strong.transformed.expect @@ -4,7 +4,7 @@ import "dart:core" as core; class Class extends core::Object { field self::Class? _field = null; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class : super core::Object::•() ; } diff --git a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.outline.expect b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.outline.expect index 8a55652761ea..226223270374 100644 --- a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.outline.expect +++ b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.outline.expect @@ -4,7 +4,7 @@ import "dart:core" as core; class Class extends core::Object { field self::Class? _field; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class ; } extension Extension on self::Class { diff --git a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.strong.expect b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.strong.expect index 8bd81bb9f051..e86404be6a49 100644 --- a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.strong.expect +++ b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.strong.expect @@ -4,7 +4,7 @@ import "dart:core" as core; class Class extends core::Object { field self::Class? _field = null; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class : super core::Object::•() ; } diff --git a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.strong.transformed.expect index 8bd81bb9f051..e86404be6a49 100644 --- a/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/nnbd/null_shorting_extension.dart.strong.transformed.expect @@ -4,7 +4,7 @@ import "dart:core" as core; class Class extends core::Object { field self::Class? _field = null; - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class : super core::Object::•() ; } diff --git a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.outline.expect b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.outline.expect index 348efe9278fa..6b81c57b8ed3 100644 --- a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.outline.expect +++ b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.outline.expect @@ -3,7 +3,7 @@ import self as self; import "dart:core" as core; class Class1 extends core::Object { - synthetic constructor •() → self::Class1* + synthetic constructor •() → self::Class1 ; get field() → self::Class2? ; @@ -14,7 +14,7 @@ class Class1 extends core::Object { } class Class2 extends core::Object { field core::int field; - synthetic constructor •() → self::Class2* + synthetic constructor •() → self::Class2 ; } extension Extension on self::Class2 { diff --git a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.expect b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.expect index 621559ae08c3..4352c2828c81 100644 --- a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.expect +++ b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.expect @@ -3,7 +3,7 @@ import self as self; import "dart:core" as core; class Class1 extends core::Object { - synthetic constructor •() → self::Class1* + synthetic constructor •() → self::Class1 : super core::Object::•() ; get field() → self::Class2? @@ -14,7 +14,7 @@ class Class1 extends core::Object { } class Class2 extends core::Object { field core::int field = null; - synthetic constructor •() → self::Class2* + synthetic constructor •() → self::Class2 : super core::Object::•() ; } diff --git a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.transformed.expect index 621559ae08c3..4352c2828c81 100644 --- a/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/nnbd/null_shorting_index.dart.strong.transformed.expect @@ -3,7 +3,7 @@ import self as self; import "dart:core" as core; class Class1 extends core::Object { - synthetic constructor •() → self::Class1* + synthetic constructor •() → self::Class1 : super core::Object::•() ; get field() → self::Class2? @@ -14,7 +14,7 @@ class Class1 extends core::Object { } class Class2 extends core::Object { field core::int field = null; - synthetic constructor •() → self::Class2* + synthetic constructor •() → self::Class2 : super core::Object::•() ; } diff --git a/pkg/front_end/testcases/nnbd/nullable_null.dart.outline.expect b/pkg/front_end/testcases/nnbd/nullable_null.dart.outline.expect index 9c9d87a87376..937afc398b96 100644 --- a/pkg/front_end/testcases/nnbd/nullable_null.dart.outline.expect +++ b/pkg/front_end/testcases/nnbd/nullable_null.dart.outline.expect @@ -3,15 +3,15 @@ import self as self; import "dart:core" as core; class A extends core::Object { - synthetic constructor •() → self::A* + synthetic constructor •() → self::A ; } class B extends self::A { - synthetic constructor •() → self::B* + synthetic constructor •() → self::B ; } class C extends core::Object { - synthetic constructor •() → self::C* + synthetic constructor •() → self::C ; method foo(core::Null? n, self::A an) → core::Null? ; diff --git a/pkg/front_end/testcases/nnbd/nullable_null.dart.strong.expect b/pkg/front_end/testcases/nnbd/nullable_null.dart.strong.expect index 263e44a5c0b5..f4e428283fdb 100644 --- a/pkg/front_end/testcases/nnbd/nullable_null.dart.strong.expect +++ b/pkg/front_end/testcases/nnbd/nullable_null.dart.strong.expect @@ -3,17 +3,17 @@ import self as self; import "dart:core" as core; class A extends core::Object { - synthetic constructor •() → self::A* + synthetic constructor •() → self::A : super core::Object::•() ; } class B extends self::A { - synthetic constructor •() → self::B* + synthetic constructor •() → self::B : super self::A::•() ; } class C extends core::Object { - synthetic constructor •() → self::C* + synthetic constructor •() → self::C : super core::Object::•() ; method foo(core::Null? n, self::A an) → core::Null? diff --git a/pkg/front_end/testcases/nnbd/nullable_null.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/nullable_null.dart.strong.transformed.expect index 263e44a5c0b5..f4e428283fdb 100644 --- a/pkg/front_end/testcases/nnbd/nullable_null.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/nnbd/nullable_null.dart.strong.transformed.expect @@ -3,17 +3,17 @@ import self as self; import "dart:core" as core; class A extends core::Object { - synthetic constructor •() → self::A* + synthetic constructor •() → self::A : super core::Object::•() ; } class B extends self::A { - synthetic constructor •() → self::B* + synthetic constructor •() → self::B : super self::A::•() ; } class C extends core::Object { - synthetic constructor •() → self::C* + synthetic constructor •() → self::C : super core::Object::•() ; method foo(core::Null? n, self::A an) → core::Null? diff --git a/pkg/front_end/testcases/nnbd/nullable_param.dart.outline.expect b/pkg/front_end/testcases/nnbd/nullable_param.dart.outline.expect index a40317eb155e..42f3ecaeb8f1 100644 --- a/pkg/front_end/testcases/nnbd/nullable_param.dart.outline.expect +++ b/pkg/front_end/testcases/nnbd/nullable_param.dart.outline.expect @@ -21,7 +21,7 @@ import "dart:core" as core; class Foo extends core::Object { field core::int? field; - synthetic constructor •() → self::Foo* + synthetic constructor •() → self::Foo ; abstract method bar(core::int? x) → core::int?; } diff --git a/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.expect b/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.expect index 610a9eea22ce..ffa36e4d327f 100644 --- a/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.expect +++ b/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.expect @@ -21,7 +21,7 @@ import "dart:core" as core; class Foo extends core::Object { field core::int? field = null; - synthetic constructor •() → self::Foo* + synthetic constructor •() → self::Foo : super core::Object::•() ; abstract method bar(core::int? x) → core::int?; diff --git a/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.transformed.expect index 610a9eea22ce..ffa36e4d327f 100644 --- a/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.transformed.expect @@ -21,7 +21,7 @@ import "dart:core" as core; class Foo extends core::Object { field core::int? field = null; - synthetic constructor •() → self::Foo* + synthetic constructor •() → self::Foo : super core::Object::•() ; abstract method bar(core::int? x) → core::int?; diff --git a/pkg/front_end/testcases/nnbd/required.dart.outline.expect b/pkg/front_end/testcases/nnbd/required.dart.outline.expect index d5dda81207a2..d196109cd70d 100644 --- a/pkg/front_end/testcases/nnbd/required.dart.outline.expect +++ b/pkg/front_end/testcases/nnbd/required.dart.outline.expect @@ -5,7 +5,7 @@ import "dart:core" as core; typedef Typedef1 = ({a: core::int, required b: core::int}) → dynamic; typedef Typedef2 = ({a: core::int, required b: core::int}) → dynamic; class Class extends core::Object { - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class ; method method({core::int a, required core::int b, required final core::int c, required covariant final core::int d}) → dynamic ; diff --git a/pkg/front_end/testcases/nnbd/required.dart.strong.expect b/pkg/front_end/testcases/nnbd/required.dart.strong.expect index 4ce5b20d65a7..b495798e29d3 100644 --- a/pkg/front_end/testcases/nnbd/required.dart.strong.expect +++ b/pkg/front_end/testcases/nnbd/required.dart.strong.expect @@ -5,7 +5,7 @@ import "dart:core" as core; typedef Typedef1 = ({a: core::int, required b: core::int}) → dynamic; typedef Typedef2 = ({a: core::int, required b: core::int}) → dynamic; class Class extends core::Object { - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class : super core::Object::•() ; method method({core::int a = #C1, required core::int b = #C1, required final core::int c = #C1, required covariant final core::int d = #C1}) → dynamic {} diff --git a/pkg/front_end/testcases/nnbd/required.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/required.dart.strong.transformed.expect index 4ce5b20d65a7..b495798e29d3 100644 --- a/pkg/front_end/testcases/nnbd/required.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/nnbd/required.dart.strong.transformed.expect @@ -5,7 +5,7 @@ import "dart:core" as core; typedef Typedef1 = ({a: core::int, required b: core::int}) → dynamic; typedef Typedef2 = ({a: core::int, required b: core::int}) → dynamic; class Class extends core::Object { - synthetic constructor •() → self::Class* + synthetic constructor •() → self::Class : super core::Object::•() ; method method({core::int a = #C1, required core::int b = #C1, required final core::int c = #C1, required covariant final core::int d = #C1}) → dynamic {} diff --git a/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.outline.expect b/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.outline.expect index 537af0291a58..78939a76af54 100644 --- a/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.outline.expect +++ b/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.outline.expect @@ -3,7 +3,7 @@ import self as self; import "dart:core" as core; class A extends core::Object { - synthetic constructor •() → self::A* + synthetic constructor •() → self::A ; method hest = core::List, Z extends core::List = core::List>() → dynamic ; diff --git a/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.strong.expect b/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.strong.expect index cbc95c49f389..b23b0d3bd4be 100644 --- a/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.strong.expect +++ b/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.strong.expect @@ -3,7 +3,7 @@ import self as self; import "dart:core" as core; class A extends core::Object { - synthetic constructor •() → self::A* + synthetic constructor •() → self::A : super core::Object::•() ; method hest = core::List, Z extends core::List = core::List>() → dynamic diff --git a/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.strong.transformed.expect index cbc95c49f389..b23b0d3bd4be 100644 --- a/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/nnbd/substitution_in_inference.dart.strong.transformed.expect @@ -3,7 +3,7 @@ import self as self; import "dart:core" as core; class A extends core::Object { - synthetic constructor •() → self::A* + synthetic constructor •() → self::A : super core::Object::•() ; method hest = core::List, Z extends core::List = core::List>() → dynamic diff --git a/pkg/front_end/testcases/nnbd/type_parameter_types.dart.outline.expect b/pkg/front_end/testcases/nnbd/type_parameter_types.dart.outline.expect index 54c224f2ba86..0ae7b83ec121 100644 --- a/pkg/front_end/testcases/nnbd/type_parameter_types.dart.outline.expect +++ b/pkg/front_end/testcases/nnbd/type_parameter_types.dart.outline.expect @@ -3,7 +3,7 @@ import self as self; import "dart:core" as core; class A extends core::Object { - synthetic constructor •() → self::A* + synthetic constructor •() → self::A ; method foo() → self::A::X ; @@ -13,19 +13,19 @@ class A = core::List, Y extends core::Object? = core::Object?> extends core::Object { - synthetic constructor •() → self::B* + synthetic constructor •() → self::B ; method foo(generic-covariant-impl self::B::X x, generic-covariant-impl self::B::Y% y) → dynamic ; } class C? = core::List?, Y extends core::List? = core::List?> extends core::Object { - synthetic constructor •() → self::C* + synthetic constructor •() → self::C ; method foo(generic-covariant-impl self::C::X% x, generic-covariant-impl self::C::Y% y) → dynamic ; } class D extends core::Object { - synthetic constructor •() → self::D* + synthetic constructor •() → self::D ; method foo(generic-covariant-impl self::D::X% x, generic-covariant-impl self::D::Y% y, generic-covariant-impl self::D::Z% z) → dynamic ; diff --git a/pkg/front_end/testcases/nnbd/type_parameter_types.dart.strong.expect b/pkg/front_end/testcases/nnbd/type_parameter_types.dart.strong.expect index da778be607d7..9b7ac71de806 100644 --- a/pkg/front_end/testcases/nnbd/type_parameter_types.dart.strong.expect +++ b/pkg/front_end/testcases/nnbd/type_parameter_types.dart.strong.expect @@ -3,7 +3,7 @@ import self as self; import "dart:core" as core; class A extends core::Object { - synthetic constructor •() → self::A* + synthetic constructor •() → self::A : super core::Object::•() ; method foo() → self::A::X @@ -14,19 +14,19 @@ class A = core::List, Y extends core::Object? = core::Object?> extends core::Object { - synthetic constructor •() → self::B* + synthetic constructor •() → self::B : super core::Object::•() ; method foo(generic-covariant-impl self::B::X x, generic-covariant-impl self::B::Y% y) → dynamic {} } class C? = core::List?, Y extends core::List? = core::List?> extends core::Object { - synthetic constructor •() → self::C* + synthetic constructor •() → self::C : super core::Object::•() ; method foo(generic-covariant-impl self::C::X% x, generic-covariant-impl self::C::Y% y) → dynamic {} } class D extends core::Object { - synthetic constructor •() → self::D* + synthetic constructor •() → self::D : super core::Object::•() ; method foo(generic-covariant-impl self::D::X% x, generic-covariant-impl self::D::Y% y, generic-covariant-impl self::D::Z% z) → dynamic {} diff --git a/pkg/front_end/testcases/nnbd/type_parameter_types.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/type_parameter_types.dart.strong.transformed.expect index da778be607d7..9b7ac71de806 100644 --- a/pkg/front_end/testcases/nnbd/type_parameter_types.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/nnbd/type_parameter_types.dart.strong.transformed.expect @@ -3,7 +3,7 @@ import self as self; import "dart:core" as core; class A extends core::Object { - synthetic constructor •() → self::A* + synthetic constructor •() → self::A : super core::Object::•() ; method foo() → self::A::X @@ -14,19 +14,19 @@ class A = core::List, Y extends core::Object? = core::Object?> extends core::Object { - synthetic constructor •() → self::B* + synthetic constructor •() → self::B : super core::Object::•() ; method foo(generic-covariant-impl self::B::X x, generic-covariant-impl self::B::Y% y) → dynamic {} } class C? = core::List?, Y extends core::List? = core::List?> extends core::Object { - synthetic constructor •() → self::C* + synthetic constructor •() → self::C : super core::Object::•() ; method foo(generic-covariant-impl self::C::X% x, generic-covariant-impl self::C::Y% y) → dynamic {} } class D extends core::Object { - synthetic constructor •() → self::D* + synthetic constructor •() → self::D : super core::Object::•() ; method foo(generic-covariant-impl self::D::X% x, generic-covariant-impl self::D::Y% y, generic-covariant-impl self::D::Z% z) → dynamic {} diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart index 575a8878a1fb..971bc21ed73a 100644 --- a/pkg/kernel/lib/ast.dart +++ b/pkg/kernel/lib/ast.dart @@ -1281,12 +1281,6 @@ class Class extends NamedNode implements Annotatable, FileUriNode { return coreTypes.thisInterfaceType(this, nullability); } - InterfaceType _bottomType; - InterfaceType get bottomType { - return _bottomType ??= new InterfaceType(this, Nullability.legacy, - new List.filled(typeParameters.length, const BottomType())); - } - /// Returns a possibly synthesized name for this class, consistent with /// the names used across all [toString] calls. String toString() => debugQualifiedClassName(this); @@ -2647,14 +2641,19 @@ abstract class Expression extends TreeNode { typeParameterType.promotedBound ?? typeParameterType.parameter.bound; } if (type == context.typeEnvironment.nullType) { - return superclass.bottomType; + return context.typeEnvironment.coreTypes + .bottomInterfaceType(superclass, context.nullable); } if (type is InterfaceType) { - var upcastType = - context.typeEnvironment.getTypeAsInstanceOf(type, superclass); - if (upcastType != null) return upcastType; + List upcastTypeArguments = context.typeEnvironment + .getTypeArgumentsAsInstanceOf(type, superclass); + if (upcastTypeArguments != null) { + return new InterfaceType( + superclass, type.nullability, upcastTypeArguments); + } } else if (type is BottomType) { - return superclass.bottomType; + return context.typeEnvironment.coreTypes + .bottomInterfaceType(superclass, context.nonNullable); } context.typeEnvironment .typeError(this, '$type is not a subtype of $superclass'); @@ -3038,9 +3037,10 @@ class SuperPropertyGet extends Expression { if (declaringClass.typeParameters.isEmpty) { return interfaceTarget.getterType; } - var receiver = context.typeEnvironment - .getTypeAsInstanceOf(context.thisType, declaringClass); - return Substitution.fromInterfaceType(receiver) + List receiverArguments = context.typeEnvironment + .getTypeArgumentsAsInstanceOf(context.thisType, declaringClass); + return Substitution.fromPairs( + declaringClass.typeParameters, receiverArguments) .substituteType(interfaceTarget.getterType); } @@ -3397,10 +3397,11 @@ class SuperMethodInvocation extends InvocationExpression { DartType getStaticType(StaticTypeContext context) { if (interfaceTarget == null) return const DynamicType(); Class superclass = interfaceTarget.enclosingClass; - var receiverType = context.typeEnvironment - .getTypeAsInstanceOf(context.thisType, superclass); - var returnType = Substitution.fromInterfaceType(receiverType) - .substituteType(interfaceTarget.function.returnType); + List receiverTypeArguments = context.typeEnvironment + .getTypeArgumentsAsInstanceOf(context.thisType, superclass); + DartType returnType = + Substitution.fromPairs(superclass.typeParameters, receiverTypeArguments) + .substituteType(interfaceTarget.function.returnType); return Substitution.fromPairs( interfaceTarget.function.typeParameters, arguments.types) .substituteType(returnType); diff --git a/pkg/kernel/lib/class_hierarchy.dart b/pkg/kernel/lib/class_hierarchy.dart index b2431be2d939..2e2a7fc865f9 100644 --- a/pkg/kernel/lib/class_hierarchy.dart +++ b/pkg/kernel/lib/class_hierarchy.dart @@ -9,8 +9,9 @@ import 'dart:typed_data'; import 'ast.dart'; import 'core_types.dart'; -import 'src/heap.dart'; import 'type_algebra.dart'; +import 'src/heap.dart'; +import 'src/future_or.dart'; typedef HandleAmbiguousSupertypes = void Function(Class, Supertype, Supertype); @@ -62,8 +63,8 @@ abstract class ClassHierarchy { /// Dart 2 least upper bound, which has special behaviors in the case where /// one type is a subtype of the other, or where both types are based on the /// same class. - InterfaceType getLegacyLeastUpperBound( - InterfaceType type1, InterfaceType type2, CoreTypes coreTypes); + InterfaceType getLegacyLeastUpperBound(InterfaceType type1, + InterfaceType type2, Library clientLibrary, CoreTypes coreTypes); /// Returns the instantiation of [superclass] that is implemented by [class_], /// or `null` if [class_] does not implement [superclass] at all. @@ -71,7 +72,14 @@ abstract class ClassHierarchy { /// Returns the instantiation of [superclass] that is implemented by [type], /// or `null` if [type] does not implement [superclass] at all. - InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass); + InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass, + Library clientLibrary, CoreTypes coreTypes); + + /// Returns the type arguments of the instantiation of [superclass] that is + /// implemented by [type], or `null` if [type] does not implement [superclass] + /// at all. + List getTypeArgumentsAsInstanceOf( + InterfaceType type, Class superclass); /// Returns the instantiation of [superclass] that is implemented by [type], /// or `null` if [type] does not implement [superclass]. [superclass] must @@ -540,8 +548,8 @@ class ClosedWorldClassHierarchy implements ClassHierarchy { } @override - InterfaceType getLegacyLeastUpperBound( - InterfaceType type1, InterfaceType type2, CoreTypes coreTypes) { + InterfaceType getLegacyLeastUpperBound(InterfaceType type1, + InterfaceType type2, Library clientLibrary, CoreTypes coreTypes) { // The algorithm is: first we compute a list of superclasses for both types, // ordered from greatest to least depth, and ordered by topological sort // index within each depth. Due to the sort order, we can find the @@ -561,6 +569,16 @@ class ClosedWorldClassHierarchy implements ClassHierarchy { // Compute the list of superclasses for both types, with the above // optimization. + + // LLUB(Null, List*) works differently for opt-in and opt-out + // libraries. In opt-out libraries the legacy behavior is preserved, so + // LLUB(Null, List*) = List*. In opt-in libraries the + // rules imply that LLUB(Null, List*) = List?. + if (!clientLibrary.isNonNullableByDefault) { + if (type1 == coreTypes.nullType) return type2; + if (type2 == coreTypes.nullType) return type1; + } + _ClassInfo info1 = infoFor(type1.classNode); _ClassInfo info2 = infoFor(type2.classNode); List<_ClassInfo> classes1; @@ -615,8 +633,8 @@ class ClosedWorldClassHierarchy implements ClassHierarchy { // immediately. Since all interface types are subtypes of Object, this // ensures the loop terminates. if (next.classNode.typeParameters.isEmpty) { - // TODO(dmitryas): Update nullability as necessary for the LUB spec. - candidate = coreTypes.legacyRawType(next.classNode); + candidate = coreTypes.rawType(next.classNode, + uniteNullabilities(type1.nullability, type2.nullability)); if (currentDepth == 0) return candidate; ++numCandidatesAtThisDepth; } else { @@ -629,7 +647,8 @@ class ClosedWorldClassHierarchy implements ClassHierarchy { : Substitution.fromInterfaceType(type2).substituteType( info2.genericSuperTypes[next.classNode].first.asInterfaceType); if (superType1 == superType2) { - candidate = superType1; + candidate = superType1.withNullability( + uniteNullabilities(type1.nullability, type2.nullability)); ++numCandidatesAtThisDepth; } } @@ -653,11 +672,30 @@ class ClosedWorldClassHierarchy implements ClassHierarchy { } @override - InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass) { + InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass, + Library clientLibrary, CoreTypes coreTypes) { + List typeArguments = + getTypeArgumentsAsInstanceOf(type, superclass); + if (typeArguments == null) return null; + // The return value should be a legacy type if it's computed for an + // opted-out library, unless the return value is Null? which is always + // nullable. + Nullability nullability = superclass == coreTypes.nullClass || + clientLibrary.isNonNullableByDefault + ? type.nullability + : Nullability.legacy; + return new InterfaceType(superclass, nullability, typeArguments); + } + + @override + List getTypeArgumentsAsInstanceOf( + InterfaceType type, Class superclass) { Supertype castedType = getClassAsInstanceOf(type.classNode, superclass); if (castedType == null) return null; + if (superclass.typeParameters.isEmpty) return const []; return Substitution.fromInterfaceType(type) - .substituteType(castedType.asInterfaceType); + .substituteSupertype(castedType) + .typeArguments; } @override diff --git a/pkg/kernel/lib/core_types.dart b/pkg/kernel/lib/core_types.dart index 173fb0387d5b..df54fecea0b9 100644 --- a/pkg/kernel/lib/core_types.dart +++ b/pkg/kernel/lib/core_types.dart @@ -171,6 +171,8 @@ class CoreTypes { new Map.identity(); final Map _thisTypedefTypes = new Map.identity(); + final Map _bottomInterfaceTypes = + new Map.identity(); CoreTypes(Component component) : index = new LibraryIndex.coreLibraries(component); @@ -1222,4 +1224,19 @@ class CoreTypes { return _lateInitializationErrorConstructor ??= index.getMember('dart:_internal', 'LateInitializationErrorImpl', ''); } + + InterfaceType bottomInterfaceType(Class klass, Nullability nullability) { + InterfaceType result = _bottomInterfaceTypes[klass]; + if (result == null) { + return _bottomInterfaceTypes[klass] = new InterfaceType( + klass, + nullability, + new List.filled( + klass.typeParameters.length, const BottomType())); + } + if (result.nullability != nullability) { + return _bottomInterfaceTypes[klass] = result.withNullability(nullability); + } + return result; + } } diff --git a/pkg/kernel/lib/src/hierarchy_based_type_environment.dart b/pkg/kernel/lib/src/hierarchy_based_type_environment.dart index 5ef4e9f4b93f..a7358c2ce662 100644 --- a/pkg/kernel/lib/src/hierarchy_based_type_environment.dart +++ b/pkg/kernel/lib/src/hierarchy_based_type_environment.dart @@ -4,7 +4,7 @@ library kernel.hierarchy_based_type_environment; -import '../ast.dart' show Class, InterfaceType, Member, Name; +import '../ast.dart' show Class, DartType, InterfaceType, Library, Member, Name; import '../class_hierarchy.dart' show ClassHierarchy; @@ -19,8 +19,16 @@ class HierarchyBasedTypeEnvironment extends TypeEnvironment { : super.fromSubclass(coreTypes); @override - InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass) { - return hierarchy.getTypeAsInstanceOf(type, superclass); + InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass, + Library clientLibrary, CoreTypes coreTypes) { + return hierarchy.getTypeAsInstanceOf( + type, superclass, clientLibrary, coreTypes); + } + + @override + List getTypeArgumentsAsInstanceOf( + InterfaceType type, Class superclass) { + return hierarchy.getTypeArgumentsAsInstanceOf(type, superclass); } @override diff --git a/pkg/kernel/lib/type_checker.dart b/pkg/kernel/lib/type_checker.dart index ba3e192983cc..59c41e6394e8 100644 --- a/pkg/kernel/lib/type_checker.dart +++ b/pkg/kernel/lib/type_checker.dart @@ -255,9 +255,11 @@ class TypeCheckingVisitor } if (type is InterfaceType) { // The receiver type should implement the interface declaring the member. - var upcastType = hierarchy.getTypeAsInstanceOf(type, superclass); - if (upcastType != null) { - return Substitution.fromInterfaceType(upcastType); + List upcastTypeArguments = + hierarchy.getTypeArgumentsAsInstanceOf(type, superclass); + if (upcastTypeArguments != null) { + return Substitution.fromPairs( + superclass.typeParameters, upcastTypeArguments); } } if (type is FunctionType && superclass == coreTypes.functionClass) { @@ -909,17 +911,23 @@ class TypeCheckingVisitor var iteratorGetter = hierarchy.getInterfaceMember(iterable.classNode, iteratorName); if (iteratorGetter == null) return const DynamicType(); - var castedIterable = hierarchy.getTypeAsInstanceOf( - iterable, iteratorGetter.enclosingClass); - var iteratorType = Substitution.fromInterfaceType(castedIterable) + List castedIterableArguments = + hierarchy.getTypeArgumentsAsInstanceOf( + iterable, iteratorGetter.enclosingClass); + DartType iteratorType = Substitution.fromPairs( + iteratorGetter.enclosingClass.typeParameters, + castedIterableArguments) .substituteType(iteratorGetter.getterType); if (iteratorType is InterfaceType) { var currentGetter = hierarchy.getInterfaceMember(iteratorType.classNode, currentName); if (currentGetter == null) return const DynamicType(); - var castedIteratorType = hierarchy.getTypeAsInstanceOf( - iteratorType, currentGetter.enclosingClass); - return Substitution.fromInterfaceType(castedIteratorType) + List castedIteratorTypeArguments = + hierarchy.getTypeArgumentsAsInstanceOf( + iteratorType, currentGetter.enclosingClass); + return Substitution.fromPairs( + currentGetter.enclosingClass.typeParameters, + castedIteratorTypeArguments) .substituteType(currentGetter.getterType); } } @@ -928,10 +936,10 @@ class TypeCheckingVisitor DartType getStreamElementType(DartType stream) { if (stream is InterfaceType) { - var asStream = - hierarchy.getTypeAsInstanceOf(stream, coreTypes.streamClass); - if (asStream == null) return const DynamicType(); - return asStream.typeArguments.single; + List asStreamArguments = + hierarchy.getTypeArgumentsAsInstanceOf(stream, coreTypes.streamClass); + if (asStreamArguments == null) return const DynamicType(); + return asStreamArguments.single; } return const DynamicType(); } @@ -1026,13 +1034,13 @@ class TypeCheckingVisitor Class container = currentAsyncMarker == AsyncMarker.AsyncStar ? coreTypes.streamClass : coreTypes.iterableClass; - var type = visitExpression(node.expression); - var asContainer = type is InterfaceType - ? hierarchy.getTypeAsInstanceOf(type, container) + DartType type = visitExpression(node.expression); + List asContainerArguments = type is InterfaceType + ? hierarchy.getTypeArgumentsAsInstanceOf(type, container) : null; - if (asContainer != null) { + if (asContainerArguments != null) { checkAssignable( - node.expression, asContainer.typeArguments[0], currentYieldType); + node.expression, asContainerArguments[0], currentYieldType); } else { fail(node.expression, '$type is not an instance of $container'); } diff --git a/pkg/kernel/lib/type_environment.dart b/pkg/kernel/lib/type_environment.dart index 84f5a8f63ab9..918025446ab5 100644 --- a/pkg/kernel/lib/type_environment.dart +++ b/pkg/kernel/lib/type_environment.dart @@ -83,9 +83,10 @@ abstract class TypeEnvironment extends SubtypeTester { // we aren't concerned with it. If a class implements multiple // instantiations of Future, getTypeAsInstanceOf is responsible for // picking the least one in the sense required by the spec. - InterfaceType future = getTypeAsInstanceOf(type, coreTypes.futureClass); - if (future != null) { - return future.typeArguments[0]; + List futureArguments = + getTypeArgumentsAsInstanceOf(type, coreTypes.futureClass); + if (futureArguments != null) { + return futureArguments[0]; } } return type; @@ -105,13 +106,13 @@ abstract class TypeEnvironment extends SubtypeTester { typeParameterType.promotedBound ?? typeParameterType.parameter.bound; } if (node.isAsync) { - InterfaceType type = - getTypeAsInstanceOf(iterableType, coreTypes.streamClass); - return type.typeArguments.single; + List typeArguments = + getTypeArgumentsAsInstanceOf(iterableType, coreTypes.streamClass); + return typeArguments.single; } else { - InterfaceType type = - getTypeAsInstanceOf(iterableType, coreTypes.iterableClass); - return type.typeArguments.single; + List typeArguments = + getTypeArgumentsAsInstanceOf(iterableType, coreTypes.iterableClass); + return typeArguments.single; } } @@ -375,7 +376,11 @@ abstract class SubtypeTester { static List typeChecks; - InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass); + InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass, + Library clientLibrary, CoreTypes coreTypes); + + List getTypeArgumentsAsInstanceOf( + InterfaceType type, Class superclass); /// Determines if the given type is at the top of the type hierarchy. May be /// overridden in subclasses. @@ -487,13 +492,15 @@ abstract class SubtypeTester { } if (subtype is InterfaceType && supertype is InterfaceType) { - var upcastType = getTypeAsInstanceOf(subtype, supertype.classNode); - if (upcastType == null) return const IsSubtypeOf.never(); + Class supertypeClass = supertype.classNode; + List upcastTypeArguments = + getTypeArgumentsAsInstanceOf(subtype, supertypeClass); + if (upcastTypeArguments == null) return const IsSubtypeOf.never(); IsSubtypeOf result = const IsSubtypeOf.always(); - for (int i = 0; i < upcastType.typeArguments.length; ++i) { + for (int i = 0; i < upcastTypeArguments.length; ++i) { // Termination: the 'supertype' parameter decreases in size. - int variance = upcastType.classNode.typeParameters[i].variance; - DartType leftType = upcastType.typeArguments[i]; + int variance = supertypeClass.typeParameters[i].variance; + DartType leftType = upcastTypeArguments[i]; DartType rightType = supertype.typeArguments[i]; if (variance == Variance.contravariant) { result = result diff --git a/pkg/kernel/test/class_hierarchy_test.dart b/pkg/kernel/test/class_hierarchy_test.dart index d6be1b277033..52c931cf8a9e 100644 --- a/pkg/kernel/test/class_hierarchy_test.dart +++ b/pkg/kernel/test/class_hierarchy_test.dart @@ -1214,9 +1214,10 @@ class B extends self::A {} '''); var b_int = new InterfaceType(b, Nullability.legacy, [int]); - expect(hierarchy.getTypeAsInstanceOf(b_int, a), + expect(hierarchy.getTypeAsInstanceOf(b_int, a, library, coreTypes), new InterfaceType(a, Nullability.legacy, [int, bool])); - expect(hierarchy.getTypeAsInstanceOf(b_int, objectClass), + expect( + hierarchy.getTypeAsInstanceOf(b_int, objectClass, library, coreTypes), new InterfaceType(objectClass, Nullability.legacy)); }