@@ -2264,56 +2264,61 @@ class Shape {
2264
2264
}
2265
2265
}
2266
2266
2267
- final _shape = JS ('' , 'Symbol("shape")' );
2268
-
2269
- final Object _RecordImpl = JS (
2270
- '!' ,
2271
- '''
2272
- class _RecordImpl {
2273
- constructor(values) {
2274
- this.values = values;
2275
- }
2276
-
2277
- [#](other) {
2278
- if (!(other instanceof #)) return false;
2279
- if (this.# !== other.#) return false;
2280
- if (this.values.length !== other.values.length) return false;
2281
- for (let i = 0; i < this.values.length; i++)
2282
- if (!#(this.values[i], other.values[i]))
2267
+ /// Internal base class for all concrete records.
2268
+ class _RecordImpl implements Record {
2269
+ Shape shape;
2270
+ List values;
2271
+
2272
+ int ? _hashCode;
2273
+ String ? _printed;
2274
+
2275
+ _RecordImpl (this .shape, this .values);
2276
+
2277
+ @override
2278
+ bool operator == (Object ? other) {
2279
+ if (! (other is _RecordImpl )) return false ;
2280
+ if (shape != other.shape) return false ;
2281
+ if (values.length != other.values.length) {
2282
+ return false ;
2283
+ }
2284
+ for (var i = 0 ; i < values.length; i++ ) {
2285
+ if (values[i] != other.values[i]) {
2283
2286
return false ;
2287
+ }
2288
+ }
2284
2289
return true ;
2285
2290
}
2286
2291
2287
- get [#]() {
2288
- return #([this.#].concat(this.values));
2292
+ @override
2293
+ int get hashCode {
2294
+ if (_hashCode == null ) {
2295
+ _hashCode = Object .hashAll ([shape, ...values]);
2296
+ }
2297
+ return _hashCode! ;
2289
2298
}
2290
2299
2291
- [#]() {
2292
- let shape = this.#;
2293
- let s = '(';
2294
- for (let i = 0; i < this.values.length; i++) {
2295
- if (i >= shape.positionals) {
2296
- s += shape.named[i - shape.positionals] + ': '
2300
+ @override
2301
+ String toString () {
2302
+ if (_printed == null ) {
2303
+ var buffer = StringBuffer ();
2304
+ var posCount = shape.positionals;
2305
+ var count = values.length;
2306
+
2307
+ buffer.write ('(' );
2308
+ for (var i = 0 ; i < count; i++ ) {
2309
+ if (i >= posCount) {
2310
+ buffer.write ('${shape .named ![i - posCount ]}' );
2311
+ buffer.write (': ' );
2312
+ }
2313
+ buffer.write ('${values [i ]}' );
2314
+ if (i < count - 1 ) buffer.write (', ' );
2297
2315
}
2298
- s += #(this.values[i] );
2299
- if (i < this.values.length - 1) s += ', ' ;
2316
+ buffer. write ( ')' );
2317
+ _printed = buffer. toString () ;
2300
2318
}
2301
- s += ')';
2302
- return s;
2319
+ return _printed! ;
2303
2320
}
2304
2321
}
2305
- ''' ,
2306
- extensionSymbol ('_equals' ),
2307
- _RecordImpl ,
2308
- _shape,
2309
- _shape,
2310
- equals,
2311
- extensionSymbol ('hashCode' ),
2312
- Object .hashAll,
2313
- _shape,
2314
- extensionSymbol ('toString' ),
2315
- _shape,
2316
- _toString);
2317
2322
2318
2323
/// Cache for Record shapes. These are keyed by a distinct shape recipe,
2319
2324
/// which consists of an integer followed by space-separated named labels.
@@ -2339,20 +2344,21 @@ Object registerRecord(@notNull String shapeRecipe, @notNull int positionals,
2339
2344
return cached;
2340
2345
}
2341
2346
2342
- Object recordClass = JS (
2347
+ Object recordClass = JS ('!' , 'class _Record extends # {}' , _RecordImpl );
2348
+ // Add a 'new' function to be used instead of a constructor
2349
+ // (which is disallowed on dart objects).
2350
+ Object newRecord = JS (
2343
2351
'!' ,
2344
2352
'''
2345
- class _Record extends # {
2346
- constructor(values) {
2347
- super(values);
2353
+ #.new = function (shape, values) {
2354
+ #.__proto__.new.call(this, shape, values);
2348
2355
}
2349
- }
2350
2356
''' ,
2351
- _RecordImpl );
2357
+ recordClass,
2358
+ recordClass);
2352
2359
2353
- var shape = registerShape (shapeRecipe, positionals, named );
2360
+ JS ( '!' , '#.prototype = #.prototype' , newRecord, recordClass );
2354
2361
var recordPrototype = JS ('' , '#.prototype' , recordClass);
2355
- JS ('' , '#[#] = #' , recordPrototype, _shape, shape);
2356
2362
2357
2363
_recordGet (@notNull int index) =>
2358
2364
JS ('!' , 'function recordGet() {return this.values[#];}' , index);
@@ -2373,8 +2379,8 @@ Object registerRecord(@notNull String shapeRecipe, @notNull int positionals,
2373
2379
}
2374
2380
}
2375
2381
2376
- JS ('' , '#.set(#, #)' , _records, shapeRecipe, recordClass );
2377
- return recordClass ;
2382
+ JS ('' , '#.set(#, #)' , _records, shapeRecipe, newRecord );
2383
+ return newRecord ;
2378
2384
}
2379
2385
2380
2386
/// Creates a record type.
@@ -2388,8 +2394,9 @@ RecordType recordType(@notNull Shape shape, @notNull List types) =>
2388
2394
/// named element in sorted order.
2389
2395
Object recordLiteral (@notNull String shapeRecipe, @notNull int positionals,
2390
2396
List <String >? named, @notNull List values) {
2397
+ var shape = registerShape (shapeRecipe, positionals, named);
2391
2398
var record = registerRecord (shapeRecipe, positionals, named);
2392
- return JS ('!' , 'new #(#)' , record, values);
2399
+ return JS ('!' , 'new #(#, # )' , record, shape , values);
2393
2400
}
2394
2401
2395
2402
/// Creates a shape and binds it to [types] .
0 commit comments