diff --git a/src/js_printer.zig b/src/js_printer.zig index ebe08d3d59..c510555bba 100644 --- a/src/js_printer.zig +++ b/src/js_printer.zig @@ -3685,6 +3685,8 @@ fn NewPrinter( switch (stmt.data) { .s_comment => |s| { + p.printIndent(); + p.addSourceMapping(stmt.loc); p.printIndentedComment(s.text); }, .s_function => |s| { @@ -5146,16 +5148,26 @@ fn NewPrinter( if (strings.startsWith(text, "/*")) { // Re-indent multi-line comments while (strings.indexOfChar(text, '\n')) |newline_index| { + + // Skip over \r if it precedes \n + if (newline_index > 0 and text[newline_index - 1] == '\r') { + p.print(text[0 .. newline_index - 1]); + p.print("\n"); + } else { + p.print(text[0 .. newline_index + 1]); + } p.printIndent(); - p.print(text[0 .. newline_index + 1]); + text = text[newline_index + 1 ..]; } - p.printIndent(); p.print(text); p.printNewline(); } else { // Print a mandatory newline after single-line comments - p.printIndent(); + if (text.len > 0 and text[text.len - 1] == '\r') { + text = text[0 .. text.len - 1]; + } + p.print(text); p.print("\n"); } diff --git a/test/bundler/bundler_comments.test.ts b/test/bundler/bundler_comments.test.ts index 7abcd563bc..540129c5ce 100644 --- a/test/bundler/bundler_comments.test.ts +++ b/test/bundler/bundler_comments.test.ts @@ -1,4 +1,5 @@ -import { describe } from "bun:test"; +import { describe, expect } from "bun:test"; +import { SourceMap } from "node:module"; import { itBundled } from "./expectBundled"; describe("single-line comments", () => { @@ -351,3 +352,42 @@ describe("single-line comments", () => { }, }); }); + +describe("multi-line comments", () => { + itBundled("comment with \\r\\n has sourcemap", { + files: { + "/entry.js": "/*!\r\n * Legal comment line 1\r\n * Legal comment line 2\r\n */\r\nexport const x = 1;", + }, + sourceMap: "external", + onAfterBundle(api) { + const output = api.readFile("/out.js"); + const sourcemapContent = api.readFile("/out.js.map"); + const sourcemap = JSON.parse(sourcemapContent); + const sm = new SourceMap(sourcemap); + + // Find the multi-line legal comment in the output + const outputLines = output.split("\n"); + let commentLineIndex = -1; + for (let i = 0; i < outputLines.length; i++) { + if (outputLines[i].includes("Legal comment")) { + commentLineIndex = i; + break; + } + } + + expect(commentLineIndex).toBeGreaterThanOrEqual(0); + + // The multi-line legal comment should have a sourcemap entry + const entry = sm.findEntry(commentLineIndex, 0); + + // Verify we found a mapping for the comment + expect(entry).toBeTruthy(); + expect(Object.keys(entry).length).toBeGreaterThan(0); + + // The mapping should point back to the original source + expect(entry!.originalSource!).toContain("entry.js"); + expect(typeof entry.originalLine).toBe("number"); + expect(entry.originalLine).toBeGreaterThanOrEqual(0); + }, + }); +}); diff --git a/test/no-validate-exceptions.txt b/test/no-validate-exceptions.txt index 2d31e15934..67563774a7 100644 --- a/test/no-validate-exceptions.txt +++ b/test/no-validate-exceptions.txt @@ -49,6 +49,7 @@ test/bundler/esbuild/default.test.ts test/cli/install/bun-repl.test.ts test/js/third_party/astro/astro-post.test.js test/regression/issue/ctrl-c.test.ts +test/bundler/bundler_comments.test.ts test/js/node/test/parallel/test-fs-promises-file-handle-readLines.mjs # trips asan on my macos test machine