diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart index e95a0afe84a..506b32d30ae 100644 --- a/pkg/dev_compiler/lib/src/kernel/compiler.dart +++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart @@ -4779,9 +4779,18 @@ class ProgramCompiler extends ComputeOnceConstantVisitor return js.call('#.# = #', [jsReceiver, jsName, jsValue]); } + @override + js_ast.Expression visitAbstractSuperPropertyGet( + AbstractSuperPropertyGet node) { + return _emitSuperPropertyGet(node.interfaceTarget); + } + @override js_ast.Expression visitSuperPropertyGet(SuperPropertyGet node) { - var target = node.interfaceTarget; + return _emitSuperPropertyGet(node.interfaceTarget); + } + + js_ast.Expression _emitSuperPropertyGet(Member target) { if (_reifyTearoff(target)) { if (_superAllowed) { var jsTarget = _emitSuperTarget(target); @@ -4793,11 +4802,20 @@ class ProgramCompiler extends ComputeOnceConstantVisitor return _emitSuperTarget(target); } + @override + js_ast.Expression visitAbstractSuperPropertySet( + AbstractSuperPropertySet node) { + return _emitSuperPropertySet(node.interfaceTarget, node.value); + } + @override js_ast.Expression visitSuperPropertySet(SuperPropertySet node) { - var target = node.interfaceTarget; + return _emitSuperPropertySet(node.interfaceTarget, node.value); + } + + js_ast.Expression _emitSuperPropertySet(Member target, Expression value) { var jsTarget = _emitSuperTarget(target, setter: true); - return _visitExpression(node.value).toAssignExpression(jsTarget); + return _visitExpression(value).toAssignExpression(jsTarget); } @override @@ -5403,11 +5421,21 @@ class ProgramCompiler extends ComputeOnceConstantVisitor } // TODO(jmesserly): optimize super operators for kernel + @override + js_ast.Expression visitAbstractSuperMethodInvocation( + AbstractSuperMethodInvocation node) { + return _emitSuperMethodInvocation(node.interfaceTarget, node.arguments); + } + @override js_ast.Expression visitSuperMethodInvocation(SuperMethodInvocation node) { - var target = node.interfaceTarget; - return js_ast.Call(_emitSuperTarget(target), - _emitArgumentList(node.arguments, target: target)); + return _emitSuperMethodInvocation(node.interfaceTarget, node.arguments); + } + + js_ast.Expression _emitSuperMethodInvocation( + Member target, Arguments arguments) { + return js_ast.Call( + _emitSuperTarget(target), _emitArgumentList(arguments, target: target)); } /// Emits the [js_ast.PropertyAccess] for accessors or method calls to diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart index bd6983c9800..320a50cfe09 100644 --- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart +++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart @@ -3771,10 +3771,23 @@ class ConstantEvaluator implements ExpressionVisitor { @override Constant visitStaticSet(StaticSet node) => defaultExpression(node); + @override + Constant visitAbstractSuperMethodInvocation( + AbstractSuperMethodInvocation node) => + defaultExpression(node); + @override Constant visitSuperMethodInvocation(SuperMethodInvocation node) => defaultExpression(node); + @override + Constant visitAbstractSuperPropertyGet(AbstractSuperPropertyGet node) => + defaultExpression(node); + + @override + Constant visitAbstractSuperPropertySet(AbstractSuperPropertySet node) => + defaultExpression(node); + @override Constant visitSuperPropertyGet(SuperPropertyGet node) => defaultExpression(node); 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 dd68ba0b7cf..71ba7f611a8 100644 --- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart +++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart @@ -1196,6 +1196,8 @@ class InferenceVisitor return new LocalForInVariable(syntheticAssignment); } else if (syntheticAssignment is PropertySet) { return new PropertyForInVariable(syntheticAssignment); + } else if (syntheticAssignment is AbstractSuperPropertySet) { + return new AbstractSuperPropertyForInVariable(syntheticAssignment); } else if (syntheticAssignment is SuperPropertySet) { return new SuperPropertyForInVariable(syntheticAssignment); } else if (syntheticAssignment is StaticSet) { @@ -6148,6 +6150,21 @@ class InferenceVisitor inferenceResult); } + @override + ExpressionInferenceResult visitAbstractSuperMethodInvocation( + AbstractSuperMethodInvocation node, DartType typeContext) { + if (node.interfaceTarget != null) { + inferrer.instrumentation?.record( + inferrer.uriForInstrumentation, + node.fileOffset, + 'target', + new InstrumentationValueForMember(node.interfaceTarget!)); + } + assert(node.interfaceTarget == null || node.interfaceTarget is Procedure); + return inferrer.inferSuperMethodInvocation(node, node.name, + node.arguments as ArgumentsImpl, typeContext, node.interfaceTarget); + } + @override ExpressionInferenceResult visitSuperMethodInvocation( SuperMethodInvocation node, DartType typeContext) { @@ -6159,8 +6176,22 @@ class InferenceVisitor new InstrumentationValueForMember(node.interfaceTarget!)); } assert(node.interfaceTarget == null || node.interfaceTarget is Procedure); - return inferrer.inferSuperMethodInvocation( - node, typeContext, node.interfaceTarget); + return inferrer.inferSuperMethodInvocation(node, node.name, + node.arguments as ArgumentsImpl, typeContext, node.interfaceTarget); + } + + @override + ExpressionInferenceResult visitAbstractSuperPropertyGet( + AbstractSuperPropertyGet node, DartType typeContext) { + if (node.interfaceTarget != null) { + inferrer.instrumentation?.record( + inferrer.uriForInstrumentation, + node.fileOffset, + 'target', + new InstrumentationValueForMember(node.interfaceTarget!)); + } + return inferrer.inferSuperPropertyGet( + node, node.name, typeContext, node.interfaceTarget); } @override @@ -6174,7 +6205,33 @@ class InferenceVisitor new InstrumentationValueForMember(node.interfaceTarget!)); } return inferrer.inferSuperPropertyGet( - node, typeContext, node.interfaceTarget); + node, node.name, typeContext, node.interfaceTarget); + } + + @override + ExpressionInferenceResult visitAbstractSuperPropertySet( + AbstractSuperPropertySet node, DartType typeContext) { + DartType receiverType = inferrer.classHierarchy.getTypeAsInstanceOf( + inferrer.thisType!, + inferrer.thisType!.classNode.supertype!.classNode, + inferrer.libraryBuilder.library)!; + + ObjectAccessTarget writeTarget = node.interfaceTarget != null + ? new ObjectAccessTarget.interfaceMember(node.interfaceTarget!, + isPotentiallyNullable: false) + : const ObjectAccessTarget.missing(); + DartType writeContext = inferrer.getSetterType(writeTarget, receiverType); + if (node.interfaceTarget != null) { + writeContext = inferrer.computeTypeFromSuperClass( + node.interfaceTarget!.enclosingClass!, writeContext); + } + ExpressionInferenceResult rhsResult = inferrer + .inferExpression(node.value, writeContext, true, isVoidAllowed: true); + rhsResult = inferrer.ensureAssignableResult(writeContext, rhsResult, + fileOffset: node.fileOffset, isVoidAllowed: writeContext is VoidType); + Expression rhs = rhsResult.expression; + node.value = rhs..parent = node; + return new ExpressionInferenceResult(rhsResult.inferredType, node); } @override @@ -7158,6 +7215,46 @@ class PropertyForInVariable implements ForInVariable { } } +class AbstractSuperPropertyForInVariable implements ForInVariable { + final AbstractSuperPropertySet superPropertySet; + + DartType? _writeType; + + AbstractSuperPropertyForInVariable(this.superPropertySet); + + @override + DartType computeElementType(TypeInferrerImpl inferrer) { + DartType receiverType = inferrer.thisType!; + ObjectAccessTarget writeTarget = inferrer.findInterfaceMember( + receiverType, superPropertySet.name, superPropertySet.fileOffset, + callSiteAccessKind: CallSiteAccessKind.setterInvocation, + instrumented: true); + if (writeTarget.isInstanceMember || writeTarget.isObjectMember) { + superPropertySet.interfaceTarget = writeTarget.member; + } + return _writeType = inferrer.getSetterType(writeTarget, receiverType); + } + + @override + Expression inferAssignment(TypeInferrerImpl inferrer, DartType rhsType) { + Expression rhs = inferrer.ensureAssignable( + inferrer.computeGreatestClosure(_writeType!), + rhsType, + superPropertySet.value, + errorTemplate: templateForInLoopElementTypeNotAssignable, + nullabilityErrorTemplate: + templateForInLoopElementTypeNotAssignableNullability, + nullabilityPartErrorTemplate: + templateForInLoopElementTypeNotAssignablePartNullability, + isVoidAllowed: true); + superPropertySet.value = rhs..parent = superPropertySet; + ExpressionInferenceResult result = inferrer.inferExpression( + superPropertySet, const UnknownType(), !inferrer.isTopLevel, + isVoidAllowed: true); + return result.expression; + } +} + class SuperPropertyForInVariable implements ForInVariable { final SuperPropertySet superPropertySet; 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 979bf9dd504..bb6d2eee178 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 @@ -4132,16 +4132,16 @@ class TypeInferrerImpl implements TypeInferrer { /// Performs the core type inference algorithm for super method invocations. ExpressionInferenceResult inferSuperMethodInvocation( - SuperMethodInvocation expression, + Expression expression, + Name methodName, + ArgumentsImpl arguments, DartType typeContext, Procedure? procedure) { + int fileOffset = expression.fileOffset; ObjectAccessTarget target = procedure != null ? new ObjectAccessTarget.interfaceMember(procedure, isPotentiallyNullable: false) : const ObjectAccessTarget.missing(); - int fileOffset = expression.fileOffset; - Name methodName = expression.name; - ArgumentsImpl arguments = expression.arguments as ArgumentsImpl; DartType receiverType = thisType!; bool isSpecialCasedBinaryOperator = isSpecialCasedBinaryOperatorForReceiverType(target, receiverType); @@ -4155,7 +4155,7 @@ class TypeInferrerImpl implements TypeInferrer { as FunctionType; } if (isNonNullableByDefault && - expression.name == equalsName && + methodName == equalsName && functionType.positionalParameters.length == 1) { // operator == always allows nullable arguments. functionType = new FunctionType([ @@ -4200,7 +4200,7 @@ class TypeInferrerImpl implements TypeInferrer { /// Performs the core type inference algorithm for super property get. ExpressionInferenceResult inferSuperPropertyGet( - SuperPropertyGet expression, DartType typeContext, Member? member) { + Expression expression, Name name, DartType typeContext, Member? member) { ObjectAccessTarget readTarget = member != null ? new ObjectAccessTarget.interfaceMember(member, isPotentiallyNullable: false) @@ -4215,7 +4215,7 @@ class TypeInferrerImpl implements TypeInferrer { return instantiateTearOff(inferredType, typeContext, expression); } flowAnalysis.thisOrSuperPropertyGet( - expression, expression.name.text, member, inferredType); + expression, name.text, member, inferredType); return new ExpressionInferenceResult(inferredType, expression); } diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md index 63f765a3196..25388c5c9a2 100644 --- a/pkg/kernel/binary.md +++ b/pkg/kernel/binary.md @@ -147,7 +147,7 @@ type CanonicalName { type ComponentFile { UInt32 magic = 0x90ABCDEF; - UInt32 formatVersion = 80; + UInt32 formatVersion = 81; Byte[10] shortSdkHash; List problemsAsJson; // Described in problems.md. Library[] libraries; @@ -598,6 +598,23 @@ type SpecializedVariableSet extends Expression { // Equivalent to VariableSet with index N. } +type AbstractSuperPropertyGet extends Expression { + Byte tag = 22; + FileOffset fileOffset; + Name name; + MemberReference interfaceTarget; // May be NullReference. + MemberReference interfaceTargetOrigin; // May be NullReference. +} + +type AbstractSuperPropertySet extends Expression { + Byte tag = 23; + FileOffset fileOffset; + Name name; + Expression value; + MemberReference interfaceTarget; // May be NullReference. + MemberReference interfaceTargetOrigin; // May be NullReference. +} + type SuperPropertyGet extends Expression { Byte tag = 24; FileOffset fileOffset; @@ -820,6 +837,15 @@ type EqualsCall extends Expression { MemberReference interfaceTargetOrigin; // May be NullReference. } +type AbstractSuperMethodInvocation extends Expression { + Byte tag = 28; + FileOffset fileOffset; + Name name; + Arguments arguments; + MemberReference interfaceTarget; // May be NullReference. + MemberReference interfaceTargetOrigin; // May be NullReference. +} + type SuperMethodInvocation extends Expression { Byte tag = 29; FileOffset fileOffset; diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart index 78972bc8874..5f049a00069 100644 --- a/pkg/kernel/lib/ast.dart +++ b/pkg/kernel/lib/ast.dart @@ -4772,6 +4772,99 @@ class InstanceSet extends Expression { } } +/// Expression of form `super.foo` occurring in a mixin declaration. +/// +/// In this setting, the target is looked up on the types in the mixin 'on' +/// clause and are therefore not necessary the runtime targets of the read. An +/// [AbstractSuperPropertyGet] must be converted into a [SuperPropertyGet] to +/// statically bind the target. +/// +/// For instance +/// +/// abstract class Interface { +/// get getter; +/// } +/// mixin Mixin on Interface { +/// get getter { +/// // This is an [AbstractSuperPropertyGet] with interface target +/// // `Interface.getter`. +/// return super.getter; +/// } +/// } +/// class Super implements Interface { +/// // This is the target when `Mixin` is applied to `Class`. +/// get getter => 42; +/// } +/// class Class extends Super with Mixin {} +/// +/// This may invoke a getter, read a field, or tear off a method. +class AbstractSuperPropertyGet extends Expression { + Name name; + + Reference? interfaceTargetReference; + + AbstractSuperPropertyGet(Name name, [Member? interfaceTarget]) + : this.byReference(name, getMemberReferenceGetter(interfaceTarget)); + + AbstractSuperPropertyGet.byReference( + this.name, this.interfaceTargetReference); + + Member? get interfaceTarget => interfaceTargetReference?.asMember; + + void set interfaceTarget(Member? member) { + interfaceTargetReference = getMemberReferenceGetter(member); + } + + @override + DartType getStaticTypeInternal(StaticTypeContext context) { + Member? interfaceTarget = this.interfaceTarget; + if (interfaceTarget == null) { + // TODO(johnniwinther): SuperPropertyGet without a target should be + // replaced by invalid expressions. + return const DynamicType(); + } + Class declaringClass = interfaceTarget.enclosingClass!; + if (declaringClass.typeParameters.isEmpty) { + return interfaceTarget.getterType; + } + List? receiverArguments = context.typeEnvironment + .getTypeArgumentsAsInstanceOf(context.thisType!, declaringClass); + return Substitution.fromPairs( + declaringClass.typeParameters, receiverArguments!) + .substituteType(interfaceTarget.getterType); + } + + @override + R accept(ExpressionVisitor v) => v.visitAbstractSuperPropertyGet(this); + + @override + R accept1(ExpressionVisitor1 v, A arg) => + v.visitAbstractSuperPropertyGet(this, arg); + + @override + void visitChildren(Visitor v) { + interfaceTarget?.acceptReference(v); + name.accept(v); + } + + @override + void transformChildren(Transformer v) {} + + @override + void transformOrRemoveChildren(RemovingTransformer v) {} + + @override + String toString() { + return "AbstractSuperPropertyGet(${toStringInternal()})"; + } + + @override + void toTextInternal(AstPrinter printer) { + printer.write('super.{abstract}'); + printer.writeInterfaceMemberName(interfaceTargetReference, name); + } +} + /// Expression of form `super.field`. /// /// This may invoke a getter, read a field, or tear off a method. @@ -4841,6 +4934,103 @@ class SuperPropertyGet extends Expression { } } +/// Expression of form `super.foo = x` occurring in a mixin declaration. +/// +/// In this setting, the target is looked up on the types in the mixin 'on' +/// clause and are therefore not necessary the runtime targets of the +/// assignment. An [AbstractSuperPropertySet] must be converted into a +/// [SuperPropertySet] to statically bind the target. +/// +/// For instance +/// +/// abstract class Interface { +/// void set setter(value); +/// } +/// mixin Mixin on Interface { +/// void set setter(value) { +/// // This is an [AbstractSuperPropertySet] with interface target +/// // `Interface.setter`. +/// super.setter = value; +/// } +/// } +/// class Super implements Interface { +/// // This is the target when `Mixin` is applied to `Class`. +/// void set setter(value) {} +/// } +/// class Class extends Super with Mixin {} +/// +/// This may invoke a setter or assign a field. +class AbstractSuperPropertySet extends Expression { + Name name; + Expression value; + + Reference? interfaceTargetReference; + + AbstractSuperPropertySet(Name name, Expression value, Member? interfaceTarget) + : this.byReference( + name, value, getMemberReferenceSetter(interfaceTarget)); + + AbstractSuperPropertySet.byReference( + this.name, this.value, this.interfaceTargetReference) { + value.parent = this; + } + + Member? get interfaceTarget => interfaceTargetReference?.asMember; + + void set interfaceTarget(Member? member) { + interfaceTargetReference = getMemberReferenceSetter(member); + } + + @override + DartType getStaticTypeInternal(StaticTypeContext context) => + value.getStaticType(context); + + @override + R accept(ExpressionVisitor v) => v.visitAbstractSuperPropertySet(this); + + @override + R accept1(ExpressionVisitor1 v, A arg) => + v.visitAbstractSuperPropertySet(this, arg); + + @override + void visitChildren(Visitor v) { + interfaceTarget?.acceptReference(v); + name.accept(v); + value.accept(v); + } + + @override + void transformChildren(Transformer v) { + // ignore: unnecessary_null_comparison + if (value != null) { + value = v.transform(value); + value.parent = this; + } + } + + @override + void transformOrRemoveChildren(RemovingTransformer v) { + // ignore: unnecessary_null_comparison + if (value != null) { + value = v.transform(value); + value.parent = this; + } + } + + @override + String toString() { + return "AbstractSuperPropertySet(${toStringInternal()})"; + } + + @override + void toTextInternal(AstPrinter printer) { + printer.write('super.{abstract}'); + printer.writeInterfaceMemberName(interfaceTargetReference, name); + printer.write(' = '); + printer.writeExpression(value); + } +} + /// Expression of form `super.field = value`. /// /// This may invoke a setter or assign a field. @@ -6158,6 +6348,121 @@ class EqualsCall extends Expression { } } +/// Expression of form `super.foo(x)` occurring in a mixin declaration. +/// +/// In this setting, the target is looked up on the types in the mixin 'on' +/// clause and are therefore not necessary the runtime targets of the +/// invocation. An [AbstractSuperMethodInvocation] must be converted into +/// a [SuperMethodInvocation] to statically bind the target. +/// +/// For instance +/// +/// abstract class Interface { +/// void method(); +/// } +/// mixin Mixin on Interface { +/// void method() { +/// // This is an [AbstractSuperMethodInvocation] with interface target +/// // `Interface.method`. +/// super.method(); // This targets Super.method. +/// } +/// } +/// class Super implements Interface { +/// // This is the target when `Mixin` is applied to `Class`. +/// void method() {} +/// } +/// class Class extends Super with Mixin {} +/// +class AbstractSuperMethodInvocation extends InvocationExpression { + @override + Name name; + + @override + Arguments arguments; + + Reference? interfaceTargetReference; + + AbstractSuperMethodInvocation(Name name, Arguments arguments, + [Procedure? interfaceTarget]) + : this.byReference( + name, + arguments, + // An invocation doesn't refer to the setter. + getMemberReferenceGetter(interfaceTarget)); + + AbstractSuperMethodInvocation.byReference( + this.name, this.arguments, this.interfaceTargetReference) { + arguments.parent = this; + } + + Procedure? get interfaceTarget => interfaceTargetReference?.asProcedure; + + void set interfaceTarget(Procedure? target) { + // An invocation doesn't refer to the setter. + interfaceTargetReference = getMemberReferenceGetter(target); + } + + @override + DartType getStaticTypeInternal(StaticTypeContext context) { + Procedure? interfaceTarget = this.interfaceTarget; + if (interfaceTarget == null) return const DynamicType(); + Class superclass = interfaceTarget.enclosingClass!; + 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); + } + + @override + R accept(ExpressionVisitor v) => + v.visitAbstractSuperMethodInvocation(this); + + @override + R accept1(ExpressionVisitor1 v, A arg) => + v.visitAbstractSuperMethodInvocation(this, arg); + + @override + void visitChildren(Visitor v) { + interfaceTarget?.acceptReference(v); + name.accept(v); + arguments.accept(v); + } + + @override + void transformChildren(Transformer v) { + // ignore: unnecessary_null_comparison + if (arguments != null) { + arguments = v.transform(arguments); + arguments.parent = this; + } + } + + @override + void transformOrRemoveChildren(RemovingTransformer v) { + // ignore: unnecessary_null_comparison + if (arguments != null) { + arguments = v.transform(arguments); + arguments.parent = this; + } + } + + @override + String toString() { + return "AbstractSuperMethodInvocation(${toStringInternal()})"; + } + + @override + void toTextInternal(AstPrinter printer) { + printer.write('super.{abstract}'); + printer.writeInterfaceMemberName(interfaceTargetReference, name); + printer.writeArguments(arguments); + } +} + /// Expression of form `super.foo(x)`. /// /// The provided arguments might not match the parameters of the target. diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart index 9df6792ab5f..d2a39f116b6 100644 --- a/pkg/kernel/lib/binary/ast_from_binary.dart +++ b/pkg/kernel/lib/binary/ast_from_binary.dart @@ -2001,6 +2001,10 @@ class BinaryBuilder { return _readInstanceSet(); case Tag.DynamicSet: return _readDynamicSet(); + case Tag.AbstractSuperPropertyGet: + return _readAbstractSuperPropertyGet(); + case Tag.AbstractSuperPropertySet: + return _readAbstractSuperPropertySet(); case Tag.SuperPropertyGet: return _readSuperPropertyGet(); case Tag.SuperPropertySet: @@ -2033,6 +2037,8 @@ class BinaryBuilder { return _readEqualsNull(); case Tag.EqualsCall: return _readEqualsCall(); + case Tag.AbstractSuperMethodInvocation: + return _readAbstractSuperMethodInvocation(); case Tag.SuperMethodInvocation: return _readSuperMethodInvocation(); case Tag.StaticInvocation: @@ -2209,6 +2215,22 @@ class BinaryBuilder { ..fileOffset = offset; } + Expression _readAbstractSuperPropertyGet() { + int offset = readOffset(); + addTransformerFlag(TransformerFlag.superCalls); + return new AbstractSuperPropertyGet.byReference( + readName(), readNullableInstanceMemberReference()) + ..fileOffset = offset; + } + + Expression _readAbstractSuperPropertySet() { + int offset = readOffset(); + addTransformerFlag(TransformerFlag.superCalls); + return new AbstractSuperPropertySet.byReference( + readName(), readExpression(), readNullableInstanceMemberReference()) + ..fileOffset = offset; + } + Expression _readSuperPropertyGet() { int offset = readOffset(); addTransformerFlag(TransformerFlag.superCalls); @@ -2347,6 +2369,14 @@ class BinaryBuilder { ..fileOffset = offset; } + Expression _readAbstractSuperMethodInvocation() { + int offset = readOffset(); + addTransformerFlag(TransformerFlag.superCalls); + return new AbstractSuperMethodInvocation.byReference( + readName(), readArguments(), readNullableInstanceMemberReference()) + ..fileOffset = offset; + } + Expression _readSuperMethodInvocation() { int offset = readOffset(); addTransformerFlag(TransformerFlag.superCalls); diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart index 1f678e9dda1..dab017c1dba 100644 --- a/pkg/kernel/lib/binary/ast_to_binary.dart +++ b/pkg/kernel/lib/binary/ast_to_binary.dart @@ -1578,6 +1578,23 @@ class BinaryPrinter implements Visitor, BinarySink { writeNonNullInstanceMemberReference(node.interfaceTargetReference); } + @override + void visitAbstractSuperPropertyGet(AbstractSuperPropertyGet node) { + writeByte(Tag.AbstractSuperPropertyGet); + writeOffset(node.fileOffset); + writeName(node.name); + writeNullAllowedInstanceMemberReference(node.interfaceTargetReference); + } + + @override + void visitAbstractSuperPropertySet(AbstractSuperPropertySet node) { + writeByte(Tag.AbstractSuperPropertySet); + writeOffset(node.fileOffset); + writeName(node.name); + writeNode(node.value); + writeNullAllowedInstanceMemberReference(node.interfaceTargetReference); + } + @override void visitSuperPropertyGet(SuperPropertyGet node) { writeByte(Tag.SuperPropertyGet); @@ -1717,6 +1734,15 @@ class BinaryPrinter implements Visitor, BinarySink { writeDartType(node.functionType); } + @override + void visitAbstractSuperMethodInvocation(AbstractSuperMethodInvocation node) { + writeByte(Tag.AbstractSuperMethodInvocation); + writeOffset(node.fileOffset); + writeName(node.name); + writeArgumentsNode(node.arguments); + writeNullAllowedInstanceMemberReference(node.interfaceTargetReference); + } + @override void visitSuperMethodInvocation(SuperMethodInvocation node) { writeByte(Tag.SuperMethodInvocation); diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart index aed4155fed5..b0a13a0214b 100644 --- a/pkg/kernel/lib/binary/tag.dart +++ b/pkg/kernel/lib/binary/tag.dart @@ -37,10 +37,13 @@ class Tag { static const int InvalidExpression = 19; static const int VariableGet = 20; static const int VariableSet = 21; + static const int AbstractSuperPropertyGet = 22; + static const int AbstractSuperPropertySet = 23; static const int SuperPropertyGet = 24; static const int SuperPropertySet = 25; static const int StaticGet = 26; static const int StaticSet = 27; + static const int AbstractSuperMethodInvocation = 28; static const int SuperMethodInvocation = 29; static const int StaticInvocation = 30; static const int ConstructorInvocation = 31; @@ -176,7 +179,7 @@ class Tag { /// Internal version of kernel binary format. /// Bump it when making incompatible changes in kernel binaries. /// Keep in sync with runtime/vm/kernel_binary.h, pkg/kernel/binary.md. - static const int BinaryFormatVersion = 80; + static const int BinaryFormatVersion = 81; } abstract class ConstantTag { diff --git a/pkg/kernel/lib/clone.dart b/pkg/kernel/lib/clone.dart index c69fe096e45..348ff655fc4 100644 --- a/pkg/kernel/lib/clone.dart +++ b/pkg/kernel/lib/clone.dart @@ -175,6 +175,18 @@ class CloneVisitorNotMembers implements TreeVisitor { return new VariableSet(getVariableClone(node.variable)!, clone(node.value)); } + @override + TreeNode visitAbstractSuperPropertyGet(AbstractSuperPropertyGet node) { + return new AbstractSuperPropertyGet.byReference( + node.name, node.interfaceTargetReference); + } + + @override + TreeNode visitAbstractSuperPropertySet(AbstractSuperPropertySet node) { + return new AbstractSuperPropertySet.byReference( + node.name, clone(node.value), node.interfaceTargetReference); + } + @override TreeNode visitSuperPropertyGet(SuperPropertyGet node) { return new SuperPropertyGet.byReference( @@ -197,6 +209,13 @@ class CloneVisitorNotMembers implements TreeVisitor { return new StaticSet.byReference(node.targetReference, clone(node.value)); } + @override + TreeNode visitAbstractSuperMethodInvocation( + AbstractSuperMethodInvocation node) { + return new AbstractSuperMethodInvocation.byReference( + node.name, clone(node.arguments), node.interfaceTargetReference); + } + @override TreeNode visitSuperMethodInvocation(SuperMethodInvocation node) { return new SuperMethodInvocation.byReference( diff --git a/pkg/kernel/lib/src/coverage.dart b/pkg/kernel/lib/src/coverage.dart index 35a56929b5e..553e22f62e1 100644 --- a/pkg/kernel/lib/src/coverage.dart +++ b/pkg/kernel/lib/src/coverage.dart @@ -185,12 +185,24 @@ class CoverageVisitor implements Visitor { node.visitChildren(this); } + @override + void visitAbstractSuperPropertyGet(AbstractSuperPropertyGet node) { + visited.add(ExpressionKind.AbstractSuperPropertyGet); + node.visitChildren(this); + } + @override void visitSuperPropertyGet(SuperPropertyGet node) { visited.add(ExpressionKind.SuperPropertyGet); node.visitChildren(this); } + @override + void visitAbstractSuperPropertySet(AbstractSuperPropertySet node) { + visited.add(ExpressionKind.AbstractSuperPropertySet); + node.visitChildren(this); + } + @override void visitSuperPropertySet(SuperPropertySet node) { visited.add(ExpressionKind.SuperPropertySet); @@ -245,6 +257,12 @@ class CoverageVisitor implements Visitor { node.visitChildren(this); } + @override + void visitAbstractSuperMethodInvocation(AbstractSuperMethodInvocation node) { + visited.add(ExpressionKind.AbstractSuperMethodInvocation); + node.visitChildren(this); + } + @override void visitSuperMethodInvocation(SuperMethodInvocation node) { visited.add(ExpressionKind.SuperMethodInvocation); @@ -1009,6 +1027,9 @@ enum InitializerKind { } enum ExpressionKind { + AbstractSuperMethodInvocation, + AbstractSuperPropertyGet, + AbstractSuperPropertySet, AsExpression, AwaitExpression, BlockExpression, diff --git a/pkg/kernel/lib/src/equivalence.dart b/pkg/kernel/lib/src/equivalence.dart index 840f85bc831..015d0214d28 100644 --- a/pkg/kernel/lib/src/equivalence.dart +++ b/pkg/kernel/lib/src/equivalence.dart @@ -185,11 +185,23 @@ class EquivalenceVisitor implements Visitor1 { return strategy.checkInstanceSet(this, node, other); } + @override + bool visitAbstractSuperPropertyGet( + AbstractSuperPropertyGet node, Node other) { + return strategy.checkAbstractSuperPropertyGet(this, node, other); + } + @override bool visitSuperPropertyGet(SuperPropertyGet node, Node other) { return strategy.checkSuperPropertyGet(this, node, other); } + @override + bool visitAbstractSuperPropertySet( + AbstractSuperPropertySet node, Node other) { + return strategy.checkAbstractSuperPropertySet(this, node, other); + } + @override bool visitSuperPropertySet(SuperPropertySet node, Node other) { return strategy.checkSuperPropertySet(this, node, other); @@ -236,6 +248,12 @@ class EquivalenceVisitor implements Visitor1 { return strategy.checkLocalFunctionInvocation(this, node, other); } + @override + bool visitAbstractSuperMethodInvocation( + AbstractSuperMethodInvocation node, Node other) { + return strategy.checkAbstractSuperMethodInvocation(this, node, other); + } + @override bool visitSuperMethodInvocation(SuperMethodInvocation node, Node other) { return strategy.checkSuperMethodInvocation(this, node, other); @@ -2270,6 +2288,27 @@ class EquivalenceStrategy { return result; } + bool checkAbstractSuperPropertyGet(EquivalenceVisitor visitor, + AbstractSuperPropertyGet? node, Object? other) { + if (identical(node, other)) return true; + if (node is! AbstractSuperPropertyGet) return false; + if (other is! AbstractSuperPropertyGet) return false; + visitor.pushNodeState(node, other); + bool result = true; + if (!checkAbstractSuperPropertyGet_name(visitor, node, other)) { + result = visitor.resultOnInequivalence; + } + if (!checkAbstractSuperPropertyGet_interfaceTargetReference( + visitor, node, other)) { + result = visitor.resultOnInequivalence; + } + if (!checkAbstractSuperPropertyGet_fileOffset(visitor, node, other)) { + result = visitor.resultOnInequivalence; + } + visitor.popState(); + return result; + } + bool checkSuperPropertyGet( EquivalenceVisitor visitor, SuperPropertyGet? node, Object? other) { if (identical(node, other)) return true; @@ -2290,6 +2329,30 @@ class EquivalenceStrategy { return result; } + bool checkAbstractSuperPropertySet(EquivalenceVisitor visitor, + AbstractSuperPropertySet? node, Object? other) { + if (identical(node, other)) return true; + if (node is! AbstractSuperPropertySet) return false; + if (other is! AbstractSuperPropertySet) return false; + visitor.pushNodeState(node, other); + bool result = true; + if (!checkAbstractSuperPropertySet_name(visitor, node, other)) { + result = visitor.resultOnInequivalence; + } + if (!checkAbstractSuperPropertySet_value(visitor, node, other)) { + result = visitor.resultOnInequivalence; + } + if (!checkAbstractSuperPropertySet_interfaceTargetReference( + visitor, node, other)) { + result = visitor.resultOnInequivalence; + } + if (!checkAbstractSuperPropertySet_fileOffset(visitor, node, other)) { + result = visitor.resultOnInequivalence; + } + visitor.popState(); + return result; + } + bool checkSuperPropertySet( EquivalenceVisitor visitor, SuperPropertySet? node, Object? other) { if (identical(node, other)) return true; @@ -2514,6 +2577,30 @@ class EquivalenceStrategy { return result; } + bool checkAbstractSuperMethodInvocation(EquivalenceVisitor visitor, + AbstractSuperMethodInvocation? node, Object? other) { + if (identical(node, other)) return true; + if (node is! AbstractSuperMethodInvocation) return false; + if (other is! AbstractSuperMethodInvocation) return false; + visitor.pushNodeState(node, other); + bool result = true; + if (!checkAbstractSuperMethodInvocation_name(visitor, node, other)) { + result = visitor.resultOnInequivalence; + } + if (!checkAbstractSuperMethodInvocation_arguments(visitor, node, other)) { + result = visitor.resultOnInequivalence; + } + if (!checkAbstractSuperMethodInvocation_interfaceTargetReference( + visitor, node, other)) { + result = visitor.resultOnInequivalence; + } + if (!checkAbstractSuperMethodInvocation_fileOffset(visitor, node, other)) { + result = visitor.resultOnInequivalence; + } + visitor.popState(); + return result; + } + bool checkSuperMethodInvocation( EquivalenceVisitor visitor, SuperMethodInvocation? node, Object? other) { if (identical(node, other)) return true; @@ -5604,6 +5691,24 @@ class EquivalenceStrategy { return checkExpression_fileOffset(visitor, node, other); } + bool checkAbstractSuperPropertyGet_name(EquivalenceVisitor visitor, + AbstractSuperPropertyGet node, AbstractSuperPropertyGet other) { + return visitor.checkNodes(node.name, other.name, 'name'); + } + + bool checkAbstractSuperPropertyGet_interfaceTargetReference( + EquivalenceVisitor visitor, + AbstractSuperPropertyGet node, + AbstractSuperPropertyGet other) { + return visitor.checkReferences(node.interfaceTargetReference, + other.interfaceTargetReference, 'interfaceTargetReference'); + } + + bool checkAbstractSuperPropertyGet_fileOffset(EquivalenceVisitor visitor, + AbstractSuperPropertyGet node, AbstractSuperPropertyGet other) { + return checkExpression_fileOffset(visitor, node, other); + } + bool checkSuperPropertyGet_name(EquivalenceVisitor visitor, SuperPropertyGet node, SuperPropertyGet other) { return visitor.checkNodes(node.name, other.name, 'name'); @@ -5622,6 +5727,29 @@ class EquivalenceStrategy { return checkExpression_fileOffset(visitor, node, other); } + bool checkAbstractSuperPropertySet_name(EquivalenceVisitor visitor, + AbstractSuperPropertySet node, AbstractSuperPropertySet other) { + return visitor.checkNodes(node.name, other.name, 'name'); + } + + bool checkAbstractSuperPropertySet_value(EquivalenceVisitor visitor, + AbstractSuperPropertySet node, AbstractSuperPropertySet other) { + return visitor.checkNodes(node.value, other.value, 'value'); + } + + bool checkAbstractSuperPropertySet_interfaceTargetReference( + EquivalenceVisitor visitor, + AbstractSuperPropertySet node, + AbstractSuperPropertySet other) { + return visitor.checkReferences(node.interfaceTargetReference, + other.interfaceTargetReference, 'interfaceTargetReference'); + } + + bool checkAbstractSuperPropertySet_fileOffset(EquivalenceVisitor visitor, + AbstractSuperPropertySet node, AbstractSuperPropertySet other) { + return checkExpression_fileOffset(visitor, node, other); + } + bool checkSuperPropertySet_name(EquivalenceVisitor visitor, SuperPropertySet node, SuperPropertySet other) { return visitor.checkNodes(node.name, other.name, 'name'); @@ -5853,6 +5981,29 @@ class EquivalenceStrategy { return checkInvocationExpression_fileOffset(visitor, node, other); } + bool checkAbstractSuperMethodInvocation_name(EquivalenceVisitor visitor, + AbstractSuperMethodInvocation node, AbstractSuperMethodInvocation other) { + return visitor.checkNodes(node.name, other.name, 'name'); + } + + bool checkAbstractSuperMethodInvocation_arguments(EquivalenceVisitor visitor, + AbstractSuperMethodInvocation node, AbstractSuperMethodInvocation other) { + return visitor.checkNodes(node.arguments, other.arguments, 'arguments'); + } + + bool checkAbstractSuperMethodInvocation_interfaceTargetReference( + EquivalenceVisitor visitor, + AbstractSuperMethodInvocation node, + AbstractSuperMethodInvocation other) { + return visitor.checkReferences(node.interfaceTargetReference, + other.interfaceTargetReference, 'interfaceTargetReference'); + } + + bool checkAbstractSuperMethodInvocation_fileOffset(EquivalenceVisitor visitor, + AbstractSuperMethodInvocation node, AbstractSuperMethodInvocation other) { + return checkInvocationExpression_fileOffset(visitor, node, other); + } + bool checkSuperMethodInvocation_name(EquivalenceVisitor visitor, SuperMethodInvocation node, SuperMethodInvocation other) { return visitor.checkNodes(node.name, other.name, 'name'); diff --git a/pkg/kernel/lib/src/node_creator.dart b/pkg/kernel/lib/src/node_creator.dart index 8c0337d4cb8..d51a1bb555e 100644 --- a/pkg/kernel/lib/src/node_creator.dart +++ b/pkg/kernel/lib/src/node_creator.dart @@ -859,6 +859,14 @@ class NodeCreator { ]); case ExpressionKind.StringLiteral: return StringLiteral('foo'); + case ExpressionKind.AbstractSuperMethodInvocation: + return _createOneOf(_pendingExpressions, kind, index, [ + () => AbstractSuperMethodInvocation(_createName(), _createArguments()) + ..fileOffset = _needFileOffset(), + () => AbstractSuperMethodInvocation( + _createName(), _createArguments(), _needProcedure()) + ..fileOffset = _needFileOffset(), + ]); case ExpressionKind.SuperMethodInvocation: return _createOneOf(_pendingExpressions, kind, index, [ () => SuperMethodInvocation(_createName(), _createArguments()) @@ -867,6 +875,22 @@ class NodeCreator { _createName(), _createArguments(), _needProcedure()) ..fileOffset = _needFileOffset(), ]); + case ExpressionKind.AbstractSuperPropertyGet: + return _createOneOf(_pendingExpressions, kind, index, [ + () => AbstractSuperPropertyGet(_createName()) + ..fileOffset = _needFileOffset(), + () => AbstractSuperPropertyGet(_createName(), _needField()) + ..fileOffset = _needFileOffset(), + ]); + case ExpressionKind.AbstractSuperPropertySet: + return _createOneOf(_pendingExpressions, kind, index, [ + () => + AbstractSuperPropertySet(_createName(), _createExpression(), null) + ..fileOffset = _needFileOffset(), + () => AbstractSuperPropertySet( + _createName(), _createExpression(), _needField()) + ..fileOffset = _needFileOffset(), + ]); case ExpressionKind.SuperPropertyGet: return _createOneOf(_pendingExpressions, kind, index, [ () => SuperPropertyGet(_createName())..fileOffset = _needFileOffset(), diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart index 542324eb634..722da3d6b0c 100644 --- a/pkg/kernel/lib/text/ast_to_text.dart +++ b/pkg/kernel/lib/text/ast_to_text.dart @@ -3009,6 +3009,10 @@ class Precedence implements ExpressionVisitor { @override int visitEqualsNull(EqualsNull node) => EQUALITY; + @override + int visitAbstractSuperMethodInvocation(AbstractSuperMethodInvocation node) => + CALLEE; + @override int visitSuperMethodInvocation(SuperMethodInvocation node) => CALLEE; @@ -3103,6 +3107,13 @@ class Precedence implements ExpressionVisitor { @override int visitFunctionTearOff(FunctionTearOff node) => PRIMARY; + @override + int visitAbstractSuperPropertyGet(AbstractSuperPropertyGet node) => PRIMARY; + + @override + int visitAbstractSuperPropertySet(AbstractSuperPropertySet node) => + EXPRESSION; + @override int visitSuperPropertyGet(SuperPropertyGet node) => PRIMARY; diff --git a/pkg/kernel/lib/type_checker.dart b/pkg/kernel/lib/type_checker.dart index 293015daef6..6e444994a65 100644 --- a/pkg/kernel/lib/type_checker.dart +++ b/pkg/kernel/lib/type_checker.dart @@ -752,6 +752,19 @@ class TypeCheckingVisitor return environment.coreTypes.stringLegacyRawType; } + @override + DartType visitAbstractSuperMethodInvocation( + AbstractSuperMethodInvocation node) { + Member? target = node.interfaceTarget; + if (target == null) { + checkUnresolvedInvocation(currentThisType!, node); + return handleDynamicCall(currentThisType!, node.arguments); + } else { + return handleCall(node.arguments, target.superGetterType, + receiver: getSuperReceiverType(target)); + } + } + @override DartType visitSuperMethodInvocation(SuperMethodInvocation node) { Member? target = node.interfaceTarget; @@ -764,6 +777,32 @@ class TypeCheckingVisitor } } + @override + DartType visitAbstractSuperPropertyGet(AbstractSuperPropertyGet node) { + Member? target = node.interfaceTarget; + if (target == null) { + checkUnresolvedInvocation(currentThisType!, node); + return const DynamicType(); + } else { + Substitution receiver = getSuperReceiverType(target); + return receiver.substituteType(target.superGetterType); + } + } + + @override + DartType visitAbstractSuperPropertySet(AbstractSuperPropertySet node) { + Member? target = node.interfaceTarget; + DartType value = visitExpression(node.value); + if (target != null) { + Substitution receiver = getSuperReceiverType(target); + checkAssignable(node.value, value, + receiver.substituteType(target.superSetterType, contravariant: true)); + } else { + checkUnresolvedInvocation(currentThisType!, node); + } + return value; + } + @override DartType visitSuperPropertyGet(SuperPropertyGet node) { Member? target = node.interfaceTarget; diff --git a/pkg/kernel/lib/visitor.dart b/pkg/kernel/lib/visitor.dart index d88c2a9dfff..64f3accd32f 100644 --- a/pkg/kernel/lib/visitor.dart +++ b/pkg/kernel/lib/visitor.dart @@ -23,6 +23,10 @@ abstract class ExpressionVisitor { R visitInstanceGet(InstanceGet node) => defaultExpression(node); R visitInstanceSet(InstanceSet node) => defaultExpression(node); R visitInstanceTearOff(InstanceTearOff node) => defaultExpression(node); + R visitAbstractSuperPropertyGet(AbstractSuperPropertyGet node) => + defaultExpression(node); + R visitAbstractSuperPropertySet(AbstractSuperPropertySet node) => + defaultExpression(node); R visitSuperPropertyGet(SuperPropertyGet node) => defaultExpression(node); R visitSuperPropertySet(SuperPropertySet node) => defaultExpression(node); R visitStaticGet(StaticGet node) => defaultExpression(node); @@ -37,6 +41,8 @@ abstract class ExpressionVisitor { defaultExpression(node); R visitEqualsNull(EqualsNull node) => defaultExpression(node); R visitEqualsCall(EqualsCall node) => defaultExpression(node); + R visitAbstractSuperMethodInvocation(AbstractSuperMethodInvocation node) => + defaultExpression(node); R visitSuperMethodInvocation(SuperMethodInvocation node) => defaultExpression(node); R visitStaticInvocation(StaticInvocation node) => defaultExpression(node); @@ -209,6 +215,12 @@ abstract class TreeVisitor @override R visitInstanceTearOff(InstanceTearOff node) => defaultExpression(node); @override + R visitAbstractSuperPropertyGet(AbstractSuperPropertyGet node) => + defaultExpression(node); + @override + R visitAbstractSuperPropertySet(AbstractSuperPropertySet node) => + defaultExpression(node); + @override R visitSuperPropertyGet(SuperPropertyGet node) => defaultExpression(node); @override R visitSuperPropertySet(SuperPropertySet node) => defaultExpression(node); @@ -235,6 +247,9 @@ abstract class TreeVisitor @override R visitEqualsCall(EqualsCall node) => defaultExpression(node); @override + R visitAbstractSuperMethodInvocation(AbstractSuperMethodInvocation node) => + defaultExpression(node); + @override R visitSuperMethodInvocation(SuperMethodInvocation node) => defaultExpression(node); @override @@ -457,6 +472,12 @@ abstract class TreeVisitor1 R visitInstanceTearOff(InstanceTearOff node, A arg) => defaultExpression(node, arg); @override + R visitAbstractSuperPropertyGet(AbstractSuperPropertyGet node, A arg) => + defaultExpression(node, arg); + @override + R visitAbstractSuperPropertySet(AbstractSuperPropertySet node, A arg) => + defaultExpression(node, arg); + @override R visitSuperPropertyGet(SuperPropertyGet node, A arg) => defaultExpression(node, arg); @override @@ -489,6 +510,10 @@ abstract class TreeVisitor1 @override R visitEqualsCall(EqualsCall node, A arg) => defaultExpression(node, arg); @override + R visitAbstractSuperMethodInvocation( + AbstractSuperMethodInvocation node, A arg) => + defaultExpression(node, arg); + @override R visitSuperMethodInvocation(SuperMethodInvocation node, A arg) => defaultExpression(node, arg); @override @@ -1976,6 +2001,10 @@ abstract class ExpressionVisitor1 { R visitInstanceSet(InstanceSet node, T arg) => defaultExpression(node, arg); R visitInstanceTearOff(InstanceTearOff node, T arg) => defaultExpression(node, arg); + R visitAbstractSuperPropertyGet(AbstractSuperPropertyGet node, T arg) => + defaultExpression(node, arg); + R visitAbstractSuperPropertySet(AbstractSuperPropertySet node, T arg) => + defaultExpression(node, arg); R visitSuperPropertyGet(SuperPropertyGet node, T arg) => defaultExpression(node, arg); R visitSuperPropertySet(SuperPropertySet node, T arg) => @@ -1996,6 +2025,9 @@ abstract class ExpressionVisitor1 { defaultExpression(node, arg); R visitEqualsNull(EqualsNull node, T arg) => defaultExpression(node, arg); R visitEqualsCall(EqualsCall node, T arg) => defaultExpression(node, arg); + R visitAbstractSuperMethodInvocation( + AbstractSuperMethodInvocation node, T arg) => + defaultExpression(node, arg); R visitSuperMethodInvocation(SuperMethodInvocation node, T arg) => defaultExpression(node, arg); R visitStaticInvocation(StaticInvocation node, T arg) => diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc index abfc8a7fbb4..a1f6765cfc5 100644 --- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc +++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc @@ -1172,6 +1172,16 @@ Fragment StreamingFlowGraphBuilder::BuildExpression(TokenPosition* position) { return BuildInstanceSet(position); case kDynamicSet: return BuildDynamicSet(position); + case kAbstractSuperPropertyGet: + // Abstract super property getters must be converted into super property + // getters during mixin transformation. + UNREACHABLE(); + break; + case kAbstractSuperPropertySet: + // Abstract super property setters must be converted into super property + // setters during mixin transformation. + UNREACHABLE(); + break; case kSuperPropertyGet: return BuildSuperPropertyGet(position); case kSuperPropertySet: @@ -1192,6 +1202,11 @@ Fragment StreamingFlowGraphBuilder::BuildExpression(TokenPosition* position) { return BuildEqualsCall(position); case kEqualsNull: return BuildEqualsNull(position); + case kAbstractSuperMethodInvocation: + // Abstract super method invocations must be converted into super + // method invocations during mixin transformation. + UNREACHABLE(); + break; case kSuperMethodInvocation: return BuildSuperMethodInvocation(position); case kStaticInvocation: diff --git a/runtime/vm/compiler/frontend/kernel_fingerprints.cc b/runtime/vm/compiler/frontend/kernel_fingerprints.cc index 3a888c48d92..73470298ca8 100644 --- a/runtime/vm/compiler/frontend/kernel_fingerprints.cc +++ b/runtime/vm/compiler/frontend/kernel_fingerprints.cc @@ -412,6 +412,16 @@ void KernelFingerprintHelper::CalculateExpressionFingerprint() { BuildHash(ReadNameAsSetterName().Hash()); // read name. CalculateExpressionFingerprint(); // read value. return; + case kAbstractSuperPropertyGet: + // Abstract super property getters must be converted into super property + // getters during mixin transformation. + UNREACHABLE(); + break; + case kAbstractSuperPropertySet: + // Abstract super property setters must be converted into super property + // setters during mixin transformation. + UNREACHABLE(); + break; case kSuperPropertyGet: ReadPosition(); // read position. BuildHash(ReadNameAsGetterName().Hash()); // read name. @@ -474,6 +484,11 @@ void KernelFingerprintHelper::CalculateExpressionFingerprint() { ReadPosition(); // read position. CalculateExpressionFingerprint(); // read expression. return; + case kAbstractSuperMethodInvocation: + // Abstract super method invocations must be converted into super + // method invocations during mixin transformation. + UNREACHABLE(); + break; case kSuperMethodInvocation: ReadPosition(); // read position. BuildHash(ReadNameAsMethodName().Hash()); // read name. diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc index e3008020158..d52cc58fba7 100644 --- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc +++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc @@ -2420,6 +2420,16 @@ void KernelReaderHelper::SkipExpression() { SkipName(); // read name. SkipExpression(); // read value. return; + case kAbstractSuperPropertyGet: + // Abstract super property getters must be converted into super property + // getters during mixin transformation. + UNREACHABLE(); + break; + case kAbstractSuperPropertySet: + // Abstract super property setters must be converted into super property + // setters during mixin transformation. + UNREACHABLE(); + break; case kSuperPropertyGet: ReadPosition(); // read position. SkipName(); // read name. @@ -2482,6 +2492,11 @@ void KernelReaderHelper::SkipExpression() { ReadPosition(); // read position. SkipExpression(); // read expression. return; + case kAbstractSuperMethodInvocation: + // Abstract super method invocations must be converted into super + // method invocations during mixin transformation. + UNREACHABLE(); + break; case kSuperMethodInvocation: ReadPosition(); // read position. SkipName(); // read name. diff --git a/runtime/vm/compiler/frontend/scope_builder.cc b/runtime/vm/compiler/frontend/scope_builder.cc index 89d7660eee8..32821614cdf 100644 --- a/runtime/vm/compiler/frontend/scope_builder.cc +++ b/runtime/vm/compiler/frontend/scope_builder.cc @@ -748,6 +748,16 @@ void ScopeBuilder::VisitExpression() { helper_.SkipName(); // read name. VisitExpression(); // read value. return; + case kAbstractSuperPropertyGet: + // Abstract super property getters must be converted into super property + // getters during mixin transformation. + UNREACHABLE(); + break; + case kAbstractSuperPropertySet: + // Abstract super property setters must be converted into super property + // setters during mixin transformation. + UNREACHABLE(); + break; case kSuperPropertyGet: HandleLoadReceiver(); helper_.ReadPosition(); // read position. @@ -817,6 +827,11 @@ void ScopeBuilder::VisitExpression() { helper_.ReadPosition(); // read position. VisitExpression(); // read expression. return; + case kAbstractSuperMethodInvocation: + // Abstract super method invocations must be converted into super + // method invocations during mixin transformation. + UNREACHABLE(); + break; case kSuperMethodInvocation: HandleLoadReceiver(); helper_.ReadPosition(); // read position. diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h index 6e6972f3b30..96c196d7147 100644 --- a/runtime/vm/kernel_binary.h +++ b/runtime/vm/kernel_binary.h @@ -20,8 +20,8 @@ namespace kernel { static const uint32_t kMagicProgramFile = 0x90ABCDEFu; // Both version numbers are inclusive. -static const uint32_t kMinSupportedKernelFormatVersion = 80; -static const uint32_t kMaxSupportedKernelFormatVersion = 80; +static const uint32_t kMinSupportedKernelFormatVersion = 81; +static const uint32_t kMaxSupportedKernelFormatVersion = 81; // Keep in sync with package:kernel/lib/binary/tag.dart #define KERNEL_TAG_LIST(V) \ @@ -49,10 +49,13 @@ static const uint32_t kMaxSupportedKernelFormatVersion = 80; V(InvalidExpression, 19) \ V(VariableGet, 20) \ V(VariableSet, 21) \ + V(AbstractSuperPropertyGet, 22) \ + V(AbstractSuperPropertySet, 23) \ V(SuperPropertyGet, 24) \ V(SuperPropertySet, 25) \ V(StaticGet, 26) \ V(StaticSet, 27) \ + V(AbstractSuperMethodInvocation, 28) \ V(SuperMethodInvocation, 29) \ V(StaticInvocation, 30) \ V(ConstructorInvocation, 31) \