Skip to content

Commit

Permalink
Extract printInterface and printCallExpression (#9715)
Browse files Browse the repository at this point in the history
  • Loading branch information
fisker committed Nov 19, 2020
1 parent c03a38e commit 05236cf
Show file tree
Hide file tree
Showing 4 changed files with 207 additions and 175 deletions.
103 changes: 103 additions & 0 deletions src/language-js/print/call-expression.js
@@ -0,0 +1,103 @@
"use strict";

const {
builders: { concat, join, group },
} = require("../../document");
const pathNeedsParens = require("../needs-parens");
const {
getCallArguments,
hasFlowAnnotationComment,
isCallOrOptionalCallExpression,
isMemberish,
isTemplateOnItsOwnLine,
isTestCall,
iterateCallArgumentsPath,
} = require("../utils");
const printMemberChain = require("./member-chain");
const printCallArguments = require("./call-arguments");
const { printOptionalToken, printFunctionTypeParameters } = require("./misc");

function printCallExpression(path, options, print) {
const n = path.getValue();
const isNew = n.type === "NewExpression";
const isDynamicImport = n.type === "ImportExpression";

const optional = printOptionalToken(path);
const args = getCallArguments(n);
if (
// Dangling comments not handled, all these special cases should has argument #9668
args.length > 0 &&
// We want to keep CommonJS- and AMD-style require calls, and AMD-style
// define calls, as a unit.
// e.g. `define(["some/lib", (lib) => {`
((!isDynamicImport &&
!isNew &&
n.callee.type === "Identifier" &&
(n.callee.name === "require" || n.callee.name === "define")) ||
// Template literals as single arguments
(args.length === 1 &&
isTemplateOnItsOwnLine(args[0], options.originalText)) ||
// Keep test declarations on a single line
// e.g. `it('long name', () => {`
(!isNew && isTestCall(n, path.getParentNode())))
) {
const printed = [];
iterateCallArgumentsPath(path, (argPath) => {
printed.push(print(argPath));
});
return concat([
isNew ? "new " : "",
path.call(print, "callee"),
optional,
printFunctionTypeParameters(path, options, print),
concat(["(", join(", ", printed), ")"]),
]);
}

// Inline Flow annotation comments following Identifiers in Call nodes need to
// stay with the Identifier. For example:
//
// foo /*:: <SomeGeneric> */(bar);
//
// Here, we ensure that such comments stay between the Identifier and the Callee.
const isIdentifierWithFlowAnnotation =
(options.parser === "babel" || options.parser === "babel-flow") &&
n.callee &&
n.callee.type === "Identifier" &&
hasFlowAnnotationComment(n.callee.trailingComments);
if (isIdentifierWithFlowAnnotation) {
n.callee.trailingComments[0].printed = true;
}

// We detect calls on member lookups and possibly print them in a
// special chain format. See `printMemberChain` for more info.
if (
!isDynamicImport &&
!isNew &&
isMemberish(n.callee) &&
!path.call((path) => pathNeedsParens(path, options), "callee")
) {
return printMemberChain(path, options, print);
}

const contents = concat([
isNew ? "new " : "",
isDynamicImport ? "import" : path.call(print, "callee"),
optional,
isIdentifierWithFlowAnnotation
? `/*:: ${n.callee.trailingComments[0].value.slice(2).trim()} */`
: "",
printFunctionTypeParameters(path, options, print),
printCallArguments(path, options, print),
]);

// We group here when the callee is itself a call expression.
// See `isLongCurriedCallExpression` for more info.
if (isDynamicImport || isCallOrOptionalCallExpression(n.callee)) {
return group(contents);
}

return contents;
}

module.exports = { printCallExpression };
83 changes: 83 additions & 0 deletions src/language-js/print/interface.js
@@ -0,0 +1,83 @@
"use strict";

const {
builders: { concat, join, line, group, indent, ifBreak },
} = require("../../document");
const {
hasTrailingComment,
hasTrailingLineComment,
identity,
} = require("../utils");
const { getTypeParametersGroupId } = require("./type-parameters");
const { printTypeScriptModifiers } = require("./misc");

function printInterface(path, options, print) {
const n = path.getValue();
const parts = [];
if (n.type === "DeclareInterface" || n.declare) {
parts.push("declare ");
}

if (n.type === "TSInterfaceDeclaration") {
parts.push(
n.abstract ? "abstract " : "",
printTypeScriptModifiers(path, options, print)
);
}

parts.push("interface");

const partsGroup = [];
const extendsParts = [];

if (n.type !== "InterfaceTypeAnnotation") {
partsGroup.push(
" ",
path.call(print, "id"),
path.call(print, "typeParameters")
);
}

const shouldIndentOnlyHeritageClauses =
n.typeParameters && !hasTrailingLineComment(n.typeParameters);

if (n.extends && n.extends.length !== 0) {
extendsParts.push(
shouldIndentOnlyHeritageClauses
? ifBreak(" ", line, {
groupId: getTypeParametersGroupId(n.typeParameters),
})
: line,
"extends ",
(n.extends.length === 1 ? identity : indent)(
join(concat([",", line]), path.map(print, "extends"))
)
);
}

if (
(n.id && hasTrailingComment(n.id)) ||
(n.extends && n.extends.length !== 0)
) {
const printedExtends = concat(extendsParts);
if (shouldIndentOnlyHeritageClauses) {
parts.push(
group(
concat(
partsGroup.concat(ifBreak(indent(printedExtends), printedExtends))
)
)
);
} else {
parts.push(group(indent(concat(partsGroup.concat(printedExtends)))));
}
} else {
parts.push(...partsGroup, ...extendsParts);
}

parts.push(" ", path.call(print, "body"));

return group(concat(parts));
}

module.exports = { printInterface };
16 changes: 13 additions & 3 deletions src/language-js/print/misc.js
@@ -1,11 +1,12 @@
"use strict";

const { isNumericLiteral } = require("../utils");

const {
builders: { concat, softline, group, indent, join, line, hardline },
} = require("../../document");
const { hasNewlineBetweenOrAfterDecorators } = require("../utils");
const {
hasNewlineBetweenOrAfterDecorators,
isNumericLiteral,
} = require("../utils");

function printOptionalToken(path) {
const node = path.getValue();
Expand Down Expand Up @@ -59,6 +60,14 @@ function printBindExpressionCallee(path, options, print) {
return concat(["::", path.call(print, "callee")]);
}

function printTypeScriptModifiers(path, options, print) {
const n = path.getValue();
if (!n.modifiers || !n.modifiers.length) {
return "";
}
return concat([join(" ", path.map(print, "modifiers")), " "]);
}

function printDecorators(path, options, print) {
const node = path.getValue();
return group(
Expand All @@ -74,5 +83,6 @@ module.exports = {
printFunctionTypeParameters,
printMemberLookup,
printBindExpressionCallee,
printTypeScriptModifiers,
printDecorators,
};

0 comments on commit 05236cf

Please sign in to comment.