Skip to content

Commit

Permalink
Move to comments.ts
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolo-ribaudo committed Oct 24, 2022
1 parent 43ab4a6 commit 2b1184c
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 42 deletions.
61 changes: 61 additions & 0 deletions packages/babel-parser/src/parser/comments.ts
Expand Up @@ -289,4 +289,65 @@ export default class CommentsParser extends BaseParser {
}
}
}

/*
* Used to finalize the leading comments of a node, even if they could
* be attached as leading comments to a parent node.
*
* In case of comments followed by a decorator followed by `export`,
* we manually attach them to the decorator node rather than to the
* class declaration node. This is because the class location range
* overlaps with `export`, and this causes confusing comments behavior:
*
*/ // /* comment */ @dec export class Foo {}
/*
* See [takeLeadingCommentsAfterLastToken] for the hanling of comments
* after `export`.
*/
forceFinalizeLeadingComments(node: Node): void {
const { commentStack } = this.state;
for (let i = commentStack.length - 1; i >= 0; i--) {
const commentWS = commentStack[i];
if (commentWS.trailingNode === node) {
this.finalizeComment(commentWS);
commentStack.splice(i, 1);
} else if (commentWS.end < node.start) {
break;
}
}
}

/*
* Used to take the comments after the last token as leading
* comments of the given node, even if their start position
* is after the start position of the node.
*
* In case of decorators followed by `export`, we manually mark the
* comments between `export` and `class` as leading comments of the
* class declaration node.
* This is needed because the class location range overlaps with
* `export`, and thus they would be marked as inner comments of
* the class declaration:
*
*/ // @dec export /* comment */ class Foo {}
/*
* See [forceFinalizeLeadingComments] for the handling of comments
* before decorators.
*/
takeLeadingCommentsAfterLastToken(node: Undone<Node>): void {
const {
start,
lastTokEndLoc: { index: lastTokEnd },
} = this.state;

const { commentStack } = this.state;
for (let i = commentStack.length - 1; i >= 0; i--) {
const commentWS = commentStack[i];
if (commentWS.start >= lastTokEnd && commentWS.end <= start) {
commentWS.trailingNode = node as Node;
} else if (commentWS.end < lastTokEnd) {
break;
}
}
}
}
51 changes: 9 additions & 42 deletions packages/babel-parser/src/parser/statement.ts
Expand Up @@ -547,32 +547,14 @@ export default abstract class StatementParser extends ExpressionParser {
this.resetStartLocationFromNode(node, decorators[0]);
this.state.decoratorStack[this.state.decoratorStack.length - 1] = [];

// In case of decorators followed by `export`, we manually mark the
// comments between `export` and `class` as leading comments of the
// class declaration node.
// This is needed because the class location range overlaps with
// `export`, and thus they would me marked as inner comments of
// the class declaration.
// @dec export /* comment */ class Foo {}
// See [parseDecorators] for the hanling of comments before decorators
if (this.decoratorsEnabledBeforeExport()) {
const {
start,
lastTokStart,
lastTokEndLoc: { index: lastTokEnd },
} = this.state;

if (this.input.slice(lastTokStart, lastTokEnd) === "export") {
const { commentStack } = this.state;
for (let i = commentStack.length - 1; i >= 0; i--) {
const commentWS = commentStack[i];
if (commentWS.start >= lastTokEnd && commentWS.end <= start) {
commentWS.trailingNode = node as N.Node;
} else if (commentWS.end < lastTokEnd) {
break;
}
}
}
if (
this.decoratorsEnabledBeforeExport() &&
this.input.slice(
this.state.lastTokStart,
this.state.lastTokEndLoc.index,
) === "export"
) {
this.takeLeadingCommentsAfterLastToken(node);
}
}
}
Expand All @@ -599,23 +581,8 @@ export default abstract class StatementParser extends ExpressionParser {
this.raise(Errors.DecoratorExportClass, { at: this.state.startLoc });
}

// In case of comments followed by a decorator followed by `export`,
// we manually attach them to the decorator node rather than to the
// class declaration node. This is because the class location range
// overlaps with `export`, and this causes confusing comments behavior:
// /* comment */ @dec export class Foo {}
// See [takeDecorators] for the hanling of comments after `export`
const firstDecorator = decoratorStack[decoratorStack.length - 1][0];
const { commentStack } = this.state;
for (let i = commentStack.length - 1; i >= 0; i--) {
const commentWS = commentStack[i];
if (commentWS.trailingNode === firstDecorator) {
this.finalizeComment(commentWS);
commentStack.splice(i, 1);
} else if (commentWS.end < firstDecorator.start) {
break;
}
}
this.forceFinalizeLeadingComments(firstDecorator);
} else if (!this.canHaveLeadingDecorator()) {
throw this.raise(Errors.UnexpectedLeadingDecorator, {
at: this.state.startLoc,
Expand Down

0 comments on commit 2b1184c

Please sign in to comment.