Skip to content

fix: preserve inner comment when adding a property to an empty object#165

Open
naveentehrpariya wants to merge 1 commit into
unjs:mainfrom
naveentehrpariya:fix/preserve-inner-comment-on-object-add
Open

fix: preserve inner comment when adding a property to an empty object#165
naveentehrpariya wants to merge 1 commit into
unjs:mainfrom
naveentehrpariya:fix/preserve-inner-comment-on-object-add

Conversation

@naveentehrpariya

@naveentehrpariya naveentehrpariya commented Jun 16, 2026

Copy link
Copy Markdown

Problem

Comments placed inside an otherwise-empty object literal are lost as soon as a property is added to that object.

import { parseModule, generateCode } from "magicast";

const mod = parseModule(`
export default {
  /* inner comment */
}
`);

mod.exports.default.foo = 1;

console.log(generateCode(mod).code);

Actual:

export default {
  foo: 1
};

Expected — the inner comment is preserved:

export default {
  /* inner comment */
  foo: 1
};

Cause

@babel/parser attaches comments that sit inside an empty object as innerComments on the ObjectExpression node. recast's printer only looks at node.comments (entries flagged leading/trailing) and ignores innerComments. While the node is untouched recast reuses the original source verbatim, so the comment survives; once a property is added the node is reprinted and the comment is dropped.

Fix

When inserting the first property into an object that still carries innerComments, move those comments onto the new property as leading comments so recast emits them. Objects that already have properties, and objects without inner comments, are unaffected.

Both block (/* */) and line (//) inner comments are covered by the added tests.

Fixes #33

Summary by CodeRabbit

  • Bug Fixes

    • Fixed an issue where comments on empty objects were inadvertently lost during code transformation and generation. Comments now persist correctly through object modifications and appear properly in the final code output.
  • Tests

    • Added comprehensive test cases to ensure proper comment preservation when transforming empty objects, covering both block and line comments

Babel attaches comments inside an otherwise-empty object literal
(e.g. `{ /* keep me */ }`) as `innerComments`. recast's printer reads
comments from `node.comments` and ignores `innerComments`, so once the
object is modified and reprinted the comment was silently dropped.

When inserting the first property into such an object, move the inner
comments onto the new property as leading comments so they survive code
generation.

Fixes unjs#33
@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 71b83f65-046d-4eba-9dd7-ecfc67ee661f

📥 Commits

Reviewing files that changed from the base of the PR and between 8d4fed0 and 22abfaa.

📒 Files selected for processing (2)
  • src/proxy/object.ts
  • test/object.test.ts

📝 Walkthrough

Walkthrough

proxifyObject in src/proxy/object.ts is updated to migrate Babel innerComments from an empty object literal onto the first inserted property as leading comments, then clears node.innerComments. Two Vitest tests are added to verify block and line inner comments survive generate() after a property insertion.

Changes

Inner comment preservation on empty object literals

Layer / File(s) Summary
innerComments migration and verification tests
src/proxy/object.ts, test/object.test.ts
When inserting the first property into an empty object, node.innerComments are remapped as leading comments on the new property node and then cleared. Two new tests assert that block-style and line-style inner comments both appear in the generated output after property insertion.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

🐇 A comment hid inside an empty {},
Forgotten when a prop came along to stay.
But now little rabbit moves it up front,
As a leading remark — a delightful stunt!
No more lost words in the AST hay. 🌿

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely summarizes the main change: preserving inner comments when adding a property to an empty object.
Linked Issues check ✅ Passed The code changes directly address the core requirement from issue #33 by implementing logic to preserve inner comments when properties are added to empty objects.
Out of Scope Changes check ✅ Passed All changes are scoped to fixing the inner comment preservation issue; no unrelated modifications are present.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

Inner comment lost when manipulating an object

1 participant