[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>
This commit is contained in:
Mark Zhou 2022-11-15 22:15:25 +00:00 committed by Commit Queue
parent 26a5c637a4
commit f504ad2a20
2 changed files with 58 additions and 8 deletions

View file

@ -4899,12 +4899,12 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
@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 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
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) {

View file

@ -2215,18 +2215,56 @@ class Shape {
}
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.