js-on-sx: for-in walks proto chain with shadowing, stops at native prototypes
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 41s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 41s
This commit is contained in:
@@ -3844,6 +3844,42 @@
|
||||
(k)
|
||||
(or (= k "__js_order__") (= k "__proto__"))))
|
||||
|
||||
(define
|
||||
js-for-in-keys
|
||||
(fn
|
||||
(o)
|
||||
(let
|
||||
((result (list)))
|
||||
(begin (js-for-in-walk o result) result))))
|
||||
|
||||
(define
|
||||
js-for-in-walk
|
||||
(fn
|
||||
(o acc)
|
||||
(cond
|
||||
((not (dict? o)) nil)
|
||||
((= o (get Object "prototype")) nil)
|
||||
((= o (get Array "prototype")) nil)
|
||||
((= o (get Number "prototype")) nil)
|
||||
((= o (get String "prototype")) nil)
|
||||
((= o (get Boolean "prototype")) nil)
|
||||
((= o (get Date "prototype")) nil)
|
||||
((= o (get RegExp "prototype")) nil)
|
||||
((= o (get Map "prototype")) nil)
|
||||
((= o (get Set "prototype")) nil)
|
||||
((= o (get js-function-global "prototype")) nil)
|
||||
(else
|
||||
(let
|
||||
((own (js-object-keys o)))
|
||||
(begin
|
||||
(for-each
|
||||
(fn (k) (if (contains? acc k) nil (append! acc k)))
|
||||
own)
|
||||
(cond
|
||||
((contains? (keys o) "__proto__")
|
||||
(js-for-in-walk (get o "__proto__") acc))
|
||||
(else nil))))))))
|
||||
|
||||
(define
|
||||
js-object-keys
|
||||
(fn
|
||||
|
||||
@@ -948,7 +948,7 @@
|
||||
(if
|
||||
(= iter-kind "of")
|
||||
(list (js-sym "js-iterable-to-list") iter-sx)
|
||||
(list (js-sym "js-object-keys") iter-sx))))
|
||||
(list (js-sym "js-for-in-keys") iter-sx))))
|
||||
(list
|
||||
(js-sym "for-each")
|
||||
(list
|
||||
|
||||
@@ -158,6 +158,8 @@ Each item: implement → tests → update progress. Mark `[x]` when tests green.
|
||||
|
||||
Append-only record of completed iterations. Loop writes one line per iteration: date, what was done, test count delta.
|
||||
|
||||
- 2026-05-09 — **`for…in` walks the prototype chain (with shadowing) but stops at native prototypes.** Was using `js-object-keys` which only returns own enumerable keys, so `for (k in instance)` only saw the instance's own properties — not inherited ones from `FACTORY.prototype`. Per spec, for-in walks the entire chain and yields each unique enumerable key once. Added `js-for-in-keys` + `js-for-in-walk` that iterate the chain, deduping via `contains?`. Stops at `Object.prototype` / `Array.prototype` / etc. since those carry "non-enumerable" methods we don't track property-attribute-wise — without this guard, `for (k in {})` would enumerate `toString`/`valueOf`/etc. Result: language/statements/for-in 10/30 → 12/30. Object 30/30, Array 18/30 unchanged. conformance.sh: 148/148.
|
||||
|
||||
- 2026-05-09 — **Parser swallows label declarations + accepts optional ident on `break`/`continue`.** Was rejecting `outer: while (...) { break outer; }` at parse time. Per spec, labels are valid syntax and target unwinding to the labeled enclosing loop. Added a parser branch for `<ident> ':' <stmt>` that just parses through to the inner statement (label is dropped; the runtime treats unlabeled `break`/`continue` the same way for the common case where the inner loop is the target). Also extended `break`/`continue` to optionally consume a trailing ident. Result: language/statements/while 14/30 → 16/30, for 27/30 → 28/30. labeled itself dropped 6/15 → 4/15 because we now accept some sources that should be parse errors (e.g. `label: let x;` is a SyntaxError per spec) — net positive across the suite. Object 30/30, Array 18/30 unchanged. conformance.sh: 148/148.
|
||||
|
||||
- 2026-05-09 — **`new function(){...}(args)` and `new f(...rest)` now parse and execute.** Two fixes for `new` expression handling: (1) `jp-parse-new-primary` didn't accept the `function` keyword as a primary, so `new function(){...}` raised "Unexpected token after new"; added a branch that mirrors `jp-parse-async-tail` for the function-expression case. (2) `js-transpile-new` always built the args via `js-args` regardless of spread, so `new f(1, ...[])` failed at transpile with "unknown AST tag: js-spread"; now uses `js-array-spread-build` when any arg is a spread, matching what `js-transpile-args` does for regular calls. Result: language/expressions/new 16/30 → 19/30. Object 30/30, Array 18/30, language/expressions/call 21/30 unchanged. conformance.sh: 148/148.
|
||||
|
||||
Reference in New Issue
Block a user