typecheck updates & fixes in src/language-js (#8759)

Co-authored-by: fisker <lionkay@gmail.com>
This commit is contained in:
Chris Brodyandfisker authored and GitHub committed 2020-08-21 09:08:14 +08:00
1 parent 69ce8eab81
commit cdc250c21a
15 files changed
+421 -49

No files matched your search

+1
View File
@@ -354,6 +354,7 @@
"Transloadit",
"TSAs",
"tsep",
"TSESTree",
"TSJS",
"tslib",
"typeahead",
+5 -1
View File
@@ -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",
+4
View File
@@ -1,5 +1,9 @@
"use strict";
/**
* @typedef {import("./doc-builders").Doc} Doc
*/
module.exports = {
builders: require("./doc-builders"),
printer: require("./doc-printer"),
+12 -4
View File
@@ -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
View File
@@ -1,5 +1,6 @@
"use strict";
/** @type {import("assert")} */
const assert = require("assert");
const {
+1 -1
View File
@@ -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) {
+3 -4
View File
@@ -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)
);
}
+7
View File
@@ -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) {
+17 -10
View File
@@ -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
+19 -2
View File
@@ -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.
+97
View File
@@ -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
View File
@@ -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) {
+5 -1
View File
@@ -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) {
-2
View File
@@ -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",
+7 -2
View File
@@ -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"