flow-parser
Advanced tools
@@ -452,2 +452,3 @@ 'use strict'; | ||
| type: 'DeclareFunction', | ||
| implicitDeclare: false, | ||
| id: { | ||
@@ -454,0 +455,0 @@ type: 'Identifier', |
+2
-2
| { | ||
| "name": "flow-parser", | ||
| "version": "0.322.0", | ||
| "version": "0.323.0", | ||
| "description": "JavaScript parser written in OCaml. Produces ESTree AST", | ||
@@ -25,3 +25,3 @@ "homepage": "https://flow.org", | ||
| "dependencies": { | ||
| "flow-estree": "0.322.0" | ||
| "flow-estree": "0.323.0" | ||
| }, | ||
@@ -28,0 +28,0 @@ "devDependencies": { |
+23
-30
@@ -1,37 +0,30 @@ | ||
| # The flow-parser package | ||
| # flow-parser | ||
| This package contains the Flow parser in its JavaScript package form. | ||
| A JavaScript parser built from the Flow's parser compiled to WebAssembly. Can parse ES6, Flow, and JSX syntax. | ||
| # What is Flow | ||
| ## What is Flow | ||
| See [flow.org](https://flow.org/). The code for the Flow parser [lives on GitHub](https://github.com/facebook/flow/tree/master/src/parser). | ||
| # What is the Flow Parser | ||
| ## What is the Flow Parser | ||
| The Flow Parser is a JavaScript parser for Flow syntax. It produces an AST that conforms to the [ESTree spec](https://github.com/estree/estree). This npm package contains the Flow Rust parser compiled to WASM with JavaScript bindings. | ||
| The Flow Parser is a JavaScript parser for Flow syntax. It produces an AST that conforms to the [ESTree spec](https://github.com/estree/estree). | ||
| # Usage | ||
| You can use the Flow parser in node: | ||
| ```JavaScript | ||
| const {parse} = require('flow-parser'); | ||
| parse('1+1', {}); | ||
| ``` | ||
| ## Options | ||
| The second argument to `parse` is the options object. Common options: | ||
| ### Basic options | ||
| * `flow` (`'detect'` or `'all'`, default `'detect'`) - parse Flow syntax only with an `@flow` pragma, or always parse Flow syntax | ||
| * `sourceType` (`'module'`, `'script'`, or `'unambiguous'`) - parse the file as a module, script, or infer it from the contents | ||
| * `tokens` (boolean, default `false`) - include a list of all parsed tokens in a top-level `tokens` property | ||
| * `babel` (boolean, default `false`) - return a Babel-shaped AST | ||
| ### Language features | ||
| * `enableEnums` (boolean, default `true`) - enable parsing of [enums](https://flow.org/en/docs/enums/) | ||
| * `enableExperimentalFlowMatchSyntax` (boolean, default `true`) - enable parsing of [match expressions and match statements](https://flow.org/en/docs/match/) | ||
| * `enableExperimentalComponentSyntax` (boolean, default `true`) - enable parsing of [component syntax](https://flow.org/en/docs/react/component-syntax/) | ||
| * `assertOperator` (boolean, default `false`) - enable parsing of the assert operator | ||
| * `enableExperimentalDecorators` (boolean, default `true`) - enable parsing of decorators | ||
| ## API | ||
| The Flow parser exposes a single `parse(code, [options])` function, where `code` is the source code to parse as a string, and `options` is an optional object that may contain the following properties: | ||
| - **babel**: `boolean`, defaults to `false`. If `true`, output an AST conforming to Babel's AST format. If `false`, output an AST conforming to the ESTree AST format. | ||
| - **allowReturnOutsideFunction**: `boolean`, defaults to `false`. If `true`, do not error on return statements found outside functions. | ||
| - **assertOperator**: `boolean`, defaults to `false`. If `true`, enable Flow's postfix non-null assertion syntax (`value!`). | ||
| - **flow**: `"all"` or `"detect"`, defaults to `"detect"`. If `"detect"`, only parse syntax as Flow syntax where it is ambiguous whether it is a Flow feature or regular JavaScript when the `@flow` pragma is present in the file. Otherwise if `"all"`, always parse ambiguous syntax as Flow syntax regardless of the presence of an `@flow` pragma. For example `foo<T>(x)` in a file without an `@flow` pragma will be parsed as two comparisons if set to `"detect"`, otherwise if set to `"all"` or the `@flow` pragma is included it will be parsed as a call expression with a type argument. | ||
| - **enableExperimentalComponentSyntax**: `boolean`, defaults to `true`. Controls parsing of Flow component syntax. | ||
| - **enableExperimentalFlowMatchSyntax**: `boolean`, defaults to `true`. Controls parsing of Flow match syntax. | ||
| - **enableExperimentalFlowRecordSyntax**: `boolean`, defaults to `true`. Controls parsing of Flow record syntax. | ||
| - **reactRuntimeTarget**: `"18"` or `"19"`, defaults to `"18"`. Controls how component `ref` parameters are lowered when `babel` is `true`. React 18 treats `ref` as a separate parameter; React 19 treats it as a regular prop. | ||
| - **sourceFilename**: `string`, defaults to `null`. The filename corresponding to the code that is to be parsed. If non-null, the filename will be added to all source locations in the output AST. | ||
| - **sourceType**: `"module"`, `"script"`, or `"unambiguous"` (default). If `"unambiguous"`, source type will be automatically detected and set to `"module"` if any ES6 imports or exports are present in the code, otherwise source type will be set to `"script"`. | ||
| - **throwOnParseErrors**: `boolean`, defaults to `true`. If `true`, throw a `SyntaxError` for the first parse error. If `false`, return the partial AST with parse errors in the root node's `errors` property. | ||
| - **tokens**: `boolean`, defaults to `false`. If `true`, add all tokens to a `tokens` property on the root node. | ||
| - **transformOptions**: `object`. Options to be supplied to relevant transforms. | ||
| - `TransformEnumSyntax` | ||
| - `enable`: `boolean` - Whether to enable the transform. By default, `false`. | ||
| - `getRuntime` (optional): `() => Expression` - The expression which should be a reference to the Flow Enums runtime. By default, is `require('flow-enums-runtime')`. |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { | ||
| value: true | ||
| }); | ||
| exports.CommentPlacement = void 0; | ||
| exports.addComment = addComment; | ||
| exports.appendCommentToSource = appendCommentToSource; | ||
| exports.attachComments = attachComments; | ||
| exports.cloneComment = cloneComment; | ||
| exports.cloneCommentWithMarkers = cloneCommentWithMarkers; | ||
| exports.cloneCommentsToNewNode = cloneCommentsToNewNode; | ||
| exports.cloneJSDocCommentsToNewNode = cloneJSDocCommentsToNewNode; | ||
| exports.getCommentsForNode = getCommentsForNode; | ||
| exports.getLeadingCommentsForNode = getLeadingCommentsForNode; | ||
| exports.getTrailingCommentsForNode = getTrailingCommentsForNode; | ||
| exports.isAttachedComment = isAttachedComment; | ||
| exports.isLeadingComment = isLeadingComment; | ||
| exports.isTrailingComment = isTrailingComment; | ||
| exports.makeCommentOwnLine = makeCommentOwnLine; | ||
| exports.moveCommentsToNewNode = moveCommentsToNewNode; | ||
| exports.mutateESTreeASTCommentsForPrettier = mutateESTreeASTCommentsForPrettier; | ||
| exports.setCommentsOnNode = setCommentsOnNode; | ||
| var _comments = require("./prettier/main/comments"); | ||
| var _loc = require("./prettier/language-js/loc"); | ||
| var _printerEstree = _interopRequireDefault(require("./prettier/language-js/printer-estree")); | ||
| var _util = require("./prettier/common/util"); | ||
| var _flowEstree = require("flow-estree"); | ||
| var _os = require("os"); | ||
| function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } | ||
| const CommentPlacement = exports.CommentPlacement = require("flow-enums-runtime").Mirrored(["LEADING_OWN_LINE", "LEADING_INLINE", "TRAILING_OWN_LINE", "TRAILING_INLINE"]); | ||
| function attachComments(comments, ast, text) { | ||
| (0, _comments.attach)(comments, ast, text, { | ||
| locStart: _loc.locStart, | ||
| locEnd: _loc.locEnd, | ||
| printer: _printerEstree.default | ||
| }); | ||
| } | ||
| function mutateESTreeASTCommentsForPrettier(program, text) { | ||
| let code = text; | ||
| delete program.comments; | ||
| if (program.docblock != null && program.docblock.comment != null) { | ||
| const docblockComment = program.docblock.comment; | ||
| const isDocblockCommentNew = !isAttachedComment(docblockComment); | ||
| if (isDocblockCommentNew) { | ||
| docblockComment.printed = false; | ||
| docblockComment.leading = true; | ||
| docblockComment.trailing = false; | ||
| } | ||
| if (program.body.length > 0) { | ||
| const firstStatement = program.body[0]; | ||
| const leadingComments = getLeadingCommentsForNode(firstStatement); | ||
| if (!leadingComments.includes(docblockComment)) { | ||
| setCommentsOnNode(firstStatement, [docblockComment, ...getCommentsForNode(firstStatement)]); | ||
| if (isDocblockCommentNew) { | ||
| code = makeCommentOwnLine(code, docblockComment); | ||
| } | ||
| } | ||
| } else { | ||
| setCommentsOnNode(program, [docblockComment]); | ||
| } | ||
| } | ||
| delete program.docblock; | ||
| return code; | ||
| } | ||
| function moveCommentsToNewNode(oldNode, newNode) { | ||
| setCommentsOnNode(newNode, getCommentsForNode(oldNode)); | ||
| setCommentsOnNode(oldNode, []); | ||
| } | ||
| function cloneCommentsToNewNode(oldNode, newNode) { | ||
| setCommentsOnNode(newNode, getCommentsForNode(oldNode).map(comment => cloneCommentWithMarkers(comment))); | ||
| } | ||
| function cloneJSDocCommentsToNewNode(oldNode, newNode) { | ||
| const comments = getCommentsForNode(oldNode).filter(comment => { | ||
| return (0, _flowEstree.isBlockComment)(comment) && comment.value.startsWith('*'); | ||
| }); | ||
| setCommentsOnNode(newNode, [...getCommentsForNode(newNode), ...comments.map(cloneCommentWithMarkers)]); | ||
| } | ||
| function setCommentsOnNode(node, comments) { | ||
| node.comments = comments; | ||
| } | ||
| function getCommentsForNode(node) { | ||
| var _node$comments; | ||
| return (_node$comments = node.comments) != null ? _node$comments : []; | ||
| } | ||
| function isAttachedComment(comment) { | ||
| return comment.printed === false; | ||
| } | ||
| function isLeadingComment(comment) { | ||
| return comment.leading === true; | ||
| } | ||
| function isTrailingComment(comment) { | ||
| return comment.trailing === true; | ||
| } | ||
| function getLeadingCommentsForNode(node) { | ||
| return getCommentsForNode(node).filter(isLeadingComment); | ||
| } | ||
| function getTrailingCommentsForNode(node) { | ||
| return getCommentsForNode(node).filter(isTrailingComment); | ||
| } | ||
| function addComment(node, comment, placement) { | ||
| switch (placement) { | ||
| case CommentPlacement.LEADING_OWN_LINE: | ||
| case CommentPlacement.LEADING_INLINE: | ||
| { | ||
| (0, _util.addLeadingComment)(node, comment); | ||
| break; | ||
| } | ||
| case CommentPlacement.TRAILING_OWN_LINE: | ||
| case CommentPlacement.TRAILING_INLINE: | ||
| { | ||
| (0, _util.addTrailingComment)(node, comment); | ||
| break; | ||
| } | ||
| } | ||
| } | ||
| function cloneComment(comment) { | ||
| return { | ||
| type: comment.type, | ||
| value: comment.value, | ||
| loc: comment.loc, | ||
| range: comment.range | ||
| }; | ||
| } | ||
| function cloneCommentWithMarkers(comment) { | ||
| return { | ||
| type: comment.type, | ||
| value: comment.value, | ||
| loc: comment.loc, | ||
| range: comment.range, | ||
| leading: isLeadingComment(comment), | ||
| trailing: isTrailingComment(comment) | ||
| }; | ||
| } | ||
| function getFirstNewlineIndex(code) { | ||
| return code.search(/\r\n|\n|\r/); | ||
| } | ||
| function getFirstNonWhitespaceIndex(code) { | ||
| return code.search(/\S/); | ||
| } | ||
| function makeCommentOwnLine(code, comment) { | ||
| let newCode = code; | ||
| let firstNewline = getFirstNewlineIndex(code); | ||
| if (firstNewline === -1) { | ||
| newCode += _os.EOL; | ||
| firstNewline = newCode.length; | ||
| } | ||
| comment.range = [firstNewline + 1, firstNewline]; | ||
| return newCode; | ||
| } | ||
| function appendCommentToSource(code, comment, placement) { | ||
| let newCode = code; | ||
| switch (comment.type) { | ||
| case 'Block': | ||
| { | ||
| switch (placement) { | ||
| case CommentPlacement.LEADING_OWN_LINE: | ||
| case CommentPlacement.TRAILING_OWN_LINE: | ||
| { | ||
| newCode = makeCommentOwnLine(code, comment); | ||
| break; | ||
| } | ||
| case CommentPlacement.LEADING_INLINE: | ||
| case CommentPlacement.TRAILING_INLINE: | ||
| { | ||
| let firstNonWhitespace = getFirstNonWhitespaceIndex(code); | ||
| if (firstNonWhitespace === -1) { | ||
| newCode += '$FORCE_INLINE_ON_EMPTY_FILE_TOKEN$;'; | ||
| firstNonWhitespace = newCode.length; | ||
| break; | ||
| } | ||
| comment.range = [firstNonWhitespace + 1, firstNonWhitespace]; | ||
| break; | ||
| } | ||
| } | ||
| break; | ||
| } | ||
| case 'Line': | ||
| { | ||
| const commentText = `//${comment.value}`; | ||
| const lastChar = newCode[newCode.length - 1]; | ||
| if (lastChar !== '\n' && lastChar !== '\r') { | ||
| newCode += _os.EOL; | ||
| } | ||
| if (placement === CommentPlacement.TRAILING_INLINE) { | ||
| newCode += '$FORCE_END_OF_LINE_COMMENT_TOKEN$;'; | ||
| } | ||
| const start = newCode.length; | ||
| newCode += commentText; | ||
| const end = newCode.length; | ||
| comment.range = [start, end]; | ||
| break; | ||
| } | ||
| } | ||
| return newCode; | ||
| } |
Sorry, the diff of this file is not supported yet
| 'use strict'; | ||
| const stringWidth = require('string-width'); | ||
| const getLast = require('../utils/get-last.js'); | ||
| const notAsciiRegex = /[^\x20-\x7F]/; | ||
| function skip(chars) { | ||
| return (text, index, opts) => { | ||
| const backwards = opts && opts.backwards; | ||
| if (index === false) { | ||
| return false; | ||
| } | ||
| const { | ||
| length | ||
| } = text; | ||
| let cursor = index; | ||
| while (cursor >= 0 && cursor < length) { | ||
| const c = text.charAt(cursor); | ||
| if (chars instanceof RegExp) { | ||
| if (!chars.test(c)) { | ||
| return cursor; | ||
| } | ||
| } else if (!chars.includes(c)) { | ||
| return cursor; | ||
| } | ||
| backwards ? cursor-- : cursor++; | ||
| } | ||
| if (cursor === -1 || cursor === length) { | ||
| return cursor; | ||
| } | ||
| return false; | ||
| }; | ||
| } | ||
| const skipWhitespace = skip(/\s/); | ||
| const skipSpaces = skip(' \t'); | ||
| const skipToLineEnd = skip(',; \t'); | ||
| const skipEverythingButNewLine = skip(/[^\n\r]/); | ||
| function skipInlineComment(text, index) { | ||
| if (index === false) { | ||
| return false; | ||
| } | ||
| if (text.charAt(index) === '/' && text.charAt(index + 1) === '*') { | ||
| for (let i = index + 2; i < text.length; ++i) { | ||
| if (text.charAt(i) === '*' && text.charAt(i + 1) === '/') { | ||
| return i + 2; | ||
| } | ||
| } | ||
| } | ||
| return index; | ||
| } | ||
| function skipTrailingComment(text, index) { | ||
| if (index === false) { | ||
| return false; | ||
| } | ||
| if (text.charAt(index) === '/' && text.charAt(index + 1) === '/') { | ||
| return skipEverythingButNewLine(text, index); | ||
| } | ||
| return index; | ||
| } | ||
| function skipNewline(text, index, opts) { | ||
| const backwards = opts && opts.backwards; | ||
| if (index === false) { | ||
| return false; | ||
| } | ||
| const atIndex = text.charAt(index); | ||
| if (backwards) { | ||
| if (text.charAt(index - 1) === '\r' && atIndex === '\n') { | ||
| return index - 2; | ||
| } | ||
| if (atIndex === '\n' || atIndex === '\r' || atIndex === '\u2028' || atIndex === '\u2029') { | ||
| return index - 1; | ||
| } | ||
| } else { | ||
| if (atIndex === '\r' && text.charAt(index + 1) === '\n') { | ||
| return index + 2; | ||
| } | ||
| if (atIndex === '\n' || atIndex === '\r' || atIndex === '\u2028' || atIndex === '\u2029') { | ||
| return index + 1; | ||
| } | ||
| } | ||
| return index; | ||
| } | ||
| function hasNewline(text, index, opts = {}) { | ||
| const idx = skipSpaces(text, opts.backwards ? index - 1 : index, opts); | ||
| const idx2 = skipNewline(text, idx, opts); | ||
| return idx !== idx2; | ||
| } | ||
| function hasNewlineInRange(text, start, end) { | ||
| for (let i = start; i < end; ++i) { | ||
| if (text.charAt(i) === '\n') { | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
| function isNextLineEmptyAfterIndex(text, index) { | ||
| let oldIdx = null; | ||
| let idx = index; | ||
| while (idx !== oldIdx) { | ||
| oldIdx = idx; | ||
| idx = skipToLineEnd(text, idx); | ||
| idx = skipInlineComment(text, idx); | ||
| idx = skipSpaces(text, idx); | ||
| } | ||
| idx = skipTrailingComment(text, idx); | ||
| idx = skipNewline(text, idx); | ||
| return idx !== false && hasNewline(text, idx); | ||
| } | ||
| function getNextNonSpaceNonCommentCharacterIndexWithStartIndex(text, idx) { | ||
| let oldIdx = null; | ||
| let nextIdx = idx; | ||
| while (nextIdx !== oldIdx) { | ||
| oldIdx = nextIdx; | ||
| nextIdx = skipSpaces(text, nextIdx); | ||
| nextIdx = skipInlineComment(text, nextIdx); | ||
| nextIdx = skipTrailingComment(text, nextIdx); | ||
| nextIdx = skipNewline(text, nextIdx); | ||
| } | ||
| return nextIdx; | ||
| } | ||
| function getNextNonSpaceNonCommentCharacterIndex(text, node, locEnd) { | ||
| return getNextNonSpaceNonCommentCharacterIndexWithStartIndex(text, locEnd(node)); | ||
| } | ||
| function getNextNonSpaceNonCommentCharacter(text, node, locEnd) { | ||
| return text.charAt(getNextNonSpaceNonCommentCharacterIndex(text, node, locEnd)); | ||
| } | ||
| function getStringWidth(text) { | ||
| if (!text) { | ||
| return 0; | ||
| } | ||
| if (!notAsciiRegex.test(text)) { | ||
| return text.length; | ||
| } | ||
| return stringWidth(text); | ||
| } | ||
| function addCommentHelper(node, comment) { | ||
| const comments = node.comments || (node.comments = []); | ||
| comments.push(comment); | ||
| comment.printed = false; | ||
| comment.nodeDescription = describeNodeForDebugging(node); | ||
| } | ||
| function addLeadingComment(node, comment) { | ||
| comment.leading = true; | ||
| comment.trailing = false; | ||
| addCommentHelper(node, comment); | ||
| } | ||
| function addDanglingComment(node, comment, marker) { | ||
| comment.leading = false; | ||
| comment.trailing = false; | ||
| if (marker) { | ||
| comment.marker = marker; | ||
| } | ||
| addCommentHelper(node, comment); | ||
| } | ||
| function addTrailingComment(node, comment) { | ||
| comment.leading = false; | ||
| comment.trailing = true; | ||
| addCommentHelper(node, comment); | ||
| } | ||
| function isNonEmptyArray(object) { | ||
| return Array.isArray(object) && object.length > 0; | ||
| } | ||
| function describeNodeForDebugging(node) { | ||
| const nodeType = node.type || node.kind || '(unknown type)'; | ||
| let nodeName = String(node.name || node.id && (typeof node.id === 'object' ? node.id.name : node.id) || node.key && (typeof node.key === 'object' ? node.key.name : node.key) || node.value && (typeof node.value === 'object' ? '' : String(node.value)) || node.operator || ''); | ||
| if (nodeName.length > 20) { | ||
| nodeName = nodeName.slice(0, 19) + '…'; | ||
| } | ||
| return nodeType + (nodeName ? ' ' + nodeName : ''); | ||
| } | ||
| module.exports = { | ||
| getStringWidth, | ||
| getLast, | ||
| getNextNonSpaceNonCommentCharacterIndexWithStartIndex, | ||
| getNextNonSpaceNonCommentCharacterIndex, | ||
| getNextNonSpaceNonCommentCharacter, | ||
| skipWhitespace, | ||
| skipSpaces, | ||
| skipNewline, | ||
| isNextLineEmptyAfterIndex, | ||
| hasNewline, | ||
| hasNewlineInRange, | ||
| addLeadingComment, | ||
| addDanglingComment, | ||
| addTrailingComment, | ||
| isNonEmptyArray | ||
| }; |
| 'use strict'; | ||
| const { | ||
| getLast, | ||
| hasNewline, | ||
| addLeadingComment, | ||
| getNextNonSpaceNonCommentCharacterIndexWithStartIndex, | ||
| getNextNonSpaceNonCommentCharacterIndex, | ||
| hasNewlineInRange, | ||
| addTrailingComment, | ||
| addDanglingComment, | ||
| getNextNonSpaceNonCommentCharacter, | ||
| isNonEmptyArray | ||
| } = require('../common/util.js'); | ||
| const { | ||
| isBlockComment, | ||
| getFunctionParameters, | ||
| isPrettierIgnoreComment, | ||
| isCallLikeExpression, | ||
| getCallArguments, | ||
| isCallExpression, | ||
| isMemberExpression, | ||
| isObjectProperty | ||
| } = require('./utils.js'); | ||
| const { | ||
| locStart, | ||
| locEnd | ||
| } = require('./loc.js'); | ||
| function handleOwnLineComment(context) { | ||
| return [handleIgnoreComments, handleLastFunctionArgComments, handleMemberExpressionComments, handleIfStatementComments, handleWhileComments, handleTryStatementComments, handleClassComments, handleImportSpecifierComments, handleForComments, handleUnionTypeComments, handleMatchOrPatternComments, handleOnlyComments, handleImportDeclarationComments, handleAssignmentPatternComments, handleMethodNameComments, handleLabeledStatementComments].some(fn => fn(context)); | ||
| } | ||
| function handleEndOfLineComment(context) { | ||
| return [handleClosureTypeCastComments, handleLastFunctionArgComments, handleConditionalExpressionComments, handleImportSpecifierComments, handleIfStatementComments, handleWhileComments, handleTryStatementComments, handleClassComments, handleLabeledStatementComments, handleCallExpressionComments, handlePropertyComments, handleOnlyComments, handleTypeAliasComments, handleVariableDeclaratorComments].some(fn => fn(context)); | ||
| } | ||
| function handleRemainingComment(context) { | ||
| return [handleIgnoreComments, handleIfStatementComments, handleWhileComments, handleObjectPropertyAssignment, handleCommentInEmptyParens, handleMethodNameComments, handleOnlyComments, handleCommentAfterArrowParams, handleFunctionNameComments, handleTSMappedTypeComments, handleBreakAndContinueStatementComments, handleTSFunctionTrailingComments].some(fn => fn(context)); | ||
| } | ||
| function addBlockStatementFirstComment(node, comment) { | ||
| const firstNonEmptyNode = (node.body || node.properties).find(({ | ||
| type | ||
| }) => type !== 'EmptyStatement'); | ||
| if (firstNonEmptyNode) { | ||
| addLeadingComment(firstNonEmptyNode, comment); | ||
| } else { | ||
| addDanglingComment(node, comment); | ||
| } | ||
| } | ||
| function addBlockOrNotComment(node, comment) { | ||
| if (node.type === 'BlockStatement') { | ||
| addBlockStatementFirstComment(node, comment); | ||
| } else { | ||
| addLeadingComment(node, comment); | ||
| } | ||
| } | ||
| function handleClosureTypeCastComments({ | ||
| comment, | ||
| followingNode | ||
| }) { | ||
| if (followingNode && isTypeCastComment(comment)) { | ||
| addLeadingComment(followingNode, comment); | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
| function handleIfStatementComments({ | ||
| comment, | ||
| precedingNode, | ||
| enclosingNode, | ||
| followingNode, | ||
| text | ||
| }) { | ||
| if (!enclosingNode || enclosingNode.type !== 'IfStatement' || !followingNode) { | ||
| return false; | ||
| } | ||
| const nextCharacter = getNextNonSpaceNonCommentCharacter(text, comment, locEnd); | ||
| if (nextCharacter === ')') { | ||
| addTrailingComment(precedingNode, comment); | ||
| return true; | ||
| } | ||
| if (precedingNode === enclosingNode.consequent && followingNode === enclosingNode.alternate) { | ||
| if (precedingNode.type === 'BlockStatement') { | ||
| addTrailingComment(precedingNode, comment); | ||
| } else { | ||
| addDanglingComment(enclosingNode, comment); | ||
| } | ||
| return true; | ||
| } | ||
| if (followingNode.type === 'BlockStatement') { | ||
| addBlockStatementFirstComment(followingNode, comment); | ||
| return true; | ||
| } | ||
| if (followingNode.type === 'IfStatement') { | ||
| addBlockOrNotComment(followingNode.consequent, comment); | ||
| return true; | ||
| } | ||
| if (enclosingNode.consequent === followingNode) { | ||
| addLeadingComment(followingNode, comment); | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
| function handleWhileComments({ | ||
| comment, | ||
| precedingNode, | ||
| enclosingNode, | ||
| followingNode, | ||
| text | ||
| }) { | ||
| if (!enclosingNode || enclosingNode.type !== 'WhileStatement' || !followingNode) { | ||
| return false; | ||
| } | ||
| const nextCharacter = getNextNonSpaceNonCommentCharacter(text, comment, locEnd); | ||
| if (nextCharacter === ')') { | ||
| addTrailingComment(precedingNode, comment); | ||
| return true; | ||
| } | ||
| if (followingNode.type === 'BlockStatement') { | ||
| addBlockStatementFirstComment(followingNode, comment); | ||
| return true; | ||
| } | ||
| if (enclosingNode.body === followingNode) { | ||
| addLeadingComment(followingNode, comment); | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
| function handleTryStatementComments({ | ||
| comment, | ||
| precedingNode, | ||
| enclosingNode, | ||
| followingNode | ||
| }) { | ||
| if (!enclosingNode || enclosingNode.type !== 'TryStatement' && enclosingNode.type !== 'CatchClause' || !followingNode) { | ||
| return false; | ||
| } | ||
| if (enclosingNode.type === 'CatchClause' && precedingNode) { | ||
| addTrailingComment(precedingNode, comment); | ||
| return true; | ||
| } | ||
| if (followingNode.type === 'BlockStatement') { | ||
| addBlockStatementFirstComment(followingNode, comment); | ||
| return true; | ||
| } | ||
| if (followingNode.type === 'TryStatement') { | ||
| addBlockOrNotComment(followingNode.finalizer, comment); | ||
| return true; | ||
| } | ||
| if (followingNode.type === 'CatchClause') { | ||
| addBlockOrNotComment(followingNode.body, comment); | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
| function handleMemberExpressionComments({ | ||
| comment, | ||
| enclosingNode, | ||
| followingNode | ||
| }) { | ||
| if (isMemberExpression(enclosingNode) && followingNode && followingNode.type === 'Identifier') { | ||
| addLeadingComment(enclosingNode, comment); | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
| function handleConditionalExpressionComments({ | ||
| comment, | ||
| precedingNode, | ||
| enclosingNode, | ||
| followingNode, | ||
| text | ||
| }) { | ||
| const isSameLineAsPrecedingNode = precedingNode && !hasNewlineInRange(text, locEnd(precedingNode), locStart(comment)); | ||
| if ((!precedingNode || !isSameLineAsPrecedingNode) && enclosingNode && (enclosingNode.type === 'ConditionalExpression' || enclosingNode.type === 'TSConditionalType') && followingNode) { | ||
| addLeadingComment(followingNode, comment); | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
| function handleObjectPropertyAssignment({ | ||
| comment, | ||
| precedingNode, | ||
| enclosingNode | ||
| }) { | ||
| if (isObjectProperty(enclosingNode) && enclosingNode.shorthand && enclosingNode.key === precedingNode && enclosingNode.value.type === 'AssignmentPattern') { | ||
| addTrailingComment(enclosingNode.value.left, comment); | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
| function handleClassComments({ | ||
| comment, | ||
| precedingNode, | ||
| enclosingNode, | ||
| followingNode | ||
| }) { | ||
| if (enclosingNode && (enclosingNode.type === 'ClassDeclaration' || enclosingNode.type === 'ClassExpression' || enclosingNode.type === 'DeclareClass' || enclosingNode.type === 'DeclareInterface' || enclosingNode.type === 'InterfaceDeclaration' || enclosingNode.type === 'TSInterfaceDeclaration')) { | ||
| if (isNonEmptyArray(enclosingNode.decorators) && !(followingNode && followingNode.type === 'Decorator')) { | ||
| addTrailingComment(getLast(enclosingNode.decorators), comment); | ||
| return true; | ||
| } | ||
| if (enclosingNode.body && followingNode === enclosingNode.body) { | ||
| addBlockStatementFirstComment(enclosingNode.body, comment); | ||
| return true; | ||
| } | ||
| if (followingNode) { | ||
| for (const prop of ['implements', 'extends', 'mixins']) { | ||
| if (enclosingNode[prop] && followingNode === enclosingNode[prop][0]) { | ||
| if (precedingNode && (precedingNode === enclosingNode.id || precedingNode === enclosingNode.typeParameters || precedingNode === enclosingNode.superClass)) { | ||
| addTrailingComment(precedingNode, comment); | ||
| } else { | ||
| addDanglingComment(enclosingNode, comment, prop); | ||
| } | ||
| return true; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
| function handleMethodNameComments({ | ||
| comment, | ||
| precedingNode, | ||
| enclosingNode, | ||
| text | ||
| }) { | ||
| if (enclosingNode && precedingNode && (enclosingNode.type === 'Property' || enclosingNode.type === 'TSDeclareMethod' || enclosingNode.type === 'TSAbstractMethodDefinition') && precedingNode.type === 'Identifier' && enclosingNode.key === precedingNode && getNextNonSpaceNonCommentCharacter(text, precedingNode, locEnd) !== ':') { | ||
| addTrailingComment(precedingNode, comment); | ||
| return true; | ||
| } | ||
| if (precedingNode && enclosingNode && precedingNode.type === 'Decorator' && (enclosingNode.type === 'ClassMethod' || enclosingNode.type === 'ClassProperty' || enclosingNode.type === 'PropertyDefinition' || enclosingNode.type === 'TSAbstractPropertyDefinition' || enclosingNode.type === 'TSAbstractMethodDefinition' || enclosingNode.type === 'TSDeclareMethod' || enclosingNode.type === 'MethodDefinition')) { | ||
| addTrailingComment(precedingNode, comment); | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
| function handleFunctionNameComments({ | ||
| comment, | ||
| precedingNode, | ||
| enclosingNode, | ||
| text | ||
| }) { | ||
| if (getNextNonSpaceNonCommentCharacter(text, comment, locEnd) !== '(') { | ||
| return false; | ||
| } | ||
| if (precedingNode && enclosingNode && (enclosingNode.type === 'FunctionDeclaration' || enclosingNode.type === 'FunctionExpression' || enclosingNode.type === 'ClassMethod' || enclosingNode.type === 'MethodDefinition' || enclosingNode.type === 'ObjectMethod')) { | ||
| addTrailingComment(precedingNode, comment); | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
| function handleCommentAfterArrowParams({ | ||
| comment, | ||
| enclosingNode, | ||
| text | ||
| }) { | ||
| if (!(enclosingNode && enclosingNode.type === 'ArrowFunctionExpression')) { | ||
| return false; | ||
| } | ||
| const index = getNextNonSpaceNonCommentCharacterIndex(text, comment, locEnd); | ||
| if (index !== false && text.slice(index, index + 2) === '=>') { | ||
| addDanglingComment(enclosingNode, comment); | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
| function handleCommentInEmptyParens({ | ||
| comment, | ||
| enclosingNode, | ||
| text | ||
| }) { | ||
| if (getNextNonSpaceNonCommentCharacter(text, comment, locEnd) !== ')') { | ||
| return false; | ||
| } | ||
| if (enclosingNode && (isRealFunctionLikeNode(enclosingNode) && getFunctionParameters(enclosingNode).length === 0 || isCallLikeExpression(enclosingNode) && getCallArguments(enclosingNode).length === 0)) { | ||
| addDanglingComment(enclosingNode, comment); | ||
| return true; | ||
| } | ||
| if (enclosingNode && (enclosingNode.type === 'MethodDefinition' || enclosingNode.type === 'TSAbstractMethodDefinition') && getFunctionParameters(enclosingNode.value).length === 0) { | ||
| addDanglingComment(enclosingNode.value, comment); | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
| function handleLastFunctionArgComments({ | ||
| comment, | ||
| precedingNode, | ||
| enclosingNode, | ||
| followingNode, | ||
| text | ||
| }) { | ||
| if (precedingNode && precedingNode.type === 'FunctionTypeParam' && enclosingNode && enclosingNode.type === 'FunctionTypeAnnotation' && followingNode && followingNode.type !== 'FunctionTypeParam') { | ||
| addTrailingComment(precedingNode, comment); | ||
| return true; | ||
| } | ||
| if (precedingNode && (precedingNode.type === 'Identifier' || precedingNode.type === 'AssignmentPattern') && enclosingNode && isRealFunctionLikeNode(enclosingNode) && getNextNonSpaceNonCommentCharacter(text, comment, locEnd) === ')') { | ||
| addTrailingComment(precedingNode, comment); | ||
| return true; | ||
| } | ||
| if (enclosingNode && enclosingNode.type === 'FunctionDeclaration' && followingNode && followingNode.type === 'BlockStatement') { | ||
| const functionParamRightParenIndex = (() => { | ||
| const parameters = getFunctionParameters(enclosingNode); | ||
| if (parameters.length > 0) { | ||
| return getNextNonSpaceNonCommentCharacterIndexWithStartIndex(text, locEnd(getLast(parameters))); | ||
| } | ||
| const functionParamLeftParenIndex = getNextNonSpaceNonCommentCharacterIndexWithStartIndex(text, locEnd(enclosingNode.id)); | ||
| return functionParamLeftParenIndex !== false && getNextNonSpaceNonCommentCharacterIndexWithStartIndex(text, functionParamLeftParenIndex + 1); | ||
| })(); | ||
| if (locStart(comment) > functionParamRightParenIndex) { | ||
| addBlockStatementFirstComment(followingNode, comment); | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
| function handleImportSpecifierComments({ | ||
| comment, | ||
| enclosingNode | ||
| }) { | ||
| if (enclosingNode && enclosingNode.type === 'ImportSpecifier') { | ||
| addLeadingComment(enclosingNode, comment); | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
| function handleLabeledStatementComments({ | ||
| comment, | ||
| enclosingNode | ||
| }) { | ||
| if (enclosingNode && enclosingNode.type === 'LabeledStatement') { | ||
| addLeadingComment(enclosingNode, comment); | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
| function handleBreakAndContinueStatementComments({ | ||
| comment, | ||
| enclosingNode | ||
| }) { | ||
| if (enclosingNode && (enclosingNode.type === 'ContinueStatement' || enclosingNode.type === 'BreakStatement') && !enclosingNode.label) { | ||
| addTrailingComment(enclosingNode, comment); | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
| function handleCallExpressionComments({ | ||
| comment, | ||
| precedingNode, | ||
| enclosingNode | ||
| }) { | ||
| if (isCallExpression(enclosingNode) && precedingNode && enclosingNode.callee === precedingNode && enclosingNode.arguments.length > 0) { | ||
| addLeadingComment(enclosingNode.arguments[0], comment); | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
| function handleUnionTypeComments({ | ||
| comment, | ||
| precedingNode, | ||
| enclosingNode, | ||
| followingNode | ||
| }) { | ||
| if (enclosingNode && (enclosingNode.type === 'UnionTypeAnnotation' || enclosingNode.type === 'TSUnionType')) { | ||
| if (isPrettierIgnoreComment(comment)) { | ||
| followingNode.prettierIgnore = true; | ||
| comment.unignore = true; | ||
| } | ||
| if (precedingNode) { | ||
| addTrailingComment(precedingNode, comment); | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
| if (followingNode && (followingNode.type === 'UnionTypeAnnotation' || followingNode.type === 'TSUnionType') && isPrettierIgnoreComment(comment)) { | ||
| followingNode.types[0].prettierIgnore = true; | ||
| comment.unignore = true; | ||
| } | ||
| return false; | ||
| } | ||
| function handleMatchOrPatternComments({ | ||
| comment, | ||
| precedingNode, | ||
| enclosingNode, | ||
| followingNode | ||
| }) { | ||
| if (enclosingNode && enclosingNode.type === 'MatchOrPattern') { | ||
| if (isPrettierIgnoreComment(comment)) { | ||
| followingNode.prettierIgnore = true; | ||
| comment.unignore = true; | ||
| } | ||
| if (precedingNode) { | ||
| addTrailingComment(precedingNode, comment); | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
| if (followingNode && followingNode.type === 'MatchOrPattern' && isPrettierIgnoreComment(comment)) { | ||
| followingNode.types[0].prettierIgnore = true; | ||
| comment.unignore = true; | ||
| } | ||
| return false; | ||
| } | ||
| function handlePropertyComments({ | ||
| comment, | ||
| enclosingNode | ||
| }) { | ||
| if (isObjectProperty(enclosingNode)) { | ||
| addLeadingComment(enclosingNode, comment); | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
| function handleOnlyComments({ | ||
| comment, | ||
| enclosingNode, | ||
| followingNode, | ||
| ast, | ||
| isLastComment | ||
| }) { | ||
| if (ast && ast.body && ast.body.length === 0) { | ||
| if (isLastComment) { | ||
| addDanglingComment(ast, comment); | ||
| } else { | ||
| addLeadingComment(ast, comment); | ||
| } | ||
| return true; | ||
| } | ||
| if (enclosingNode && enclosingNode.type === 'Program' && enclosingNode.body.length === 0 && !isNonEmptyArray(enclosingNode.directives)) { | ||
| if (isLastComment) { | ||
| addDanglingComment(enclosingNode, comment); | ||
| } else { | ||
| addLeadingComment(enclosingNode, comment); | ||
| } | ||
| return true; | ||
| } | ||
| if (followingNode && followingNode.type === 'Program' && followingNode.body.length === 0 && enclosingNode && enclosingNode.type === 'ModuleExpression') { | ||
| addDanglingComment(followingNode, comment); | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
| function handleForComments({ | ||
| comment, | ||
| enclosingNode | ||
| }) { | ||
| if (enclosingNode && (enclosingNode.type === 'ForInStatement' || enclosingNode.type === 'ForOfStatement')) { | ||
| addLeadingComment(enclosingNode, comment); | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
| function handleImportDeclarationComments({ | ||
| comment, | ||
| precedingNode, | ||
| enclosingNode, | ||
| text | ||
| }) { | ||
| if (precedingNode && precedingNode.type === 'ImportSpecifier' && enclosingNode && enclosingNode.type === 'ImportDeclaration' && hasNewline(text, locEnd(comment))) { | ||
| addTrailingComment(precedingNode, comment); | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
| function handleAssignmentPatternComments({ | ||
| comment, | ||
| enclosingNode | ||
| }) { | ||
| if (enclosingNode && enclosingNode.type === 'AssignmentPattern') { | ||
| addLeadingComment(enclosingNode, comment); | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
| function handleTypeAliasComments({ | ||
| comment, | ||
| enclosingNode | ||
| }) { | ||
| if (enclosingNode && enclosingNode.type === 'TypeAlias') { | ||
| addLeadingComment(enclosingNode, comment); | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
| function handleVariableDeclaratorComments({ | ||
| comment, | ||
| enclosingNode, | ||
| followingNode | ||
| }) { | ||
| if (enclosingNode && (enclosingNode.type === 'VariableDeclarator' || enclosingNode.type === 'AssignmentExpression') && followingNode && (followingNode.type === 'ObjectExpression' || followingNode.type === 'ArrayExpression' || followingNode.type === 'TemplateLiteral' || followingNode.type === 'TaggedTemplateExpression' || isBlockComment(comment))) { | ||
| addLeadingComment(followingNode, comment); | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
| function handleTSFunctionTrailingComments({ | ||
| comment, | ||
| enclosingNode, | ||
| followingNode, | ||
| text | ||
| }) { | ||
| if (!followingNode && enclosingNode && (enclosingNode.type === 'TSMethodSignature' || enclosingNode.type === 'TSDeclareFunction' || enclosingNode.type === 'TSAbstractMethodDefinition') && getNextNonSpaceNonCommentCharacter(text, comment, locEnd) === ';') { | ||
| addTrailingComment(enclosingNode, comment); | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
| function handleIgnoreComments({ | ||
| comment, | ||
| enclosingNode, | ||
| followingNode | ||
| }) { | ||
| if (isPrettierIgnoreComment(comment) && enclosingNode && enclosingNode.type === 'TSMappedType' && followingNode && followingNode.type === 'TSTypeParameter' && followingNode.constraint) { | ||
| enclosingNode.prettierIgnore = true; | ||
| comment.unignore = true; | ||
| return true; | ||
| } | ||
| } | ||
| function handleTSMappedTypeComments({ | ||
| comment, | ||
| precedingNode, | ||
| enclosingNode, | ||
| followingNode | ||
| }) { | ||
| if (!enclosingNode || enclosingNode.type !== 'TSMappedType') { | ||
| return false; | ||
| } | ||
| if (followingNode && followingNode.type === 'TSTypeParameter' && followingNode.name) { | ||
| addLeadingComment(followingNode.name, comment); | ||
| return true; | ||
| } | ||
| if (precedingNode && precedingNode.type === 'TSTypeParameter' && precedingNode.constraint) { | ||
| addTrailingComment(precedingNode.constraint, comment); | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
| function isRealFunctionLikeNode(node) { | ||
| return node.type === 'ArrowFunctionExpression' || node.type === 'FunctionExpression' || node.type === 'FunctionDeclaration' || node.type === 'ObjectMethod' || node.type === 'ClassMethod' || node.type === 'TSDeclareFunction' || node.type === 'TSCallSignatureDeclaration' || node.type === 'TSConstructSignatureDeclaration' || node.type === 'TSMethodSignature' || node.type === 'TSConstructorType' || node.type === 'TSFunctionType' || node.type === 'TSDeclareMethod'; | ||
| } | ||
| function getCommentChildNodes(node, options) { | ||
| if ((options.parser === 'typescript' || options.parser === 'flow' || options.parser === 'espree' || options.parser === 'meriyah' || options.parser === '__babel_estree') && node.type === 'MethodDefinition' && node.value && node.value.type === 'FunctionExpression' && getFunctionParameters(node.value).length === 0 && !node.value.returnType && !isNonEmptyArray(node.value.typeParameters) && node.value.body) { | ||
| return [...(node.decorators || []), node.key, node.value.body]; | ||
| } | ||
| } | ||
| function isTypeCastComment(comment) { | ||
| return isBlockComment(comment) && comment.value[0] === '*' && /@type\b/.test(comment.value); | ||
| } | ||
| module.exports = { | ||
| handleOwnLineComment, | ||
| handleEndOfLineComment, | ||
| handleRemainingComment, | ||
| getCommentChildNodes | ||
| }; |
| 'use strict'; | ||
| const { | ||
| isNonEmptyArray | ||
| } = require('../common/util.js'); | ||
| function locStart(node, opts) { | ||
| const { | ||
| ignoreDecorators | ||
| } = opts || {}; | ||
| if (!ignoreDecorators) { | ||
| const decorators = node.declaration && node.declaration.decorators || node.decorators; | ||
| if (isNonEmptyArray(decorators)) { | ||
| return locStart(decorators[0]); | ||
| } | ||
| } | ||
| return node.range ? node.range[0] : node.start; | ||
| } | ||
| function locEnd(node) { | ||
| return node.range ? node.range[1] : node.end; | ||
| } | ||
| module.exports = { | ||
| locStart, | ||
| locEnd | ||
| }; |
| 'use strict'; | ||
| const handleComments = require('./comments.js'); | ||
| const { | ||
| isBlockComment, | ||
| isLineComment | ||
| } = require('./utils.js'); | ||
| function canAttachComment(node) { | ||
| return node.type && !isBlockComment(node) && !isLineComment(node) && node.type !== 'EmptyStatement' && node.type !== 'TemplateElement' && node.type !== 'Import' && node.type !== 'TSEmptyBodyFunctionExpression'; | ||
| } | ||
| module.exports = { | ||
| canAttachComment, | ||
| handleComments: { | ||
| avoidAstMutation: true, | ||
| ownLine: handleComments.handleOwnLineComment, | ||
| endOfLine: handleComments.handleEndOfLineComment, | ||
| remaining: handleComments.handleRemainingComment | ||
| }, | ||
| getCommentChildNodes: handleComments.getCommentChildNodes | ||
| }; |
| 'use strict'; | ||
| function isBlockComment(comment) { | ||
| return comment.type === 'Block' || comment.type === 'CommentBlock' || comment.type === 'MultiLine'; | ||
| } | ||
| function isLineComment(comment) { | ||
| return comment.type === 'Line' || comment.type === 'CommentLine' || comment.type === 'SingleLine' || comment.type === 'HashbangComment' || comment.type === 'HTMLOpen' || comment.type === 'HTMLClose'; | ||
| } | ||
| function isCallExpression(node) { | ||
| return node && (node.type === 'CallExpression' || node.type === 'OptionalCallExpression'); | ||
| } | ||
| function isMemberExpression(node) { | ||
| return node && (node.type === 'MemberExpression' || node.type === 'OptionalMemberExpression'); | ||
| } | ||
| const functionParametersCache = new WeakMap(); | ||
| function getFunctionParameters(node) { | ||
| if (functionParametersCache.has(node)) { | ||
| return functionParametersCache.get(node); | ||
| } | ||
| const parameters = []; | ||
| if (node.this) { | ||
| parameters.push(node.this); | ||
| } | ||
| if (Array.isArray(node.parameters)) { | ||
| parameters.push(...node.parameters); | ||
| } else if (Array.isArray(node.params)) { | ||
| parameters.push(...node.params); | ||
| } | ||
| if (node.rest) { | ||
| parameters.push(node.rest); | ||
| } | ||
| functionParametersCache.set(node, parameters); | ||
| return parameters; | ||
| } | ||
| const callArgumentsCache = new WeakMap(); | ||
| function getCallArguments(node) { | ||
| if (callArgumentsCache.has(node)) { | ||
| return callArgumentsCache.get(node); | ||
| } | ||
| let args = node.arguments; | ||
| if (node.type === 'ImportExpression') { | ||
| args = [node.source]; | ||
| if (node.attributes) { | ||
| args.push(node.attributes); | ||
| } | ||
| } | ||
| callArgumentsCache.set(node, args); | ||
| return args; | ||
| } | ||
| function isPrettierIgnoreComment(comment) { | ||
| return comment.value.trim() === 'prettier-ignore' && !comment.unignore; | ||
| } | ||
| function isCallLikeExpression(node) { | ||
| return isCallExpression(node) || node.type === 'NewExpression' || node.type === 'ImportExpression'; | ||
| } | ||
| function isObjectProperty(node) { | ||
| return node && (node.type === 'ObjectProperty' || node.type === 'Property' && !node.method && node.kind === 'init'); | ||
| } | ||
| module.exports = { | ||
| getFunctionParameters, | ||
| getCallArguments, | ||
| isBlockComment, | ||
| isCallLikeExpression, | ||
| isLineComment, | ||
| isPrettierIgnoreComment, | ||
| isCallExpression, | ||
| isMemberExpression, | ||
| isObjectProperty | ||
| }; |
| 'use strict'; | ||
| const assert = require('assert'); | ||
| const { | ||
| hasNewline, | ||
| addLeadingComment, | ||
| addDanglingComment, | ||
| addTrailingComment | ||
| } = require('../common/util.js'); | ||
| const childNodesCache = new WeakMap(); | ||
| function getSortedChildNodes(node, options, resultArray) { | ||
| if (!node) { | ||
| return; | ||
| } | ||
| const { | ||
| printer, | ||
| locStart, | ||
| locEnd | ||
| } = options; | ||
| if (resultArray) { | ||
| if (printer.canAttachComment && printer.canAttachComment(node)) { | ||
| let i; | ||
| for (i = resultArray.length - 1; i >= 0; --i) { | ||
| if (locStart(resultArray[i]) <= locStart(node) && locEnd(resultArray[i]) <= locEnd(node)) { | ||
| break; | ||
| } | ||
| } | ||
| resultArray.splice(i + 1, 0, node); | ||
| return; | ||
| } | ||
| } else if (childNodesCache.has(node)) { | ||
| return childNodesCache.get(node); | ||
| } | ||
| const childNodes = printer.getCommentChildNodes && printer.getCommentChildNodes(node, options) || typeof node === 'object' && Object.entries(node).filter(([key]) => key !== 'enclosingNode' && key !== 'precedingNode' && key !== 'followingNode' && key !== 'tokens' && key !== 'comments' && key !== 'parent').map(([, value]) => value); | ||
| if (!childNodes) { | ||
| return; | ||
| } | ||
| if (!resultArray) { | ||
| resultArray = []; | ||
| childNodesCache.set(node, resultArray); | ||
| } | ||
| for (const childNode of childNodes) { | ||
| getSortedChildNodes(childNode, options, resultArray); | ||
| } | ||
| return resultArray; | ||
| } | ||
| function decorateComment(node, comment, options, enclosingNode) { | ||
| const { | ||
| locStart, | ||
| locEnd | ||
| } = options; | ||
| const commentStart = locStart(comment); | ||
| const commentEnd = locEnd(comment); | ||
| const childNodes = getSortedChildNodes(node, options); | ||
| let precedingNode; | ||
| let followingNode; | ||
| let left = 0; | ||
| let right = childNodes.length; | ||
| while (left < right) { | ||
| const middle = left + right >> 1; | ||
| const child = childNodes[middle]; | ||
| const start = locStart(child); | ||
| const end = locEnd(child); | ||
| if (start <= commentStart && commentEnd <= end) { | ||
| return decorateComment(child, comment, options, child); | ||
| } | ||
| if (end <= commentStart) { | ||
| precedingNode = child; | ||
| left = middle + 1; | ||
| continue; | ||
| } | ||
| if (commentEnd <= start) { | ||
| followingNode = child; | ||
| right = middle; | ||
| continue; | ||
| } | ||
| throw new Error('Comment location overlaps with node location'); | ||
| } | ||
| if (enclosingNode && enclosingNode.type === 'TemplateLiteral') { | ||
| const { | ||
| quasis | ||
| } = enclosingNode; | ||
| const commentIndex = findExpressionIndexForComment(quasis, comment, options); | ||
| if (precedingNode && findExpressionIndexForComment(quasis, precedingNode, options) !== commentIndex) { | ||
| precedingNode = null; | ||
| } | ||
| if (followingNode && findExpressionIndexForComment(quasis, followingNode, options) !== commentIndex) { | ||
| followingNode = null; | ||
| } | ||
| } | ||
| return { | ||
| enclosingNode, | ||
| precedingNode, | ||
| followingNode | ||
| }; | ||
| } | ||
| const returnFalse = () => false; | ||
| function attach(comments, ast, text, options) { | ||
| if (!Array.isArray(comments)) { | ||
| return; | ||
| } | ||
| const tiesToBreak = []; | ||
| const { | ||
| locStart, | ||
| locEnd, | ||
| printer: { | ||
| handleComments = {} | ||
| } | ||
| } = options; | ||
| const { | ||
| avoidAstMutation, | ||
| ownLine: handleOwnLineComment = returnFalse, | ||
| endOfLine: handleEndOfLineComment = returnFalse, | ||
| remaining: handleRemainingComment = returnFalse | ||
| } = handleComments; | ||
| const decoratedComments = comments.map((comment, index) => ({ | ||
| ...decorateComment(ast, comment, options), | ||
| comment, | ||
| text, | ||
| options, | ||
| ast, | ||
| isLastComment: comments.length - 1 === index | ||
| })); | ||
| for (const [index, context] of decoratedComments.entries()) { | ||
| const { | ||
| comment, | ||
| precedingNode, | ||
| enclosingNode, | ||
| followingNode, | ||
| text, | ||
| options, | ||
| ast, | ||
| isLastComment | ||
| } = context; | ||
| if (options.parser === 'json' || options.parser === 'json5' || options.parser === '__js_expression' || options.parser === '__vue_expression') { | ||
| if (locStart(comment) - locStart(ast) <= 0) { | ||
| addLeadingComment(ast, comment); | ||
| continue; | ||
| } | ||
| if (locEnd(comment) - locEnd(ast) >= 0) { | ||
| addTrailingComment(ast, comment); | ||
| continue; | ||
| } | ||
| } | ||
| let args; | ||
| if (avoidAstMutation) { | ||
| args = [context]; | ||
| } else { | ||
| comment.enclosingNode = enclosingNode; | ||
| comment.precedingNode = precedingNode; | ||
| comment.followingNode = followingNode; | ||
| args = [comment, text, options, ast, isLastComment]; | ||
| } | ||
| if (isOwnLineComment(text, options, decoratedComments, index)) { | ||
| comment.placement = 'ownLine'; | ||
| if (handleOwnLineComment(...args)) {} else if (followingNode) { | ||
| addLeadingComment(followingNode, comment); | ||
| } else if (precedingNode) { | ||
| addTrailingComment(precedingNode, comment); | ||
| } else if (enclosingNode) { | ||
| addDanglingComment(enclosingNode, comment); | ||
| } else { | ||
| addDanglingComment(ast, comment); | ||
| } | ||
| } else if (isEndOfLineComment(text, options, decoratedComments, index)) { | ||
| comment.placement = 'endOfLine'; | ||
| if (handleEndOfLineComment(...args)) {} else if (precedingNode) { | ||
| addTrailingComment(precedingNode, comment); | ||
| } else if (followingNode) { | ||
| addLeadingComment(followingNode, comment); | ||
| } else if (enclosingNode) { | ||
| addDanglingComment(enclosingNode, comment); | ||
| } else { | ||
| addDanglingComment(ast, comment); | ||
| } | ||
| } else { | ||
| comment.placement = 'remaining'; | ||
| if (handleRemainingComment(...args)) {} else if (precedingNode && followingNode) { | ||
| const tieCount = tiesToBreak.length; | ||
| if (tieCount > 0) { | ||
| const lastTie = tiesToBreak[tieCount - 1]; | ||
| if (lastTie.followingNode !== followingNode) { | ||
| breakTies(tiesToBreak, text, options); | ||
| } | ||
| } | ||
| tiesToBreak.push(context); | ||
| } else if (precedingNode) { | ||
| addTrailingComment(precedingNode, comment); | ||
| } else if (followingNode) { | ||
| addLeadingComment(followingNode, comment); | ||
| } else if (enclosingNode) { | ||
| addDanglingComment(enclosingNode, comment); | ||
| } else { | ||
| addDanglingComment(ast, comment); | ||
| } | ||
| } | ||
| } | ||
| breakTies(tiesToBreak, text, options); | ||
| if (!avoidAstMutation) { | ||
| for (const comment of comments) { | ||
| delete comment.precedingNode; | ||
| delete comment.enclosingNode; | ||
| delete comment.followingNode; | ||
| } | ||
| } | ||
| } | ||
| const isAllEmptyAndNoLineBreak = text => !/[\S\n\u2028\u2029]/.test(text); | ||
| function isOwnLineComment(text, options, decoratedComments, commentIndex) { | ||
| const { | ||
| comment, | ||
| precedingNode | ||
| } = decoratedComments[commentIndex]; | ||
| const { | ||
| locStart, | ||
| locEnd | ||
| } = options; | ||
| let start = locStart(comment); | ||
| if (precedingNode) { | ||
| for (let index = commentIndex - 1; index >= 0; index--) { | ||
| const { | ||
| comment, | ||
| precedingNode: currentCommentPrecedingNode | ||
| } = decoratedComments[index]; | ||
| if (currentCommentPrecedingNode !== precedingNode || !isAllEmptyAndNoLineBreak(text.slice(locEnd(comment), start))) { | ||
| break; | ||
| } | ||
| start = locStart(comment); | ||
| } | ||
| } | ||
| return hasNewline(text, start, { | ||
| backwards: true | ||
| }); | ||
| } | ||
| function isEndOfLineComment(text, options, decoratedComments, commentIndex) { | ||
| const { | ||
| comment, | ||
| followingNode | ||
| } = decoratedComments[commentIndex]; | ||
| const { | ||
| locStart, | ||
| locEnd | ||
| } = options; | ||
| let end = locEnd(comment); | ||
| if (followingNode) { | ||
| for (let index = commentIndex + 1; index < decoratedComments.length; index++) { | ||
| const { | ||
| comment, | ||
| followingNode: currentCommentFollowingNode | ||
| } = decoratedComments[index]; | ||
| if (currentCommentFollowingNode !== followingNode || !isAllEmptyAndNoLineBreak(text.slice(end, locStart(comment)))) { | ||
| break; | ||
| } | ||
| end = locEnd(comment); | ||
| } | ||
| } | ||
| return hasNewline(text, end); | ||
| } | ||
| function breakTies(tiesToBreak, text, options) { | ||
| const tieCount = tiesToBreak.length; | ||
| if (tieCount === 0) { | ||
| return; | ||
| } | ||
| const { | ||
| precedingNode, | ||
| followingNode, | ||
| enclosingNode | ||
| } = tiesToBreak[0]; | ||
| const gapRegExp = options.printer.getGapRegex && options.printer.getGapRegex(enclosingNode) || /^[\s(]*$/; | ||
| let gapEndPos = options.locStart(followingNode); | ||
| let indexOfFirstLeadingComment; | ||
| for (indexOfFirstLeadingComment = tieCount; indexOfFirstLeadingComment > 0; --indexOfFirstLeadingComment) { | ||
| const { | ||
| comment, | ||
| precedingNode: currentCommentPrecedingNode, | ||
| followingNode: currentCommentFollowingNode | ||
| } = tiesToBreak[indexOfFirstLeadingComment - 1]; | ||
| assert.strictEqual(currentCommentPrecedingNode, precedingNode); | ||
| assert.strictEqual(currentCommentFollowingNode, followingNode); | ||
| const gap = text.slice(options.locEnd(comment), gapEndPos); | ||
| if (gapRegExp.test(gap)) { | ||
| gapEndPos = options.locStart(comment); | ||
| } else { | ||
| break; | ||
| } | ||
| } | ||
| for (const [i, { | ||
| comment | ||
| }] of tiesToBreak.entries()) { | ||
| if (i < indexOfFirstLeadingComment) { | ||
| addTrailingComment(precedingNode, comment); | ||
| } else { | ||
| addLeadingComment(followingNode, comment); | ||
| } | ||
| } | ||
| for (const node of [precedingNode, followingNode]) { | ||
| if (node.comments && node.comments.length > 1) { | ||
| node.comments.sort((a, b) => options.locStart(a) - options.locStart(b)); | ||
| } | ||
| } | ||
| tiesToBreak.length = 0; | ||
| } | ||
| function findExpressionIndexForComment(quasis, comment, options) { | ||
| const startPos = options.locStart(comment) - 1; | ||
| for (let i = 1; i < quasis.length; ++i) { | ||
| if (startPos < options.locStart(quasis[i])) { | ||
| return i - 1; | ||
| } | ||
| } | ||
| return 0; | ||
| } | ||
| module.exports = { | ||
| attach | ||
| }; |
| 'use strict'; | ||
| const getLast = arr => arr[arr.length - 1]; | ||
| module.exports = getLast; |
| 'use strict'; |
Sorry, the diff of this file is not supported yet
| 'use strict'; | ||
| Object.defineProperty(exports, "__esModule", { | ||
| value: true | ||
| }); | ||
| exports.print = print; | ||
| var _mutateESTreeASTForPrettier = _interopRequireDefault(require("../../utils/mutateESTreeASTForPrettier")); | ||
| var prettier = _interopRequireWildcard(require("prettier")); | ||
| var _comments = require("./comments/comments"); | ||
| function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } | ||
| function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } | ||
| async function print(ast, originalCode, prettierOptions = {}, visitorKeys) { | ||
| const program = ast; | ||
| if (program.body.length === 0) { | ||
| var _program$docblock; | ||
| const docblockComment = (_program$docblock = program.docblock) == null ? void 0 : _program$docblock.comment; | ||
| if (docblockComment != null) { | ||
| return '/*' + docblockComment.value + '*/\n'; | ||
| } | ||
| return ''; | ||
| } | ||
| const codeForPrinting = (0, _comments.mutateESTreeASTCommentsForPrettier)(program, originalCode); | ||
| (0, _mutateESTreeASTForPrettier.default)(program, visitorKeys); | ||
| let pluginParserName = 'flow'; | ||
| let pluginParser; | ||
| let pluginPrinter; | ||
| try { | ||
| const prettierHermesPlugin = await Promise.resolve().then(() => _interopRequireWildcard(require('prettier-plugin-hermes-parser'))); | ||
| pluginParser = prettierHermesPlugin.parsers.hermes; | ||
| pluginPrinter = prettierHermesPlugin.printers; | ||
| pluginParserName = 'hermes'; | ||
| } catch { | ||
| const prettierFlowPlugin = require('prettier/plugins/flow'); | ||
| pluginParser = prettierFlowPlugin.parsers.flow; | ||
| } | ||
| return prettier.format(codeForPrinting, { | ||
| ...prettierOptions, | ||
| parser: pluginParserName, | ||
| requirePragma: false, | ||
| plugins: [{ | ||
| parsers: { | ||
| [pluginParserName]: { | ||
| ...pluginParser, | ||
| parse() { | ||
| return program; | ||
| } | ||
| } | ||
| }, | ||
| printers: pluginPrinter | ||
| }] | ||
| }); | ||
| } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
1308249
-4.37%55
-19.12%6366
-18.11%31
-18.42%+ Added
- Removed
Updated