mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 00:09:49 +00:00
[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:
parent
36607d877a
commit
cb3cac408d
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) =>
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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) \
|
||||
|
|
Loading…
Reference in a new issue