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];
|
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 (
|
if (
|
||||||
|
!this.format.retainLines &&
|
||||||
|
// Auxiliary comments can introduce unexpected newlines
|
||||||
|
!this.format.auxiliaryCommentBefore &&
|
||||||
|
!this.format.auxiliaryCommentAfter &&
|
||||||
node.params.length === 1 &&
|
node.params.length === 1 &&
|
||||||
t.isIdentifier(firstParam) &&
|
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.print(firstParam, node);
|
||||||
this.dedent();
|
|
||||||
this._catchUp("start", node.body.loc);
|
|
||||||
} else {
|
|
||||||
this.print(firstParam, node);
|
|
||||||
}
|
|
||||||
this.token(")");
|
|
||||||
} else {
|
|
||||||
this.print(firstParam, node);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
this._params(node);
|
this._params(node);
|
||||||
}
|
}
|
||||||
@ -151,12 +137,18 @@ export function ArrowFunctionExpression(
|
|||||||
this.print(node.body, node);
|
this.print(node.body, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasTypes(node, param) {
|
function hasTypesOrComments(
|
||||||
return (
|
node: t.ArrowFunctionExpression,
|
||||||
|
param: t.Identifier,
|
||||||
|
): boolean {
|
||||||
|
return !!(
|
||||||
node.typeParameters ||
|
node.typeParameters ||
|
||||||
node.returnType ||
|
node.returnType ||
|
||||||
|
// @ts-expect-error
|
||||||
|
node.predicate ||
|
||||||
param.typeAnnotation ||
|
param.typeAnnotation ||
|
||||||
param.optional ||
|
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 (
|
var fn = async (
|
||||||
arg
|
arg) =>
|
||||||
) => {};
|
{};
|
||||||
|
|
||||||
async (x) =>
|
async (x) =>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
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";
|
const foo2 = (x: mixed): boolean %checks => typeof x === "string";
|
||||||
|
|
||||||
x: %checks => x !== null;
|
(x): %checks => x !== null;
|
||||||
@ -1,7 +1,7 @@
|
|||||||
var _ref2;
|
var _ref2;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
[(_ref) => {
|
[_ref => {
|
||||||
let rest = babelHelpers.extends({}, _ref);
|
let rest = babelHelpers.extends({}, _ref);
|
||||||
let b = babelHelpers.extends({}, {});
|
let b = babelHelpers.extends({}, {});
|
||||||
}]: a,
|
}]: a,
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
var _ref2;
|
var _ref2;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
a = (_ref) => {
|
a = _ref => {
|
||||||
let rest = babelHelpers.extends({}, _ref);
|
let rest = babelHelpers.extends({}, _ref);
|
||||||
let b = babelHelpers.extends({}, {});
|
let b = babelHelpers.extends({}, {});
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
(_ref) => {
|
_ref => {
|
||||||
let R = babelHelpers.extends({}, _ref);
|
let R = babelHelpers.extends({}, _ref);
|
||||||
let a = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : R;
|
let a = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : R;
|
||||||
};
|
};
|
||||||
@ -32,7 +32,7 @@
|
|||||||
}();
|
}();
|
||||||
};
|
};
|
||||||
|
|
||||||
(_ref6) => {
|
_ref6 => {
|
||||||
let R = babelHelpers.extends({}, _ref6);
|
let R = babelHelpers.extends({}, _ref6);
|
||||||
let a = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : f(R);
|
let a = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : f(R);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -15,7 +15,7 @@ const _bar = bar(),
|
|||||||
|
|
||||||
const {
|
const {
|
||||||
a
|
a
|
||||||
} = foo((_ref) => {
|
} = foo(_ref => {
|
||||||
let {
|
let {
|
||||||
b
|
b
|
||||||
} = _ref,
|
} = _ref,
|
||||||
|
|||||||
@ -3,7 +3,7 @@ const get = () => {
|
|||||||
return 3;
|
return 3;
|
||||||
};
|
};
|
||||||
|
|
||||||
const f = (_ref) => {
|
const f = _ref => {
|
||||||
let {
|
let {
|
||||||
a = get(),
|
a = get(),
|
||||||
b
|
b
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
// Edge
|
// Edge
|
||||||
(_ref) => {
|
_ref => {
|
||||||
var {
|
var {
|
||||||
x = 2
|
x = 2
|
||||||
} = _ref;
|
} = _ref;
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
(_ref) => {
|
_ref => {
|
||||||
var {
|
var {
|
||||||
x = 2
|
x = 2
|
||||||
} = _ref;
|
} = _ref;
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
(_ref) => {
|
_ref => {
|
||||||
let _ref$x = _ref.x,
|
let _ref$x = _ref.x,
|
||||||
x = _ref$x === void 0 ? 2 : _ref$x;
|
x = _ref$x === void 0 ? 2 : _ref$x;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
(_ref) => {
|
_ref => {
|
||||||
let {
|
let {
|
||||||
x = 2
|
x = 2
|
||||||
} = _ref;
|
} = _ref;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user