From 622cb5efe0045c06d278fca1b76a64c4ff205092 Mon Sep 17 00:00:00 2001 From: copilot-swe-agent <198982749+copilot-swe-agent@users.noreply.github.com> Date: Fri, 21 Nov 2025 14:50:45 +0000 Subject: [PATCH] fix(parser): preserve legal comments with @preserve/@license when preceded by other annotations (#15929) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Legal comments like `/* @foo @preserve */` were not being preserved when legal comment output was enabled. The parser only checked if the first `@` annotation matched known patterns, missing `@preserve`/`@license` later in the comment. ## Changes **Parser (`oxc_parser/src/lexer/trivia_builder.rs`)** - Add fallback check using `contains_license_or_preserve_comment` after `__PURE__`/`__NO_SIDE_EFFECTS__` checks - Ensures `@license`/`@preserve` detected anywhere in comment text ## Example ```javascript // Before: Legal comment not detected by parser /* @foo @preserve */ function foo() {} // Parser classifies as: CommentContent::None ❌ // After: Legal comment correctly detected /* @foo @preserve */ function foo() {} // Parser classifies as: CommentContent::Legal ✅ ``` Related: https://github.com/rolldown/rolldown/issues/7160
Original prompt > `/* @foo @preserve */` should be preserved when legal comment output is enabled even if comment output is disabled. https://github.com/rolldown/rolldown/issues/7160 is related
--- ✨ Let Copilot coding agent [set things up for you](https://github.com/oxc-project/oxc/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo. --- crates/oxc_parser/src/lexer/trivia_builder.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/crates/oxc_parser/src/lexer/trivia_builder.rs b/crates/oxc_parser/src/lexer/trivia_builder.rs index b360476a94657..fb29d2dba23b7 100644 --- a/crates/oxc_parser/src/lexer/trivia_builder.rs +++ b/crates/oxc_parser/src/lexer/trivia_builder.rs @@ -248,11 +248,19 @@ impl TriviaBuilder { if rest.starts_with(b"PURE__") { comment.content = CommentContent::Pure; self.has_pure_comment = true; + return; } else if rest.starts_with(b"NO_SIDE_EFFECTS__") { comment.content = CommentContent::NoSideEffects; self.has_no_side_effects_comment = true; + return; } } + + // Fallback: check for @license or @preserve anywhere in the comment + // This handles cases like /* @foo @preserve */ where the first @ doesn't match known patterns + if contains_license_or_preserve_comment(s) { + comment.content = CommentContent::Legal; + } } } @@ -504,6 +512,8 @@ token /* Trailing 1 */ ("/* @license */", CommentContent::Legal), ("/* foo @preserve */", CommentContent::Legal), ("/* foo @license */", CommentContent::Legal), + ("/* @foo @preserve */", CommentContent::Legal), + ("/* @foo @license */", CommentContent::Legal), ("/** foo @preserve */", CommentContent::JsdocLegal), ("/** foo @license */", CommentContent::JsdocLegal), ("/** jsdoc */", CommentContent::Jsdoc),