Fix some innerComments issues
MODIFY
packages/@romejs/cli-reporter/Reporter.ts
packages/@romejs/cli-reporter/Reporter.ts
@@ -1308,8 +1308,7 @@ export default class Reporter {
});
},
- setTotal: (total: number,
- approximate: boolean = false) => {
+ setTotal: (total: number, approximate: boolean = false) => {
dispatch({
type: 'PROGRESS_SET_TOTAL',
total,

MODIFY
packages/@romejs/js-formatter/builders/expressions/CallExpression.ts
packages/@romejs/js-formatter/builders/expressions/CallExpression.ts
@@ -28,6 +28,7 @@ export default function CallExpression(builder: Builder, node: AnyNode): Tokens
return [
concat(tokens),
operator('('),
+ ...builder.tokenizeInnerComments(node),
builder.tokenizeCommaList(node.arguments, node, {
trailing: true,
}),

MODIFY
packages/@romejs/js-parser/parser.ts
packages/@romejs/js-parser/parser.ts
@@ -225,6 +225,17 @@ const createJSParser = createParser(
return node;
}
+ // Sometimes we want to pretend we're in different locations to consume the comments of other nodes
+ finishNodeWithCommentStarts<T extends AnyNode>(
+ starts: Array<Position>,
+ node: T,
+ ): T {
+ for (const start of starts) {
+ node = this.finishNode(start, node);
+ }
+ return node;
+ }
+
finishNode<T extends AnyNode>(start: Position, node: T): T {
return this.finishNodeAt(start, this.getLastEndPosition(), node);
}

MODIFY
packages/@romejs/js-parser/parser/comments.ts
packages/@romejs/js-parser/parser/comments.ts
@@ -64,6 +64,30 @@ function hasComments(
return comments !== undefined && comments.length > 0;
}
+function setComments(
+ node: AnyNode,
+ key: 'leadingComments' | 'trailingComments',
+ comments: Array<AnyComment>,
+) {
+ let innerEndIndex = -1;
+
+ for (let i = 0; i < comments.length; i++) {
+ const comment = comments[i];
+ if (start(comment) >= start(node) && end(comment) <= end(node)) {
+ innerEndIndex++;
+ } else {
+ break;
+ }
+ }
+
+ if (innerEndIndex === -1) {
+ node[key] = getIds(comments);
+ } else {
+ node.innerComments = getIds(comments.slice(0, innerEndIndex + 1));
+ node[key] = getIds(comments.slice(innerEndIndex + 1));
+ }
+}
+
export function addComment(parser: JSParser, comment: AnyComment): void {
parser.state.trailingComments.push(comment);
parser.state.leadingComments.push(comment);
@@ -238,7 +262,9 @@ export function attachComments(parser: JSParser, node: AnyNode) {
if (lastChild !== node && end(parser.comments.assertGetCommentFromId(last(
lastChild.leadingComments,
))) <= start(node)) {
- node.leadingComments = lastChild.leadingComments;
+ setComments(node, 'leadingComments', parser.comments.getCommentsFromIds(
+ lastChild.leadingComments,
+ ));
lastChild.leadingComments = undefined;
} else {
// A leading comment for an anonymous class had been stolen by its first ClassMethod,
@@ -248,7 +274,13 @@ export function attachComments(parser: JSParser, node: AnyNode) {
if (end(parser.comments.assertGetCommentFromId(
lastChild.leadingComments[i],
)) <= start(node)) {
- node.leadingComments = lastChild.leadingComments.splice(0, i + 1);
+ setComments(
+ node,
+ 'leadingComments',
+ parser.comments.getCommentsFromIds(
+ lastChild.leadingComments.splice(0, i + 1),
+ ),
+ );
break;
}
}
@@ -268,7 +300,7 @@ export function attachComments(parser: JSParser, node: AnyNode) {
}
if (parser.state.leadingComments.length > 0) {
- node.leadingComments = getIds(parser.state.leadingComments);
+ setComments(node, 'leadingComments', parser.state.leadingComments);
parser.state.leadingComments = [];
}
} else {
@@ -299,7 +331,7 @@ export function attachComments(parser: JSParser, node: AnyNode) {
const leadingComments = parser.state.leadingComments.slice(0, i);
if (leadingComments.length > 0) {
- node.leadingComments = getIds(leadingComments);
+ setComments(node, 'leadingComments', leadingComments);
}
// Similarly, trailing comments are attached later. The variable
@@ -314,23 +346,7 @@ export function attachComments(parser: JSParser, node: AnyNode) {
parser.state.commentPreviousNode = node;
if (trailingComments) {
- let innerEndIndex = -1;
-
- for (let i = 0; i < trailingComments.length; i++) {
- const comment = trailingComments[i];
- if (start(comment) >= start(node) && end(comment) <= end(node)) {
- innerEndIndex++;
- } else {
- break;
- }
- }
-
- if (innerEndIndex === -1) {
- node.trailingComments = getIds(trailingComments);
- } else {
- node.innerComments = getIds(trailingComments.slice(0, innerEndIndex + 1));
- node.trailingComments = getIds(trailingComments.slice(innerEndIndex + 1));
- }
+ setComments(node, 'trailingComments', trailingComments);
}
commentStack.push(node);

MODIFY
packages/@romejs/js-parser/parser/expression.ts
packages/@romejs/js-parser/parser/expression.ts
@@ -759,6 +759,7 @@ export function parseSubscripts(
if (base.type === 'ReferenceIdentifier' && base.name === 'async' &&
parser.state.noArrowAt.includes(startPos.index)) {
+ const argsStart = parser.getPosition();
const openContext = parser.expectOpening(
tt.parenL,
tt.parenR,
@@ -766,7 +767,7 @@ export function parseSubscripts(
);
const callee = base;
const {args} = parseCallExpressionArguments(parser, openContext, false);
- base = parser.finishNode(startPos, {
+ base = parser.finishNodeWithCommentStarts([argsStart, startPos], {
type: 'CallExpression',
callee,
arguments: args,
@@ -974,13 +975,17 @@ export function parseExpressionSubscript(
const typeArguments = parseTypeCallArguments(parser);
if (!noCalls && parser.match(tt.parenL)) {
+ const argsStart = parser.getPosition();
const openContext = parser.expectOpening(
tt.parenL,
tt.parenR,
'call arguments',
);
const {args} = parseCallExpressionArguments(parser, openContext, false);
- const node: CallExpression = parser.finishNode(startPos, {
+ const node: CallExpression = parser.finishNodeWithCommentStarts([
+ argsStart,
+ startPos,
+ ], {
type: 'CallExpression',
arguments: args,
callee: base,
@@ -1015,6 +1020,7 @@ export function parseExpressionSubscript(
parser.state.yieldPos = number0;
parser.state.awaitPos = number0;
+ const argsStart = parser.getPosition();
const openContext = parser.expectOpening(
tt.parenL,
tt.parenR,
@@ -1059,7 +1065,7 @@ export function parseExpressionSubscript(
parser.state.maybeInArrowParameters = oldMaybeInArrowParameters;
parser.state.commaAfterSpreadAt = oldCommaAfterSpreadAt;
- return parser.finishNode(startPos, {
+ return parser.finishNodeWithCommentStarts([argsStart, startPos], {
type: 'CallExpression',
callee,
arguments: args,
@@ -2634,6 +2640,7 @@ export function parseMethod(parser: JSParser, opts: {
parser.state.awaitPos = number0;
const allowTSModifiers = isConstructor;
+ const headStart = parser.getPosition();
const {typeParameters, rest, params} = parseFunctionParams(
parser,
kind,
@@ -2641,6 +2648,7 @@ export function parseMethod(parser: JSParser, opts: {
);
const start = parser.getPosition();
const {body, head} = parseFunctionBodyAndFinish(parser, {
+ headStart,
rest,
params,
id: undefined,
@@ -2727,16 +2735,6 @@ isAsync: boolean = false): ArrowFunctionExpression {
const headEnd = parser.getPosition();
- const {body, hasHoistedVars} = parseFunctionBody(parser, {
- id: undefined,
- allowBodiless: false,
- isArrowFunction: true,
- isMethod: false,
- isAsync,
- isGenerator: false,
- start,
- });
-
let params: Array<AnyBindingPattern> = [];
let rest: undefined | AnyTargetBindingPattern = opts.rest;
@@ -2752,6 +2750,31 @@ isAsync: boolean = false): ArrowFunctionExpression {
));
}
+ let head = parser.finishNodeAt(start, headEnd, createFunctionHead(
+ parser,
+ params,
+ rest,
+ {
+ hasHoistedVars: false,
+ async: isAsync,
+ },
+ ));
+
+ const {body, hasHoistedVars} = parseFunctionBody(parser, {
+ id: undefined,
+ allowBodiless: false,
+ isArrowFunction: true,
+ isMethod: false,
+ isAsync,
+ isGenerator: false,
+ start,
+ });
+
+ head = {
+ ...head,
+ hasHoistedVars,
+ };
+
checkFunctionNameAndParams(parser, {
isArrowFunction: true,
isMethod: false,
@@ -2770,11 +2793,7 @@ isAsync: boolean = false): ArrowFunctionExpression {
return parser.finishNode(start, {
type: 'ArrowFunctionExpression',
body,
- head: createFunctionHead(parser, params, rest, {
- loc: parser.finishLocAt(start, headEnd),
- hasHoistedVars,
- async: isAsync,
- }),
+ head,
});
}
@@ -2802,7 +2821,9 @@ type FunctionBodyParseOpts = {
export function parseFunctionBodyAndFinish(
parser: JSParser,
- opts: CheckFunctionNameParamsOpts & FunctionBodyParseOpts,
+ opts: CheckFunctionNameParamsOpts & FunctionBodyParseOpts & {
+ headStart: Position;
+ },
): {
head: FunctionHead;
body: undefined | ParseFunctionBodyReturn['body'];
@@ -2815,34 +2836,30 @@ export function parseFunctionBodyAndFinish(
[returnType, predicate] = parseTypeAnnotationAndPredicate(parser);
}
- if (opts.allowBodiless && !parser.match(tt.braceL) &&
- parser.isLineTerminator()) {
- return {
- head: createFunctionHead(parser, opts.params, opts.rest, {
- loc: parser.finishLoc(opts.start),
- hasHoistedVars: false,
+ const headEnd = parser.getPosition();
+ const head = parser.finishNodeAt(opts.headStart, headEnd, createFunctionHead(
+ parser,
+ opts.params,
+ opts.rest,
+ {
generator: opts.isGenerator,
async: opts.isAsync,
+ hasHoistedVars: false,
returnType,
predicate,
- }),
+ },
+ ));
+
+ if (opts.allowBodiless && !parser.match(tt.braceL) &&
+ parser.isLineTerminator()) {
+ return {
+ head,
body: undefined,
};
}
- const headEnd = parser.getPosition();
-
const {body, hasHoistedVars} = parseFunctionBody(parser, opts);
- const head = createFunctionHead(parser, opts.params, opts.rest, {
- loc: parser.finishLocAt(opts.start, headEnd),
- generator: opts.isGenerator,
- async: opts.isAsync,
- hasHoistedVars: false,
- returnType,
- predicate,
- });
-
checkFunctionNameAndParams(parser, {
isArrowFunction: opts.isArrowFunction,
isMethod: opts.isMethod,

MODIFY
packages/@romejs/js-parser/parser/statement.ts
packages/@romejs/js-parser/parser/statement.ts
@@ -1437,6 +1437,7 @@ export function parseFunction(parser: JSParser, opts: {
id = parseFunctionId(parser, false);
}
+ const headStart = parser.getPosition();
const {params, rest, typeParameters} = parseFunctionParams(parser);
const {head, body} = parseFunctionBodyAndFinish(parser, {
allowBodiless: isStatement,
@@ -1447,6 +1448,7 @@ export function parseFunction(parser: JSParser, opts: {
isMethod: false,
isAsync,
isGenerator,
+ headStart,
start,
});

ADD
packages/@romejs/js-parser/test-fixtures/comments/call-expression-inner/input.js
+callExpression(/* EMPTY */);

ADD
packages/@romejs/js-parser/test-fixtures/comments/function-head-inner/input.ts
+function x(/* EMPTY */);
+function x(/* ARGS */) {
+ // BODY
+}

MODIFY
packages/@romejs/js-parser/tokenizer/context.ts
packages/@romejs/js-parser/tokenizer/context.ts
@@ -23,8 +23,7 @@ export class TokContext {
isExpr?: boolean,
preserveSpace?: boolean,
override?: TokContextOverride,
- ) // Takes a Tokenizer as a parser.parameter, and returns void.
- {
+ ) {
this.token = token;
this.isExpr = !!isExpr;
this.preserveSpace = !!preserveSpace;

Fix some innerComments issues