Skip to content

util: canonicalize namespaced tags in inspect() - #63257

Open
Renegade334 wants to merge 1 commit into
nodejs:mainfrom
Renegade334:inspect-namespaced-tags
Open

util: canonicalize namespaced tags in inspect()#63257
Renegade334 wants to merge 1 commit into
nodejs:mainfrom
Renegade334:inspect-namespaced-tags

Conversation

@Renegade334

@Renegade334 Renegade334 commented May 11, 2026

Copy link
Copy Markdown
Member

Precursor to adding support for Temporal objects in #63154.

Namespaced toString tags are becoming more common in ES builtins. inspect() currently has no logic for dealing with these, leading to rather ugly output:

> new WebAssembly.Memory({ initial: 1 })
Memory [WebAssembly.Memory] {}

This PR adds logic to handle namespaced tags. If the basename of the namespaced tag matches the constructor name, then it will be treated as the canonical name for that object.

> new WebAssembly.Memory({ initial: 1 })
WebAssembly.Memory {}

Derived classes retain the same behaviour as exists currently.

> class MyMemory extends WebAssembly.Memory {}
> new MyMemory({ initial: 1 })
MyMemory [WebAssembly.Memory] {}

Note that this replaces, and effectively reverts, some previous logic that existed here from #59687. That PR made partial string tag matches suppress the derived class output, so derived class instances might be formatted as either derived classes or base classes depending on how they're named:

> class Base { [Symbol.toStringTag] = 'Base' }
> class LooksLikeADerivedClass extends Base {}
> new LooksLikeADerivedClass()
LooksLikeADerivedClass [Base] {}
> class LooksLikeABaseClass extends Base {}
> new LooksLikeABaseClass()
LooksLikeABaseClass {}

This logic doesn't really fit with namespaced tags and was fairly quirky to start with, and I think the easiest approach is just to replace it entirely. (cc @BridgeAR, @miguelmarcondesf)

@nodejs-github-bot nodejs-github-bot added needs-ci PRs that need a full CI run. util Issues and PRs related to the built-in util module. labels May 11, 2026
@codecov

codecov Bot commented May 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.11%. Comparing base (54b4e37) to head (ad239e3).
⚠️ Report is 4 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #63257      +/-   ##
==========================================
- Coverage   90.13%   90.11%   -0.03%     
==========================================
  Files         751      751              
  Lines      253635   253630       -5     
  Branches    47786    47796      +10     
==========================================
- Hits       228615   228555      -60     
- Misses      16268    16315      +47     
- Partials     8752     8760       +8     
Files with missing lines Coverage Δ
lib/internal/util/inspect.js 97.06% <100.00%> (-0.01%) ⬇️

... and 34 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

constructor[endPos] === constructor[endPos].toLowerCase()) {
result += `[${tag}] `;
}
const dot = StringPrototypeLastIndexOf(tag, '.');

@legendecas legendecas May 15, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think it is not straightforward to write a class with . in its name, like class Namespace.Class {} is not valid. So we can branch here with the presence of . and keep the original behavior, right?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

As in the previous suppression behaviour?

I really do think that divergent behaviour isn't helpful here – there's no difference between the inheritance models of class MapDerived extends Map and class InstantDerived extends Temporal.Instant, so I can't see that formatting one as a primary class and one as a derived class is at all useful for users.

@Renegade334
Renegade334 requested review from BridgeAR and ljharb May 15, 2026 15:11
@github-actions

Copy link
Copy Markdown
Contributor

This pull request has been marked as stale due to 90 days of inactivity.
It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.

@github-actions github-actions Bot added the stale label Aug 14, 2026
@Renegade334

Renegade334 commented Aug 21, 2026

Copy link
Copy Markdown
Member Author

@BridgeAR Do you have an opinion on this?

As mentioned, this is mainly observable in the context of Temporal objects. Formatting these as

ZonedDateTime [Temporal.ZonedDateTime] {...}

is overly verbose, and implies that these are derived subclasses when they're not.

@github-actions github-actions Bot removed the stale label Aug 22, 2026
@Renegade334 Renegade334 added the review wanted PRs that need reviews. label Aug 25, 2026
Signed-off-by: Renegade334 <contact.9a5d6388@renegade334.me.uk>
@Renegade334
Renegade334 force-pushed the inspect-namespaced-tags branch from b7bebca to ad239e3 Compare August 25, 2026 12:02
@legendecas legendecas added the request-ci Add this label to start a Jenkins CI on a PR. label Aug 25, 2026
@github-actions github-actions Bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Aug 25, 2026
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-ci PRs that need a full CI run. review wanted PRs that need reviews. util Issues and PRs related to the built-in util module.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants