Skip to content

Conversation

@theaniketgiri
Copy link

…le.log

Fixes #18324

Previously, Generator and AsyncGenerator objects were falling through to the default JSON formatter, causing them to display as '{}' instead of their proper type identifiers.

Node.js displays these as:

  • Generator: 'Object [Generator] {}'
  • AsyncGenerator: 'Object [AsyncGenerator] {}'

This change adds:

  1. Generator and AsyncGenerator tags to the Formatter.Tag enum
  2. Type mappings from JSType.Generator/AsyncGenerator to the new tags
  3. Formatters that output the proper 'Object [Generator/AsyncGenerator] {}' format

This matches Node.js behavior for consistency.

What does this PR do?

Adds proper console.log formatting for Generator and AsyncGenerator objects to match Node.js behavior. Previously these displayed as {}, now they display as Object [Generator] {} and Object [AsyncGenerator] {}.

How did you verify your code works?

Code analysis of the existing patterns in ConsoleObject.zig - the fix follows the same pattern used for MapIterator, SetIterator, and other similar types. CI tests will verify the implementation.

…le.log

Fixes oven-sh#18324

Previously, Generator and AsyncGenerator objects were falling through to
the default JSON formatter, causing them to display as '{}' instead of
their proper type identifiers.

Node.js displays these as:
- Generator: 'Object [Generator] {}'
- AsyncGenerator: 'Object [AsyncGenerator] {}'

This change adds:
1. Generator and AsyncGenerator tags to the Formatter.Tag enum
2. Type mappings from JSType.Generator/AsyncGenerator to the new tags
3. Formatters that output the proper 'Object [Generator/AsyncGenerator] {}' format

This matches Node.js behavior for consistency.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 3, 2025

Walkthrough

Adds support for Generator and AsyncGenerator types to the console object formatter. Two new enum variants are added to Formatter.Tag and corresponding formatting logic is implemented to display these types explicitly as Object [Generator] {} and Object [AsyncGenerator] {} representations.

Changes

Cohort / File(s) Change Summary
Console formatter generator support
src/bun.js/ConsoleObject.zig
Added Generator and AsyncGenerator enum variants to Formatter.Tag. Implemented tag classification and formatting logic to produce explicit object representations for Generator and AsyncGenerator values instead of empty objects.

Suggested reviewers

  • pfgithub
  • dylan-conway

Pre-merge checks

✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: adding proper Generator and AsyncGenerator support to console.log formatting, directly addressing the linked issue #18324.
Description check ✅ Passed The description follows the template with both required sections completed: 'What does this PR do?' and 'How did you verify your code works?' are both present with adequate detail.
Linked Issues check ✅ Passed The PR fully addresses issue #18324 by implementing Generator and AsyncGenerator formatting to display as 'Object [Generator] {}' and 'Object [AsyncGenerator] {}' instead of '{}', matching Node.js behavior.
Out of Scope Changes check ✅ Passed All changes are scoped to console formatting for Generator and AsyncGenerator types in ConsoleObject.zig, directly addressing the linked issue with no extraneous modifications.

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between e9e9324 and 6be5c4d.

📒 Files selected for processing (1)
  • src/bun.js/ConsoleObject.zig (3 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
src/**/*.{cpp,zig}

📄 CodeRabbit inference engine (.cursor/rules/building-bun.mdc)

src/**/*.{cpp,zig}: Use bun bd or bun run build:debug to build debug versions for C++ and Zig source files; creates debug build at ./build/debug/bun-debug
Run tests using bun bd test <test-file> with the debug build; never use bun test directly as it will not include your changes
Execute files using bun bd <file> <...args>; never use bun <file> directly as it will not include your changes
Enable debug logs for specific scopes using BUN_DEBUG_$(SCOPE)=1 environment variable
Code generation happens automatically as part of the build process; no manual code generation commands are required

Files:

  • src/bun.js/ConsoleObject.zig
src/**/*.zig

📄 CodeRabbit inference engine (.cursor/rules/building-bun.mdc)

Use bun.Output.scoped(.${SCOPE}, .hidden) for creating debug logs in Zig code

Implement core functionality in Zig, typically in its own directory in src/

src/**/*.zig: Private fields in Zig are fully supported using the # prefix: struct { #foo: u32 };
Use decl literals in Zig for declaration initialization: const decl: Decl = .{ .binding = 0, .value = 0 };
Prefer @import at the bottom of the file (auto formatter will move them automatically)

Be careful with memory management in Zig code - use defer for cleanup with allocators

Files:

  • src/bun.js/ConsoleObject.zig
**/*.zig

📄 CodeRabbit inference engine (.cursor/rules/zig-javascriptcore-classes.mdc)

**/*.zig: Expose generated bindings in Zig structs using pub const js = JSC.Codegen.JS<ClassName> with trait conversion methods: toJS, fromJS, and fromJSDirect
Use consistent parameter name globalObject instead of ctx in Zig constructor and method implementations
Use bun.JSError!JSValue return type for Zig methods and constructors to enable proper error handling and exception propagation
Implement resource cleanup using deinit() method that releases resources, followed by finalize() called by the GC that invokes deinit() and frees the pointer
Use JSC.markBinding(@src()) in finalize methods for debugging purposes before calling deinit()
For methods returning cached properties in Zig, declare external C++ functions using extern fn and callconv(JSC.conv) calling convention
Implement getter functions with naming pattern get<PropertyName> in Zig that accept this and globalObject parameters and return JSC.JSValue
Access JavaScript CallFrame arguments using callFrame.argument(i), check argument count with callFrame.argumentCount(), and get this with callFrame.thisValue()
For reference-counted objects, use .deref() in finalize instead of destroy() to release references to other JS objects

Files:

  • src/bun.js/ConsoleObject.zig
🧠 Learnings (13)
📓 Common learnings
Learnt from: markovejnovic
Repo: oven-sh/bun PR: 23253
File: test/js/valkey/valkey.failing-subscriber-no-ipc.ts:40-59
Timestamp: 2025-10-04T21:17:53.040Z
Learning: In Bun runtime, the global `console` object is an AsyncIterable that yields lines from stdin. The pattern `for await (const line of console)` is valid and documented in Bun for reading input line-by-line from the child process stdin.
📚 Learning: 2025-11-24T18:36:08.558Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/zig-javascriptcore-classes.mdc:0-0
Timestamp: 2025-11-24T18:36:08.558Z
Learning: Applies to src/bun.js/bindings/generated_classes_list.zig : Include new class bindings in `src/bun.js/bindings/generated_classes_list.zig` to register them with the code generator

Applied to files:

  • src/bun.js/ConsoleObject.zig
📚 Learning: 2025-10-01T21:59:54.571Z
Learnt from: taylordotfish
Repo: oven-sh/bun PR: 23169
File: src/bun.js/bindings/webcore/JSDOMConvertEnumeration.h:47-74
Timestamp: 2025-10-01T21:59:54.571Z
Learning: In the new bindings generator (bindgenv2) for `src/bun.js/bindings/webcore/JSDOMConvertEnumeration.h`, the context-aware enumeration conversion overloads intentionally use stricter validation (requiring `value.isString()` without ToString coercion), diverging from Web IDL semantics. This is a design decision documented in comments.

Applied to files:

  • src/bun.js/ConsoleObject.zig
📚 Learning: 2025-11-24T18:35:39.205Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/registering-bun-modules.mdc:0-0
Timestamp: 2025-11-24T18:35:39.205Z
Learning: Applies to src/bun.js/api/BunObject.zig : Implement getter functions in `src/bun.js/api/BunObject.zig` that return your feature, and export them in the `exportAll()` function

Applied to files:

  • src/bun.js/ConsoleObject.zig
📚 Learning: 2025-11-24T18:36:08.558Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/zig-javascriptcore-classes.mdc:0-0
Timestamp: 2025-11-24T18:36:08.558Z
Learning: Applies to **/*.zig : Expose generated bindings in Zig structs using `pub const js = JSC.Codegen.JS<ClassName>` with trait conversion methods: `toJS`, `fromJS`, and `fromJSDirect`

Applied to files:

  • src/bun.js/ConsoleObject.zig
📚 Learning: 2025-10-18T20:50:47.750Z
Learnt from: theshadow27
Repo: oven-sh/bun PR: 23798
File: src/bun.js/telemetry.zig:366-373
Timestamp: 2025-10-18T20:50:47.750Z
Learning: In Bun's Zig codebase (src/bun.js/bindings/JSValue.zig), the JSValue enum uses `.null` (not `.js_null`) for JavaScript's null value. Only `js_undefined` has the `js_` prefix to avoid collision with Zig's built-in `undefined` keyword. The correct enum fields are: `js_undefined`, `null`, `true`, `false`, and `zero`.

Applied to files:

  • src/bun.js/ConsoleObject.zig
📚 Learning: 2025-11-24T18:35:39.205Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/registering-bun-modules.mdc:0-0
Timestamp: 2025-11-24T18:35:39.205Z
Learning: Applies to src/bun.js/bindings/BunObject+exports.h : Add an entry to the `FOR_EACH_GETTER` macro in `src/bun.js/bindings/BunObject+exports.h` when registering new features

Applied to files:

  • src/bun.js/ConsoleObject.zig
📚 Learning: 2025-10-04T21:17:53.040Z
Learnt from: markovejnovic
Repo: oven-sh/bun PR: 23253
File: test/js/valkey/valkey.failing-subscriber-no-ipc.ts:40-59
Timestamp: 2025-10-04T21:17:53.040Z
Learning: In Bun runtime, the global `console` object is an AsyncIterable that yields lines from stdin. The pattern `for await (const line of console)` is valid and documented in Bun for reading input line-by-line from the child process stdin.

Applied to files:

  • src/bun.js/ConsoleObject.zig
📚 Learning: 2025-11-24T18:35:39.205Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/registering-bun-modules.mdc:0-0
Timestamp: 2025-11-24T18:35:39.205Z
Learning: Applies to **/*js_bindings.classes.ts : Use `JSC.Codegen` correctly to generate necessary binding code for JavaScript-Zig integration

Applied to files:

  • src/bun.js/ConsoleObject.zig
📚 Learning: 2025-11-24T18:36:59.706Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: src/bun.js/bindings/v8/CLAUDE.md:0-0
Timestamp: 2025-11-24T18:36:59.706Z
Learning: Applies to src/bun.js/bindings/v8/src/napi/napi.zig : For each new V8 C++ method, add both GCC/Clang and MSVC mangled symbol names to the V8API struct in src/napi/napi.zig using extern fn declarations

Applied to files:

  • src/bun.js/ConsoleObject.zig
📚 Learning: 2025-11-24T18:35:25.883Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/javascriptcore-class.mdc:0-0
Timestamp: 2025-11-24T18:35:25.883Z
Learning: Applies to *.cpp : To create JavaScript objects from Zig, implement C++ functions following the `Bun__ClassName__toJS(Zig::GlobalObject*, NativeType*)` convention that construct and return the JavaScript object as an encoded JSValue

Applied to files:

  • src/bun.js/ConsoleObject.zig
📚 Learning: 2025-10-01T22:13:08.081Z
Learnt from: taylordotfish
Repo: oven-sh/bun PR: 23169
File: src/codegen/bindgenv2/internal/base.ts:120-125
Timestamp: 2025-10-01T22:13:08.081Z
Learning: Iterator.some() and other Iterator helper methods (map, filter, etc.) are supported in Bun and modern Node.js (22+) runtimes and can be safely used on string iterators and other iterator objects.

Applied to files:

  • src/bun.js/ConsoleObject.zig
📚 Learning: 2025-11-24T18:35:25.883Z
Learnt from: CR
Repo: oven-sh/bun PR: 0
File: .cursor/rules/javascriptcore-class.mdc:0-0
Timestamp: 2025-11-24T18:35:25.883Z
Learning: Applies to *.cpp : Define properties on the prototype using `JSC_DECLARE_HOST_FUNCTION` for methods and `JSC_DECLARE_CUSTOM_GETTER`/`JSC_DECLARE_CUSTOM_SETTER` for accessors, organized in a const HashTableValue array

Applied to files:

  • src/bun.js/ConsoleObject.zig
🔇 Additional comments (3)
src/bun.js/ConsoleObject.zig (3)

1099-1100: LGTM: Enum additions are correct.

The Generator and AsyncGenerator tags are properly added to the Tag enum, following the existing pattern for iterator types.


1335-1336: LGTM: Type mappings are correct.

The JSType to Tag mappings for Generator and AsyncGenerator are implemented correctly and consistently with other iterator types.


2827-2832: Output format is correct and matches Node.js behavior.

Verified: The implementations correctly output Object [Generator] {} and Object [AsyncGenerator] {}, matching Node.js console.log behavior exactly, including spacing and capitalization.


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.

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.

Async generator function are not properly identified in console.log

1 participant