typecheck updates & fixes in src/language-js (#8759)
Co-authored-by: fisker <lionkay@gmail.com>
This commit is contained in:
1 parent
69ce8eab81
commit
cdc250c21a
15 files changed
+421
-49
No files matched your search
@@ -354,6 +354,7 @@
|
||||
"Transloadit",
|
||||
"TSAs",
|
||||
"tsep",
|
||||
"TSESTree",
|
||||
"TSJS",
|
||||
"tslib",
|
||||
"typeahead",
|
||||
|
||||
+5
-1
@@ -85,6 +85,7 @@
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.11.1",
|
||||
"@babel/preset-env": "7.11.0",
|
||||
"@babel/types": "7.11.0",
|
||||
"@glimmer/reference": "0.58.0",
|
||||
"@rollup/plugin-alias": "3.1.1",
|
||||
"@rollup/plugin-babel": "5.2.0",
|
||||
@@ -92,6 +93,9 @@
|
||||
"@rollup/plugin-json": "4.1.0",
|
||||
"@rollup/plugin-node-resolve": "9.0.0",
|
||||
"@rollup/plugin-replace": "2.3.3",
|
||||
"@types/estree": "0.0.45",
|
||||
"@types/node": "14.6.0",
|
||||
"@typescript-eslint/types": "3.9.1",
|
||||
"babel-loader": "8.1.0",
|
||||
"benchmark": "2.1.4",
|
||||
"builtin-modules": "3.1.0",
|
||||
@@ -139,7 +143,7 @@
|
||||
"lint:typecheck": "tsc",
|
||||
"lint:eslint": "cross-env EFF_NO_LINK_RULES=true eslint . --format friendly",
|
||||
"lint:changelog": "node ./scripts/lint-changelog.js",
|
||||
"lint:prettier": "prettier \"**/*.{md,json,yml,html,css,js}\" \"!test*\" --check",
|
||||
"lint:prettier": "prettier \"**/*.{md,json,yml,html,css,js,d.ts}\" \"!test*\" --check",
|
||||
"lint:dist": "eslint --no-eslintrc --no-ignore --env=es6,browser --parser-options=ecmaVersion:2016 \"dist/!(bin-prettier|index|third-party).js\"",
|
||||
"lint:spellcheck": "cspell \"**/*\" \".github/**/*\"",
|
||||
"lint:deps": "node ./scripts/check-deps.js",
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* @typedef {import("./doc-builders").Doc} Doc
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
builders: require("./doc-builders"),
|
||||
printer: require("./doc-printer"),
|
||||
|
||||
@@ -578,7 +578,7 @@ function handleCommentAfterArrowParams(text, enclosingNode, comment, options) {
|
||||
comment,
|
||||
options.locEnd
|
||||
);
|
||||
if (text.slice(index, index + 2) === "=>") {
|
||||
if (index !== false && text.slice(index, index + 2) === "=>") {
|
||||
addDanglingComment(enclosingNode, comment);
|
||||
return true;
|
||||
}
|
||||
@@ -672,9 +672,12 @@ function handleLastFunctionArgComments(
|
||||
text,
|
||||
options.locEnd(enclosingNode.id)
|
||||
);
|
||||
return getNextNonSpaceNonCommentCharacterIndexWithStartIndex(
|
||||
text,
|
||||
functionParamLeftParenIndex + 1
|
||||
return (
|
||||
functionParamLeftParenIndex !== false &&
|
||||
getNextNonSpaceNonCommentCharacterIndexWithStartIndex(
|
||||
text,
|
||||
functionParamLeftParenIndex + 1
|
||||
)
|
||||
);
|
||||
})();
|
||||
if (options.locStart(comment) > functionParamRightParenIndex) {
|
||||
@@ -930,6 +933,11 @@ function isBlockComment(comment) {
|
||||
return comment.type === "Block" || comment.type === "CommentBlock";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} node
|
||||
* @param {(comment: any) => boolean} fn
|
||||
* @returns boolean
|
||||
*/
|
||||
function hasLeadingComment(node, fn = () => true) {
|
||||
if (node.leadingComments) {
|
||||
return node.leadingComments.some(fn);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"use strict";
|
||||
|
||||
/** @type {import("assert")} */
|
||||
const assert = require("assert");
|
||||
|
||||
const {
|
||||
|
||||
@@ -159,7 +159,7 @@ function printCallArguments(path, options, print) {
|
||||
shouldBreakForArrowFunction;
|
||||
|
||||
// We want to print the last argument with a special flag
|
||||
let printedExpanded;
|
||||
let printedExpanded = [];
|
||||
let i = 0;
|
||||
const printArgument = (argPath) => {
|
||||
if (shouldGroupFirst && i === 0) {
|
||||
|
||||
@@ -80,10 +80,9 @@ function printMemberChain(path, options, print) {
|
||||
// if it is cut off by a parenthesis, we only account for one typed empty
|
||||
// line after that parenthesis
|
||||
if (nextChar === ")") {
|
||||
return isNextLineEmptyAfterIndex(
|
||||
originalText,
|
||||
nextCharIndex + 1,
|
||||
options.locEnd
|
||||
return (
|
||||
nextCharIndex !== false &&
|
||||
isNextLineEmptyAfterIndex(originalText, nextCharIndex + 1)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,13 @@
|
||||
const {
|
||||
builders: { concat, softline, group, indent, join, line, ifBreak },
|
||||
} = require("../../document");
|
||||
|
||||
const { shouldPrintComma } = require("../utils");
|
||||
|
||||
/**
|
||||
* @typedef {import("../../document").Doc} Doc
|
||||
*/
|
||||
|
||||
function printModuleSource(path, options, print) {
|
||||
const node = path.getValue();
|
||||
return node.source ? concat([" from ", path.call(print, "source")]) : "";
|
||||
@@ -12,6 +17,8 @@ function printModuleSource(path, options, print) {
|
||||
|
||||
function printModuleSpecifiers(path, options, print) {
|
||||
const node = path.getValue();
|
||||
|
||||
/** @type{Doc[]} */
|
||||
const parts = [node.type === "ImportDeclaration" ? " " : ""];
|
||||
|
||||
if (node.specifiers && node.specifiers.length > 0) {
|
||||
|
||||
@@ -19,6 +19,22 @@ const {
|
||||
},
|
||||
} = require("../../document");
|
||||
|
||||
/**
|
||||
* @typedef {import("../../document").Doc} Doc
|
||||
* @typedef {import("../../common/fast-path")} FastPath
|
||||
*
|
||||
* @typedef {any} Options - Prettier options (TBD ...)
|
||||
*
|
||||
* @typedef {Object} OperatorOptions
|
||||
* @property {() => Array<string | Doc>} beforeParts - Parts to print before the `?`.
|
||||
* @property {(breakClosingParen: boolean) => Array<string | Doc>} afterParts - Parts to print after the conditional expression.
|
||||
* @property {boolean} shouldCheckJsx - Whether to check for and print in JSX mode.
|
||||
* @property {string} conditionalNodeType - The type of the conditional expression node, ie "ConditionalExpression" or "TSConditionalType".
|
||||
* @property {string} consequentNodePropertyName - The property at which the consequent node can be found on the main node, eg "consequent".
|
||||
* @property {string} alternateNodePropertyName - The property at which the alternate node can be found on the main node, eg "alternate".
|
||||
* @property {string[]} testNodePropertyNames - The properties at which the test nodes can be found on the main node, eg "test".
|
||||
*/
|
||||
|
||||
// If we have nested conditional expressions, we want to print them in JSX mode
|
||||
// if there's at least one JSXElement somewhere in the tree.
|
||||
//
|
||||
@@ -118,16 +134,7 @@ function conditionalExpressionChainContainsJSX(node) {
|
||||
* The following is the shared logic for
|
||||
* ternary operators, namely ConditionalExpression
|
||||
* and TSConditionalType
|
||||
* @typedef {import("../../document/doc-builders").Doc} Doc
|
||||
* @typedef {Object} OperatorOptions
|
||||
* @property {() => Array<string | Doc>} beforeParts - Parts to print before the `?`.
|
||||
* @property {(breakClosingParen: boolean) => Array<string | Doc>} afterParts - Parts to print after the conditional expression.
|
||||
* @property {boolean} shouldCheckJsx - Whether to check for and print in JSX mode.
|
||||
* @property {string} conditionalNodeType - The type of the conditional expression node, ie "ConditionalExpression" or "TSConditionalType".
|
||||
* @property {string} consequentNodePropertyName - The property at which the consequent node can be found on the main node, eg "consequent".
|
||||
* @property {string} alternateNodePropertyName - The property at which the alternate node can be found on the main node, eg "alternate".
|
||||
* @property {string[]} testNodePropertyNames - The properties at which the test nodes can be found on the main node, eg "test".
|
||||
* @param {import("../../common/fast-path")} path - The path to the ConditionalExpression/TSConditionalType node.
|
||||
* @param {FastPath} path - The path to the ConditionalExpression/TSConditionalType node.
|
||||
* @param {Options} options - Prettier options
|
||||
* @param {Function} print - Print function to call recursively
|
||||
* @param {OperatorOptions} operatorOptions
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
"use strict";
|
||||
|
||||
/** @typedef {import("../document").Doc} Doc */
|
||||
|
||||
/** @type {import("assert")} */
|
||||
const assert = require("assert");
|
||||
|
||||
// TODO(azz): anything that imports from main shouldn't be in a `language-*` dir.
|
||||
@@ -256,7 +259,9 @@ function printPathNoParens(path, options, print, args) {
|
||||
return htmlBinding;
|
||||
}
|
||||
|
||||
/** @type{Doc[]} */
|
||||
let parts = [];
|
||||
|
||||
switch (n.type) {
|
||||
case "JsExpressionRoot":
|
||||
return path.call(print, "node");
|
||||
@@ -481,17 +486,23 @@ function printPathNoParens(path, options, print, args) {
|
||||
// )
|
||||
|
||||
const hasJSX = isJSXNode(n.right);
|
||||
const firstGroupIndex = parts.findIndex((part) => part.type === "group");
|
||||
|
||||
const firstGroupIndex = parts.findIndex(
|
||||
(part) => typeof part !== "string" && part.type === "group"
|
||||
);
|
||||
|
||||
// Separate the leftmost expression, possibly with its leading comments.
|
||||
const headParts = parts.slice(
|
||||
0,
|
||||
firstGroupIndex === -1 ? 1 : firstGroupIndex + 1
|
||||
);
|
||||
|
||||
const rest = concat(
|
||||
parts.slice(headParts.length, hasJSX ? -1 : undefined)
|
||||
);
|
||||
|
||||
const groupId = Symbol("logicalChain-" + ++uid);
|
||||
|
||||
const chain = group(
|
||||
concat([
|
||||
// Don't include the initial expression in the indentation
|
||||
@@ -672,8 +683,9 @@ function printPathNoParens(path, options, print, args) {
|
||||
options.locEnd
|
||||
);
|
||||
return (
|
||||
nextCharacter !== false &&
|
||||
options.originalText.slice(nextCharacter, nextCharacter + 2) ===
|
||||
"=>"
|
||||
"=>"
|
||||
);
|
||||
}
|
||||
);
|
||||
@@ -4067,7 +4079,10 @@ function printReturnType(path, print, options) {
|
||||
|
||||
function printExportDeclaration(path, options, print) {
|
||||
const decl = path.getValue();
|
||||
|
||||
const semi = options.semi ? ";" : "";
|
||||
|
||||
/** @type{Doc[]} */
|
||||
const parts = ["export "];
|
||||
|
||||
const isDefault = decl.default || decl.type === "ExportDefaultDeclaration";
|
||||
@@ -4823,7 +4838,9 @@ function printBinaryishExpressions(
|
||||
isNested,
|
||||
isInsideParenthesis
|
||||
) {
|
||||
/** @type{Doc[]} */
|
||||
let parts = [];
|
||||
|
||||
const node = path.getValue();
|
||||
|
||||
// We treat BinaryExpression and LogicalExpression nodes the same.
|
||||
|
||||
Vendored
+97
@@ -0,0 +1,97 @@
|
||||
import * as ESTree from "estree";
|
||||
import * as Babel from "@babel/types";
|
||||
import { TSESTree } from "@typescript-eslint/types";
|
||||
import * as NGTree from "angular-estree-parser/lib/types";
|
||||
|
||||
// WORKAROUND HACK for typescript-eslint issue:
|
||||
// https://github.com/typescript-eslint/typescript-eslint/issues/2388
|
||||
// MUST REMOVE to avoid errors with TypeScript 4.0.0:
|
||||
import * as ts from "typescript";
|
||||
declare module "typescript" {
|
||||
type NamedTupleMember = Node;
|
||||
}
|
||||
|
||||
type AdditionalFields = {
|
||||
extra?: {
|
||||
parenthesized?: boolean;
|
||||
parenStart?: number;
|
||||
raw?: string;
|
||||
};
|
||||
comments?: Comment[];
|
||||
trailingComments?: ReadonlyArray<Comment> | Comment[];
|
||||
leadingComments?: ReadonlyArray<Comment> | Comment[];
|
||||
};
|
||||
|
||||
export type Comment = (ESTree.Comment | Babel.Comment | TSESTree.Comment) & {
|
||||
printed?: boolean;
|
||||
trailing?: boolean;
|
||||
leading?: boolean;
|
||||
};
|
||||
|
||||
export type Node = (ESTree.Node | Babel.Node | TSESTree.Node | NGTree.NGNode) &
|
||||
AdditionalFields;
|
||||
|
||||
export type TemplateLiteral = (
|
||||
| ESTree.TemplateLiteral
|
||||
| Babel.TemplateLiteral
|
||||
| TSESTree.TemplateLiteral
|
||||
) &
|
||||
AdditionalFields;
|
||||
|
||||
export type CallExpression = (
|
||||
| ESTree.CallExpression
|
||||
| Babel.CallExpression
|
||||
| TSESTree.CallExpression
|
||||
) &
|
||||
AdditionalFields;
|
||||
|
||||
export type OptionalCallExpression = (
|
||||
| Babel.OptionalCallExpression
|
||||
| TSESTree.OptionalCallExpression
|
||||
) &
|
||||
AdditionalFields;
|
||||
|
||||
export type MemberExpression = (
|
||||
| ESTree.MemberExpression
|
||||
| Babel.MemberExpression
|
||||
| TSESTree.MemberExpression
|
||||
) &
|
||||
AdditionalFields;
|
||||
|
||||
export type OptionalMemberExpression = (
|
||||
| Babel.OptionalMemberExpression
|
||||
| TSESTree.OptionalMemberExpression
|
||||
) &
|
||||
AdditionalFields;
|
||||
|
||||
export type Expression = (
|
||||
| ESTree.Expression
|
||||
| Babel.Expression
|
||||
| TSESTree.Expression
|
||||
) &
|
||||
AdditionalFields;
|
||||
|
||||
export type BindExpression = Babel.BindExpression & AdditionalFields;
|
||||
|
||||
export type Property = (ESTree.Property | Babel.Property | TSESTree.Property) &
|
||||
AdditionalFields;
|
||||
|
||||
export type ClassPrivateProperty = Babel.ClassPrivateProperty &
|
||||
AdditionalFields;
|
||||
|
||||
export type ObjectTypeProperty = Babel.ObjectTypeProperty & AdditionalFields;
|
||||
|
||||
export type JSXElement = (Babel.JSXElement | TSESTree.JSXElement) &
|
||||
AdditionalFields;
|
||||
|
||||
export type TaggedTemplateExpression = (
|
||||
| ESTree.TaggedTemplateExpression
|
||||
| Babel.TaggedTemplateExpression
|
||||
| TSESTree.TaggedTemplateExpression
|
||||
) &
|
||||
AdditionalFields;
|
||||
|
||||
export type Literal = (ESTree.Literal | Babel.Literal | TSESTree.Literal) &
|
||||
AdditionalFields;
|
||||
|
||||
export { ESTree, Babel, TSESTree, NGTree };
|
||||
+242
-22
@@ -11,6 +11,24 @@ const {
|
||||
} = require("../common/util");
|
||||
const handleComments = require("./comments");
|
||||
|
||||
/**
|
||||
* @typedef {import("./types/estree").Node} Node
|
||||
* @typedef {import("./types/estree").TemplateLiteral} TemplateLiteral
|
||||
* @typedef {import("./types/estree").Comment} Comment
|
||||
* @typedef {import("./types/estree").MemberExpression} MemberExpression
|
||||
* @typedef {import("./types/estree").OptionalMemberExpression} OptionalMemberExpression
|
||||
* @typedef {import("./types/estree").CallExpression} CallExpression
|
||||
* @typedef {import("./types/estree").OptionalCallExpression} OptionalCallExpression
|
||||
* @typedef {import("./types/estree").Expression} Expression
|
||||
* @typedef {import("./types/estree").Property} Property
|
||||
* @typedef {import("./types/estree").ObjectTypeProperty} ObjectTypeProperty
|
||||
* @typedef {import("./types/estree").JSXElement} JSXElement
|
||||
* @typedef {import("./types/estree").TaggedTemplateExpression} TaggedTemplateExpression
|
||||
* @typedef {import("./types/estree").Literal} Literal
|
||||
*
|
||||
* @typedef {import("../common/fast-path")} FastPath
|
||||
*/
|
||||
|
||||
// We match any whitespace except line terminators because
|
||||
// Flow annotation comments cannot be split across lines. For example:
|
||||
//
|
||||
@@ -26,6 +44,10 @@ const FLOW_SHORTHAND_ANNOTATION = new RegExp(
|
||||
);
|
||||
const FLOW_ANNOTATION = new RegExp(`^${NON_LINE_TERMINATING_WHITE_SPACE}*::`);
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function hasFlowShorthandAnnotationComment(node) {
|
||||
// https://flow.org/en/docs/types/comments/
|
||||
// Syntax example: const r = new (window.Request /*: Class<Request> */)("");
|
||||
@@ -34,14 +56,23 @@ function hasFlowShorthandAnnotationComment(node) {
|
||||
node.extra &&
|
||||
node.extra.parenthesized &&
|
||||
node.trailingComments &&
|
||||
node.trailingComments[0].value.match(FLOW_SHORTHAND_ANNOTATION)
|
||||
FLOW_SHORTHAND_ANNOTATION.test(node.trailingComments[0].value)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Comment[]} comments
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function hasFlowAnnotationComment(comments) {
|
||||
return comments && comments[0].value.match(FLOW_ANNOTATION);
|
||||
return comments && FLOW_ANNOTATION.test(comments[0].value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @param {(Node) => boolean} fn
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function hasNode(node, fn) {
|
||||
if (!node || typeof node !== "object") {
|
||||
return false;
|
||||
@@ -55,6 +86,10 @@ function hasNode(node, fn) {
|
||||
: Object.keys(node).some((key) => hasNode(node[key], fn));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function hasNakedLeftSide(node) {
|
||||
return (
|
||||
node.type === "AssignmentExpression" ||
|
||||
@@ -115,7 +150,7 @@ function getLeftSidePathName(path, node) {
|
||||
if (node.expression) {
|
||||
return ["expression"];
|
||||
}
|
||||
throw new Error("Unexpected node has no left side", node);
|
||||
throw new Error("Unexpected node has no left side.");
|
||||
}
|
||||
|
||||
const exportDeclarationTypes = new Set([
|
||||
@@ -125,10 +160,19 @@ const exportDeclarationTypes = new Set([
|
||||
"ExportNamedDeclaration",
|
||||
"ExportAllDeclaration",
|
||||
]);
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isExportDeclaration(node) {
|
||||
return node && exportDeclarationTypes.has(node.type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {FastPath} path
|
||||
* @returns {Node | null}
|
||||
*/
|
||||
function getParentExportDeclaration(path) {
|
||||
const parentNode = path.getParentNode();
|
||||
if (path.getName() === "declaration" && isExportDeclaration(parentNode)) {
|
||||
@@ -138,6 +182,10 @@ function getParentExportDeclaration(path) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isLiteral(node) {
|
||||
return (
|
||||
node.type === "BooleanLiteral" ||
|
||||
@@ -155,6 +203,10 @@ function isLiteral(node) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isLiteralLikeValue(node) {
|
||||
return (
|
||||
isLiteral(node) ||
|
||||
@@ -173,6 +225,10 @@ function isLiteralLikeValue(node) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isNumericLiteral(node) {
|
||||
return (
|
||||
node.type === "NumericLiteral" ||
|
||||
@@ -180,6 +236,10 @@ function isNumericLiteral(node) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isStringLiteral(node) {
|
||||
return (
|
||||
node.type === "StringLiteral" ||
|
||||
@@ -187,10 +247,18 @@ function isStringLiteral(node) {
|
||||
);
|
||||
}
|
||||
|
||||
function isObjectType(n) {
|
||||
return n.type === "ObjectTypeAnnotation" || n.type === "TSTypeLiteral";
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isObjectType(node) {
|
||||
return node.type === "ObjectTypeAnnotation" || node.type === "TSTypeLiteral";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isFunctionOrArrowExpression(node) {
|
||||
return (
|
||||
node.type === "FunctionExpression" ||
|
||||
@@ -198,6 +266,10 @@ function isFunctionOrArrowExpression(node) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isFunctionOrArrowExpressionWithBody(node) {
|
||||
return (
|
||||
node.type === "FunctionExpression" ||
|
||||
@@ -206,12 +278,21 @@ function isFunctionOrArrowExpressionWithBody(node) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isTemplateLiteral(node) {
|
||||
return node.type === "TemplateLiteral";
|
||||
}
|
||||
|
||||
// `inject` is used in AngularJS 1.x, `async` in Angular 2+
|
||||
// example: https://docs.angularjs.org/guide/unit-testing#using-beforeall-
|
||||
/**
|
||||
* Note: `inject` is used in AngularJS 1.x, `async` in Angular 2+
|
||||
* example: https://docs.angularjs.org/guide/unit-testing#using-beforeall-
|
||||
*
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isAngularTestWrapper(node) {
|
||||
return (
|
||||
(node.type === "CallExpression" ||
|
||||
@@ -223,6 +304,10 @@ function isAngularTestWrapper(node) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isJSXNode(node) {
|
||||
return node.type === "JSXElement" || node.type === "JSXFragment";
|
||||
}
|
||||
@@ -253,6 +338,10 @@ function isJSXWhitespaceExpression(node) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isMemberExpressionChain(node) {
|
||||
if (
|
||||
node.type !== "MemberExpression" &&
|
||||
@@ -270,6 +359,11 @@ function isGetterOrSetter(node) {
|
||||
return node.kind === "get" || node.kind === "set";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} nodeA
|
||||
* @param {Node} nodeB
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function sameLocStart(nodeA, nodeB, options) {
|
||||
return options.locStart(nodeA) === options.locStart(nodeB);
|
||||
}
|
||||
@@ -283,6 +377,10 @@ function isFunctionNotation(node, options) {
|
||||
// Hack to differentiate between the following two which have the same ast
|
||||
// type T = { method: () => void };
|
||||
// type T = { method(): void };
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isObjectTypePropertyAFunction(node, options) {
|
||||
return (
|
||||
(node.type === "ObjectTypeProperty" ||
|
||||
@@ -310,15 +408,24 @@ const binaryishNodeTypes = new Set([
|
||||
"LogicalExpression",
|
||||
"NGPipeExpression",
|
||||
]);
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isBinaryish(node) {
|
||||
return binaryishNodeTypes.has(node.type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isMemberish(node) {
|
||||
return (
|
||||
node.type === "MemberExpression" ||
|
||||
node.type === "OptionalMemberExpression" ||
|
||||
(node.type === "BindExpression" && node.object)
|
||||
(node.type === "BindExpression" && Boolean(node.object))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -335,6 +442,11 @@ const flowTypeAnnotations = new Set([
|
||||
"BooleanLiteralTypeAnnotation",
|
||||
"StringTypeAnnotation",
|
||||
]);
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isSimpleFlowType(node) {
|
||||
return (
|
||||
node &&
|
||||
@@ -345,6 +457,10 @@ function isSimpleFlowType(node) {
|
||||
|
||||
const unitTestRe = /^(skip|[fx]?(it|describe|test))$/;
|
||||
|
||||
/**
|
||||
* @param {CallExpression} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isSkipOrOnlyBlock(node) {
|
||||
return (
|
||||
(node.callee.type === "MemberExpression" ||
|
||||
@@ -357,12 +473,16 @@ function isSkipOrOnlyBlock(node) {
|
||||
);
|
||||
}
|
||||
|
||||
function isUnitTestSetUp(n) {
|
||||
/**
|
||||
* @param {CallExpression} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isUnitTestSetUp(node) {
|
||||
const unitTestSetUpRe = /^(before|after)(Each|All)$/;
|
||||
return (
|
||||
n.callee.type === "Identifier" &&
|
||||
unitTestSetUpRe.test(n.callee.name) &&
|
||||
n.arguments.length === 1
|
||||
node.callee.type === "Identifier" &&
|
||||
unitTestSetUpRe.test(node.callee.name) &&
|
||||
node.arguments.length === 1
|
||||
);
|
||||
}
|
||||
|
||||
@@ -401,14 +521,26 @@ function isTestCall(n, parent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function hasLeadingComment(node) {
|
||||
return node.comments && node.comments.some((comment) => comment.leading);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function hasTrailingComment(node) {
|
||||
return node.comments && node.comments.some((comment) => comment.trailing);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function hasTrailingLineComment(node) {
|
||||
return (
|
||||
node.comments &&
|
||||
@@ -418,12 +550,20 @@ function hasTrailingLineComment(node) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {CallExpression | OptionalCallExpression} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isCallOrOptionalCallExpression(node) {
|
||||
return (
|
||||
node.type === "CallExpression" || node.type === "OptionalCallExpression"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function hasDanglingComments(node) {
|
||||
return (
|
||||
node.comments &&
|
||||
@@ -432,6 +572,10 @@ function hasDanglingComments(node) {
|
||||
}
|
||||
|
||||
/** identify if an angular expression seems to have side effects */
|
||||
/**
|
||||
* @param {FastPath} path
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function hasNgSideEffect(path) {
|
||||
return hasNode(path.getValue(), (node) => {
|
||||
switch (node.type) {
|
||||
@@ -455,7 +599,11 @@ function isNgForOf(node, index, parentNode) {
|
||||
);
|
||||
}
|
||||
|
||||
/** @param node {import("estree").TemplateLiteral} */
|
||||
/**
|
||||
*
|
||||
* @param {TemplateLiteral} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isSimpleTemplateLiteral(node) {
|
||||
if (node.expressions.length === 0) {
|
||||
return false;
|
||||
@@ -507,15 +655,18 @@ function isSimpleTemplateLiteral(node) {
|
||||
});
|
||||
}
|
||||
|
||||
function getFlowVariance(path) {
|
||||
if (!path.variance) {
|
||||
/**
|
||||
* @param {ObjectTypeProperty} node
|
||||
*/
|
||||
function getFlowVariance(node) {
|
||||
if (!node.variance) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Babel 7.0 currently uses variance node type, and flow should
|
||||
// follow suit soon:
|
||||
// https://github.com/babel/babel/issues/4722
|
||||
const variance = path.variance.kind || path.variance;
|
||||
const variance = node.variance.kind || node.variance;
|
||||
|
||||
switch (variance) {
|
||||
case "plus":
|
||||
@@ -528,6 +679,10 @@ function getFlowVariance(path) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {FastPath} path
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function classPropMayCauseASIProblems(path) {
|
||||
const node = path.getNode();
|
||||
|
||||
@@ -593,6 +748,11 @@ function classChildNeedsASIProtection(node) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} tokenNode
|
||||
* @param {string} keyword
|
||||
* @returns {string}
|
||||
*/
|
||||
function getTypeScriptMappedTypeModifier(tokenNode, keyword) {
|
||||
if (tokenNode === "+") {
|
||||
return "+" + keyword;
|
||||
@@ -623,6 +783,10 @@ const containsNonJsxWhitespaceRegex = new RegExp(
|
||||
|
||||
// Meaningful if it contains non-whitespace characters,
|
||||
// or it contains whitespace without a new line.
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isMeaningfulJSXText(node) {
|
||||
return (
|
||||
isLiteral(node) &&
|
||||
@@ -631,6 +795,10 @@ function isMeaningfulJSXText(node) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {FastPath} path
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function hasJsxIgnoreComment(path) {
|
||||
const node = path.getValue();
|
||||
const parent = path.getParentNode();
|
||||
@@ -661,6 +829,10 @@ function hasJsxIgnoreComment(path) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {JSXElement} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isEmptyJSXElement(node) {
|
||||
if (node.children.length === 0) {
|
||||
return true;
|
||||
@@ -675,10 +847,18 @@ function isEmptyJSXElement(node) {
|
||||
return isLiteral(child) && !isMeaningfulJSXText(child);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {FastPath} path
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function hasPrettierIgnore(path) {
|
||||
return hasIgnoreComment(path) || hasJsxIgnoreComment(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {FastPath} path
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isLastStatement(path) {
|
||||
const parent = path.getParentNode();
|
||||
if (!parent) {
|
||||
@@ -691,14 +871,26 @@ function isLastStatement(path) {
|
||||
return body && body[body.length - 1] === node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} text
|
||||
* @param {Node} typeAnnotation
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isFlowAnnotationComment(text, typeAnnotation, options) {
|
||||
const start = options.locStart(typeAnnotation);
|
||||
const end = skipWhitespace(text, options.locEnd(typeAnnotation));
|
||||
return (
|
||||
text.slice(start, start + 2) === "/*" && text.slice(end, end + 2) === "*/"
|
||||
end !== false &&
|
||||
text.slice(start, start + 2) === "/*" &&
|
||||
text.slice(end, end + 2) === "*/"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} text
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function hasLeadingOwnLineComment(text, node, options) {
|
||||
if (isJSXNode(node)) {
|
||||
return hasNodeIgnoreComment(node);
|
||||
@@ -784,6 +976,11 @@ function isSimpleNumber(numberString) {
|
||||
return /^(\d+|\d+\.\d+)$/.test(numberString);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @param {Node} parentNode
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isJestEachTemplateLiteral(node, parentNode) {
|
||||
/**
|
||||
* describe.each`table`(name, fn)
|
||||
@@ -813,10 +1010,19 @@ function isJestEachTemplateLiteral(node, parentNode) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TemplateLiteral} template
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function templateLiteralHasNewLines(template) {
|
||||
return template.quasis.some((quasi) => quasi.value.raw.includes("\n"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TemplateLiteral | TaggedTemplateExpression} n
|
||||
* @param {string} text
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isTemplateOnItsOwnLine(n, text, options) {
|
||||
return (
|
||||
((n.type === "TemplateLiteral" && templateLiteralHasNewLines(n)) ||
|
||||
@@ -826,6 +1032,10 @@ function isTemplateOnItsOwnLine(n, text, options) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function needsHardlineAfterDanglingComment(node) {
|
||||
if (!node.comments) {
|
||||
return false;
|
||||
@@ -869,6 +1079,10 @@ function isFunctionCompositionArgs(args) {
|
||||
// `connect(a, b, c)(d)`
|
||||
// In the above call expression, the second call is the parent node and the
|
||||
// first call is the current node.
|
||||
/**
|
||||
* @param {FastPath} path
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isLongCurriedCallExpression(path) {
|
||||
const node = path.getValue();
|
||||
const parent = path.getParentNode();
|
||||
@@ -882,7 +1096,7 @@ function isLongCurriedCallExpression(path) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('estree').Node} node
|
||||
* @param {Node} node
|
||||
* @param {number} depth
|
||||
* @returns {boolean}
|
||||
*/
|
||||
@@ -894,7 +1108,7 @@ function isSimpleCallArgument(node, depth) {
|
||||
const isChildSimple = (child) => isSimpleCallArgument(child, depth + 1);
|
||||
|
||||
const regexpPattern =
|
||||
(node.type === "Literal" && node.regex && node.regex.pattern) ||
|
||||
(node.type === "Literal" && "regex" in node && node.regex.pattern) ||
|
||||
(node.type === "RegExpLiteral" && node.pattern);
|
||||
|
||||
if (regexpPattern && regexpPattern.length > 5) {
|
||||
@@ -997,9 +1211,15 @@ function shouldPrintComma(options, level = "es5") {
|
||||
);
|
||||
}
|
||||
|
||||
// Tests if an expression starts with `{`, or (if forbidFunctionClassAndDoExpr
|
||||
// holds) `function`, `class`, or `do {}`. Will be overzealous if there's
|
||||
// already necessary grouping parentheses.
|
||||
/**
|
||||
* Tests if an expression starts with `{`, or (if forbidFunctionClassAndDoExpr
|
||||
* holds) `function`, `class`, or `do {}`. Will be overzealous if there's
|
||||
* already necessary grouping parentheses.
|
||||
*
|
||||
* @param {Node} node
|
||||
* @param {boolean} forbidFunctionClassAndDoExpr
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function startsWithNoLookaheadToken(node, forbidFunctionClassAndDoExpr) {
|
||||
node = getLeftMost(node);
|
||||
switch (node.type) {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
"use strict";
|
||||
/** @type {any} */
|
||||
|
||||
/** @type {import("assert")} */
|
||||
const assert = require("assert");
|
||||
|
||||
const {
|
||||
concat,
|
||||
line,
|
||||
@@ -11,6 +13,7 @@ const {
|
||||
join,
|
||||
cursor,
|
||||
} = require("../document").builders;
|
||||
|
||||
const {
|
||||
hasNewline,
|
||||
skipNewline,
|
||||
@@ -20,6 +23,7 @@ const {
|
||||
addDanglingComment,
|
||||
addTrailingComment,
|
||||
} = require("../common/util");
|
||||
|
||||
const childNodesCacheKey = Symbol("child-nodes");
|
||||
|
||||
function getSortedChildNodes(node, options, resultArray) {
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
"src/main/ast-to-doc.js",
|
||||
"src/main/core.js",
|
||||
"src/common/create-ignorer.js",
|
||||
"src/common/parser-create-error.js",
|
||||
"src/config/resolve-config.js",
|
||||
"src/main/options-normalizer.js",
|
||||
"src/common/get-file-info.js",
|
||||
@@ -24,7 +23,6 @@
|
||||
"src/main/options.js",
|
||||
// [TBD] src/language-* source directory trees with known JSDoc type issues:
|
||||
"src/language-html",
|
||||
"src/language-js",
|
||||
// [TBD] JavaScript sources affected by JSDoc issues in src/language-*:
|
||||
"src/common/load-plugins.js",
|
||||
"src/cli/index.js",
|
||||
|
||||
@@ -857,7 +857,7 @@
|
||||
globals "^11.1.0"
|
||||
lodash "^4.17.19"
|
||||
|
||||
"@babel/types@^7.0.0", "@babel/types@^7.10.4", "@babel/types@^7.11.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4":
|
||||
"@babel/types@7.11.0", "@babel/types@^7.0.0", "@babel/types@^7.10.4", "@babel/types@^7.11.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4":
|
||||
version "7.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.0.tgz#2ae6bf1ba9ae8c3c43824e5861269871b206e90d"
|
||||
integrity sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==
|
||||
@@ -1299,7 +1299,7 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
|
||||
integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==
|
||||
|
||||
"@types/estree@*":
|
||||
"@types/estree@*", "@types/estree@0.0.45":
|
||||
version "0.0.45"
|
||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.45.tgz#e9387572998e5ecdac221950dab3e8c3b16af884"
|
||||
integrity sha512-jnqIUKDUqJbDIUxm0Uj7bnlMnRm1T/eZ9N+AVMqhPgzrba2GhGG5o/jCTwmdPK709nEZsGoMzXEDUjcXHa3W0g==
|
||||
@@ -1358,6 +1358,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.14.tgz#24a0b5959f16ac141aeb0c5b3cd7a15b7c64cbce"
|
||||
integrity sha512-syUgf67ZQpaJj01/tRTknkMNoBBLWJOBODF0Zm4NrXmiSuxjymFrxnTu1QVYRubhVkRcZLYZG8STTwJRdVm/WQ==
|
||||
|
||||
"@types/node@14.6.0":
|
||||
version "14.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.6.0.tgz#7d4411bf5157339337d7cff864d9ff45f177b499"
|
||||
integrity sha512-mikldZQitV94akrc4sCcSjtJfsTKt4p+e/s0AGscVA6XArQ9kFclP+ZiYUMnq987rc6QlYxXv/EivqlfSLxpKA==
|
||||
|
||||
"@types/normalize-package-data@^2.4.0":
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e"
|
||||
|
||||
Reference in new issue
Block a user