Adopt define_method for Map/Set/WeakMap/WeakSet prototype builtins#199
Open
pmatos wants to merge 1 commit into
Open
Adopt define_method for Map/Set/WeakMap/WeakSet prototype builtins#199pmatos wants to merge 1 commit into
pmatos wants to merge 1 commit into
Conversation
setup_map/set/weakmap/weakset_prototype (plus WeakRef and FinalizationRegistry) hand-rolled the create_function + insert_builtin dance at 40 method call sites, even though define_method — added for atomics.rs and adopted for Array.prototype in 1d1152d — already captures that exact pattern. Switching collections.rs over removes ~200 lines of repetition and brings the file in line with the one established convention. Behavior is unchanged: define_method installs the same writable/non-enumerable/configurable own property the two-step dance did. The reused iterator functions (Map.prototype.entries reused for [@@iterator]; Set.prototype.values reused for keys and [@@iterator]) keep their let-bindings so the aliasing is preserved; getters (size, species), symbol-keyed installs, the constructor property, and the static Map.groupBy are deliberately left untouched. Adds collection_prototype_methods_have_correctly_shaped_builtins, a JS-level characterization test pinning the name/length/descriptor shape and functional behavior of every migrated method plus the iterator aliasing, written before the refactor and left in place as a regression guard. Verified: cargo test (197/197), cargo clippy -D warnings, cargo fmt --check, and test262 built-ins/{Map,Set,WeakMap,WeakSet,WeakRef, FinalizationRegistry} (1772/1772, 100%) all green before and after. The full-suite run shows 0 regressions attributable to this change — the 22 baseline deltas are pre-existing intl402/DateTimeFormat ICU-data drift, identical with this change stashed. 🤖 Generated with Claude Code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refactoring goal
Continue the
define_methodmigration started in #197 / commit1d1152d(Adopt define_method for Array.prototype builtins).collections.rsstill hand-rolled the two-stepcreate_function+insert_builtindance at 40 method call sites acrosssetup_map/set/weakmap/weakset_prototype(plusWeakRefandFinalizationRegistry), even thoughInterpreter::define_method— whose own doc comment says it "replaces the two-step create_function + insert_builtin dance repeated at every builtin call site" — already captures exactly that pattern.This was surfaced as the single highest impact × safety opportunity by an
improve-codebase-architectureaudit (top finding in 3 of 4 subsystem explorers). Switchingcollections.rsover removes ~200 lines of net duplication and brings the file in line with the one established convention.What changed
let x = self.create_function(JsFunction::native("name", len, |…| {…})); cell.borrow_mut().insert_builtin("name", x);sites → one-lineself.define_method(target, "name", len, |…| {…})calls.let-binding so aliasing is preserved:Map.prototype.entriesis reused for[@@iterator];Set.prototype.valuesis reused forkeysand[@@iterator].size/speciesgetters, symbol-keyed installs, theconstructordata property, and the staticMap.groupBy.define_methodinstalls the same writable / non-enumerable / configurable own property the two-step dance did, so behavior is unchanged. The large line delta is mechanical re-indentation (cargo fmtde-indents each closure body one level once the wrapper is gone) — the same shape as the Array migration's diff.Tests that validate it
Written before the refactor (TDD) and left in place as a regression guard:
collection_prototype_methods_have_correctly_shaped_builtins(src/interpreter/tests.rs) — a JS-level characterization test (public seam, not internals) pinning, for every migrated method:typeof === "function", correct.nameand.length;writable:true / enumerable:false / configurable:truedescriptor (Object.getOwnPropertyDescriptor);Map.prototype[@@iterator] === entries;Set.prototype.keys === values === [@@iterator]);union/intersection/isSubsetOf.Verification
cargo test --releasecargo clippy --release -- -D warningscargo fmt --checkrun-custom-tests.pybuilt-ins/{Map,Set,WeakMap,WeakSet,WeakRef,FinalizationRegistry}The full-suite run reports 22 baseline deltas, but they are entirely in
intl402/DateTimeFormat/ TemporaltoLocaleString(ICU-data-sensitive locale formatting) and reproduce identically with this change stashed — pre-existing environment/baseline drift, not caused by this refactor, which touches no Intl code.🤖 Generated with Claude Code