@@ -288,27 +288,23 @@ function synthesizePartialObject(root: string, bindPaths: BindPath[]): string {
288288 if ( node . size === 0 ) {
289289 return root + segments . map ( ( segment ) => `.${ segment } ` ) . join ( '' )
290290 }
291- const entries = [ ...node . entries ( ) ]
292- . map (
293- ( [ k , child ] ) =>
294- `${ serializeObjectKey ( k ) } : ${ serialize ( child , [ ...segments , k ] ) } ` ,
295- )
296- . join ( ', ' )
297- return `{ ${ entries } }`
291+ const entries : string [ ] = [ ]
292+ for ( const [ key , child ] of node ) {
293+ // ECMAScript object literals treat `__proto__: value` specially: when the
294+ // property name is non-computed and equals "__proto__", evaluation performs
295+ // [[SetPrototypeOf]] instead of creating a normal own data property. Emit a
296+ // computed key here so synthesized partial objects preserve the original
297+ // member-path shape rather than mutating the new object's prototype.
298+ // Spec: https://tc39.es/ecma262/#sec-runtime-semantics-propertydefinitionevaluation
299+ const safeKey = key === '__proto__' ? `["__proto__"]` : key
300+ entries . push ( `${ safeKey } : ${ serialize ( child , [ ...segments , key ] ) } ` )
301+ }
302+ return `{ ${ entries . join ( ', ' ) } }`
298303 }
299304
300305 return serialize ( trie , [ ] )
301306}
302307
303- function serializeObjectKey ( key : string ) : string {
304- // ECMAScript object literals treat `__proto__: value` specially: when the
305- // property name is non-computed and equals "__proto__", evaluation performs
306- // [[SetPrototypeOf]] instead of creating a normal own data property. Emit a
307- // computed key here so synthesized partial objects preserve the original
308- // member-path shape rather than mutating the new object's prototype.
309- return key === '__proto__' ? `[${ JSON . stringify ( key ) } ]` : key
310- }
311-
312308// e.g.
313309// [x.y, x.y.z, x.w] -> [x.y, x.w]
314310// [x.y.z, x.y.z.w] -> [x.y.z]
0 commit comments