[kernel] Add SetConstant node to Kernel.
Change-Id: I83da1afc9f15009c650a871a51ca8171b482d4df
Reviewed-on: https://dart-review.googlesource.com/c/94863
Reviewed-by: Kevin Millikin <kmillikin@google.com>
diff --git a/pkg/compiler/lib/src/ir/visitors.dart b/pkg/compiler/lib/src/ir/visitors.dart
index 739df67..fabd55d 100644
--- a/pkg/compiler/lib/src/ir/visitors.dart
+++ b/pkg/compiler/lib/src/ir/visitors.dart
@@ -717,6 +717,12 @@
}
@override
+ ConstantValue visitSetConstant(ir.SetConstant node) {
+ // TODO(johnniwinther, fishythefish): Create a set constant value.
+ throw new UnsupportedError("Set literal constants not implemented.");
+ }
+
+ @override
ConstantValue visitMapConstant(ir.MapConstant node) {
List<ConstantValue> keys = [];
List<ConstantValue> values = [];
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index fc31457..302d6ef 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -5150,6 +5150,14 @@
}
@override
+ visitSetConstant(node) {
+ // Set literals are currently desugared in the frontend.
+ // Implement this method before flipping the supportsSetLiterals flag
+ // in DevCompilerTarget to true.
+ throw "Set literal constants not supported.";
+ }
+
+ @override
visitInstanceConstant(node) {
entryToProperty(entry) {
var field = entry.key.asField.name.name;
diff --git a/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart b/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart
index c0be105..43815bf 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart
@@ -25,6 +25,7 @@
NullConstant,
PartialInstantiationConstant,
Procedure,
+ SetConstant,
StringConstant,
SymbolConstant,
TearOffConstant,
@@ -266,6 +267,19 @@
result.add("]");
}
+ void visitSetConstant(SetConstant node) {
+ result.add("<");
+ node.typeArgument.accept(this);
+ result.add(">{");
+ bool first = true;
+ for (Constant constant in node.entries) {
+ if (!first) result.add(", ");
+ constant.accept(this);
+ first = false;
+ }
+ result.add("}");
+ }
+
void visitMapConstant(MapConstant node) {
result.add("<");
node.keyType.accept(this);
diff --git a/pkg/front_end/test/type_labeler_test.dart b/pkg/front_end/test/type_labeler_test.dart
index f24c86d..d303273 100644
--- a/pkg/front_end/test/type_labeler_test.dart
+++ b/pkg/front_end/test/type_labeler_test.dart
@@ -230,6 +230,12 @@
Constant listBoolConst = new ListConstant(boolType, [falseConst, trueConst]);
check({listBoolConst: "<bool>[false, true]"}, 0);
+ Constant setConst = new SetConstant(dynamicType, [intConst, doubleConst]);
+ check({setConst: "<dynamic>{2, 2.5}"}, 0);
+
+ Constant setBoolConst = new SetConstant(boolType, [falseConst, trueConst]);
+ check({setBoolConst: "<bool>{false, true}"}, 0);
+
Constant mapConst = new MapConstant(boolType, numType, [
new ConstantMapEntry(trueConst, intConst),
new ConstantMapEntry(falseConst, doubleConst)
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index 5071104..5fab418 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -137,7 +137,7 @@
type ComponentFile {
UInt32 magic = 0x90ABCDEF;
- UInt32 formatVersion = 19;
+ UInt32 formatVersion = 20;
List<String> problemsAsJson; // Described in problems.md.
Library[] libraries;
UriSource sourceMap;
@@ -917,6 +917,12 @@
List<ConstantReference> values;
}
+type SetConstant extends Constant {
+ Byte tag = 13; // Note: tag is out of order.
+ DartType type;
+ List<ConstantReference> values;
+}
+
type InstanceConstant extends Constant {
Byte tag = 8;
CanonicalNameReference class;
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index fbf28c4..939af1f 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -5346,6 +5346,38 @@
types.literalListType(typeArgument);
}
+class SetConstant extends Constant {
+ final DartType typeArgument;
+ final List<Constant> entries;
+
+ SetConstant(this.typeArgument, this.entries);
+
+ visitChildren(Visitor v) {
+ typeArgument.accept(v);
+ for (final Constant constant in entries) {
+ constant.acceptReference(v);
+ }
+ }
+
+ accept(ConstantVisitor v) => v.visitSetConstant(this);
+ acceptReference(Visitor v) => v.visitSetConstantReference(this);
+
+ String toString() => '${this.runtimeType}<$typeArgument>($entries)';
+
+ int _cachedHashCode;
+ int get hashCode {
+ return _cachedHashCode ??= typeArgument.hashCode ^ listHashCode(entries);
+ }
+
+ bool operator ==(Object other) =>
+ identical(this, other) ||
+ (other is SetConstant &&
+ other.typeArgument == typeArgument &&
+ listEquals(other.entries, entries));
+
+ DartType getType(TypeEnvironment types) => types.literalSetType(typeArgument);
+}
+
class InstanceConstant extends Constant {
final Reference classReference;
final List<DartType> typeArguments;
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index b423a75..29fc2cc 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -239,6 +239,15 @@
entries[i] = readConstantReference();
}
return new ListConstant(typeArgument, entries);
+ case ConstantTag.SetConstant:
+ final DartType typeArgument = readDartType();
+ final int length = readUInt();
+ final List<Constant> entries =
+ new List<Constant>.filled(length, null, growable: true);
+ for (int i = 0; i < length; i++) {
+ entries[i] = readConstantReference();
+ }
+ return new SetConstant(typeArgument, entries);
case ConstantTag.InstanceConstant:
final Reference classReference = readClassReference();
final int typeArgumentCount = readUInt();
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index e9b56f0..383e6ba 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -219,6 +219,11 @@
writeDartType(constant.typeArgument);
writeUInt30(constant.entries.length);
constant.entries.forEach(writeConstantReference);
+ } else if (constant is SetConstant) {
+ writeByte(ConstantTag.SetConstant);
+ writeDartType(constant.typeArgument);
+ writeUInt30(constant.entries.length);
+ constant.entries.forEach(writeConstantReference);
} else if (constant is InstanceConstant) {
writeByte(ConstantTag.InstanceConstant);
writeClassReference(constant.classNode);
@@ -2120,6 +2125,16 @@
}
@override
+ void visitSetConstant(SetConstant node) {
+ throw new UnsupportedError('serialization of SetConstants');
+ }
+
+ @override
+ void visitSetConstantReference(SetConstant node) {
+ throw new UnsupportedError('serialization of SetConstant references');
+ }
+
+ @override
void visitMapConstant(MapConstant node) {
throw new UnsupportedError('serialization of MapConstants');
}
diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart
index b4bf895..ff6e228 100644
--- a/pkg/kernel/lib/binary/tag.dart
+++ b/pkg/kernel/lib/binary/tag.dart
@@ -139,7 +139,7 @@
/// 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 = 19;
+ static const int BinaryFormatVersion = 20;
}
abstract class ConstantTag {
@@ -151,9 +151,11 @@
static const int SymbolConstant = 5;
static const int MapConstant = 6;
static const int ListConstant = 7;
+ static const int SetConstant = 13;
static const int InstanceConstant = 8;
static const int PartialInstantiationConstant = 9;
static const int TearOffConstant = 10;
static const int TypeLiteralConstant = 11;
static const int UnevaluatedConstant = 12;
+ // 13 is occupied by [SetConstant]
}
diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart
index aaca753..94d2f55 100644
--- a/pkg/kernel/lib/text/ast_to_text.dart
+++ b/pkg/kernel/lib/text/ast_to_text.dart
@@ -1948,6 +1948,15 @@
endLine('${node.runtimeType}<${node.typeArgument}>($entries)');
}
+ visitSetConstant(SetConstant node) {
+ final String name = syntheticNames.nameConstant(node);
+ write(' $name = ');
+ final String entries = node.entries.map((Constant constant) {
+ return syntheticNames.nameConstant(constant);
+ }).join(', ');
+ endLine('${node.runtimeType}<${node.typeArgument}>($entries)');
+ }
+
visitMapConstant(MapConstant node) {
final String name = syntheticNames.nameConstant(node);
write(' $name = ');
diff --git a/pkg/kernel/lib/text/text_serialization_verifier.dart b/pkg/kernel/lib/text/text_serialization_verifier.dart
index 02ce55f..2625376 100644
--- a/pkg/kernel/lib/text/text_serialization_verifier.dart
+++ b/pkg/kernel/lib/text/text_serialization_verifier.dart
@@ -288,6 +288,12 @@
}
@override
+ void visitSetConstantReference(SetConstant node) {
+ storeLastSeenUriAndOffset(node);
+ node.visitChildren(this);
+ }
+
+ @override
void visitMapConstantReference(MapConstant node) {
storeLastSeenUriAndOffset(node);
node.visitChildren(this);
@@ -372,6 +378,12 @@
}
@override
+ void visitSetConstant(SetConstant node) {
+ storeLastSeenUriAndOffset(node);
+ node.visitChildren(this);
+ }
+
+ @override
void visitMapConstant(MapConstant node) {
storeLastSeenUriAndOffset(node);
node.visitChildren(this);
diff --git a/pkg/kernel/lib/visitor.dart b/pkg/kernel/lib/visitor.dart
index 4d2b2bb..53ea440 100644
--- a/pkg/kernel/lib/visitor.dart
+++ b/pkg/kernel/lib/visitor.dart
@@ -292,6 +292,7 @@
R visitSymbolConstant(SymbolConstant node) => defaultConstant(node);
R visitMapConstant(MapConstant node) => defaultConstant(node);
R visitListConstant(ListConstant node) => defaultConstant(node);
+ R visitSetConstant(SetConstant node) => defaultConstant(node);
R visitInstanceConstant(InstanceConstant node) => defaultConstant(node);
R visitPartialInstantiationConstant(PartialInstantiationConstant node) =>
defaultConstant(node);
@@ -346,6 +347,7 @@
R visitSymbolConstant(SymbolConstant node) => defaultConstant(node);
R visitMapConstant(MapConstant node) => defaultConstant(node);
R visitListConstant(ListConstant node) => defaultConstant(node);
+ R visitSetConstant(SetConstant node) => defaultConstant(node);
R visitInstanceConstant(InstanceConstant node) => defaultConstant(node);
R visitPartialInstantiationConstant(PartialInstantiationConstant node) =>
defaultConstant(node);
@@ -375,6 +377,8 @@
defaultConstantReference(node);
R visitListConstantReference(ListConstant node) =>
defaultConstantReference(node);
+ R visitSetConstantReference(SetConstant node) =>
+ defaultConstantReference(node);
R visitInstanceConstantReference(InstanceConstant node) =>
defaultConstantReference(node);
R visitPartialInstantiationConstantReference(
diff --git a/runtime/vm/compiler/frontend/constant_evaluator.cc b/runtime/vm/compiler/frontend/constant_evaluator.cc
index a16e229..1be64ab 100644
--- a/runtime/vm/compiler/frontend/constant_evaluator.cc
+++ b/runtime/vm/compiler/frontend/constant_evaluator.cc
@@ -1205,6 +1205,11 @@
temp_instance_ = H.Canonicalize(temp_array_);
break;
}
+ case kSetConstant:
+ // Set literals are currently desugared in the frontend and will not
+ // reach the VM. See http://dartbug.com/35124 for discussion.
+ UNREACHABLE();
+ break;
case kInstanceConstant: {
const NameIndex index = helper_.ReadCanonicalNameReference();
if (ShouldSkipConstant(index)) {
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index 0cc7f0e..7129b5f 100644
--- a/runtime/vm/kernel_binary.h
+++ b/runtime/vm/kernel_binary.h
@@ -20,7 +20,7 @@
// Both version numbers are inclusive.
static const uint32_t kMinSupportedKernelFormatVersion = 18;
-static const uint32_t kMaxSupportedKernelFormatVersion = 19;
+static const uint32_t kMaxSupportedKernelFormatVersion = 20;
// Keep in sync with package:kernel/lib/binary/tag.dart
#define KERNEL_TAG_LIST(V) \
@@ -147,6 +147,7 @@
kSymbolConstant = 5,
kMapConstant = 6,
kListConstant = 7,
+ kSetConstant = 13,
kInstanceConstant = 8,
kPartialInstantiationConstant = 9,
kTearOffConstant = 10,