Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Clean up parser comments #15252

Merged
merged 3 commits into from Dec 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
72 changes: 28 additions & 44 deletions packages/babel-parser/src/parser/comments.ts
Expand Up @@ -7,32 +7,38 @@ import type { Undone } from "./node";

/**
* A whitespace token containing comments
* @typedef CommentWhitespace
* @type {object}
* @property {number} start - the start of the whitespace token.
* @property {number} end - the end of the whitespace token.
* @property {Array<Comment>} comments - the containing comments
* @property {Node | null} leadingNode - the immediately preceding AST node of the whitespace token
* @property {Node | null} trailingNode - the immediately following AST node of the whitespace token
* @property {Node | null} containingNode - the innermost AST node containing the whitespace
* with minimal size (|end - start|)
*/
export type CommentWhitespace = {
/**
* the start of the whitespace token.
*/
start: number;
/**
* the end of the whitespace token.
*/
end: number;
/**
* the containing comments
*/
comments: Array<Comment>;
/**
* the immediately preceding AST node of the whitespace token
*/
leadingNode: Node | null;
/**
* the immediately following AST node of the whitespace token
*/
trailingNode: Node | null;
/**
* the innermost AST node containing the whitespace with minimal size (|end - start|)
*/
containingNode: Node | null;
};

/**
* Merge comments with node's trailingComments or assign comments to be
* trailingComments. New comments will be placed before old comments
* because the commentStack is enumerated reversely.
*
* @param {Undone<Node>} node
* @param {Array<Comment>} comments
*/
function setTrailingComments(node: Undone<Node>, comments: Array<Comment>) {
if (node.trailingComments === undefined) {
Expand All @@ -46,9 +52,6 @@ function setTrailingComments(node: Undone<Node>, comments: Array<Comment>) {
* Merge comments with node's leadingComments or assign comments to be
* leadingComments. New comments will be placed before old comments
* because the commentStack is enumerated reversely.
*
* @param {Undone<Node>} node
* @param {Array<Comment>} comments
*/
function setLeadingComments(node: Undone<Node>, comments: Array<Comment>) {
if (node.leadingComments === undefined) {
Expand All @@ -62,9 +65,6 @@ function setLeadingComments(node: Undone<Node>, comments: Array<Comment>) {
* Merge comments with node's innerComments or assign comments to be
* innerComments. New comments will be placed before old comments
* because the commentStack is enumerated reversely.
*
* @param {Undone<Node>} node
* @param {Array<Comment>} comments
*/
export function setInnerComments(
node: Undone<Node>,
Expand All @@ -81,10 +81,6 @@ export function setInnerComments(
* Given node and elements array, if elements has non-null element,
* merge comments to its trailingComments, otherwise merge comments
* to node's innerComments
*
* @param {Undone<Node>} node
* @param {Array<Node>} elements
* @param {Array<Comment>} comments
*/
function adjustInnerComments(
node: Undone<Node>,
Expand All @@ -103,7 +99,6 @@ function adjustInnerComments(
}
}

/** @class CommentsParser */
export default class CommentsParser extends BaseParser {
addComment(comment: Comment): void {
if (this.filename) comment.loc.filename = this.filename;
Expand All @@ -113,10 +108,6 @@ export default class CommentsParser extends BaseParser {
/**
* Given a newly created AST node _n_, attach _n_ to a comment whitespace _w_ if applicable
* {@see {@link CommentWhitespace}}
*
* @param {Node} node
* @returns {void}
* @memberof CommentsParser
*/
processComment(node: Node): void {
const { commentStack } = this.state;
Expand Down Expand Up @@ -158,8 +149,6 @@ export default class CommentsParser extends BaseParser {
/**
* Assign the comments of comment whitespaces to related AST nodes.
* Also adjust innerComments following trailing comma.
*
* @memberof CommentsParser
*/
finalizeComment(commentWS: CommentWhitespace) {
const { comments } = commentWS;
Expand Down Expand Up @@ -219,8 +208,6 @@ export default class CommentsParser extends BaseParser {
* to each comment whitespace. Used only in parseExpression
* where the top level AST node is _not_ Program
* {@see {@link CommentsParser#finalizeComment}}
*
* @memberof CommentsParser
*/
finalizeRemainingComments() {
const { commentStack } = this.state;
Expand All @@ -230,24 +217,25 @@ export default class CommentsParser extends BaseParser {
this.state.commentStack = [];
}

/* eslint-disable no-irregular-whitespace */
/**
* Reset previous node trailing comments. Used in object / class
* property parsing. We parse `async`, `static`, `set` and `get`
* as an identifier but may reinterpret it into an async/static/accessor
* method later. In this case the identifier is not part of the AST and we
* should sync the knowledge to commentStacks
*
* For example, when parsing */
// async /* 1 */ function f() {}
/*
* the comment whitespace "* 1 *" has leading node Identifier(async). When
* we see the function token, we create a Function node and mark "* 1 *" as
* inner comments. So "* 1 *" should be detached from the Identifier node.
* For example, when parsing
* ```
* async /* 1 *​/ function f() {}
* ```
* the comment whitespace `/* 1 *​/` has leading node Identifier(async). When
* we see the function token, we create a Function node and mark `/* 1 *​/` as
* inner comments. So `/* 1 *​/` should be detached from the Identifier node.
*
* @param {N.Node} node the last finished AST node _before_ current token
* @returns
* @memberof CommentsParser
* @param node the last finished AST node _before_ current token
*/
/* eslint-enable no-irregular-whitespace */
resetPreviousNodeTrailingComments(node: Node) {
const { commentStack } = this.state;
const { length } = commentStack;
Expand All @@ -264,10 +252,6 @@ export default class CommentsParser extends BaseParser {
*
* This is used to properly attach comments around parenthesized
* expressions as leading/trailing comments of the inner expression.
*
* @param {Node} node
* @param {number} start
* @param {number} end
*/
takeSurroundingComments(node: Node, start: number, end: number) {
const { commentStack } = this.state;
Expand Down
53 changes: 25 additions & 28 deletions packages/babel-parser/src/parser/lval.ts
Expand Up @@ -84,19 +84,18 @@ export default abstract class LValParser extends NodeUtils {
/**
* Convert existing expression atom to assignable pattern
* if possible. Also checks invalid destructuring targets:

- Parenthesized Destructuring patterns
- RestElement is not the last element
- Missing `=` in assignment pattern

NOTE: There is a corresponding "isAssignable" method.
When this one is updated, please check if also that one needs to be updated.

* @param {Node} node The expression atom
* @param {boolean} [isLHS=false] Whether we are parsing a LeftHandSideExpression.
* If isLHS is `true`, the following cases are allowed: `[(a)] = [0]`, `[(a.b)] = [0]`
* If isLHS is `false`, we are in an arrow function parameters list.
* @memberof LValParser
*
* - Parenthesized Destructuring patterns
* - RestElement is not the last element
* - Missing `=` in assignment pattern
*
* NOTE: There is a corresponding "isAssignable" method.
* When this one is updated, please check if also that one needs to be updated.
*
* @param node The expression atom
* @param isLHS Whether we are parsing a LeftHandSideExpression.
* If isLHS is `true`, the following cases are allowed: `[(a)] = [0]`, `[(a.b)] = [0]`
* If isLHS is `false`, we are in an arrow function parameters list.
*/
toAssignable(node: Node, isLHS: boolean = false): void {
let parenthesized = undefined;
Expand All @@ -108,7 +107,7 @@ export default abstract class LValParser extends NodeUtils {
// i.e. `([(a) = []] = []) => {}`
// see also `recordArrowParemeterBindingError` signature in packages/babel-parser/src/util/expression-scope.js
if (parenthesized.type === "Identifier") {
this.expressionScope.recordArrowParemeterBindingError(
this.expressionScope.recordArrowParameterBindingError(
Errors.InvalidParenthesizedAssignment,
{ at: node },
);
Expand Down Expand Up @@ -510,15 +509,14 @@ export default abstract class LValParser extends NodeUtils {
* The `string`-only return option is actually just a shorthand for:
* `[key: string, parenthesized: false]`.
*
* @param {NodeType} type A Node `type` string
* @param {boolean} isUnparenthesizedInAssign
* @param type A Node `type` string
* @param isUnparenthesizedInAssign
* Whether the node in question is unparenthesized and its parent
* is either an assignment pattern or an assignment expression.
* @param {BindingTypes} binding
* @param binding
* The binding operation that is being considered for this potential
* LVal.
* @returns { boolean | string | [string, boolean] }
* `true` or `false` if we can immediately determine whether the node
* @returns `true` or `false` if we can immediately determine whether the node
* type in question can be treated as an `LVal`.
* A `string` key to traverse if we must check this child.
* A `[string, boolean]` tuple if we need to check this child and
Expand Down Expand Up @@ -548,31 +546,30 @@ export default abstract class LValParser extends NodeUtils {
/**
* Verify that a target expression is an lval (something that can be assigned to).
*
* @param {Expression} expression The expression in question to check.
* @param {Object} options A set of options described below.
* @param {LValAncestor} options.in
* @param expression The expression in question to check.
* @param options A set of options described below.
* @param options.in
* The relevant ancestor to provide context information for the error
* if the check fails.
* @param {BindingTypes} [options.binding=BIND_NONE]
* @param options.binding
* The desired binding type. If the given expression is an identifier
* and `binding` is not `BIND_NONE`, `checkLVal` will register binding
* to the parser scope See also `src/util/scopeflags.js`
* @param {Set<string>|false} [options.checkClashes=false]
* @param options.checkClashes
* An optional string set to check if an identifier name is included.
* `checkLVal` will add checked identifier name to `checkClashes` It is
* used in tracking duplicates in function parameter lists. If it is
* false, `checkLVal` will skip duplicate checks
* @param {boolean} [options.allowingSloppyLetBinding]
* @param options.allowingSloppyLetBinding
* Whether an identifier named "let" should be allowed in sloppy mode.
* Defaults to `true` unless lexical scope its being used. This property
* is only relevant if the parser's state is in sloppy mode.
* @param {boolean} [options.strictModeChanged=false]
* @param options.strictModeChanged
* Whether an identifier has been parsed in a sloppy context but should
* be reinterpreted as strict-mode. e.g. `(arguments) => { "use strict "}`
* @param {boolean} [options.hasParenthesizedAncestor=false]
* @param options.hasParenthesizedAncestor
* This is only used internally during recursive calls, and you should
* not have to set it yourself.
* @memberof LValParser
*/

checkLVal(
Expand Down
20 changes: 1 addition & 19 deletions packages/babel-parser/src/parser/statement.ts
Expand Up @@ -73,8 +73,6 @@ const keywordRelationalOperator = /in(?:stanceof)?/y;
* tt.templateNonTail => tt.backquote/tt.braceR + tt.template + tt.dollarBraceL
* For performance reasons this routine mutates `tokens`, it is okay
* here since we execute `parseTopLevel` once for every file.
* @param {*} tokens
* @returns
*/
function babel7CompatTokens(tokens: (Token | N.Comment)[], input: string) {
for (let i = 0; i < tokens.length; i++) {
Expand Down Expand Up @@ -248,14 +246,8 @@ export default abstract class StatementParser extends ExpressionParser {
return finishedProgram;
}

// TODO

/**
* cast a Statement to a Directive. This method mutates input statement.
*
* @param {N.Statement} stmt
* @returns {N.Directive}
* @memberof StatementParser
*/
stmtToDirective(stmt: N.Statement): N.Directive {
const directive = stmt as any;
Expand Down Expand Up @@ -323,9 +315,6 @@ export default abstract class StatementParser extends ExpressionParser {
/**
* Assuming we have seen a contextual `let` and declaration is allowed, check if it
* starts a variable declaration so that it should be interpreted as a keyword.
*
* @returns {boolean}
* @memberof StatementParser
*/
hasFollowingBindingAtom(): boolean {
const next = this.nextTokenStart();
Expand All @@ -339,9 +328,6 @@ export default abstract class StatementParser extends ExpressionParser {
/**
* Assuming we have seen a contextual `using` and declaration is allowed, check if it
* starts a variable declaration so that it should be interpreted as a keyword.
*
* @returns {boolean}
* @memberof StatementParser
*/
hasFollowingBindingIdentifier(): boolean {
const next = this.nextTokenStart();
Expand Down Expand Up @@ -2982,9 +2968,7 @@ export default abstract class StatementParser extends ExpressionParser {
/**
* parse assert entries
*
* @see {@link https://tc39.es/proposal-import-assertions/#prod-AssertEntries |AssertEntries}
* @returns {N.ImportAttribute[]}
* @memberof StatementParser
* @see {@link https://tc39.es/proposal-import-assertions/#prod-AssertEntries AssertEntries}
*/
parseAssertEntries(): N.ImportAttribute[] {
const attrs = [];
Expand Down Expand Up @@ -3031,8 +3015,6 @@ export default abstract class StatementParser extends ExpressionParser {
/**
* parse module attributes
* @deprecated It will be removed in Babel 8
* @returns
* @memberof StatementParser
*/
maybeParseModuleAttributes() {
if (this.match(tt._with) && !this.hasPrecedingLineBreak()) {
Expand Down
12 changes: 4 additions & 8 deletions packages/babel-parser/src/parser/util.ts
Expand Up @@ -39,8 +39,6 @@ export default abstract class UtilParser extends Tokenizer {
// Forward-declaration: defined in parser/index.js
abstract getScopeHandler(): { new (...args: any): ScopeHandler };

// TODO

addExtra(
node: Partial<Node>,
key: string,
Expand Down Expand Up @@ -128,8 +126,6 @@ export default abstract class UtilParser extends Tokenizer {
return skipWhiteSpaceToLineBreak.test(this.input);
}

// TODO

isLineTerminator(): boolean {
return this.eat(tt.semi) || this.canInsertSemicolon();
}
Expand Down Expand Up @@ -264,15 +260,15 @@ export default abstract class UtilParser extends Tokenizer {
return tokenIsLiteralPropertyName(this.state.type);
}

/*
/**
* Test if given node is a PrivateName
* will be overridden in ESTree plugin
*/
isPrivateName(node: Node): boolean {
return node.type === "PrivateName";
}

/*
/**
* Return the string value of a given private name
* WITHOUT `#`
* @see {@link https://tc39.es/ecma262/#sec-static-semantics-stringvalue}
Expand All @@ -281,7 +277,7 @@ export default abstract class UtilParser extends Tokenizer {
return node.id.name;
}

/*
/**
* Return whether the given node is a member/optional chain that
* contains a private name as its property
* It is overridden in ESTree plugin
Expand Down Expand Up @@ -380,7 +376,7 @@ export default abstract class UtilParser extends Tokenizer {
* - **shorthandAssignLoc**: track initializer `=` position
* - **doubleProtoLoc**: track the duplicate `__proto__` key position
* - **privateKey**: track private key `#p` position
* - **optionalParametersLoc**: track the optional paramter (`?`).
* - **optionalParametersLoc**: track the optional parameter (`?`).
* It's only used by typescript and flow plugins
*/
export class ExpressionErrors {
Expand Down