[cfe] Make (Abstract)Super*.interfaceTarget non-nullable
This is a step towards improving the semantics of these nodes. TEST=existing Change-Id: I95bdb86790414b38af73e9e932cc228b3c0f1f6e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/249040 Commit-Queue: Johnni Winther <johnniwinther@google.com> Reviewed-by: Alexander Markov <alexmarkov@google.com> Reviewed-by: Jens Johansen <jensj@google.com> Reviewed-by: Joshua Litt <joshualitt@google.com>
This commit is contained in:
committed by
Commit Bot
parent
3c793774c3
commit
391540c889
@@ -1085,22 +1085,14 @@ abstract class StaticTypeVisitor extends StaticTypeBase {
|
||||
ir.DartType visitSuperPropertyGet(ir.SuperPropertyGet node) {
|
||||
ir.DartType resultType;
|
||||
final interfaceTarget = node.interfaceTarget;
|
||||
if (interfaceTarget == null) {
|
||||
// TODO(johnniwinther): Resolve and set the target here.
|
||||
resultType = const ir.DynamicType();
|
||||
ir.Class declaringClass = interfaceTarget.enclosingClass!;
|
||||
if (declaringClass.typeParameters.isEmpty) {
|
||||
resultType = interfaceTarget.superGetterType;
|
||||
} else {
|
||||
ir.Class declaringClass = interfaceTarget.enclosingClass!;
|
||||
if (declaringClass.typeParameters.isEmpty) {
|
||||
resultType = interfaceTarget.superGetterType;
|
||||
} else {
|
||||
ir.InterfaceType receiver = typeEnvironment.getTypeAsInstanceOf(
|
||||
thisType,
|
||||
declaringClass,
|
||||
currentLibrary,
|
||||
typeEnvironment.coreTypes)!;
|
||||
resultType = ir.Substitution.fromInterfaceType(receiver)
|
||||
.substituteType(interfaceTarget.superGetterType);
|
||||
}
|
||||
ir.InterfaceType receiver = typeEnvironment.getTypeAsInstanceOf(
|
||||
thisType, declaringClass, currentLibrary, typeEnvironment.coreTypes)!;
|
||||
resultType = ir.Substitution.fromInterfaceType(receiver)
|
||||
.substituteType(interfaceTarget.superGetterType);
|
||||
}
|
||||
_staticTypeCache._expressionTypes[node] = resultType;
|
||||
handleSuperPropertyGet(node, resultType);
|
||||
@@ -1125,19 +1117,14 @@ abstract class StaticTypeVisitor extends StaticTypeBase {
|
||||
ArgumentTypes argumentTypes = _visitArguments(node.arguments);
|
||||
ir.DartType returnType;
|
||||
final interfaceTarget = node.interfaceTarget;
|
||||
if (interfaceTarget == null) {
|
||||
// TODO(johnniwinther): Resolve and set the target here.
|
||||
returnType = const ir.DynamicType();
|
||||
} else {
|
||||
ir.Class superclass = interfaceTarget.enclosingClass!;
|
||||
ir.InterfaceType receiverType = typeEnvironment.getTypeAsInstanceOf(
|
||||
thisType, superclass, currentLibrary, typeEnvironment.coreTypes)!;
|
||||
returnType = ir.Substitution.fromInterfaceType(receiverType)
|
||||
.substituteType(interfaceTarget.function.returnType);
|
||||
returnType = ir.Substitution.fromPairs(
|
||||
interfaceTarget.function.typeParameters, node.arguments.types)
|
||||
.substituteType(returnType);
|
||||
}
|
||||
ir.Class superclass = interfaceTarget.enclosingClass!;
|
||||
ir.InterfaceType receiverType = typeEnvironment.getTypeAsInstanceOf(
|
||||
thisType, superclass, currentLibrary, typeEnvironment.coreTypes)!;
|
||||
returnType = ir.Substitution.fromInterfaceType(receiverType)
|
||||
.substituteType(interfaceTarget.function.returnType);
|
||||
returnType = ir.Substitution.fromPairs(
|
||||
interfaceTarget.function.typeParameters, node.arguments.types)
|
||||
.substituteType(returnType);
|
||||
_staticTypeCache._expressionTypes[node] = returnType;
|
||||
handleSuperMethodInvocation(node, argumentTypes, returnType);
|
||||
return returnType;
|
||||
|
||||
@@ -287,6 +287,11 @@ ir.Member? getEffectiveSuperTarget(ir.Member? target) {
|
||||
if (target.stubKind == ir.ProcedureStubKind.ConcreteMixinStub) {
|
||||
return getEffectiveSuperTarget(target.stubTarget);
|
||||
}
|
||||
// TODO(johnniwinther): Remove this when the CFE reports an error on
|
||||
// missing concrete super targets.
|
||||
if (target.isAbstract) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
@@ -1137,7 +1137,7 @@ class CodeGenerator extends ExpressionVisitor1<w.ValueType, w.ValueType>
|
||||
w.ValueType visitSuperMethodInvocation(
|
||||
SuperMethodInvocation node, w.ValueType expectedType) {
|
||||
Reference target =
|
||||
_lookupSuperTarget(node.interfaceTarget!, setter: false).reference;
|
||||
_lookupSuperTarget(node.interfaceTarget, setter: false).reference;
|
||||
w.BaseFunction targetFunction = translator.functions.getFunction(target);
|
||||
w.ValueType receiverType = targetFunction.type.inputs.first;
|
||||
w.ValueType thisType = visitThis(receiverType);
|
||||
@@ -1515,7 +1515,7 @@ class CodeGenerator extends ExpressionVisitor1<w.ValueType, w.ValueType>
|
||||
@override
|
||||
w.ValueType visitSuperPropertyGet(
|
||||
SuperPropertyGet node, w.ValueType expectedType) {
|
||||
Member target = _lookupSuperTarget(node.interfaceTarget!, setter: false);
|
||||
Member target = _lookupSuperTarget(node.interfaceTarget, setter: false);
|
||||
if (target is Procedure && !target.isGetter) {
|
||||
throw "Not supported: Super tear-off at ${node.location}";
|
||||
}
|
||||
@@ -1525,7 +1525,7 @@ class CodeGenerator extends ExpressionVisitor1<w.ValueType, w.ValueType>
|
||||
@override
|
||||
w.ValueType visitSuperPropertySet(
|
||||
SuperPropertySet node, w.ValueType expectedType) {
|
||||
Member target = _lookupSuperTarget(node.interfaceTarget!, setter: true);
|
||||
Member target = _lookupSuperTarget(node.interfaceTarget, setter: true);
|
||||
return _directSet(target, ThisExpression(), node.value,
|
||||
preserved: expectedType != voidMarker);
|
||||
}
|
||||
|
||||
@@ -4790,12 +4790,12 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
|
||||
@override
|
||||
js_ast.Expression visitAbstractSuperPropertyGet(
|
||||
AbstractSuperPropertyGet node) {
|
||||
return _emitSuperPropertyGet(node.interfaceTarget!);
|
||||
return _emitSuperPropertyGet(node.interfaceTarget);
|
||||
}
|
||||
|
||||
@override
|
||||
js_ast.Expression visitSuperPropertyGet(SuperPropertyGet node) {
|
||||
return _emitSuperPropertyGet(node.interfaceTarget!);
|
||||
return _emitSuperPropertyGet(node.interfaceTarget);
|
||||
}
|
||||
|
||||
js_ast.Expression _emitSuperPropertyGet(Member target) {
|
||||
@@ -4813,12 +4813,12 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
|
||||
@override
|
||||
js_ast.Expression visitAbstractSuperPropertySet(
|
||||
AbstractSuperPropertySet node) {
|
||||
return _emitSuperPropertySet(node.interfaceTarget!, node.value);
|
||||
return _emitSuperPropertySet(node.interfaceTarget, node.value);
|
||||
}
|
||||
|
||||
@override
|
||||
js_ast.Expression visitSuperPropertySet(SuperPropertySet node) {
|
||||
return _emitSuperPropertySet(node.interfaceTarget!, node.value);
|
||||
return _emitSuperPropertySet(node.interfaceTarget, node.value);
|
||||
}
|
||||
|
||||
js_ast.Expression _emitSuperPropertySet(Member target, Expression value) {
|
||||
@@ -5432,12 +5432,12 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
|
||||
@override
|
||||
js_ast.Expression visitAbstractSuperMethodInvocation(
|
||||
AbstractSuperMethodInvocation node) {
|
||||
return _emitSuperMethodInvocation(node.interfaceTarget!, node.arguments);
|
||||
return _emitSuperMethodInvocation(node.interfaceTarget, node.arguments);
|
||||
}
|
||||
|
||||
@override
|
||||
js_ast.Expression visitSuperMethodInvocation(SuperMethodInvocation node) {
|
||||
return _emitSuperMethodInvocation(node.interfaceTarget!, node.arguments);
|
||||
return _emitSuperMethodInvocation(node.interfaceTarget, node.arguments);
|
||||
}
|
||||
|
||||
js_ast.Expression _emitSuperMethodInvocation(
|
||||
|
||||
@@ -836,11 +836,13 @@ class SuperPropertyAccessGenerator extends Generator {
|
||||
}
|
||||
|
||||
Expression _createRead() {
|
||||
Member? getter = this.getter;
|
||||
if (getter == null) {
|
||||
return _helper.buildUnresolvedError(name.text, fileOffset,
|
||||
isSuper: true, kind: UnresolvedKind.Getter);
|
||||
} else {
|
||||
return new SuperPropertyGet(name, getter)..fileOffset = fileOffset;
|
||||
}
|
||||
return new SuperPropertyGet(name, getter)..fileOffset = fileOffset;
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -849,13 +851,13 @@ class SuperPropertyAccessGenerator extends Generator {
|
||||
}
|
||||
|
||||
Expression _createWrite(int offset, Expression value) {
|
||||
Member? setter = this.setter;
|
||||
if (setter == null) {
|
||||
return _helper.buildUnresolvedError(name.text, fileOffset,
|
||||
rhs: value, isSuper: true, kind: UnresolvedKind.Setter);
|
||||
} else {
|
||||
return new SuperPropertySet(name, value, setter)..fileOffset = offset;
|
||||
}
|
||||
SuperPropertySet write = new SuperPropertySet(name, value, setter)
|
||||
..fileOffset = offset;
|
||||
return write;
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -1227,6 +1229,7 @@ class SuperIndexedAccessGenerator extends Generator {
|
||||
|
||||
@override
|
||||
Expression buildSimpleRead() {
|
||||
Procedure? getter = this.getter;
|
||||
if (getter == null) {
|
||||
return _helper.buildUnresolvedError(indexGetName.text, fileOffset,
|
||||
isSuper: true,
|
||||
@@ -1234,33 +1237,36 @@ class SuperIndexedAccessGenerator extends Generator {
|
||||
_helper.forest.createArguments(fileOffset, <Expression>[index]),
|
||||
kind: UnresolvedKind.Method,
|
||||
length: noLength);
|
||||
} else {
|
||||
return _helper.forest.createSuperMethodInvocation(
|
||||
fileOffset,
|
||||
indexGetName,
|
||||
getter,
|
||||
_helper.forest.createArguments(fileOffset, <Expression>[index]));
|
||||
}
|
||||
return _helper.forest.createSuperMethodInvocation(
|
||||
fileOffset,
|
||||
indexGetName,
|
||||
getter,
|
||||
_helper.forest.createArguments(fileOffset, <Expression>[index]));
|
||||
}
|
||||
|
||||
@override
|
||||
Expression buildAssignment(Expression value, {bool voidContext: false}) {
|
||||
if (voidContext) {
|
||||
if (setter == null) {
|
||||
return _helper.buildUnresolvedError(indexSetName.text, fileOffset,
|
||||
isSuper: true,
|
||||
arguments: _helper.forest
|
||||
.createArguments(fileOffset, <Expression>[index, value]),
|
||||
kind: UnresolvedKind.Method,
|
||||
length: noLength);
|
||||
}
|
||||
return _helper.forest.createSuperMethodInvocation(
|
||||
fileOffset,
|
||||
indexSetName,
|
||||
setter,
|
||||
_helper.forest
|
||||
.createArguments(fileOffset, <Expression>[index, value]));
|
||||
Procedure? setter = this.setter;
|
||||
if (setter == null) {
|
||||
return _helper.buildUnresolvedError(indexSetName.text, fileOffset,
|
||||
isSuper: true,
|
||||
arguments: _helper.forest
|
||||
.createArguments(fileOffset, <Expression>[index, value]),
|
||||
kind: UnresolvedKind.Method,
|
||||
length: noLength);
|
||||
} else {
|
||||
return new SuperIndexSet(setter, index, value)..fileOffset = fileOffset;
|
||||
if (voidContext) {
|
||||
return _helper.forest.createSuperMethodInvocation(
|
||||
fileOffset,
|
||||
indexSetName,
|
||||
setter,
|
||||
_helper.forest
|
||||
.createArguments(fileOffset, <Expression>[index, value]));
|
||||
} else {
|
||||
return new SuperIndexSet(setter, index, value)..fileOffset = fileOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1281,13 +1287,20 @@ class SuperIndexedAccessGenerator extends Generator {
|
||||
bool voidContext: false,
|
||||
bool isPreIncDec: false,
|
||||
bool isPostIncDec: false}) {
|
||||
return new CompoundSuperIndexSet(
|
||||
getter, setter, index, binaryOperator, value,
|
||||
readOffset: fileOffset,
|
||||
binaryOffset: offset,
|
||||
writeOffset: fileOffset,
|
||||
forEffect: voidContext,
|
||||
forPostIncDec: isPostIncDec);
|
||||
Procedure? getter = this.getter;
|
||||
Procedure? setter = this.setter;
|
||||
if (getter == null || setter == null) {
|
||||
return buildAssignment(
|
||||
buildBinaryOperation(token, binaryOperator, value));
|
||||
} else {
|
||||
return new CompoundSuperIndexSet(
|
||||
getter, setter, index, binaryOperator, value,
|
||||
readOffset: fileOffset,
|
||||
binaryOffset: offset,
|
||||
writeOffset: fileOffset,
|
||||
forEffect: voidContext,
|
||||
forPostIncDec: isPostIncDec);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -752,7 +752,7 @@ class Forest {
|
||||
}
|
||||
|
||||
SuperMethodInvocation createSuperMethodInvocation(
|
||||
int fileOffset, Name name, Procedure? procedure, Arguments arguments) {
|
||||
int fileOffset, Name name, Procedure procedure, Arguments arguments) {
|
||||
// ignore: unnecessary_null_comparison
|
||||
assert(fileOffset != null);
|
||||
return new SuperMethodInvocation(name, arguments, procedure)
|
||||
|
||||
@@ -2682,7 +2682,7 @@ class IndexSet extends InternalExpression {
|
||||
///
|
||||
class SuperIndexSet extends InternalExpression {
|
||||
/// The []= member.
|
||||
Member? setter;
|
||||
Member setter;
|
||||
|
||||
/// The index expression of the operation.
|
||||
Expression index;
|
||||
@@ -3707,10 +3707,10 @@ class NullAwareIfNullSet extends InternalExpression {
|
||||
///
|
||||
class CompoundSuperIndexSet extends InternalExpression {
|
||||
/// The [] member.
|
||||
Member? getter;
|
||||
Member getter;
|
||||
|
||||
/// The []= member.
|
||||
Member? setter;
|
||||
Member setter;
|
||||
|
||||
/// The index expression of the operation.
|
||||
Expression index;
|
||||
|
||||
@@ -3521,10 +3521,9 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
|
||||
ExpressionInferenceResult visitSuperIndexSet(
|
||||
SuperIndexSet node, DartType typeContext) {
|
||||
ObjectAccessTarget indexSetTarget = node.setter != null
|
||||
? new ObjectAccessTarget.interfaceMember(node.setter!,
|
||||
isPotentiallyNullable: false)
|
||||
: const ObjectAccessTarget.missing();
|
||||
ObjectAccessTarget indexSetTarget = new ObjectAccessTarget.interfaceMember(
|
||||
node.setter,
|
||||
isPotentiallyNullable: false);
|
||||
|
||||
DartType indexType = getIndexKeyType(indexSetTarget, thisType!);
|
||||
DartType valueType = getIndexSetValueType(indexSetTarget, thisType!);
|
||||
@@ -3560,20 +3559,16 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
// the type of the value parameter.
|
||||
DartType inferredType = valueResult.inferredType;
|
||||
|
||||
Expression assignment;
|
||||
if (indexSetTarget.isMissing) {
|
||||
assignment = createMissingSuperIndexSet(node.fileOffset, index, value);
|
||||
} else {
|
||||
assert(indexSetTarget.isInstanceMember || indexSetTarget.isObjectMember);
|
||||
instrumentation?.record(uriForInstrumentation, node.fileOffset, 'target',
|
||||
new InstrumentationValueForMember(node.setter!));
|
||||
assignment = new SuperMethodInvocation(
|
||||
indexSetName,
|
||||
new Arguments(<Expression>[index, value])
|
||||
..fileOffset = node.fileOffset,
|
||||
indexSetTarget.member as Procedure)
|
||||
..fileOffset = node.fileOffset;
|
||||
}
|
||||
assert(indexSetTarget.isInstanceMember || indexSetTarget.isObjectMember,
|
||||
'Unexpected index set target $indexSetTarget.');
|
||||
instrumentation?.record(uriForInstrumentation, node.fileOffset, 'target',
|
||||
new InstrumentationValueForMember(node.setter));
|
||||
Expression assignment = new SuperMethodInvocation(
|
||||
indexSetName,
|
||||
new Arguments(<Expression>[index, value])..fileOffset = node.fileOffset,
|
||||
indexSetTarget.member as Procedure)
|
||||
..fileOffset = node.fileOffset;
|
||||
|
||||
VariableDeclaration assignmentVariable =
|
||||
createVariable(assignment, const VoidType());
|
||||
Expression replacement = createLet(assignmentVariable, returnedValue);
|
||||
@@ -3886,23 +3881,17 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
writeIndex =
|
||||
ensureAssignable(writeIndexType, indexResult.inferredType, writeIndex);
|
||||
|
||||
Expression read;
|
||||
|
||||
if (readTarget.isMissing) {
|
||||
read = createMissingSuperIndexGet(node.readOffset, readIndex);
|
||||
} else {
|
||||
assert(readTarget.isInstanceMember || readTarget.isObjectMember);
|
||||
instrumentation?.record(uriForInstrumentation, node.readOffset, 'target',
|
||||
new InstrumentationValueForMember(node.getter!));
|
||||
read = new SuperMethodInvocation(
|
||||
indexGetName,
|
||||
new Arguments(<Expression>[
|
||||
readIndex,
|
||||
])
|
||||
..fileOffset = node.readOffset,
|
||||
readTarget.member as Procedure)
|
||||
..fileOffset = node.readOffset;
|
||||
}
|
||||
assert(readTarget.isInstanceMember || readTarget.isObjectMember);
|
||||
instrumentation?.record(uriForInstrumentation, node.readOffset, 'target',
|
||||
new InstrumentationValueForMember(node.getter!));
|
||||
Expression read = new SuperMethodInvocation(
|
||||
indexGetName,
|
||||
new Arguments(<Expression>[
|
||||
readIndex,
|
||||
])
|
||||
..fileOffset = node.readOffset,
|
||||
readTarget.member as Procedure)
|
||||
..fileOffset = node.readOffset;
|
||||
|
||||
flowAnalysis.ifNullExpression_rightBegin(read, readType);
|
||||
ExpressionInferenceResult valueResult =
|
||||
@@ -3927,21 +3916,15 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
returnedValue = createVariableGet(valueVariable);
|
||||
}
|
||||
|
||||
Expression write;
|
||||
|
||||
if (writeTarget.isMissing) {
|
||||
write = createMissingSuperIndexSet(node.writeOffset, writeIndex, value);
|
||||
} else {
|
||||
assert(writeTarget.isInstanceMember || writeTarget.isObjectMember);
|
||||
instrumentation?.record(uriForInstrumentation, node.writeOffset, 'target',
|
||||
new InstrumentationValueForMember(node.setter!));
|
||||
write = new SuperMethodInvocation(
|
||||
indexSetName,
|
||||
new Arguments(<Expression>[writeIndex, value])
|
||||
..fileOffset = node.writeOffset,
|
||||
writeTarget.member as Procedure)
|
||||
..fileOffset = node.writeOffset;
|
||||
}
|
||||
assert(writeTarget.isInstanceMember || writeTarget.isObjectMember);
|
||||
instrumentation?.record(uriForInstrumentation, node.writeOffset, 'target',
|
||||
new InstrumentationValueForMember(node.setter!));
|
||||
Expression write = new SuperMethodInvocation(
|
||||
indexSetName,
|
||||
new Arguments(<Expression>[writeIndex, value])
|
||||
..fileOffset = node.writeOffset,
|
||||
writeTarget.member as Procedure)
|
||||
..fileOffset = node.writeOffset;
|
||||
|
||||
Expression replacement;
|
||||
if (node.forEffect) {
|
||||
@@ -5387,10 +5370,9 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
|
||||
ExpressionInferenceResult visitCompoundSuperIndexSet(
|
||||
CompoundSuperIndexSet node, DartType typeContext) {
|
||||
ObjectAccessTarget readTarget = node.getter != null
|
||||
? new ObjectAccessTarget.interfaceMember(node.getter!,
|
||||
isPotentiallyNullable: false)
|
||||
: const ObjectAccessTarget.missing();
|
||||
ObjectAccessTarget readTarget = new ObjectAccessTarget.interfaceMember(
|
||||
node.getter,
|
||||
isPotentiallyNullable: false);
|
||||
|
||||
DartType readType = getReturnType(readTarget, thisType!);
|
||||
DartType readIndexType = getIndexKeyType(readTarget, thisType!);
|
||||
@@ -5412,22 +5394,17 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
readIndex =
|
||||
ensureAssignable(readIndexType, indexResult.inferredType, readIndex);
|
||||
|
||||
Expression read;
|
||||
if (readTarget.isMissing) {
|
||||
read = createMissingSuperIndexGet(node.readOffset, readIndex);
|
||||
} else {
|
||||
assert(readTarget.isInstanceMember || readTarget.isObjectMember);
|
||||
instrumentation?.record(uriForInstrumentation, node.readOffset, 'target',
|
||||
new InstrumentationValueForMember(node.getter!));
|
||||
read = new SuperMethodInvocation(
|
||||
indexGetName,
|
||||
new Arguments(<Expression>[
|
||||
readIndex,
|
||||
])
|
||||
..fileOffset = node.readOffset,
|
||||
readTarget.member as Procedure)
|
||||
..fileOffset = node.readOffset;
|
||||
}
|
||||
assert(readTarget.isInstanceMember || readTarget.isObjectMember);
|
||||
instrumentation?.record(uriForInstrumentation, node.readOffset, 'target',
|
||||
new InstrumentationValueForMember(node.getter));
|
||||
Expression read = new SuperMethodInvocation(
|
||||
indexGetName,
|
||||
new Arguments(<Expression>[
|
||||
readIndex,
|
||||
])
|
||||
..fileOffset = node.readOffset,
|
||||
readTarget.member as Procedure)
|
||||
..fileOffset = node.readOffset;
|
||||
|
||||
VariableDeclaration? leftVariable;
|
||||
Expression left;
|
||||
@@ -5439,10 +5416,9 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
} else {
|
||||
left = read;
|
||||
}
|
||||
ObjectAccessTarget writeTarget = node.setter != null
|
||||
? new ObjectAccessTarget.interfaceMember(node.setter!,
|
||||
isPotentiallyNullable: false)
|
||||
: const ObjectAccessTarget.missing();
|
||||
ObjectAccessTarget writeTarget = new ObjectAccessTarget.interfaceMember(
|
||||
node.setter,
|
||||
isPotentiallyNullable: false);
|
||||
|
||||
DartType writeIndexType = getIndexKeyType(writeTarget, thisType!);
|
||||
|
||||
@@ -5474,21 +5450,15 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
valueExpression = createVariableGet(valueVariable);
|
||||
}
|
||||
|
||||
Expression write;
|
||||
if (writeTarget.isMissing) {
|
||||
write = createMissingSuperIndexSet(
|
||||
node.writeOffset, writeIndex, valueExpression);
|
||||
} else {
|
||||
assert(writeTarget.isInstanceMember || writeTarget.isObjectMember);
|
||||
instrumentation?.record(uriForInstrumentation, node.writeOffset, 'target',
|
||||
new InstrumentationValueForMember(node.setter!));
|
||||
write = new SuperMethodInvocation(
|
||||
indexSetName,
|
||||
new Arguments(<Expression>[writeIndex, valueExpression])
|
||||
..fileOffset = node.writeOffset,
|
||||
writeTarget.member as Procedure)
|
||||
..fileOffset = node.writeOffset;
|
||||
}
|
||||
assert(writeTarget.isInstanceMember || writeTarget.isObjectMember);
|
||||
instrumentation?.record(uriForInstrumentation, node.writeOffset, 'target',
|
||||
new InstrumentationValueForMember(node.setter));
|
||||
Expression write = new SuperMethodInvocation(
|
||||
indexSetName,
|
||||
new Arguments(<Expression>[writeIndex, valueExpression])
|
||||
..fileOffset = node.writeOffset,
|
||||
writeTarget.member as Procedure)
|
||||
..fileOffset = node.writeOffset;
|
||||
|
||||
Expression replacement;
|
||||
if (node.forEffect) {
|
||||
@@ -6145,11 +6115,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
@override
|
||||
ExpressionInferenceResult visitAbstractSuperMethodInvocation(
|
||||
AbstractSuperMethodInvocation node, DartType typeContext) {
|
||||
if (node.interfaceTarget != null) {
|
||||
instrumentation?.record(uriForInstrumentation, node.fileOffset, 'target',
|
||||
new InstrumentationValueForMember(node.interfaceTarget!));
|
||||
}
|
||||
assert(node.interfaceTarget == null || node.interfaceTarget is Procedure);
|
||||
instrumentation?.record(uriForInstrumentation, node.fileOffset, 'target',
|
||||
new InstrumentationValueForMember(node.interfaceTarget));
|
||||
return inferSuperMethodInvocation(this, node, node.name,
|
||||
node.arguments as ArgumentsImpl, typeContext, node.interfaceTarget);
|
||||
}
|
||||
@@ -6157,11 +6124,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
@override
|
||||
ExpressionInferenceResult visitSuperMethodInvocation(
|
||||
SuperMethodInvocation node, DartType typeContext) {
|
||||
if (node.interfaceTarget != null) {
|
||||
instrumentation?.record(uriForInstrumentation, node.fileOffset, 'target',
|
||||
new InstrumentationValueForMember(node.interfaceTarget!));
|
||||
}
|
||||
assert(node.interfaceTarget == null || node.interfaceTarget is Procedure);
|
||||
instrumentation?.record(uriForInstrumentation, node.fileOffset, 'target',
|
||||
new InstrumentationValueForMember(node.interfaceTarget));
|
||||
return inferSuperMethodInvocation(this, node, node.name,
|
||||
node.arguments as ArgumentsImpl, typeContext, node.interfaceTarget);
|
||||
}
|
||||
@@ -6169,10 +6133,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
@override
|
||||
ExpressionInferenceResult visitAbstractSuperPropertyGet(
|
||||
AbstractSuperPropertyGet node, DartType typeContext) {
|
||||
if (node.interfaceTarget != null) {
|
||||
instrumentation?.record(uriForInstrumentation, node.fileOffset, 'target',
|
||||
new InstrumentationValueForMember(node.interfaceTarget!));
|
||||
}
|
||||
instrumentation?.record(uriForInstrumentation, node.fileOffset, 'target',
|
||||
new InstrumentationValueForMember(node.interfaceTarget));
|
||||
return inferSuperPropertyGet(
|
||||
node, node.name, typeContext, node.interfaceTarget);
|
||||
}
|
||||
@@ -6180,10 +6142,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
@override
|
||||
ExpressionInferenceResult visitSuperPropertyGet(
|
||||
SuperPropertyGet node, DartType typeContext) {
|
||||
if (node.interfaceTarget != null) {
|
||||
instrumentation?.record(uriForInstrumentation, node.fileOffset, 'target',
|
||||
new InstrumentationValueForMember(node.interfaceTarget!));
|
||||
}
|
||||
instrumentation?.record(uriForInstrumentation, node.fileOffset, 'target',
|
||||
new InstrumentationValueForMember(node.interfaceTarget));
|
||||
return inferSuperPropertyGet(
|
||||
node, node.name, typeContext, node.interfaceTarget);
|
||||
}
|
||||
@@ -6194,15 +6154,12 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
DartType receiverType = classHierarchy.getTypeAsInstanceOf(thisType!,
|
||||
thisType!.classNode.supertype!.classNode, libraryBuilder.library)!;
|
||||
|
||||
ObjectAccessTarget writeTarget = node.interfaceTarget != null
|
||||
? new ObjectAccessTarget.interfaceMember(node.interfaceTarget!,
|
||||
isPotentiallyNullable: false)
|
||||
: const ObjectAccessTarget.missing();
|
||||
ObjectAccessTarget writeTarget = new ObjectAccessTarget.interfaceMember(
|
||||
node.interfaceTarget,
|
||||
isPotentiallyNullable: false);
|
||||
DartType writeContext = getSetterType(writeTarget, receiverType);
|
||||
if (node.interfaceTarget != null) {
|
||||
writeContext = computeTypeFromSuperClass(
|
||||
node.interfaceTarget!.enclosingClass!, writeContext);
|
||||
}
|
||||
writeContext = computeTypeFromSuperClass(
|
||||
node.interfaceTarget.enclosingClass!, writeContext);
|
||||
ExpressionInferenceResult rhsResult =
|
||||
inferExpression(node.value, writeContext, true, isVoidAllowed: true);
|
||||
rhsResult = ensureAssignableResult(writeContext, rhsResult,
|
||||
@@ -6218,15 +6175,12 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||
DartType receiverType = classHierarchy.getTypeAsInstanceOf(thisType!,
|
||||
thisType!.classNode.supertype!.classNode, libraryBuilder.library)!;
|
||||
|
||||
ObjectAccessTarget writeTarget = node.interfaceTarget != null
|
||||
? new ObjectAccessTarget.interfaceMember(node.interfaceTarget!,
|
||||
isPotentiallyNullable: false)
|
||||
: const ObjectAccessTarget.missing();
|
||||
ObjectAccessTarget writeTarget = new ObjectAccessTarget.interfaceMember(
|
||||
node.interfaceTarget,
|
||||
isPotentiallyNullable: false);
|
||||
DartType writeContext = getSetterType(writeTarget, receiverType);
|
||||
if (node.interfaceTarget != null) {
|
||||
writeContext = computeTypeFromSuperClass(
|
||||
node.interfaceTarget!.enclosingClass!, writeContext);
|
||||
}
|
||||
writeContext = computeTypeFromSuperClass(
|
||||
node.interfaceTarget.enclosingClass!, writeContext);
|
||||
ExpressionInferenceResult rhsResult =
|
||||
inferExpression(node.value, writeContext, true, isVoidAllowed: true);
|
||||
rhsResult = ensureAssignableResult(writeContext, rhsResult,
|
||||
@@ -7167,9 +7121,7 @@ class AbstractSuperPropertyForInVariable implements ForInVariable {
|
||||
receiverType, superPropertySet.name, superPropertySet.fileOffset,
|
||||
callSiteAccessKind: CallSiteAccessKind.setterInvocation,
|
||||
instrumented: true);
|
||||
if (writeTarget.isInstanceMember || writeTarget.isObjectMember) {
|
||||
superPropertySet.interfaceTarget = writeTarget.member;
|
||||
}
|
||||
assert(writeTarget.isInstanceMember || writeTarget.isObjectMember);
|
||||
return _writeType = visitor.getSetterType(writeTarget, receiverType);
|
||||
}
|
||||
|
||||
@@ -7207,9 +7159,7 @@ class SuperPropertyForInVariable implements ForInVariable {
|
||||
receiverType, superPropertySet.name, superPropertySet.fileOffset,
|
||||
callSiteAccessKind: CallSiteAccessKind.setterInvocation,
|
||||
instrumented: true);
|
||||
if (writeTarget.isInstanceMember || writeTarget.isObjectMember) {
|
||||
superPropertySet.interfaceTarget = writeTarget.member;
|
||||
}
|
||||
assert(writeTarget.isInstanceMember || writeTarget.isObjectMember);
|
||||
return _writeType = visitor.getSetterType(writeTarget, receiverType);
|
||||
}
|
||||
|
||||
|
||||
@@ -4500,35 +4500,6 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
|
||||
return false;
|
||||
}
|
||||
|
||||
Expression createMissingSuperIndexGet(int fileOffset, Expression index) {
|
||||
if (isTopLevel) {
|
||||
return engine.forest.createSuperMethodInvocation(fileOffset, indexGetName,
|
||||
null, engine.forest.createArguments(fileOffset, <Expression>[index]));
|
||||
} else {
|
||||
return helper.buildProblem(
|
||||
templateSuperclassHasNoMethod.withArguments(indexGetName.text),
|
||||
fileOffset,
|
||||
noLength);
|
||||
}
|
||||
}
|
||||
|
||||
Expression createMissingSuperIndexSet(
|
||||
int fileOffset, Expression index, Expression value) {
|
||||
if (isTopLevel) {
|
||||
return engine.forest.createSuperMethodInvocation(
|
||||
fileOffset,
|
||||
indexSetName,
|
||||
null,
|
||||
engine.forest
|
||||
.createArguments(fileOffset, <Expression>[index, value]));
|
||||
} else {
|
||||
return helper.buildProblem(
|
||||
templateSuperclassHasNoMethod.withArguments(indexSetName.text),
|
||||
fileOffset,
|
||||
noLength);
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates an expression the represents the invalid invocation of [name] on
|
||||
/// [receiver] with [arguments].
|
||||
///
|
||||
|
||||
@@ -197,7 +197,7 @@ class InvocationVisitor extends RecursiveVisitor {
|
||||
@override
|
||||
void visitSuperMethodInvocation(SuperMethodInvocation node) {
|
||||
super.visitSuperMethodInvocation(node);
|
||||
note(node.interfaceTargetReference!.node!, node.arguments, node);
|
||||
note(node.interfaceTargetReference.node!, node.arguments, node);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
class Super {
|
||||
void method() {}
|
||||
int property = 42;
|
||||
}
|
||||
|
||||
mixin Mixin on Super {
|
||||
void method() {
|
||||
super.method();
|
||||
}
|
||||
|
||||
int get property {
|
||||
return super.property;
|
||||
}
|
||||
|
||||
void set property(int value) {
|
||||
super.property = value;
|
||||
}
|
||||
}
|
||||
|
||||
class Class1 extends Super with Mixin {}
|
||||
|
||||
class Class2 with Mixin implements Super {}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
class Super {
|
||||
void method() {}
|
||||
int property = 42;
|
||||
}
|
||||
|
||||
mixin Mixin on Super {
|
||||
void method() {}
|
||||
int get property {}
|
||||
void set property(int value) {}
|
||||
}
|
||||
|
||||
class Class1 extends Super with Mixin {}
|
||||
|
||||
class Class2 with Mixin implements Super {}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
class Class1 extends Super with Mixin {}
|
||||
|
||||
class Class2 with Mixin implements Super {}
|
||||
|
||||
class Super {
|
||||
int property = 42;
|
||||
void method() {}
|
||||
}
|
||||
|
||||
mixin Mixin on Super {
|
||||
int get property {}
|
||||
void method() {}
|
||||
void set property(int value) {}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
library /*isNonNullableByDefault*/;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/general/abstract_super_application.dart:26:7: Error: 'Object' doesn't implement 'Super' so it can't be used with 'Mixin'.
|
||||
// - 'Object' is from 'dart:core'.
|
||||
// - 'Super' is from 'pkg/front_end/testcases/general/abstract_super_application.dart'.
|
||||
// - 'Mixin' is from 'pkg/front_end/testcases/general/abstract_super_application.dart'.
|
||||
// class Class2 with Mixin implements Super {}
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
class Super extends core::Object {
|
||||
field core::int property = 42;
|
||||
synthetic constructor •() → self::Super
|
||||
: super core::Object::•()
|
||||
;
|
||||
method method() → void {}
|
||||
}
|
||||
abstract class Mixin extends self::Super /*isMixinDeclaration*/ {
|
||||
method method() → void {
|
||||
super.{self::Super::method}();
|
||||
}
|
||||
get property() → core::int {
|
||||
return super.{self::Super::property};
|
||||
}
|
||||
set property(core::int value) → void {
|
||||
super.{self::Super::property} = value;
|
||||
}
|
||||
}
|
||||
abstract class _Class1&Super&Mixin = self::Super with self::Mixin /*isAnonymousMixin*/ {
|
||||
synthetic constructor •() → self::_Class1&Super&Mixin
|
||||
: super self::Super::•()
|
||||
;
|
||||
mixin-super-stub get property() → core::int
|
||||
return super.{self::Mixin::property};
|
||||
mixin-super-stub set property(core::int value) → void
|
||||
return super.{self::Mixin::property} = value;
|
||||
mixin-super-stub method method() → void
|
||||
return super.{self::Mixin::method}();
|
||||
}
|
||||
class Class1 extends self::_Class1&Super&Mixin {
|
||||
synthetic constructor •() → self::Class1
|
||||
: super self::_Class1&Super&Mixin::•()
|
||||
;
|
||||
}
|
||||
abstract class _Class2&Object&Mixin = core::Object with self::Mixin /*isAnonymousMixin,hasConstConstructor*/ {
|
||||
const synthetic constructor •() → self::_Class2&Object&Mixin
|
||||
: super core::Object::•()
|
||||
;
|
||||
mixin-super-stub get property() → core::int
|
||||
return super.{self::Mixin::property};
|
||||
mixin-super-stub set property(core::int value) → void
|
||||
return super.{self::Mixin::property} = value;
|
||||
mixin-super-stub method method() → void
|
||||
return super.{self::Mixin::method}();
|
||||
}
|
||||
class Class2 extends self::_Class2&Object&Mixin implements self::Super {
|
||||
synthetic constructor •() → self::Class2
|
||||
: super self::_Class2&Object&Mixin::•()
|
||||
;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
library /*isNonNullableByDefault*/;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/general/abstract_super_application.dart:26:7: Error: 'Object' doesn't implement 'Super' so it can't be used with 'Mixin'.
|
||||
// - 'Object' is from 'dart:core'.
|
||||
// - 'Super' is from 'pkg/front_end/testcases/general/abstract_super_application.dart'.
|
||||
// - 'Mixin' is from 'pkg/front_end/testcases/general/abstract_super_application.dart'.
|
||||
// class Class2 with Mixin implements Super {}
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
class Super extends core::Object {
|
||||
field core::int property = 42;
|
||||
synthetic constructor •() → self::Super
|
||||
: super core::Object::•()
|
||||
;
|
||||
method method() → void {}
|
||||
}
|
||||
abstract class Mixin extends self::Super /*isMixinDeclaration*/ {
|
||||
method method() → void {
|
||||
super.{self::Super::method}();
|
||||
}
|
||||
get property() → core::int {
|
||||
return super.{self::Super::property};
|
||||
}
|
||||
set property(core::int value) → void {
|
||||
super.{self::Super::property} = value;
|
||||
}
|
||||
}
|
||||
abstract class _Class1&Super&Mixin = self::Super with self::Mixin /*isAnonymousMixin*/ {
|
||||
synthetic constructor •() → self::_Class1&Super&Mixin
|
||||
: super self::Super::•()
|
||||
;
|
||||
mixin-super-stub get property() → core::int
|
||||
return super.{self::Mixin::property};
|
||||
mixin-super-stub set property(core::int value) → void
|
||||
return super.{self::Mixin::property} = value;
|
||||
mixin-super-stub method method() → void
|
||||
return super.{self::Mixin::method}();
|
||||
}
|
||||
class Class1 extends self::_Class1&Super&Mixin {
|
||||
synthetic constructor •() → self::Class1
|
||||
: super self::_Class1&Super&Mixin::•()
|
||||
;
|
||||
}
|
||||
abstract class _Class2&Object&Mixin = core::Object with self::Mixin /*isAnonymousMixin,hasConstConstructor*/ {
|
||||
const synthetic constructor •() → self::_Class2&Object&Mixin
|
||||
: super core::Object::•()
|
||||
;
|
||||
mixin-super-stub get property() → core::int
|
||||
return super.{self::Mixin::property};
|
||||
mixin-super-stub set property(core::int value) → void
|
||||
return super.{self::Mixin::property} = value;
|
||||
mixin-super-stub method method() → void
|
||||
return super.{self::Mixin::method}();
|
||||
}
|
||||
class Class2 extends self::_Class2&Object&Mixin implements self::Super {
|
||||
synthetic constructor •() → self::Class2
|
||||
: super self::_Class2&Object&Mixin::•()
|
||||
;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
library /*isNonNullableByDefault*/;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/general/abstract_super_application.dart:26:7: Error: 'Object' doesn't implement 'Super' so it can't be used with 'Mixin'.
|
||||
// - 'Object' is from 'dart:core'.
|
||||
// - 'Super' is from 'pkg/front_end/testcases/general/abstract_super_application.dart'.
|
||||
// - 'Mixin' is from 'pkg/front_end/testcases/general/abstract_super_application.dart'.
|
||||
// class Class2 with Mixin implements Super {}
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
class Super extends core::Object {
|
||||
field core::int property;
|
||||
synthetic constructor •() → self::Super
|
||||
;
|
||||
method method() → void
|
||||
;
|
||||
}
|
||||
abstract class Mixin extends self::Super /*isMixinDeclaration*/ {
|
||||
method method() → void
|
||||
;
|
||||
get property() → core::int
|
||||
;
|
||||
set property(core::int value) → void
|
||||
;
|
||||
}
|
||||
abstract class _Class1&Super&Mixin = self::Super with self::Mixin /*isAnonymousMixin*/ {
|
||||
synthetic constructor •() → self::_Class1&Super&Mixin
|
||||
: super self::Super::•()
|
||||
;
|
||||
mixin-super-stub get property() → core::int
|
||||
return super.{self::Mixin::property};
|
||||
mixin-super-stub set property(core::int value) → void
|
||||
return super.{self::Mixin::property} = value;
|
||||
mixin-super-stub method method() → void
|
||||
return super.{self::Mixin::method}();
|
||||
}
|
||||
class Class1 extends self::_Class1&Super&Mixin {
|
||||
synthetic constructor •() → self::Class1
|
||||
;
|
||||
}
|
||||
abstract class _Class2&Object&Mixin = core::Object with self::Mixin /*isAnonymousMixin,hasConstConstructor*/ {
|
||||
const synthetic constructor •() → self::_Class2&Object&Mixin
|
||||
: super core::Object::•()
|
||||
;
|
||||
mixin-super-stub get property() → core::int
|
||||
return super.{self::Mixin::property};
|
||||
mixin-super-stub set property(core::int value) → void
|
||||
return super.{self::Mixin::property} = value;
|
||||
mixin-super-stub method method() → void
|
||||
return super.{self::Mixin::method}();
|
||||
}
|
||||
class Class2 extends self::_Class2&Object&Mixin implements self::Super {
|
||||
synthetic constructor •() → self::Class2
|
||||
;
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
library /*isNonNullableByDefault*/;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/general/abstract_super_application.dart:26:7: Error: 'Object' doesn't implement 'Super' so it can't be used with 'Mixin'.
|
||||
// - 'Object' is from 'dart:core'.
|
||||
// - 'Super' is from 'pkg/front_end/testcases/general/abstract_super_application.dart'.
|
||||
// - 'Mixin' is from 'pkg/front_end/testcases/general/abstract_super_application.dart'.
|
||||
// class Class2 with Mixin implements Super {}
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
class Super extends core::Object {
|
||||
field core::int property = 42;
|
||||
synthetic constructor •() → self::Super
|
||||
: super core::Object::•()
|
||||
;
|
||||
method method() → void {}
|
||||
}
|
||||
abstract class Mixin extends self::Super /*isMixinDeclaration*/ {
|
||||
method method() → void {
|
||||
super.{self::Super::method}();
|
||||
}
|
||||
get property() → core::int {
|
||||
return super.{self::Super::property};
|
||||
}
|
||||
set property(core::int value) → void {
|
||||
super.{self::Super::property} = value;
|
||||
}
|
||||
}
|
||||
abstract class _Class1&Super&Mixin extends self::Super implements self::Mixin /*isAnonymousMixin,isEliminatedMixin*/ {
|
||||
synthetic constructor •() → self::_Class1&Super&Mixin
|
||||
: super self::Super::•()
|
||||
;
|
||||
get property() → core::int {
|
||||
return super.{self::Super::property};
|
||||
}
|
||||
set property(core::int value) → void {
|
||||
super.{self::Super::property} = value;
|
||||
}
|
||||
method method() → void {
|
||||
super.{self::Super::method}();
|
||||
}
|
||||
}
|
||||
class Class1 extends self::_Class1&Super&Mixin {
|
||||
synthetic constructor •() → self::Class1
|
||||
: super self::_Class1&Super&Mixin::•()
|
||||
;
|
||||
}
|
||||
abstract class _Class2&Object&Mixin extends core::Object implements self::Mixin /*isAnonymousMixin,isEliminatedMixin,hasConstConstructor*/ {
|
||||
const synthetic constructor •() → self::_Class2&Object&Mixin
|
||||
: super core::Object::•()
|
||||
;
|
||||
get property() → core::int {
|
||||
return super.{self::Super::property};
|
||||
}
|
||||
set property(core::int value) → void {
|
||||
super.{self::Super::property} = value;
|
||||
}
|
||||
method method() → void {
|
||||
super.{self::Super::method}();
|
||||
}
|
||||
}
|
||||
class Class2 extends self::_Class2&Object&Mixin implements self::Super {
|
||||
synthetic constructor •() → self::Class2
|
||||
: super self::_Class2&Object&Mixin::•()
|
||||
;
|
||||
}
|
||||
@@ -13,7 +13,7 @@ class C {
|
||||
var /*@type=dynamic*/ v2 = super.bar;
|
||||
var /*@type=dynamic*/ v3 = super[0];
|
||||
var /*@type=dynamic*/ v4 = super.bar = /*@typeArgs=dynamic*/ f();*/
|
||||
var /*@type=dynamic*/ v5 = super[0] = /*@typeArgs=dynamic*/ f();
|
||||
var /*@type=invalid-type*/ v5 = super[0] = f();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@ library test;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/inference/unresolved_super.dart:16:37: Error: Superclass has no method named '[]='.
|
||||
// var /*@type=dynamic*/ v5 = super[0] = /*@typeArgs=dynamic*/ f();
|
||||
// ^
|
||||
// pkg/front_end/testcases/inference/unresolved_super.dart:16:42: Error: Superclass has no method named '[]='.
|
||||
// var /*@type=invalid-type*/ v5 = super[0] = f();
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
@@ -14,9 +14,9 @@ class C extends core::Object {
|
||||
: super core::Object::•()
|
||||
;
|
||||
method test() → void {
|
||||
dynamic v5 = let final core::int* #t1 = 0 in let final dynamic #t2 = self::f<dynamic>() in let final void #t3 = invalid-expression "pkg/front_end/testcases/inference/unresolved_super.dart:16:37: Error: Superclass has no method named '[]='.
|
||||
var /*@type=dynamic*/ v5 = super[0] = /*@typeArgs=dynamic*/ f();
|
||||
^" in #t2;
|
||||
invalid-type v5 = invalid-expression "pkg/front_end/testcases/inference/unresolved_super.dart:16:42: Error: Superclass has no method named '[]='.
|
||||
var /*@type=invalid-type*/ v5 = super[0] = f();
|
||||
^";
|
||||
}
|
||||
abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
|
||||
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
|
||||
|
||||
@@ -2,9 +2,9 @@ library test;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/inference/unresolved_super.dart:16:37: Error: Superclass has no method named '[]='.
|
||||
// var /*@type=dynamic*/ v5 = super[0] = /*@typeArgs=dynamic*/ f();
|
||||
// ^
|
||||
// pkg/front_end/testcases/inference/unresolved_super.dart:16:42: Error: Superclass has no method named '[]='.
|
||||
// var /*@type=invalid-type*/ v5 = super[0] = f();
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
@@ -14,9 +14,9 @@ class C extends core::Object {
|
||||
: super core::Object::•()
|
||||
;
|
||||
method test() → void {
|
||||
dynamic v5 = let final core::int* #t1 = 0 in let final dynamic #t2 = self::f<dynamic>() in let final void #t3 = invalid-expression "pkg/front_end/testcases/inference/unresolved_super.dart:16:37: Error: Superclass has no method named '[]='.
|
||||
var /*@type=dynamic*/ v5 = super[0] = /*@typeArgs=dynamic*/ f();
|
||||
^" in #t2;
|
||||
invalid-type v5 = invalid-expression "pkg/front_end/testcases/inference/unresolved_super.dart:16:42: Error: Superclass has no method named '[]='.
|
||||
var /*@type=invalid-type*/ v5 = super[0] = f();
|
||||
^";
|
||||
}
|
||||
abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
|
||||
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
|
||||
|
||||
@@ -2,9 +2,9 @@ library test;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/inference/unresolved_super.dart:16:37: Error: Superclass has no method named '[]='.
|
||||
// var /*@type=dynamic*/ v5 = super[0] = /*@typeArgs=dynamic*/ f();
|
||||
// ^
|
||||
// pkg/front_end/testcases/inference/unresolved_super.dart:16:42: Error: Superclass has no method named '[]='.
|
||||
// var /*@type=invalid-type*/ v5 = super[0] = f();
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
@@ -14,9 +14,9 @@ class C extends core::Object {
|
||||
: super core::Object::•()
|
||||
;
|
||||
method test() → void {
|
||||
dynamic v5 = let final core::int* #t1 = 0 in let final dynamic #t2 = self::f<dynamic>() in let final void #t3 = invalid-expression "pkg/front_end/testcases/inference/unresolved_super.dart:16:37: Error: Superclass has no method named '[]='.
|
||||
var /*@type=dynamic*/ v5 = super[0] = /*@typeArgs=dynamic*/ f();
|
||||
^" in #t2;
|
||||
invalid-type v5 = invalid-expression "pkg/front_end/testcases/inference/unresolved_super.dart:16:42: Error: Superclass has no method named '[]='.
|
||||
var /*@type=invalid-type*/ v5 = super[0] = f();
|
||||
^";
|
||||
}
|
||||
abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
|
||||
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
|
||||
|
||||
@@ -6,10 +6,6 @@ library /*isNonNullableByDefault*/;
|
||||
// super[4] = 42;
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/unresolved_recovery.dart:9:17: Error: Superclass has no method named '[]'.
|
||||
// return super[2];
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/unresolved_recovery.dart:8:10: Error: Superclass has no method named '[]'.
|
||||
// super[4] += 5;
|
||||
// ^
|
||||
@@ -18,6 +14,10 @@ library /*isNonNullableByDefault*/;
|
||||
// super[4] += 5;
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/unresolved_recovery.dart:9:17: Error: Superclass has no method named '[]'.
|
||||
// return super[2];
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/unresolved_recovery.dart:20:3: Error: 'on' isn't a type.
|
||||
// on Exception catch (e) { }
|
||||
// ^^
|
||||
@@ -54,7 +54,7 @@ class E extends core::Object {
|
||||
invalid-expression "pkg/front_end/testcases/rasta/unresolved_recovery.dart:7:10: Error: Superclass has no method named '[]='.
|
||||
super[4] = 42;
|
||||
^";
|
||||
let final core::int #t1 = 4 in invalid-expression "pkg/front_end/testcases/rasta/unresolved_recovery.dart:8:10: Error: Superclass has no method named '[]='.
|
||||
invalid-expression "pkg/front_end/testcases/rasta/unresolved_recovery.dart:8:10: Error: Superclass has no method named '[]='.
|
||||
super[4] += 5;
|
||||
^";
|
||||
return invalid-expression "pkg/front_end/testcases/rasta/unresolved_recovery.dart:9:17: Error: Superclass has no method named '[]'.
|
||||
|
||||
@@ -6,10 +6,6 @@ library /*isNonNullableByDefault*/;
|
||||
// super[4] = 42;
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/unresolved_recovery.dart:9:17: Error: Superclass has no method named '[]'.
|
||||
// return super[2];
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/unresolved_recovery.dart:8:10: Error: Superclass has no method named '[]'.
|
||||
// super[4] += 5;
|
||||
// ^
|
||||
@@ -18,6 +14,10 @@ library /*isNonNullableByDefault*/;
|
||||
// super[4] += 5;
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/unresolved_recovery.dart:9:17: Error: Superclass has no method named '[]'.
|
||||
// return super[2];
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/unresolved_recovery.dart:20:3: Error: 'on' isn't a type.
|
||||
// on Exception catch (e) { }
|
||||
// ^^
|
||||
@@ -54,7 +54,7 @@ class E extends core::Object {
|
||||
invalid-expression "pkg/front_end/testcases/rasta/unresolved_recovery.dart:7:10: Error: Superclass has no method named '[]='.
|
||||
super[4] = 42;
|
||||
^";
|
||||
let final core::int #t1 = 4 in invalid-expression "pkg/front_end/testcases/rasta/unresolved_recovery.dart:8:10: Error: Superclass has no method named '[]='.
|
||||
invalid-expression "pkg/front_end/testcases/rasta/unresolved_recovery.dart:8:10: Error: Superclass has no method named '[]='.
|
||||
super[4] += 5;
|
||||
^";
|
||||
return invalid-expression "pkg/front_end/testcases/rasta/unresolved_recovery.dart:9:17: Error: Superclass has no method named '[]'.
|
||||
|
||||
@@ -6,10 +6,6 @@ library /*isNonNullableByDefault*/;
|
||||
// super[4] = 42;
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/unresolved_recovery.dart:9:17: Error: Superclass has no method named '[]'.
|
||||
// return super[2];
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/unresolved_recovery.dart:8:10: Error: Superclass has no method named '[]'.
|
||||
// super[4] += 5;
|
||||
// ^
|
||||
@@ -18,6 +14,10 @@ library /*isNonNullableByDefault*/;
|
||||
// super[4] += 5;
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/unresolved_recovery.dart:9:17: Error: Superclass has no method named '[]'.
|
||||
// return super[2];
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/unresolved_recovery.dart:20:3: Error: 'on' isn't a type.
|
||||
// on Exception catch (e) { }
|
||||
// ^^
|
||||
@@ -54,7 +54,7 @@ class E extends core::Object {
|
||||
invalid-expression "pkg/front_end/testcases/rasta/unresolved_recovery.dart:7:10: Error: Superclass has no method named '[]='.
|
||||
super[4] = 42;
|
||||
^";
|
||||
let final core::int #t1 = 4 in invalid-expression "pkg/front_end/testcases/rasta/unresolved_recovery.dart:8:10: Error: Superclass has no method named '[]='.
|
||||
invalid-expression "pkg/front_end/testcases/rasta/unresolved_recovery.dart:8:10: Error: Superclass has no method named '[]='.
|
||||
super[4] += 5;
|
||||
^";
|
||||
return invalid-expression "pkg/front_end/testcases/rasta/unresolved_recovery.dart:9:17: Error: Superclass has no method named '[]'.
|
||||
|
||||
+12
-12
@@ -602,8 +602,8 @@ type AbstractSuperPropertyGet extends Expression {
|
||||
Byte tag = 22;
|
||||
FileOffset fileOffset;
|
||||
Name name;
|
||||
MemberReference interfaceTarget; // May be NullReference.
|
||||
MemberReference interfaceTargetOrigin; // May be NullReference.
|
||||
MemberReference interfaceTarget;
|
||||
MemberReference interfaceTargetOrigin;
|
||||
}
|
||||
|
||||
type AbstractSuperPropertySet extends Expression {
|
||||
@@ -611,16 +611,16 @@ type AbstractSuperPropertySet extends Expression {
|
||||
FileOffset fileOffset;
|
||||
Name name;
|
||||
Expression value;
|
||||
MemberReference interfaceTarget; // May be NullReference.
|
||||
MemberReference interfaceTargetOrigin; // May be NullReference.
|
||||
MemberReference interfaceTarget;
|
||||
MemberReference interfaceTargetOrigin;
|
||||
}
|
||||
|
||||
type SuperPropertyGet extends Expression {
|
||||
Byte tag = 24;
|
||||
FileOffset fileOffset;
|
||||
Name name;
|
||||
MemberReference interfaceTarget; // May be NullReference.
|
||||
MemberReference interfaceTargetOrigin; // May be NullReference.
|
||||
MemberReference interfaceTarget;
|
||||
MemberReference interfaceTargetOrigin;
|
||||
}
|
||||
|
||||
type SuperPropertySet extends Expression {
|
||||
@@ -628,8 +628,8 @@ type SuperPropertySet extends Expression {
|
||||
FileOffset fileOffset;
|
||||
Name name;
|
||||
Expression value;
|
||||
MemberReference interfaceTarget; // May be NullReference.
|
||||
MemberReference interfaceTargetOrigin; // May be NullReference.
|
||||
MemberReference interfaceTarget;
|
||||
MemberReference interfaceTargetOrigin;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -842,8 +842,8 @@ type AbstractSuperMethodInvocation extends Expression {
|
||||
FileOffset fileOffset;
|
||||
Name name;
|
||||
Arguments arguments;
|
||||
MemberReference interfaceTarget; // May be NullReference.
|
||||
MemberReference interfaceTargetOrigin; // May be NullReference.
|
||||
MemberReference interfaceTarget;
|
||||
MemberReference interfaceTargetOrigin;
|
||||
}
|
||||
|
||||
type SuperMethodInvocation extends Expression {
|
||||
@@ -851,8 +851,8 @@ type SuperMethodInvocation extends Expression {
|
||||
FileOffset fileOffset;
|
||||
Name name;
|
||||
Arguments arguments;
|
||||
MemberReference interfaceTarget; // May be NullReference.
|
||||
MemberReference interfaceTargetOrigin; // May be NullReference.
|
||||
MemberReference interfaceTarget;
|
||||
MemberReference interfaceTargetOrigin;
|
||||
}
|
||||
|
||||
type StaticInvocation extends Expression {
|
||||
|
||||
+46
-60
@@ -4827,28 +4827,23 @@ class InstanceSet extends Expression {
|
||||
class AbstractSuperPropertyGet extends Expression {
|
||||
Name name;
|
||||
|
||||
Reference? interfaceTargetReference;
|
||||
Reference interfaceTargetReference;
|
||||
|
||||
AbstractSuperPropertyGet(Name name, [Member? interfaceTarget])
|
||||
: this.byReference(name, getMemberReferenceGetter(interfaceTarget));
|
||||
AbstractSuperPropertyGet(Name name, Member interfaceTarget)
|
||||
: this.byReference(
|
||||
name, getNonNullableMemberReferenceGetter(interfaceTarget));
|
||||
|
||||
AbstractSuperPropertyGet.byReference(
|
||||
this.name, this.interfaceTargetReference);
|
||||
|
||||
Member? get interfaceTarget => interfaceTargetReference?.asMember;
|
||||
Member get interfaceTarget => interfaceTargetReference.asMember;
|
||||
|
||||
void set interfaceTarget(Member? member) {
|
||||
interfaceTargetReference = getMemberReferenceGetter(member);
|
||||
void set interfaceTarget(Member member) {
|
||||
interfaceTargetReference = getNonNullableMemberReferenceGetter(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;
|
||||
@@ -4869,7 +4864,7 @@ class AbstractSuperPropertyGet extends Expression {
|
||||
|
||||
@override
|
||||
void visitChildren(Visitor v) {
|
||||
interfaceTarget?.acceptReference(v);
|
||||
interfaceTarget.acceptReference(v);
|
||||
name.accept(v);
|
||||
}
|
||||
|
||||
@@ -4897,27 +4892,22 @@ class AbstractSuperPropertyGet extends Expression {
|
||||
class SuperPropertyGet extends Expression {
|
||||
Name name;
|
||||
|
||||
Reference? interfaceTargetReference;
|
||||
Reference interfaceTargetReference;
|
||||
|
||||
SuperPropertyGet(Name name, [Member? interfaceTarget])
|
||||
: this.byReference(name, getMemberReferenceGetter(interfaceTarget));
|
||||
SuperPropertyGet(Name name, Member interfaceTarget)
|
||||
: this.byReference(
|
||||
name, getNonNullableMemberReferenceGetter(interfaceTarget));
|
||||
|
||||
SuperPropertyGet.byReference(this.name, this.interfaceTargetReference);
|
||||
|
||||
Member? get interfaceTarget => interfaceTargetReference?.asMember;
|
||||
Member get interfaceTarget => interfaceTargetReference.asMember;
|
||||
|
||||
void set interfaceTarget(Member? member) {
|
||||
interfaceTargetReference = getMemberReferenceGetter(member);
|
||||
void set interfaceTarget(Member member) {
|
||||
interfaceTargetReference = getNonNullableMemberReferenceGetter(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;
|
||||
@@ -4938,7 +4928,7 @@ class SuperPropertyGet extends Expression {
|
||||
|
||||
@override
|
||||
void visitChildren(Visitor v) {
|
||||
interfaceTarget?.acceptReference(v);
|
||||
interfaceTarget.acceptReference(v);
|
||||
name.accept(v);
|
||||
}
|
||||
|
||||
@@ -4990,21 +4980,21 @@ class AbstractSuperPropertySet extends Expression {
|
||||
Name name;
|
||||
Expression value;
|
||||
|
||||
Reference? interfaceTargetReference;
|
||||
Reference interfaceTargetReference;
|
||||
|
||||
AbstractSuperPropertySet(Name name, Expression value, Member? interfaceTarget)
|
||||
AbstractSuperPropertySet(Name name, Expression value, Member interfaceTarget)
|
||||
: this.byReference(
|
||||
name, value, getMemberReferenceSetter(interfaceTarget));
|
||||
name, value, getNonNullableMemberReferenceSetter(interfaceTarget));
|
||||
|
||||
AbstractSuperPropertySet.byReference(
|
||||
this.name, this.value, this.interfaceTargetReference) {
|
||||
value.parent = this;
|
||||
}
|
||||
|
||||
Member? get interfaceTarget => interfaceTargetReference?.asMember;
|
||||
Member get interfaceTarget => interfaceTargetReference.asMember;
|
||||
|
||||
void set interfaceTarget(Member? member) {
|
||||
interfaceTargetReference = getMemberReferenceSetter(member);
|
||||
void set interfaceTarget(Member member) {
|
||||
interfaceTargetReference = getNonNullableMemberReferenceSetter(member);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -5020,7 +5010,7 @@ class AbstractSuperPropertySet extends Expression {
|
||||
|
||||
@override
|
||||
void visitChildren(Visitor v) {
|
||||
interfaceTarget?.acceptReference(v);
|
||||
interfaceTarget.acceptReference(v);
|
||||
name.accept(v);
|
||||
value.accept(v);
|
||||
}
|
||||
@@ -5066,21 +5056,21 @@ class SuperPropertySet extends Expression {
|
||||
Name name;
|
||||
Expression value;
|
||||
|
||||
Reference? interfaceTargetReference;
|
||||
Reference interfaceTargetReference;
|
||||
|
||||
SuperPropertySet(Name name, Expression value, Member? interfaceTarget)
|
||||
SuperPropertySet(Name name, Expression value, Member interfaceTarget)
|
||||
: this.byReference(
|
||||
name, value, getMemberReferenceSetter(interfaceTarget));
|
||||
name, value, getNonNullableMemberReferenceSetter(interfaceTarget));
|
||||
|
||||
SuperPropertySet.byReference(
|
||||
this.name, this.value, this.interfaceTargetReference) {
|
||||
value.parent = this;
|
||||
}
|
||||
|
||||
Member? get interfaceTarget => interfaceTargetReference?.asMember;
|
||||
Member get interfaceTarget => interfaceTargetReference.asMember;
|
||||
|
||||
void set interfaceTarget(Member? member) {
|
||||
interfaceTargetReference = getMemberReferenceSetter(member);
|
||||
void set interfaceTarget(Member member) {
|
||||
interfaceTargetReference = getNonNullableMemberReferenceSetter(member);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -5096,7 +5086,7 @@ class SuperPropertySet extends Expression {
|
||||
|
||||
@override
|
||||
void visitChildren(Visitor v) {
|
||||
interfaceTarget?.acceptReference(v);
|
||||
interfaceTarget.acceptReference(v);
|
||||
name.accept(v);
|
||||
value.accept(v);
|
||||
}
|
||||
@@ -6406,32 +6396,30 @@ class AbstractSuperMethodInvocation extends InvocationExpression {
|
||||
@override
|
||||
Arguments arguments;
|
||||
|
||||
Reference? interfaceTargetReference;
|
||||
Reference interfaceTargetReference;
|
||||
|
||||
AbstractSuperMethodInvocation(Name name, Arguments arguments,
|
||||
[Procedure? interfaceTarget])
|
||||
AbstractSuperMethodInvocation(
|
||||
Name name, Arguments arguments, Procedure interfaceTarget)
|
||||
: this.byReference(
|
||||
name,
|
||||
arguments,
|
||||
// An invocation doesn't refer to the setter.
|
||||
getMemberReferenceGetter(interfaceTarget));
|
||||
getNonNullableMemberReferenceGetter(interfaceTarget));
|
||||
|
||||
AbstractSuperMethodInvocation.byReference(
|
||||
this.name, this.arguments, this.interfaceTargetReference) {
|
||||
arguments.parent = this;
|
||||
}
|
||||
|
||||
Procedure? get interfaceTarget => interfaceTargetReference?.asProcedure;
|
||||
Procedure get interfaceTarget => interfaceTargetReference.asProcedure;
|
||||
|
||||
void set interfaceTarget(Procedure? target) {
|
||||
void set interfaceTarget(Procedure target) {
|
||||
// An invocation doesn't refer to the setter.
|
||||
interfaceTargetReference = getMemberReferenceGetter(target);
|
||||
interfaceTargetReference = getNonNullableMemberReferenceGetter(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);
|
||||
@@ -6453,7 +6441,7 @@ class AbstractSuperMethodInvocation extends InvocationExpression {
|
||||
|
||||
@override
|
||||
void visitChildren(Visitor v) {
|
||||
interfaceTarget?.acceptReference(v);
|
||||
interfaceTarget.acceptReference(v);
|
||||
name.accept(v);
|
||||
arguments.accept(v);
|
||||
}
|
||||
@@ -6499,32 +6487,30 @@ class SuperMethodInvocation extends InvocationExpression {
|
||||
@override
|
||||
Arguments arguments;
|
||||
|
||||
Reference? interfaceTargetReference;
|
||||
Reference interfaceTargetReference;
|
||||
|
||||
SuperMethodInvocation(Name name, Arguments arguments,
|
||||
[Procedure? interfaceTarget])
|
||||
SuperMethodInvocation(
|
||||
Name name, Arguments arguments, Procedure interfaceTarget)
|
||||
: this.byReference(
|
||||
name,
|
||||
arguments,
|
||||
// An invocation doesn't refer to the setter.
|
||||
getMemberReferenceGetter(interfaceTarget));
|
||||
getNonNullableMemberReferenceGetter(interfaceTarget));
|
||||
|
||||
SuperMethodInvocation.byReference(
|
||||
this.name, this.arguments, this.interfaceTargetReference) {
|
||||
arguments.parent = this;
|
||||
}
|
||||
|
||||
Procedure? get interfaceTarget => interfaceTargetReference?.asProcedure;
|
||||
Procedure get interfaceTarget => interfaceTargetReference.asProcedure;
|
||||
|
||||
void set interfaceTarget(Procedure? target) {
|
||||
void set interfaceTarget(Procedure target) {
|
||||
// An invocation doesn't refer to the setter.
|
||||
interfaceTargetReference = getMemberReferenceGetter(target);
|
||||
interfaceTargetReference = getNonNullableMemberReferenceGetter(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);
|
||||
@@ -6545,7 +6531,7 @@ class SuperMethodInvocation extends InvocationExpression {
|
||||
|
||||
@override
|
||||
void visitChildren(Visitor v) {
|
||||
interfaceTarget?.acceptReference(v);
|
||||
interfaceTarget.acceptReference(v);
|
||||
name.accept(v);
|
||||
arguments.accept(v);
|
||||
}
|
||||
|
||||
@@ -2219,7 +2219,7 @@ class BinaryBuilder {
|
||||
int offset = readOffset();
|
||||
addTransformerFlag(TransformerFlag.superCalls);
|
||||
return new AbstractSuperPropertyGet.byReference(
|
||||
readName(), readNullableInstanceMemberReference())
|
||||
readName(), readNonNullInstanceMemberReference())
|
||||
..fileOffset = offset;
|
||||
}
|
||||
|
||||
@@ -2227,7 +2227,7 @@ class BinaryBuilder {
|
||||
int offset = readOffset();
|
||||
addTransformerFlag(TransformerFlag.superCalls);
|
||||
return new AbstractSuperPropertySet.byReference(
|
||||
readName(), readExpression(), readNullableInstanceMemberReference())
|
||||
readName(), readExpression(), readNonNullInstanceMemberReference())
|
||||
..fileOffset = offset;
|
||||
}
|
||||
|
||||
@@ -2235,7 +2235,7 @@ class BinaryBuilder {
|
||||
int offset = readOffset();
|
||||
addTransformerFlag(TransformerFlag.superCalls);
|
||||
return new SuperPropertyGet.byReference(
|
||||
readName(), readNullableInstanceMemberReference())
|
||||
readName(), readNonNullInstanceMemberReference())
|
||||
..fileOffset = offset;
|
||||
}
|
||||
|
||||
@@ -2243,7 +2243,7 @@ class BinaryBuilder {
|
||||
int offset = readOffset();
|
||||
addTransformerFlag(TransformerFlag.superCalls);
|
||||
return new SuperPropertySet.byReference(
|
||||
readName(), readExpression(), readNullableInstanceMemberReference())
|
||||
readName(), readExpression(), readNonNullInstanceMemberReference())
|
||||
..fileOffset = offset;
|
||||
}
|
||||
|
||||
@@ -2373,7 +2373,7 @@ class BinaryBuilder {
|
||||
int offset = readOffset();
|
||||
addTransformerFlag(TransformerFlag.superCalls);
|
||||
return new AbstractSuperMethodInvocation.byReference(
|
||||
readName(), readArguments(), readNullableInstanceMemberReference())
|
||||
readName(), readArguments(), readNonNullInstanceMemberReference())
|
||||
..fileOffset = offset;
|
||||
}
|
||||
|
||||
@@ -2381,7 +2381,7 @@ class BinaryBuilder {
|
||||
int offset = readOffset();
|
||||
addTransformerFlag(TransformerFlag.superCalls);
|
||||
return new SuperMethodInvocation.byReference(
|
||||
readName(), readArguments(), readNullableInstanceMemberReference())
|
||||
readName(), readArguments(), readNonNullInstanceMemberReference())
|
||||
..fileOffset = offset;
|
||||
}
|
||||
|
||||
|
||||
@@ -1634,7 +1634,7 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
|
||||
writeByte(Tag.AbstractSuperPropertyGet);
|
||||
writeOffset(node.fileOffset);
|
||||
writeName(node.name);
|
||||
writeNullAllowedInstanceMemberReference(node.interfaceTargetReference);
|
||||
writeNonNullInstanceMemberReference(node.interfaceTargetReference);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -1643,7 +1643,7 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
|
||||
writeOffset(node.fileOffset);
|
||||
writeName(node.name);
|
||||
writeNode(node.value);
|
||||
writeNullAllowedInstanceMemberReference(node.interfaceTargetReference);
|
||||
writeNonNullInstanceMemberReference(node.interfaceTargetReference);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -1651,7 +1651,7 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
|
||||
writeByte(Tag.SuperPropertyGet);
|
||||
writeOffset(node.fileOffset);
|
||||
writeName(node.name);
|
||||
writeNullAllowedInstanceMemberReference(node.interfaceTargetReference);
|
||||
writeNonNullInstanceMemberReference(node.interfaceTargetReference);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -1660,7 +1660,7 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
|
||||
writeOffset(node.fileOffset);
|
||||
writeName(node.name);
|
||||
writeNode(node.value);
|
||||
writeNullAllowedInstanceMemberReference(node.interfaceTargetReference);
|
||||
writeNonNullInstanceMemberReference(node.interfaceTargetReference);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -1791,7 +1791,7 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
|
||||
writeOffset(node.fileOffset);
|
||||
writeName(node.name);
|
||||
writeArgumentsNode(node.arguments);
|
||||
writeNullAllowedInstanceMemberReference(node.interfaceTargetReference);
|
||||
writeNonNullInstanceMemberReference(node.interfaceTargetReference);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -1800,7 +1800,7 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
|
||||
writeOffset(node.fileOffset);
|
||||
writeName(node.name);
|
||||
writeArgumentsNode(node.arguments);
|
||||
writeNullAllowedInstanceMemberReference(node.interfaceTargetReference);
|
||||
writeNonNullInstanceMemberReference(node.interfaceTargetReference);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -1060,8 +1060,10 @@ class MixinApplicationCloner extends CloneVisitorWithMembers {
|
||||
SuperMethodInvocation visitSuperMethodInvocation(SuperMethodInvocation node) {
|
||||
SuperMethodInvocation cloned =
|
||||
super.visitSuperMethodInvocation(node) as SuperMethodInvocation;
|
||||
cloned.interfaceTarget =
|
||||
_findSuperMember(node.name, isSetter: false) as Procedure?;
|
||||
cloned.interfaceTarget = _findSuperMember(node.name, isSetter: false)
|
||||
as Procedure? ??
|
||||
// TODO(johnniwinther): Remove this when an error is reported instead.
|
||||
cloned.interfaceTarget;
|
||||
return cloned;
|
||||
}
|
||||
|
||||
@@ -1069,7 +1071,9 @@ class MixinApplicationCloner extends CloneVisitorWithMembers {
|
||||
SuperPropertyGet visitSuperPropertyGet(SuperPropertyGet node) {
|
||||
SuperPropertyGet cloned =
|
||||
super.visitSuperPropertyGet(node) as SuperPropertyGet;
|
||||
cloned.interfaceTarget = _findSuperMember(node.name, isSetter: false);
|
||||
cloned.interfaceTarget = _findSuperMember(node.name, isSetter: false) ??
|
||||
// TODO(johnniwinther): Remove this when an error is reported instead.
|
||||
cloned.interfaceTarget;
|
||||
return cloned;
|
||||
}
|
||||
|
||||
@@ -1077,7 +1081,9 @@ class MixinApplicationCloner extends CloneVisitorWithMembers {
|
||||
SuperPropertySet visitSuperPropertySet(SuperPropertySet node) {
|
||||
SuperPropertySet cloned =
|
||||
super.visitSuperPropertySet(node) as SuperPropertySet;
|
||||
cloned.interfaceTarget = _findSuperMember(node.name, isSetter: true);
|
||||
cloned.interfaceTarget = _findSuperMember(node.name, isSetter: true) ??
|
||||
// TODO(johnniwinther): Remove this when an error is reported instead.
|
||||
cloned.interfaceTarget;
|
||||
return cloned;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -861,7 +861,8 @@ class NodeCreator {
|
||||
return StringLiteral('foo');
|
||||
case ExpressionKind.AbstractSuperMethodInvocation:
|
||||
return _createOneOf(_pendingExpressions, kind, index, [
|
||||
() => AbstractSuperMethodInvocation(_createName(), _createArguments())
|
||||
() => AbstractSuperMethodInvocation(
|
||||
_createName(), _createArguments(), _needProcedure())
|
||||
..fileOffset = _needFileOffset(),
|
||||
() => AbstractSuperMethodInvocation(
|
||||
_createName(), _createArguments(), _needProcedure())
|
||||
@@ -869,7 +870,8 @@ class NodeCreator {
|
||||
]);
|
||||
case ExpressionKind.SuperMethodInvocation:
|
||||
return _createOneOf(_pendingExpressions, kind, index, [
|
||||
() => SuperMethodInvocation(_createName(), _createArguments())
|
||||
() => SuperMethodInvocation(
|
||||
_createName(), _createArguments(), _needProcedure())
|
||||
..fileOffset = _needFileOffset(),
|
||||
() => SuperMethodInvocation(
|
||||
_createName(), _createArguments(), _needProcedure())
|
||||
@@ -877,29 +879,31 @@ class NodeCreator {
|
||||
]);
|
||||
case ExpressionKind.AbstractSuperPropertyGet:
|
||||
return _createOneOf(_pendingExpressions, kind, index, [
|
||||
() => AbstractSuperPropertyGet(_createName())
|
||||
() => AbstractSuperPropertyGet(_createName(), _needProcedure())
|
||||
..fileOffset = _needFileOffset(),
|
||||
() => AbstractSuperPropertyGet(_createName(), _needField())
|
||||
..fileOffset = _needFileOffset(),
|
||||
]);
|
||||
case ExpressionKind.AbstractSuperPropertySet:
|
||||
return _createOneOf(_pendingExpressions, kind, index, [
|
||||
() =>
|
||||
AbstractSuperPropertySet(_createName(), _createExpression(), null)
|
||||
..fileOffset = _needFileOffset(),
|
||||
() => AbstractSuperPropertySet(
|
||||
_createName(), _createExpression(), _needProcedure())
|
||||
..fileOffset = _needFileOffset(),
|
||||
() => AbstractSuperPropertySet(
|
||||
_createName(), _createExpression(), _needField())
|
||||
..fileOffset = _needFileOffset(),
|
||||
]);
|
||||
case ExpressionKind.SuperPropertyGet:
|
||||
return _createOneOf(_pendingExpressions, kind, index, [
|
||||
() => SuperPropertyGet(_createName())..fileOffset = _needFileOffset(),
|
||||
() => SuperPropertyGet(_createName(), _needProcedure())
|
||||
..fileOffset = _needFileOffset(),
|
||||
() => SuperPropertyGet(_createName(), _needField())
|
||||
..fileOffset = _needFileOffset(),
|
||||
]);
|
||||
case ExpressionKind.SuperPropertySet:
|
||||
return _createOneOf(_pendingExpressions, kind, index, [
|
||||
() => SuperPropertySet(_createName(), _createExpression(), null)
|
||||
() => SuperPropertySet(
|
||||
_createName(), _createExpression(), _needProcedure())
|
||||
..fileOffset = _needFileOffset(),
|
||||
() =>
|
||||
SuperPropertySet(_createName(), _createExpression(), _needField())
|
||||
|
||||
@@ -755,77 +755,49 @@ class TypeCheckingVisitor
|
||||
@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));
|
||||
}
|
||||
Member target = node.interfaceTarget;
|
||||
return handleCall(node.arguments, target.superGetterType,
|
||||
receiver: getSuperReceiverType(target));
|
||||
}
|
||||
|
||||
@override
|
||||
DartType visitSuperMethodInvocation(SuperMethodInvocation 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));
|
||||
}
|
||||
Member target = node.interfaceTarget;
|
||||
return handleCall(node.arguments, target.superGetterType,
|
||||
receiver: getSuperReceiverType(target));
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
Member target = node.interfaceTarget;
|
||||
Substitution receiver = getSuperReceiverType(target);
|
||||
return receiver.substituteType(target.superGetterType);
|
||||
}
|
||||
|
||||
@override
|
||||
DartType visitAbstractSuperPropertySet(AbstractSuperPropertySet node) {
|
||||
Member? target = node.interfaceTarget;
|
||||
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);
|
||||
}
|
||||
Substitution receiver = getSuperReceiverType(target);
|
||||
checkAssignable(node.value, value,
|
||||
receiver.substituteType(target.superSetterType, contravariant: true));
|
||||
return value;
|
||||
}
|
||||
|
||||
@override
|
||||
DartType visitSuperPropertyGet(SuperPropertyGet node) {
|
||||
Member? target = node.interfaceTarget;
|
||||
if (target == null) {
|
||||
checkUnresolvedInvocation(currentThisType!, node);
|
||||
return const DynamicType();
|
||||
} else {
|
||||
Substitution receiver = getSuperReceiverType(target);
|
||||
return receiver.substituteType(target.superGetterType);
|
||||
}
|
||||
Member target = node.interfaceTarget;
|
||||
Substitution receiver = getSuperReceiverType(target);
|
||||
return receiver.substituteType(target.superGetterType);
|
||||
}
|
||||
|
||||
@override
|
||||
DartType visitSuperPropertySet(SuperPropertySet node) {
|
||||
Member? target = node.interfaceTarget;
|
||||
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);
|
||||
}
|
||||
Substitution receiver = getSuperReceiverType(target);
|
||||
checkAssignable(node.value, value,
|
||||
receiver.substituteType(target.superSetterType, contravariant: true));
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
@@ -196,20 +196,20 @@ class ReferenceUpdater extends RecursiveVisitor {
|
||||
|
||||
@override
|
||||
visitSuperPropertyGet(SuperPropertyGet node) {
|
||||
node.interfaceTarget = _resolveNewInterfaceTarget(node.interfaceTarget);
|
||||
node.interfaceTarget = _resolveNewInterfaceTarget(node.interfaceTarget)!;
|
||||
super.visitSuperPropertyGet(node);
|
||||
}
|
||||
|
||||
@override
|
||||
visitSuperPropertySet(SuperPropertySet node) {
|
||||
node.interfaceTarget = _resolveNewInterfaceTarget(node.interfaceTarget);
|
||||
node.interfaceTarget = _resolveNewInterfaceTarget(node.interfaceTarget)!;
|
||||
super.visitSuperPropertySet(node);
|
||||
}
|
||||
|
||||
@override
|
||||
visitSuperMethodInvocation(SuperMethodInvocation node) {
|
||||
node.interfaceTarget =
|
||||
_resolveNewInterfaceTarget(node.interfaceTarget) as Procedure?;
|
||||
_resolveNewInterfaceTarget(node.interfaceTarget) as Procedure;
|
||||
super.visitSuperMethodInvocation(node);
|
||||
}
|
||||
|
||||
|
||||
@@ -75,11 +75,21 @@ class ToStringVisitor extends RecursiveVisitor {
|
||||
_isInTargetPackage(node) &&
|
||||
!_hasKeepAnnotation(node) &&
|
||||
!_hasInheritedKeepAnnotation(node.enclosingClass!)) {
|
||||
Procedure findSuperMethod(Class cls) {
|
||||
for (Procedure procedure in cls.procedures) {
|
||||
if (procedure.name.text == 'toString' && !procedure.isAbstract) {
|
||||
return procedure;
|
||||
}
|
||||
}
|
||||
return findSuperMethod(cls.superclass!);
|
||||
}
|
||||
|
||||
node.function.body!.replaceWith(
|
||||
ReturnStatement(
|
||||
SuperMethodInvocation(
|
||||
node.name,
|
||||
Arguments(<Expression>[]),
|
||||
findSuperMethod(node.enclosingClass!.superclass!),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -309,10 +309,7 @@ class _Collect extends RecursiveVisitor {
|
||||
|
||||
@override
|
||||
void visitSuperMethodInvocation(SuperMethodInvocation node) {
|
||||
final interfaceTarget = node.interfaceTarget;
|
||||
if (interfaceTarget != null) {
|
||||
collectCall(interfaceTarget, node.arguments);
|
||||
}
|
||||
collectCall(node.interfaceTarget, node.arguments);
|
||||
super.visitSuperMethodInvocation(node);
|
||||
}
|
||||
|
||||
@@ -649,10 +646,7 @@ class _Transform extends RecursiveVisitor {
|
||||
@override
|
||||
void visitSuperMethodInvocation(SuperMethodInvocation node) {
|
||||
super.visitSuperMethodInvocation(node);
|
||||
final interfaceTarget = node.interfaceTarget;
|
||||
if (interfaceTarget != null) {
|
||||
transformCall(interfaceTarget, node, null, node.arguments);
|
||||
}
|
||||
transformCall(node.interfaceTarget, node, null, node.arguments);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -1348,10 +1348,8 @@ class _TreeShakerPass1 extends RemovingTransformer {
|
||||
return _makeUnreachableCall(_flattenArguments(node.arguments));
|
||||
} else {
|
||||
node.interfaceTarget = fieldMorpher
|
||||
.adjustInstanceCallTarget(node.interfaceTarget) as Procedure?;
|
||||
if (node.interfaceTarget != null) {
|
||||
shaker.addUsedMember(node.interfaceTarget!);
|
||||
}
|
||||
.adjustInstanceCallTarget(node.interfaceTarget) as Procedure;
|
||||
shaker.addUsedMember(node.interfaceTarget);
|
||||
return node;
|
||||
}
|
||||
}
|
||||
@@ -1364,10 +1362,8 @@ class _TreeShakerPass1 extends RemovingTransformer {
|
||||
return _makeUnreachableCall([]);
|
||||
} else {
|
||||
node.interfaceTarget =
|
||||
fieldMorpher.adjustInstanceCallTarget(node.interfaceTarget);
|
||||
if (node.interfaceTarget != null) {
|
||||
shaker.addUsedMember(node.interfaceTarget!);
|
||||
}
|
||||
fieldMorpher.adjustInstanceCallTarget(node.interfaceTarget)!;
|
||||
shaker.addUsedMember(node.interfaceTarget);
|
||||
return node;
|
||||
}
|
||||
}
|
||||
@@ -1380,10 +1376,8 @@ class _TreeShakerPass1 extends RemovingTransformer {
|
||||
return _makeUnreachableCall([node.value]);
|
||||
} else {
|
||||
node.interfaceTarget = fieldMorpher
|
||||
.adjustInstanceCallTarget(node.interfaceTarget, isSetter: true);
|
||||
if (node.interfaceTarget != null) {
|
||||
shaker.addUsedMember(node.interfaceTarget!);
|
||||
}
|
||||
.adjustInstanceCallTarget(node.interfaceTarget, isSetter: true)!;
|
||||
shaker.addUsedMember(node.interfaceTarget);
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ class Foo extends core::Object implements self::IFoo {
|
||||
;
|
||||
@#C1
|
||||
method toString() → core::String
|
||||
return super.toString();
|
||||
return super.{core::Object::toString}();
|
||||
}
|
||||
class FooEnum extends core::_Enum /*isEnum*/ {
|
||||
static const field core::List<self::FooEnum> values = #C11;
|
||||
|
||||
Reference in New Issue
Block a user