Skip to content

fix(repl): duplicate property names in completions#27515

Open
HK-SHAO wants to merge 1 commit intooven-sh:mainfrom
HK-SHAO:patch-2
Open

fix(repl): duplicate property names in completions#27515
HK-SHAO wants to merge 1 commit intooven-sh:mainfrom
HK-SHAO:patch-2

Conversation

@HK-SHAO
Copy link
Contributor

@HK-SHAO HK-SHAO commented Feb 27, 2026

What does this PR do?

Try to fix duplicate property names in REPL tab completion when properties appear multiple times in the prototype chain. #27516

Problem: When using tab completion in the Bun REPL, property names were being duplicated in the completion suggestions. For example, entering {}.to and pressing Tab would show:

toString
toLocaleString
toString
toLocaleString

This happened because the completion function traversed the entire prototype chain and added properties from each level without checking for duplicates. Since properties like toString exist in multiple prototype objects (e.g., both Function.prototype and Object.prototype), they would appear multiple times in the completion list.

Solution: Introduce a WTF::HashSet<WTF::String> to track property names that have already been added to the completion list. Before adding any property name to the completion array, the code now checks if it's already in the set. Only unique property names are added, ensuring each property appears exactly once regardless of how many times it appears in the prototype chain.

Changes:

  • Added #include "wtf/HashSet.h" to the bindings.cpp header includes
  • Modified Bun__REPL__getCompletions function in src/bun.js/bindings/bindings.cpp to use a HashSet for deduplication
  • Added check !addedNames.contains(name) before adding property names to the completion array
  • Added addedNames.add(name) call when a property is successfully added to track it

How did you verify your code works?

  • Passed bun run zig:check-all and bun run build
  • After compilation, self-tested locally via build/debug/bun-debug repl in my terminal

Added a HashSet to track property names and avoid duplicates in completions.
@HK-SHAO HK-SHAO marked this pull request as ready for review February 27, 2026 12:50
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 27, 2026

Walkthrough

Switches REPL completion enumeration to use each object's own property list (JSObject::getOwnPropertyNames) for the target object and each prototype, preventing duplicate completion entries from traversing the prototype chain twice. No exported/public signatures were changed.

Changes

Cohort / File(s) Summary
Own-property enumeration
src/bun.js/bindings/bindings.cpp
Replaces getPropertyNames(...) calls with JSObject::getOwnPropertyNames(...) for the target object and per-prototype enumeration; updates comments to reflect own-property enumeration. No public API or signature changes.
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix(repl): duplicate property names in completions' clearly and specifically identifies the main change - fixing duplicate property names in REPL completions by using own-property enumeration instead of traversing the full prototype chain.
Description check ✅ Passed The PR description fully addresses both required template sections with comprehensive details about the problem, solution, and verification approach.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@HK-SHAO HK-SHAO changed the title fix(repl): prevent duplicate property names in completions fix(repl): duplicate property names in completions Feb 27, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/bun.js/bindings/bindings.cpp (1)

6262-6273: ⚠️ Potential issue | 🟠 Major

Duplicate completions can still occur across prototype levels.

Line 6265 collects each prototype’s own names, but Line 6271 appends them without a global seen-set. If a name exists on multiple prototypes (e.g. toString), duplicates still appear.

💡 Proposed fix
@@
+#include "wtf/HashSet.h"
@@
     JSC::PropertyNameArrayBuilder propertyNames(vm, JSC::PropertyNameMode::Strings, JSC::PrivateSymbolMode::Exclude);
     JSObject::getOwnPropertyNames(object, globalObject, propertyNames, DontEnumPropertiesMode::Include);
@@
     unsigned completionIndex = 0;
+    WTF::HashSet<WTF::String> addedNames;
     for (const auto& propertyName : propertyNames) {
         WTF::String name = propertyName.string();
-        if (prefix.isEmpty() || name.startsWith(prefix)) {
+        if ((prefix.isEmpty() || name.startsWith(prefix)) && !addedNames.contains(name)) {
+            addedNames.add(name);
             completions->putDirectIndex(globalObject, completionIndex++, JSC::jsString(vm, name));
             RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::jsUndefined()));
         }
     }
@@
         for (const auto& propertyName : protoNames) {
             WTF::String name = propertyName.string();
-            if (prefix.isEmpty() || name.startsWith(prefix)) {
+            if ((prefix.isEmpty() || name.startsWith(prefix)) && !addedNames.contains(name)) {
+                addedNames.add(name);
                 completions->putDirectIndex(globalObject, completionIndex++, JSC::jsString(vm, name));
                 RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(completions));
             }
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/bun.js/bindings/bindings.cpp` around lines 6262 - 6273, Prototype-level
property names are collected per-prototype into protoNames but duplicates can
still be emitted across prototype chain; add a seen set (e.g.,
WTF::HashSet<WTF::String> seenNames) before iterating prototypes and, inside the
loop over protoNames (where propertyName/string() is used), skip any name
already in seenNames and only insert new names into seenNames before calling
completions->putDirectIndex(...), preserving checks for prefix,
RETURN_IF_EXCEPTION and incrementing completionIndex; reference symbols:
JSC::PropertyNameArrayBuilder protoNames, propertyName, completions,
completionIndex, prefix, protoObj.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/bun.js/bindings/bindings.cpp`:
- Around line 6262-6273: Prototype-level property names are collected
per-prototype into protoNames but duplicates can still be emitted across
prototype chain; add a seen set (e.g., WTF::HashSet<WTF::String> seenNames)
before iterating prototypes and, inside the loop over protoNames (where
propertyName/string() is used), skip any name already in seenNames and only
insert new names into seenNames before calling completions->putDirectIndex(...),
preserving checks for prefix, RETURN_IF_EXCEPTION and incrementing
completionIndex; reference symbols: JSC::PropertyNameArrayBuilder protoNames,
propertyName, completions, completionIndex, prefix, protoObj.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 73039e2 and 971db6a.

📒 Files selected for processing (1)
  • src/bun.js/bindings/bindings.cpp

@HK-SHAO HK-SHAO changed the title fix(repl): duplicate property names in completions fix(repl): duplicate and incorrect property names in completions Feb 27, 2026
@HK-SHAO HK-SHAO changed the title fix(repl): duplicate and incorrect property names in completions fix(repl): duplicate property names in completions Feb 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant