From 29622cc4f7dd02caa55d0febe131da6a6fd0983a Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Tue, 23 Sep 2025 17:42:16 +0800 Subject: [PATCH] Fix comments get duplicated in angular interpolation (#17862) --- changelog_unreleased/angular/17862.md | 15 ++++ eslint.config.js | 1 + src/language-js/parse/angular.js | 17 ++-- src/language-js/print/angular.js | 14 +--- .../angular/__snapshots__/format.test.js.snap | 80 +++++++++++++++---- .../html/__snapshots__/format.test.js.snap | 16 ++++ .../angular/interpolation/html/comments.html | 1 + 7 files changed, 111 insertions(+), 33 deletions(-) create mode 100644 changelog_unreleased/angular/17862.md create mode 100644 tests/format/angular/interpolation/html/comments.html diff --git a/changelog_unreleased/angular/17862.md b/changelog_unreleased/angular/17862.md new file mode 100644 index 000000000..f0a1fae71 --- /dev/null +++ b/changelog_unreleased/angular/17862.md @@ -0,0 +1,15 @@ +#### Fix comments get duplicated in interpolation (#17862 by @fisker) + + +```html + +{{a() // comment}} + + +{{ a(// comment) // comment }} + + +{{ + a() // comment +}} +``` diff --git a/eslint.config.js b/eslint.config.js index 985802cd1..a75e6bae5 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -430,6 +430,7 @@ export default [ functions: ["hasComment", "getComments"], }, "src/language-js/pragma.js", + "src/language-js/parse/angular.js", "src/language-js/parse/babel.js", "src/language-js/parse/meriyah.js", "src/language-js/parse/json.js", diff --git a/src/language-js/parse/angular.js b/src/language-js/parse/angular.js index f4e2c9e65..9638864d4 100644 --- a/src/language-js/parse/angular.js +++ b/src/language-js/parse/angular.js @@ -13,14 +13,21 @@ function createParser(parseMethod) { return { astFormat: "estree", parse(text) { - const node = parseMethod(text); + let node = parseMethod(text); + // @ts-expect-error -- safe + const { comments } = node; + // @ts-expect-error -- safe + delete node.comments; + + if (parseMethod === parseAction && node.type !== "NGChainedExpression") { + // @ts-expect-error -- expected + node = { ...node, type: "NGChainedExpression", expressions: [node] }; + } return { type: "NGRoot", - node: - parseMethod === parseAction && node.type !== "NGChainedExpression" - ? { ...node, type: "NGChainedExpression", expressions: [node] } - : node, + node, + comments, }; }, locStart, diff --git a/src/language-js/print/angular.js b/src/language-js/print/angular.js index 923373c87..9e5ddc355 100644 --- a/src/language-js/print/angular.js +++ b/src/language-js/print/angular.js @@ -1,11 +1,6 @@ import { group, join, line } from "../../document/builders.js"; import UnexpectedNodeError from "../../utils/unexpected-node-error.js"; -import { - createTypeCheckFunction, - getComments, - hasComment, - hasNode, -} from "../utils/index.js"; +import { createTypeCheckFunction, hasNode } from "../utils/index.js"; import { printBinaryishExpression } from "./binaryish.js"; /** @import AstPath from "../../common/ast-path.js" */ @@ -20,12 +15,7 @@ function printAngular(path, options, print) { switch (node.type) { case "NGRoot": - return [ - print("node"), - hasComment(node.node) - ? " //" + getComments(node.node)[0].value.trimEnd() - : "", - ]; + return print("node"); case "NGPipeExpression": return printBinaryishExpression(path, options, print); case "NGChainedExpression": diff --git a/tests/format/angular/angular/__snapshots__/format.test.js.snap b/tests/format/angular/angular/__snapshots__/format.test.js.snap index 24cb9b66a..574d1e5bd 100644 --- a/tests/format/angular/angular/__snapshots__/format.test.js.snap +++ b/tests/format/angular/angular/__snapshots__/format.test.js.snap @@ -468,7 +468,9 @@ printWidth: 80 [target]="!x" [target]="a" [target]="a" - [target]="a // hello" + [target]=" + a // hello + " [target]="a.b" [target]="a?.b" [target]="a?.[b]" @@ -480,7 +482,9 @@ printWidth: 80 (target)="a = 1" (target)="a.b = 1" (target)="a[b] = 1" - (target)="(a) // hello" + (target)=" + (a) // hello + " (target)="(a); (b)" (event)="(0)" (event)="(a.b)" @@ -747,7 +751,9 @@ printWidth: 80 [target]="!x" [target]="a" [target]="a" - [target]="a // hello" + [target]=" + a // hello + " [target]="a.b" [target]="a?.b" [target]="a?.[b]" @@ -759,7 +765,9 @@ printWidth: 80 (target)="a = 1" (target)="a.b = 1" (target)="a[b] = 1" - (target)="(a) // hello" + (target)=" + (a) // hello + " (target)="(a); (b)" (event)="(0)" (event)="(a.b)" @@ -1653,7 +1661,9 @@ trailingComma: "es5" [target]="!x" [target]="a" [target]="a" - [target]="a // hello" + [target]=" + a // hello + " [target]="a.b" [target]="a?.b" [target]="a?.[b]" @@ -1665,7 +1675,9 @@ trailingComma: "es5" (target)="a = 1" (target)="a.b = 1" (target)="a[b] = 1" - (target)="(a) // hello" + (target)=" + (a) // hello + " (target)="(a); (b)" (event)="(0)" (event)="(a.b)" @@ -1932,7 +1944,9 @@ trailingComma: "none" [target]="!x" [target]="a" [target]="a" - [target]="a // hello" + [target]=" + a // hello + " [target]="a.b" [target]="a?.b" [target]="a?.[b]" @@ -1944,7 +1958,9 @@ trailingComma: "none" (target)="a = 1" (target)="a.b = 1" (target)="a[b] = 1" - (target)="(a) // hello" + (target)=" + (a) // hello + " (target)="(a); (b)" (event)="(0)" (event)="(a.b)" @@ -3027,11 +3043,19 @@ printWidth: 80
{{ !x }}
{{ a }}
{{ a }}
-
{{ a // hello }}
+
+ {{ + a // hello + }} +
{{ a.b }}
{{ a?.b() }}
{{ a?.b }}
-
{{ a // hello }}
+
+ {{ + a // hello + }} +