Skip to content

Commit

Permalink
Fix comments after directive (prettier#14081)
Browse files Browse the repository at this point in the history
  • Loading branch information
fisker authored and medikoo committed Jan 4, 2024
1 parent 1c5a6ce commit 40ab73c
Show file tree
Hide file tree
Showing 7 changed files with 672 additions and 27 deletions.
13 changes: 13 additions & 0 deletions changelog_unreleased/javascript/14081.md
@@ -0,0 +1,13 @@
#### Fix comments after directive (#14081 by @fisker)

<!-- prettier-ignore -->
```jsx
// Input
"use strict" /* comment */;

// Prettier stable (with other js parsers except `babel`)
Error: Comment "comment" was not printed. Please report this error!

// Prettier main
<Same as input>
```
14 changes: 13 additions & 1 deletion src/language-js/print/literal.js
@@ -1,6 +1,7 @@
"use strict";
const { printString, printNumber } = require("../../common/util.js");
const { replaceTextEndOfLine } = require("../../document/doc-utils.js");
const { printDirective } = require("./misc.js");

function printLiteral(path, options /*, print*/) {
const node = path.getNode();
Expand Down Expand Up @@ -41,14 +42,25 @@ function printLiteral(path, options /*, print*/) {
}

if (typeof value === "string") {
return replaceTextEndOfLine(printString(node.raw, options));
return isDirective(path)
? printDirective(node.raw, options)
: replaceTextEndOfLine(printString(node.raw, options));
}

return String(value);
}
}
}

function isDirective(path) {
if (path.getName() !== "expression") {
return;
}

const parent = path.getParentNode();
return parent.type === "ExpressionStatement" && parent.directive;
}

function printBigInt(raw) {
return raw.toLowerCase();
}
Expand Down
19 changes: 19 additions & 0 deletions src/language-js/print/misc.js
Expand Up @@ -93,6 +93,24 @@ function printRestSpread(path, options, print) {
return ["...", print("argument"), printTypeAnnotation(path, options, print)];
}

function printDirective(rawText, options) {
const rawContent = rawText.slice(1, -1);

// Check for the alternate quote, to determine if we're allowed to swap
// the quotes on a DirectiveLiteral.
if (rawContent.includes('"') || rawContent.includes("'")) {
return rawText;
}

const enclosingQuote = options.singleQuote ? "'" : '"';

// Directives are exact code unit sequences, which means that you can't
// change the escape sequences they use.
// See https://github.com/prettier/prettier/issues/1555
// and https://tc39.github.io/ecma262/#directive-prologue
return enclosingQuote + rawContent + enclosingQuote;
}

module.exports = {
printOptionalToken,
printDefiniteToken,
Expand All @@ -102,4 +120,5 @@ module.exports = {
printTypeAnnotation,
printRestSpread,
adjustClause,
printDirective,
};
28 changes: 2 additions & 26 deletions src/language-js/printer-estree.js
Expand Up @@ -25,7 +25,6 @@ const {
isLineComment,
isNextLineEmpty,
needsHardlineAfterDanglingComment,
rawText,
hasIgnoreComment,
isCallExpression,
isMemberExpression,
Expand All @@ -50,6 +49,7 @@ const {
adjustClause,
printRestSpread,
printDefiniteToken,
printDirective,
} = require("./print/misc.js");
const {
printImportDeclaration,
Expand Down Expand Up @@ -219,11 +219,6 @@ function printPathNoParens(path, options, print, args) {
case "EmptyStatement":
return "";
case "ExpressionStatement": {
// Detect Flow and TypeScript directives
if (node.directive) {
return [printDirective(node.expression, options), semi];
}

if (
options.parser === "__vue_event_binding" ||
options.parser === "__vue_ts_event_binding"
Expand Down Expand Up @@ -424,7 +419,7 @@ function printPathNoParens(path, options, print, args) {
case "Directive":
return [print("value"), semi]; // Babel 6
case "DirectiveLiteral":
return printDirective(node, options);
return printDirective(node.extra.raw, options);
case "UnaryExpression":
parts.push(node.operator);

Expand Down Expand Up @@ -890,25 +885,6 @@ function printPathNoParens(path, options, print, args) {
}
}

function printDirective(node, options) {
const raw = rawText(node);
const rawContent = raw.slice(1, -1);

// Check for the alternate quote, to determine if we're allowed to swap
// the quotes on a DirectiveLiteral.
if (rawContent.includes('"') || rawContent.includes("'")) {
return raw;
}

const enclosingQuote = options.singleQuote ? "'" : '"';

// Directives are exact code unit sequences, which means that you can't
// change the escape sequences they use.
// See https://github.com/prettier/prettier/issues/1555
// and https://tc39.github.io/ecma262/#directive-prologue
return enclosingQuote + rawContent + enclosingQuote;
}

function canAttachComment(node) {
return (
node.type &&
Expand Down

0 comments on commit 40ab73c

Please sign in to comment.