Fix last comment of an if test (#1042)
This one sucks. The range of the `test` of `if (a /* comment */) {}` is only `a` and doesn't include the comment nor parenthesis. This means that we have no way to know if the comment is placed before or after the `)` unless you look at the actual source and strip all the whitespace/comments characters to see if it's a `)`... This happened on the babel source code twice and many times in the fb codebase. I think we need to fix it unfortunately :( Fixes #867master
parent
f51c5daacb
commit
45796601c4
|
@ -19,6 +19,7 @@ var comparePos = util.comparePos;
|
||||||
var childNodesCacheKey = Symbol("child-nodes");
|
var childNodesCacheKey = Symbol("child-nodes");
|
||||||
var locStart = util.locStart;
|
var locStart = util.locStart;
|
||||||
var locEnd = util.locEnd;
|
var locEnd = util.locEnd;
|
||||||
|
var getNextNonSpaceNonCommentCharacter = util.getNextNonSpaceNonCommentCharacter;
|
||||||
|
|
||||||
// TODO Move a non-caching implementation of this function into ast-types,
|
// TODO Move a non-caching implementation of this function into ast-types,
|
||||||
// and implement a caching wrapper function here.
|
// and implement a caching wrapper function here.
|
||||||
|
@ -154,7 +155,7 @@ function attach(comments, ast, text, options) {
|
||||||
comment
|
comment
|
||||||
) ||
|
) ||
|
||||||
handleMemberExpressionComments(enclosingNode, followingNode, comment) ||
|
handleMemberExpressionComments(enclosingNode, followingNode, comment) ||
|
||||||
handleIfStatementComments(enclosingNode, followingNode, comment) ||
|
handleIfStatementComments(text, enclosingNode, followingNode, comment) ||
|
||||||
handleTryStatementComments(enclosingNode, followingNode, comment) ||
|
handleTryStatementComments(enclosingNode, followingNode, comment) ||
|
||||||
handleClassComments(enclosingNode, comment) ||
|
handleClassComments(enclosingNode, comment) ||
|
||||||
handleImportSpecifierComments(enclosingNode, comment) ||
|
handleImportSpecifierComments(enclosingNode, comment) ||
|
||||||
|
@ -217,7 +218,7 @@ function attach(comments, ast, text, options) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (
|
if (
|
||||||
handleIfStatementComments(enclosingNode, followingNode, comment) ||
|
handleIfStatementComments(text, enclosingNode, followingNode, comment) ||
|
||||||
handleObjectPropertyAssignment(enclosingNode, precedingNode, comment) ||
|
handleObjectPropertyAssignment(enclosingNode, precedingNode, comment) ||
|
||||||
handleTemplateLiteralComments(enclosingNode, comment) ||
|
handleTemplateLiteralComments(enclosingNode, comment) ||
|
||||||
handleCommentInEmptyParens(enclosingNode, comment) ||
|
handleCommentInEmptyParens(enclosingNode, comment) ||
|
||||||
|
@ -363,13 +364,25 @@ function addBlockOrNotComment(node, comment) {
|
||||||
// // comment
|
// // comment
|
||||||
// ...
|
// ...
|
||||||
// }
|
// }
|
||||||
function handleIfStatementComments(enclosingNode, followingNode, comment) {
|
function handleIfStatementComments(text, enclosingNode, followingNode, comment) {
|
||||||
if (
|
if (
|
||||||
!enclosingNode || enclosingNode.type !== "IfStatement" || !followingNode
|
!enclosingNode ||
|
||||||
|
enclosingNode.type !== "IfStatement" ||
|
||||||
|
!followingNode
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We unfortunately have no way using the AST or location of nodes to know
|
||||||
|
// if the comment is positioned before or after the condition parenthesis:
|
||||||
|
// if (a /* comment */) {}
|
||||||
|
// if (a) /* comment */ {}
|
||||||
|
// The only workaround I found is to look at the next character to see if
|
||||||
|
// it is a ).
|
||||||
|
if (getNextNonSpaceNonCommentCharacter(text, comment) === ")") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (followingNode.type === "BlockStatement") {
|
if (followingNode.type === "BlockStatement") {
|
||||||
addBlockStatementFirstComment(followingNode, comment);
|
addBlockStatementFirstComment(followingNode, comment);
|
||||||
return true;
|
return true;
|
||||||
|
|
14
src/util.js
14
src/util.js
|
@ -229,6 +229,19 @@ function isNextLineEmpty(text, node) {
|
||||||
return hasNewline(text, idx);
|
return hasNewline(text, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getNextNonSpaceNonCommentCharacter(text, node) {
|
||||||
|
let oldIdx = null;
|
||||||
|
let idx = locEnd(node);
|
||||||
|
while (idx !== oldIdx) {
|
||||||
|
oldIdx = idx;
|
||||||
|
idx = skipSpaces(text, idx);
|
||||||
|
idx = skipInlineComment(text, idx);
|
||||||
|
idx = skipTrailingComment(text, idx);
|
||||||
|
idx = skipNewline(text, idx);
|
||||||
|
}
|
||||||
|
return text.charAt(idx);
|
||||||
|
}
|
||||||
|
|
||||||
function hasSpaces(text, index, opts) {
|
function hasSpaces(text, index, opts) {
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
const idx = skipSpaces(text, opts.backwards ? index - 1 : index, opts);
|
const idx = skipSpaces(text, opts.backwards ? index - 1 : index, opts);
|
||||||
|
@ -306,6 +319,7 @@ module.exports = {
|
||||||
getParentExportDeclaration,
|
getParentExportDeclaration,
|
||||||
getPenultimate,
|
getPenultimate,
|
||||||
getLast,
|
getLast,
|
||||||
|
getNextNonSpaceNonCommentCharacter,
|
||||||
skipWhitespace,
|
skipWhitespace,
|
||||||
skipSpaces,
|
skipSpaces,
|
||||||
skipNewline,
|
skipNewline,
|
||||||
|
|
|
@ -115,3 +115,24 @@ async function f() {
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`trailing_comment.js 1`] = `
|
||||||
|
"if (code === 92 /* '\\\\' */) {}
|
||||||
|
if (code === 92 /* '\\\\' */ /* '\\\\' */) {}
|
||||||
|
|
||||||
|
if (code === 92) /* '\\\\' */ {}
|
||||||
|
if (code === 92) { /* '\\\\' */ }
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
if (code === 92 /* '\\\\' */) {
|
||||||
|
}
|
||||||
|
if (code === 92 /* '\\\\' */ /* '\\\\' */) {
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code === 92) {
|
||||||
|
/* '\\\\' */
|
||||||
|
}
|
||||||
|
if (code === 92) {
|
||||||
|
/* '\\\\' */
|
||||||
|
}
|
||||||
|
"
|
||||||
|
`;
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
if (code === 92 /* '\' */) {}
|
||||||
|
if (code === 92 /* '\' */ /* '\' */) {}
|
||||||
|
|
||||||
|
if (code === 92) /* '\' */ {}
|
||||||
|
if (code === 92) { /* '\' */ }
|
Loading…
Reference in New Issue