[kernel] Add AbstractSuper* nodes

This adds AbstractSuperMethodInvocation, AbstractSuperPropertyGet,
AbstractSuperPropertySet nodes which are to be used for super access
in mixin declaration.

These super accesses do not resolve to their statically bound target
but instead the interface target on the types in the 'on' clauses, and
need to be updated to the statically bound target upon mixin application.
This has lead backends to disregard the interface target provided by
the CFE and instead always compute targets for super accesses.

This change is a step towards creating a clear separation between the
two use cases, enabling a more precise handling of super accesses.

The new nodes are not created yet with this CL.

TEST=existing

Change-Id: I70ea9baf5b4b970b10cc72b7409633d270d57755
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/245168
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Johnni Winther 2022-05-20 09:50:01 +00:00 committed by Commit Bot
parent 36607d877a
commit cb3cac408d
21 changed files with 908 additions and 20 deletions

View file

@ -4779,9 +4779,18 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
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<js_ast.Expression>
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<js_ast.Expression>
}
// 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

View file

@ -3771,10 +3771,23 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
@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);

View file

@ -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;

View file

@ -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);
}

View file

@ -147,7 +147,7 @@ type CanonicalName {
type ComponentFile {
UInt32 magic = 0x90ABCDEF;
UInt32 formatVersion = 80;
UInt32 formatVersion = 81;
Byte[10] shortSdkHash;
List<String> 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;

View file

@ -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<DartType>? receiverArguments = context.typeEnvironment
.getTypeArgumentsAsInstanceOf(context.thisType!, declaringClass);
return Substitution.fromPairs(
declaringClass.typeParameters, receiverArguments!)
.substituteType(interfaceTarget.getterType);
}
@override
R accept<R>(ExpressionVisitor<R> v) => v.visitAbstractSuperPropertyGet(this);
@override
R accept1<R, A>(ExpressionVisitor1<R, A> 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<R>(ExpressionVisitor<R> v) => v.visitAbstractSuperPropertySet(this);
@override
R accept1<R, A>(ExpressionVisitor1<R, A> 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<DartType>? 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<R>(ExpressionVisitor<R> v) =>
v.visitAbstractSuperMethodInvocation(this);
@override
R accept1<R, A>(ExpressionVisitor1<R, A> 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.

View file

@ -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);

View file

@ -1578,6 +1578,23 @@ class BinaryPrinter implements Visitor<void>, 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<void>, 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);

View file

@ -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 {

View file

@ -175,6 +175,18 @@ class CloneVisitorNotMembers implements TreeVisitor<TreeNode> {
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<TreeNode> {
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(

View file

@ -185,12 +185,24 @@ class CoverageVisitor implements Visitor<void> {
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<void> {
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,

View file

@ -185,11 +185,23 @@ class EquivalenceVisitor implements Visitor1<bool, Node> {
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<bool, Node> {
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');

View file

@ -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(),

View file

@ -3009,6 +3009,10 @@ class Precedence implements ExpressionVisitor<int> {
@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<int> {
@override
int visitFunctionTearOff(FunctionTearOff node) => PRIMARY;
@override
int visitAbstractSuperPropertyGet(AbstractSuperPropertyGet node) => PRIMARY;
@override
int visitAbstractSuperPropertySet(AbstractSuperPropertySet node) =>
EXPRESSION;
@override
int visitSuperPropertyGet(SuperPropertyGet node) => PRIMARY;

View file

@ -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;

View file

@ -23,6 +23,10 @@ abstract class ExpressionVisitor<R> {
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<R> {
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<R>
@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<R>
@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, A>
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<R, A>
@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, T> {
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<R, T> {
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) =>

View file

@ -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:

View file

@ -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.

View file

@ -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.

View file

@ -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.

View file

@ -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) \