[Kernel] Add list of unused arguments to InstanceCreation nodes.

During constant evaluation, unused arguments to a const constructor are
thrown away after evaluation, since their values do not affect the
resulting instance constant. If such an unused argument ends up
unevaluated, any errors that would arise in the final evaluation are
not reported.

This CL adds space in the Kernel AST for saving these unevaluated
expressions so they can be checked during final constant evaluation.

Even though this is an incompatible change, no update is needed to the
VM code (except for the version bump), since the VM does not support
InstanceCreation nodes in the first place.

Change-Id: I4752562c1164efbba79eb018c15b07ed8354ce5f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/105761
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Aske Simon Christensen <askesc@google.com>
This commit is contained in:
Aske Simon Christensen 2019-06-13 09:42:26 +00:00 committed by commit-bot@chromium.org
parent 06b28fc60f
commit 50efd7f187
8 changed files with 27 additions and 11 deletions

View file

@ -2139,8 +2139,9 @@ class InstanceBuilder {
fields.forEach((Field field, Constant value) {
fieldValues[field.reference] = evaluator.extract(value);
});
// TODO(askesc): Put actual unused arguments.
return new InstanceCreation(
klass.reference, typeArguments, fieldValues, asserts);
klass.reference, typeArguments, fieldValues, asserts, []);
}
}

View file

@ -139,7 +139,7 @@ type CanonicalName {
type ComponentFile {
UInt32 magic = 0x90ABCDEF;
UInt32 formatVersion = 25;
UInt32 formatVersion = 26;
List<String> problemsAsJson; // Described in problems.md.
Library[] libraries;
UriSource sourceMap;
@ -730,6 +730,7 @@ type InstanceCreation extends Expression {
List<DartType> typeArguments;
List<[FieldReference, Expression]> fieldValues;
List<AssertStatement> asserts;
List<Expression> unusedArguments;
}
type IsExpression extends Expression {

View file

@ -3330,17 +3330,18 @@ class MapConcatenation extends Expression {
/// Create an instance directly from the field values.
///
/// This expression arises from const constructor calls when one or more field
/// initializing expressions, field initializers or assert initializers contain
/// unevaluated expressions. They only ever occur within unevaluated constants
/// in constant expressions.
/// initializing expressions, field initializers, assert initializers or unused
/// arguments contain unevaluated expressions. They only ever occur within
/// unevaluated constants in constant expressions.
class InstanceCreation extends Expression {
final Reference classReference;
final List<DartType> typeArguments;
final Map<Reference, Expression> fieldValues;
final List<AssertStatement> asserts;
final List<Expression> unusedArguments;
InstanceCreation(
this.classReference, this.typeArguments, this.fieldValues, this.asserts);
InstanceCreation(this.classReference, this.typeArguments, this.fieldValues,
this.asserts, this.unusedArguments);
Class get classNode => classReference.asClass;
@ -3363,6 +3364,7 @@ class InstanceCreation extends Expression {
value.accept(v);
}
visitList(asserts, v);
visitList(unusedArguments, v);
}
transformChildren(Transformer v) {
@ -3374,6 +3376,7 @@ class InstanceCreation extends Expression {
}
});
transformList(asserts, v, this);
transformList(unusedArguments, v, this);
}
}

View file

@ -1592,8 +1592,9 @@ class BinaryBuilder {
for (int i = 0; i < assertCount; i++) {
asserts[i] = readStatement();
}
return new InstanceCreation(
classReference, typeArguments, fieldValues, asserts)
List<Expression> unusedArguments = readExpressionList();
return new InstanceCreation(classReference, typeArguments, fieldValues,
asserts, unusedArguments)
..fileOffset = offset;
case Tag.IsExpression:
int offset = readOffset();

View file

@ -1544,6 +1544,7 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
writeNode(value);
});
writeNodeList(node.asserts);
writeNodeList(node.unusedArguments);
}
@override

View file

@ -214,7 +214,8 @@ class CloneVisitor implements TreeVisitor {
node.classReference,
node.typeArguments.map(visitType).toList(),
fieldValues,
node.asserts.map(clone).toList());
node.asserts.map(clone).toList(),
node.unusedArguments.map(clone).toList());
}
visitIsExpression(IsExpression node) {

View file

@ -1330,6 +1330,14 @@ class Printer extends Visitor<Null> {
writeExpression(assert_.message);
}
write(')');
first = false;
}
for (Expression unusedArgument in node.unusedArguments) {
if (!first) {
writeComma();
}
writeExpression(unusedArgument);
first = false;
}
write('}');

View file

@ -20,7 +20,7 @@ static const uint32_t kMagicProgramFile = 0x90ABCDEFu;
// Both version numbers are inclusive.
static const uint32_t kMinSupportedKernelFormatVersion = 18;
static const uint32_t kMaxSupportedKernelFormatVersion = 25;
static const uint32_t kMaxSupportedKernelFormatVersion = 26;
// Keep in sync with package:kernel/lib/binary/tag.dart
#define KERNEL_TAG_LIST(V) \