Simplify the special-case printing of single-param arrow functions (#13204)
* Simplify the special-case printing of single-param arrow functions * Update test fixtures with single-param arrow functions * Add some explicit snapshot tests for known edge-cases
This commit is contained in:
parent
10f4d08efb
commit
3d4b801bb9
@ -112,32 +112,18 @@ export function ArrowFunctionExpression(
|
||||
|
||||
const firstParam = node.params[0];
|
||||
|
||||
// Try to avoid printing parens in simple cases, but only if we're pretty
|
||||
// sure that they aren't needed by type annotations or potential newlines.
|
||||
if (
|
||||
!this.format.retainLines &&
|
||||
// Auxiliary comments can introduce unexpected newlines
|
||||
!this.format.auxiliaryCommentBefore &&
|
||||
!this.format.auxiliaryCommentAfter &&
|
||||
node.params.length === 1 &&
|
||||
t.isIdentifier(firstParam) &&
|
||||
!hasTypes(node, firstParam)
|
||||
!hasTypesOrComments(node, firstParam)
|
||||
) {
|
||||
if (
|
||||
(this.format.retainLines || node.async) &&
|
||||
((node.loc &&
|
||||
node.body.loc &&
|
||||
node.loc.start.line < node.body.loc.start.line) ||
|
||||
firstParam.leadingComments?.length ||
|
||||
firstParam.trailingComments?.length)
|
||||
) {
|
||||
this.token("(");
|
||||
if (firstParam.loc && firstParam.loc.start.line > node.loc.start.line) {
|
||||
this.indent();
|
||||
this.print(firstParam, node);
|
||||
this.dedent();
|
||||
this._catchUp("start", node.body.loc);
|
||||
} else {
|
||||
this.print(firstParam, node);
|
||||
}
|
||||
this.token(")");
|
||||
} else {
|
||||
this.print(firstParam, node);
|
||||
}
|
||||
} else {
|
||||
this._params(node);
|
||||
}
|
||||
@ -151,12 +137,18 @@ export function ArrowFunctionExpression(
|
||||
this.print(node.body, node);
|
||||
}
|
||||
|
||||
function hasTypes(node, param) {
|
||||
return (
|
||||
function hasTypesOrComments(
|
||||
node: t.ArrowFunctionExpression,
|
||||
param: t.Identifier,
|
||||
): boolean {
|
||||
return !!(
|
||||
node.typeParameters ||
|
||||
node.returnType ||
|
||||
// @ts-expect-error
|
||||
node.predicate ||
|
||||
param.typeAnnotation ||
|
||||
param.optional ||
|
||||
param.trailingComments
|
||||
param.leadingComments?.length ||
|
||||
param.trailingComments?.length
|
||||
);
|
||||
}
|
||||
|
||||
119
packages/babel-generator/test/arrow-functions.js
Normal file
119
packages/babel-generator/test/arrow-functions.js
Normal file
@ -0,0 +1,119 @@
|
||||
import generate from "../lib";
|
||||
import { parse } from "@babel/parser";
|
||||
|
||||
describe("parameter parentheses", () => {
|
||||
// Common source text for several snapshot tests
|
||||
const source = `
|
||||
() => {};
|
||||
a => {};
|
||||
(a, b) => {};
|
||||
async () => {};
|
||||
async a => {};
|
||||
async (a, b) => {};
|
||||
`;
|
||||
// Apply a callback function to each parameter in the AST of the above source
|
||||
function forEachParam(ast, callbackFn) {
|
||||
ast.program.body.forEach(s => {
|
||||
s.expression.params.forEach(p => {
|
||||
callbackFn(p);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
it("auxiliaryCommentBefore", () => {
|
||||
const ast = parse(source);
|
||||
forEachParam(ast, p => (p.loc = null));
|
||||
const output = generate(ast, { auxiliaryCommentBefore: "BEFORE" }).code;
|
||||
expect(output).toMatchInlineSnapshot(`
|
||||
"() => {};
|
||||
|
||||
(
|
||||
/*BEFORE*/
|
||||
a) => {};
|
||||
|
||||
(
|
||||
/*BEFORE*/
|
||||
a,
|
||||
/*BEFORE*/
|
||||
b) => {};
|
||||
|
||||
async () => {};
|
||||
|
||||
async (
|
||||
/*BEFORE*/
|
||||
a) => {};
|
||||
|
||||
async (
|
||||
/*BEFORE*/
|
||||
a,
|
||||
/*BEFORE*/
|
||||
b) => {};"
|
||||
`);
|
||||
});
|
||||
it("auxiliaryCommentAfter", () => {
|
||||
const ast = parse(source);
|
||||
forEachParam(ast, p => (p.loc = null));
|
||||
const output = generate(ast, { auxiliaryCommentAfter: "AFTER" }).code;
|
||||
expect(output).toMatchInlineSnapshot(`
|
||||
"() => {};
|
||||
|
||||
(a
|
||||
/*AFTER*/
|
||||
) => {};
|
||||
|
||||
(a
|
||||
/*AFTER*/
|
||||
, b
|
||||
/*AFTER*/
|
||||
) => {};
|
||||
|
||||
async () => {};
|
||||
|
||||
async (a
|
||||
/*AFTER*/
|
||||
) => {};
|
||||
|
||||
async (a
|
||||
/*AFTER*/
|
||||
, b
|
||||
/*AFTER*/
|
||||
) => {};"
|
||||
`);
|
||||
});
|
||||
it("empty leadingComments array", () => {
|
||||
const ast = parse(source);
|
||||
forEachParam(ast, p => (p.leadingComments = []));
|
||||
const output = generate(ast).code;
|
||||
expect(output).toMatchInlineSnapshot(`
|
||||
"() => {};
|
||||
|
||||
a => {};
|
||||
|
||||
(a, b) => {};
|
||||
|
||||
async () => {};
|
||||
|
||||
async a => {};
|
||||
|
||||
async (a, b) => {};"
|
||||
`);
|
||||
});
|
||||
it("empty trailingComments array", () => {
|
||||
const ast = parse(source);
|
||||
forEachParam(ast, p => (p.trailingComments = []));
|
||||
const output = generate(ast).code;
|
||||
expect(output).toMatchInlineSnapshot(`
|
||||
"() => {};
|
||||
|
||||
a => {};
|
||||
|
||||
(a, b) => {};
|
||||
|
||||
async () => {};
|
||||
|
||||
async a => {};
|
||||
|
||||
async (a, b) => {};"
|
||||
`);
|
||||
});
|
||||
});
|
||||
@ -1,11 +1,11 @@
|
||||
var fn = async (
|
||||
arg
|
||||
) => {};
|
||||
arg) =>
|
||||
{};
|
||||
|
||||
async (x) =>
|
||||
{};
|
||||
|
||||
async x => {};
|
||||
async (x) => {};
|
||||
|
||||
async (x) =>
|
||||
{};
|
||||
@ -14,4 +14,4 @@ var f = (x: mixed): %checks => typeof x === "string";
|
||||
|
||||
const foo2 = (x: mixed): boolean %checks => typeof x === "string";
|
||||
|
||||
x: %checks => x !== null;
|
||||
(x): %checks => x !== null;
|
||||
@ -1,5 +1,5 @@
|
||||
const x = async ( // some comment
|
||||
a) => {
|
||||
a) => {
|
||||
return foo(await a);
|
||||
};
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
var _ref2;
|
||||
|
||||
const {
|
||||
[(_ref) => {
|
||||
[_ref => {
|
||||
let rest = babelHelpers.extends({}, _ref);
|
||||
let b = babelHelpers.extends({}, {});
|
||||
}]: a,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
var _ref2;
|
||||
|
||||
const {
|
||||
a = (_ref) => {
|
||||
a = _ref => {
|
||||
let rest = babelHelpers.extends({}, _ref);
|
||||
let b = babelHelpers.extends({}, {});
|
||||
},
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
(_ref) => {
|
||||
_ref => {
|
||||
let R = babelHelpers.extends({}, _ref);
|
||||
let a = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : R;
|
||||
};
|
||||
@ -32,7 +32,7 @@
|
||||
}();
|
||||
};
|
||||
|
||||
(_ref6) => {
|
||||
_ref6 => {
|
||||
let R = babelHelpers.extends({}, _ref6);
|
||||
let a = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : f(R);
|
||||
};
|
||||
|
||||
@ -15,7 +15,7 @@ const _bar = bar(),
|
||||
|
||||
const {
|
||||
a
|
||||
} = foo((_ref) => {
|
||||
} = foo(_ref => {
|
||||
let {
|
||||
b
|
||||
} = _ref,
|
||||
|
||||
@ -3,7 +3,7 @@ const get = () => {
|
||||
return 3;
|
||||
};
|
||||
|
||||
const f = (_ref) => {
|
||||
const f = _ref => {
|
||||
let {
|
||||
a = get(),
|
||||
b
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// Edge
|
||||
(_ref) => {
|
||||
_ref => {
|
||||
var {
|
||||
x = 2
|
||||
} = _ref;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
(_ref) => {
|
||||
_ref => {
|
||||
var {
|
||||
x = 2
|
||||
} = _ref;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
(_ref) => {
|
||||
_ref => {
|
||||
let _ref$x = _ref.x,
|
||||
x = _ref$x === void 0 ? 2 : _ref$x;
|
||||
};
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
(_ref) => {
|
||||
_ref => {
|
||||
let {
|
||||
x = 2
|
||||
} = _ref;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user