[dartdevc] Adding support for more Record nodes and core methods
- Supports: RecordGet, RecordIndexGet, RecordConstant
- Adds methods: hashCode, toString, ==
Change-Id: I512978a0ccf2eb58e24baf8462cc93ff98bd9105
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/269745
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Mark Zhou <markzipan@google.com>
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 32d5dcc..20f1241 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -4899,12 +4899,12 @@
@override
js_ast.Expression visitRecordIndexGet(RecordIndexGet node) {
- return defaultExpression(node);
+ return _emitPropertyGet(node.receiver, null, '\$${node.index}');
}
@override
js_ast.Expression visitRecordNameGet(RecordNameGet node) {
- return defaultExpression(node);
+ return _emitPropertyGet(node.receiver, null, node.name);
}
@override
@@ -7020,8 +7020,20 @@
node.typeArgument, node.entries.map(visitConstant).toList());
@override
- js_ast.Expression visitRecordConstant(RecordConstant node) =>
- defaultConstant(node);
+ js_ast.Expression visitRecordConstant(RecordConstant node) {
+ var sortedNames = node.named.entries.toList().sortedBy((e) => e.key);
+ var names = sortedNames.map((e) => e.key);
+ var shape = '${node.positional.length} ${names.join(" ")}';
+ return runtimeCall('recordLiteral(#, #, #, [#])', [
+ js.string(shape),
+ js.number(node.positional.length),
+ names.isEmpty ? js.call('void 0') : js.stringArray(names),
+ [
+ ...node.positional.map(visitConstant),
+ ...sortedNames.map((e) => visitConstant(e.value))
+ ]
+ ]);
+ }
@override
js_ast.Expression visitInstanceConstant(InstanceConstant node) {
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
index 8f3f00f..9f3d9ec 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
@@ -2215,18 +2215,56 @@
}
final _shape = JS('', 'Symbol("shape")');
-var Record = JS('!', '''class Record {}''');
+
final Object _RecordImpl = JS(
'!',
'''
-class _RecordImpl extends # {
+class _RecordImpl {
constructor(values) {
- super();
this.values = values;
}
+
+ [#](other) {
+ if (!(other instanceof #)) return false;
+ if (this.# !== other.#) return false;
+ if (this.values.length !== other.values.length) return false;
+ for (let i = 0; i < this.values.length; i++)
+ if (!#(this.values[i], other.values[i]))
+ return false;
+ return true;
+ }
+
+ get [#]() {
+ return #([this.#].concat(this.values.map((v) => #(v))));
+ }
+
+ [#]() {
+ let shape = this.#;
+ let s = '(';
+ for (let i = 0; i < this.values.length; i++) {
+ if (i >= shape.positionals) {
+ s += shape.named[i - shape.positionals] + ': '
+ }
+ s += #(this.values[i]);
+ if (i < this.values.length - 1) s += ', ';
+ }
+ s += ')';
+ return s;
+ }
}
''',
- Record);
+ extensionSymbol('_equals'),
+ _RecordImpl,
+ _shape,
+ _shape,
+ equals,
+ extensionSymbol('hashCode'),
+ Object.hashAll,
+ _shape,
+ hashCode,
+ extensionSymbol('toString'),
+ _shape,
+ _toString);
/// Cache for Record shapes. These are keyed by a distinct shape recipe,
/// which consists of an integer followed by space-separated named labels.