/
githubmirror
/
babel
Обзор
Документация
Войти
/
githubmirror
/
babel
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
packages/babel-generator/src/generators/methods.ts
341 строка
8 KB
liuxingbaoyu
chore: Update prettier v3.9 (#18147)
20 июл 2026, 21:37
Не верифицирован
20 июл 2026, 21:37
61bfda5
Код
Авторство
О чём код?
import type Printer from "../printer.ts"; import type * as t from "@babel/types"; import { isIdentifier, type ParentMaps } from "@babel/types"; import * as charCodes from "charcodes"; import { TokenContext } from "../node/index.ts"; type ParentsOf<T extends t.Node> = ParentMaps[T["type"]]; export function _params( this: Printer, node: t.Function | t.TSDeclareMethod | t.TSDeclareFunction, noLineTerminator: boolean, idNode?: t.Expression | t.PrivateName | null, parentNode?: ParentsOf<typeof node>, ) { this.print(node.typeParameters); if (idNode !== undefined || parentNode !== undefined) { const nameInfo = _getFuncIdName.call(this, idNode!, parentNode!); if (nameInfo) { this.sourceIdentifierName(nameInfo.name, nameInfo.pos); } } this.token("("); _parameters.call(this, node.params, charCodes.rightParenthesis); this.print(node.returnType, noLineTerminator); this._noLineTerminator = noLineTerminator; } export function _parameters( this: Printer, parameters: t.Function["params"], endToken: number, ) { const oldNoLineTerminatorAfterNode = this.enterDelimited(); const trailingComma = this.shouldPrintTrailingComma(endToken); const paramLength = parameters.length; for (let i = 0; i < paramLength; i++) { _param.call(this, parameters[i]); if (trailingComma || i < paramLength - 1) { this.tokenChar(charCodes.comma, i); this.space(); } } this.tokenChar(endToken); this._noLineTerminatorAfterNode = oldNoLineTerminatorAfterNode; } export function _param( this: Printer, parameter: t.Identifier | t.RestElement | t.Pattern | t.TSParameterProperty, ) { this.printJoin( // @ts-expect-error decorators is not in VoidPattern parameter.decorators, undefined, undefined, undefined, undefined, true, ); this.print(parameter, undefined, true); if ( // @ts-expect-error optional is not in TSParameterProperty parameter.optional ) { this.token("?"); // TS / flow } this.print( // @ts-expect-error typeAnnotation is not in TSParameterProperty parameter.typeAnnotation, undefined, true, ); // TS / flow } export function _methodHead(this: Printer, node: t.Method | t.TSDeclareMethod) { const kind = node.kind; const key = node.key; if (kind === "get" || kind === "set") { this.word(kind); this.space(); } if (node.async) { this.word("async", true); this.space(); } if ( kind === "method" || // @ts-expect-error Fixme: kind: "init" is not defined kind === "init" ) { if (node.generator) { this.token("*"); } } if (node.computed) { this.token("["); this.print(key); this.token("]"); } else { this.print(key); } if ( // @ts-expect-error optional is not in ObjectMethod node.optional ) { // TS this.token("?"); } if (this._buf._map) { _params.call( this, node, false, node.computed && node.key.type !== "StringLiteral" ? undefined : node.key, ); } else { _params.call(this, node, false); } } export function _predicate( this: Printer, node: t.FunctionDeclaration | t.FunctionExpression | t.ArrowFunctionExpression, noLineTerminatorAfter?: boolean, ) { if (node.predicate) { if (!node.returnType) { this.token(":"); } this.space(); this.print(node.predicate, noLineTerminatorAfter); } } export function _functionHead( this: Printer, node: t.FunctionDeclaration | t.FunctionExpression | t.TSDeclareFunction, parent: ParentsOf<typeof node>, hasPredicate: boolean, ) { if (node.async) { this.word("async"); if (!this.format.preserveFormat) { // We prevent inner comments from being printed here, // so that they are always consistently printed in the // same place regardless of the function type. this._innerCommentsState = 0; /* INNER_COMMENT_STATE.DISALLOWED */ } this.space(); } this.word("function"); if (node.generator) { if (!this.format.preserveFormat) { // We prevent inner comments from being printed here, // so that they are always consistently printed in the // same place regardless of the function type. this._innerCommentsState = 0; /* INNER_COMMENT_STATE.DISALLOWED */ } this.token("*"); } this.space(); if (node.id) { this.print(node.id); } if (this._buf._map) { _params.call(this, node, false, node.id, parent); } else { _params.call(this, node, false); } if (hasPredicate) { _predicate.call(this, node as t.FunctionDeclaration | t.FunctionExpression); } } export function FunctionExpression( this: Printer, node: t.FunctionExpression, parent: ParentsOf<typeof node>, ) { _functionHead.call(this, node, parent, true); this.space(); this.print(node.body); } export { FunctionExpression as FunctionDeclaration }; export function ArrowFunctionExpression( this: Printer, node: t.ArrowFunctionExpression, parent: ParentsOf<typeof node>, ) { if (node.async) { this.word("async", true); this.space(); } if (_shouldPrintArrowParamsParens.call(this, node)) { _params.call( this, node, true, undefined, this._buf._map ? parent : undefined, ); } else { this.print(node.params[0], true); } _predicate.call(this, node, true); this.space(); // When printing (x)/*1*/=>{}, we remove the parentheses // and thus there aren't two contiguous inner tokens. // We forcefully print inner comments here. this.printInnerComments(); this.token("=>"); this.space(); this.tokenContext |= TokenContext.arrowBody; this.print(node.body); } // Try to avoid printing parens in simple cases, but only if we're pretty // sure that they aren't needed by type annotations or potential newlines. export function _shouldPrintArrowParamsParens( this: Printer, node: t.ArrowFunctionExpression, ): boolean { if (node.params.length !== 1) return true; if (node.typeParameters || node.returnType || node.predicate) { return true; } const firstParam = node.params[0]; if ( !isIdentifier(firstParam) || firstParam.typeAnnotation || firstParam.optional || // Flow does not support `foo /*: string*/ => {};` firstParam.leadingComments?.length || firstParam.trailingComments?.length ) { return true; } if (this.tokenMap) { if (node.loc == null) return true; if (this.tokenMap.findMatching(node, "(") !== null) return true; const arrowToken = this.tokenMap.findMatching(node, "=>"); if (arrowToken?.loc == null) return true; return arrowToken.loc.start.line !== node.loc.start.line; } if (this.format.retainLines) return true; return false; } function isRenamedIdentifier(id: t.Identifier) { return !!id.loc?.identifierName && id.loc.identifierName !== id.name; } function _getFuncIdName( this: Printer, idNode?: t.Expression | t.PrivateName | null, parent?: ParentsOf< t.Function | t.TSDeclareMethod | t.TSDeclareFunction > | null, ) { let id: t.Expression | t.PrivateName | t.LVal | t.VoidPattern | undefined | null = idNode; if (!id && parent) { const parentType = parent.type; if (parentType === "VariableDeclarator") { id = parent.id; } else if ( parentType === "AssignmentExpression" || parentType === "AssignmentPattern" ) { id = parent.left; } else if ( parentType === "ObjectProperty" || parentType === "ClassProperty" ) { if (!parent.computed || parent.key.type === "StringLiteral") { id = parent.key; } } else if ( parentType === "ClassPrivateProperty" || parentType === "ClassAccessorProperty" ) { id = parent.key; } } if (!id?.loc) return; let nameInfo; if (id.type === "Identifier") { if (!isRenamedIdentifier(id)) return; nameInfo = { pos: id.loc.start, name: id.loc.identifierName! }; } else if (id.type === "PrivateName") { if (!isRenamedIdentifier(id.id)) return; nameInfo = { pos: id.loc.start, name: "#" + id.id.loc!.identifierName!, }; } else if (id.type === "StringLiteral") { // TODO: Return empty when not renamed nameInfo = { pos: id.loc.start, name: id.value, }; } return nameInfo; }