master
Christopher Chedeau 2017-03-03 14:03:03 -08:00
parent 7d24b0a1ff
commit b570154dd5
3 changed files with 212 additions and 69 deletions

View File

@ -1,3 +1,26 @@
# 0.21.0
[link](https://github.com/jlongster/prettier/compare/0.20.0...0.21.0)
* [JSX] Break before and after jsx whitespace (#836)
* re-run snapshot tests
* Run prettier 0.20.0 (#835)
* [JSX] Don't wrap JSX Elements in parentheses in {} (#845)
* Fix comment after the last argument of a function (#856)
* Fix travis build imag
* Do not break require calls (#841)
* Stabilize import as comments (#855)
* Fix jsx expression comment that break (#852)
* Inline last arg function arguments (#847)
* Keep parenthesis on export default function (#844)
* Inline short expressions for boolean operators too (#826)
* Introduce -l option (#854)
* Add parenthesis around assignments (#862)
* Do not put \n after label (#860)
* Fix comment for `call( // comment` (#858)
* Do not break long it calls (#842)
* Fix flow union comments (#853)
# 0.20.0
[link](https://github.com/jlongster/prettier/compare/0.19.0...0.20.0)

256
docs/prettier.min.js vendored
View File

@ -9163,10 +9163,13 @@ function attach(comments, ast, text, options) {
// If a comment exists on its own line, prefer a leading comment.
// We also need to check if it's the first line of the file.
if (
handleLastFunctionArgComments(precedingNode, enclosingNode, followingNode, comment) ||
handleMemberExpressionComments(enclosingNode, followingNode, comment) ||
handleIfStatementComments(enclosingNode, followingNode, comment) ||
handleTryStatementComments(enclosingNode, followingNode, comment) ||
handleClassComments(enclosingNode, comment)
handleImportSpecifierComments(enclosingNode, comment) ||
handleClassComments(enclosingNode, comment) ||
handleUnionTypeComments(precedingNode, enclosingNode, followingNode, comment)
) {
// We're good
} else if (followingNode) {
@ -9189,7 +9192,9 @@ function attach(comments, ast, text, options) {
comment,
text
) ||
handleImportSpecifierComments(enclosingNode, comment) ||
handleTemplateLiteralComments(enclosingNode, comment) ||
handleCallExpressionComments(precedingNode, enclosingNode, comment) ||
handleClassComments(enclosingNode, comment)
) {
// We're good
@ -9467,7 +9472,8 @@ function handleFunctionDeclarationComments(enclosingNode, comment) {
// Only add dangling comments to fix the case when no params are present,
// i.e. a function without any argument.
if (
enclosingNode && enclosingNode.type === "FunctionDeclaration" &&
enclosingNode &&
enclosingNode.type === "FunctionDeclaration" &&
enclosingNode.params.length === 0
) {
addDanglingComment(enclosingNode, comment);
@ -9476,16 +9482,67 @@ function handleFunctionDeclarationComments(enclosingNode, comment) {
return false;
}
function handleLastFunctionArgComments(precedingNode, enclosingNode, followingNode, comment) {
// Type definitions functions
if (precedingNode && precedingNode.type === 'FunctionTypeParam' &&
enclosingNode && enclosingNode.type === 'FunctionTypeAnnotation' &&
followingNode && followingNode.type !== 'FunctionTypeParam') {
addTrailingComment(precedingNode, comment);
return true;
}
// Real functions
if (precedingNode && precedingNode.type === 'Identifier' &&
enclosingNode && (
enclosingNode.type === 'ArrowFunctionExpression' ||
enclosingNode.type === 'FunctionExpression') &&
followingNode && followingNode.type !== 'Identifier') {
addTrailingComment(precedingNode, comment);
return true;
}
return false;
}
function handleClassComments(enclosingNode, comment) {
if (enclosingNode &&
(enclosingNode.type === "ClassDeclaration" ||
enclosingNode.type === "ClassExpression")) {
if (
enclosingNode &&
(enclosingNode.type === "ClassDeclaration" ||
enclosingNode.type === "ClassExpression")
) {
addLeadingComment(enclosingNode, comment);
return true;
}
return false;
}
function handleImportSpecifierComments(enclosingNode, comment) {
if (enclosingNode && enclosingNode.type === "ImportSpecifier") {
addLeadingComment(enclosingNode, comment);
return true;
}
return false;
}
function handleCallExpressionComments(precedingNode, enclosingNode, comment) {
if (enclosingNode && enclosingNode.type === "CallExpression" &&
precedingNode && enclosingNode.callee === precedingNode &&
enclosingNode.arguments.length > 0) {
addLeadingComment(enclosingNode.arguments[0], comment);
return true;
}
return false;
}
function handleUnionTypeComments(precedingNode, enclosingNode, followingNode, comment) {
if (enclosingNode && enclosingNode.type === 'UnionTypeAnnotation' &&
precedingNode && precedingNode.type === 'ObjectTypeAnnotation' &&
followingNode && followingNode.type === 'ObjectTypeAnnotation') {
addTrailingComment(precedingNode, comment);
return true;
}
return false;
}
function printComment(commentPath) {
const comment = commentPath.getValue();
comment.printed = true;
@ -9659,7 +9716,7 @@ function printComments(path, print, options) {
var comments$1 = { attach, printComments, printDanglingComments };
var name = "prettier";
var version$2 = "0.19.0";
var version$2 = "0.21.0";
var description = "Prettier is an opinionated JavaScript formatter";
var bin = {"prettier":"./bin/prettier.js"};
var repository = {"type":"git","url":"git+https://github.com/jlongster/prettier.git"};
@ -10112,11 +10169,21 @@ FPp.needsParens = function(assumeExpressionContext) {
case "AssignmentExpression":
if (
parent.type === "ArrowFunctionExpression" &&
parent.body === node &&
node.left.type === "ObjectPattern"
parent.body === node
) {
return true;
return node.left.type === "ObjectPattern";
}
if (parent.type === "ForStatement" &&
(parent.init === node || parent.update === node)) {
return false;
}
if (parent.type === "ExpressionStatement") {
if (node.left.type === "ObjectPattern") {
return true;
}
return false;
}
return true;
case "ConditionalExpression":
switch (parent.type) {
@ -10159,10 +10226,10 @@ FPp.needsParens = function(assumeExpressionContext) {
return false;
case "ExportDefaultDeclaration":
if (node.type === "ArrowFunctionExpression") {
return false;
}
if (node.type === "FunctionExpression" && !node.id) {
if (
node.type === "ArrowFunctionExpression" ||
node.type === "FunctionDeclaration"
) {
return false;
}
return true;
@ -10531,9 +10598,12 @@ function genericPrintNoParens(path, options, print) {
path.call(print, "left"),
" ",
n.operator,
hasLeadingOwnLineComment(options.originalText, n.right) ?
indent$2(options.tabWidth, concat$2([hardline$2, path.call(print, "right")])) :
concat$2([" ", path.call(print, "right")]),
hasLeadingOwnLineComment(options.originalText, n.right)
? indent$2(
options.tabWidth,
concat$2([hardline$2, path.call(print, "right")])
)
: concat$2([" ", path.call(print, "right")])
])
);
case "BinaryExpression":
@ -10544,9 +10614,9 @@ function genericPrintNoParens(path, options, print) {
// Avoid indenting sub-expressions in if/etc statements.
if (
hasLeadingOwnLineComment(options.originalText, n) &&
(hasLeadingOwnLineComment(options.originalText, n) &&
(parent.type === "AssignmentExpression" ||
parent.type === "VariableDeclarator") ||
parent.type === "VariableDeclarator")) ||
shouldInlineLogicalExpression(n) ||
(n !== parent.body &&
(parent.type === "IfStatement" ||
@ -10967,7 +11037,23 @@ function genericPrintNoParens(path, options, print) {
return concat$2(parts);
case "CallExpression": {
const parent = path.getParentNode();
if (
// We want to keep require calls as a unit
n.callee.type === "Identifier" && n.callee.name === "require" ||
// `it('long name', () => {` should not break
(n.callee.type === "Identifier" && (
n.callee.name === "it" || n.callee.name === "test") &&
n.arguments.length === 2 &&
(n.arguments[0].type === "StringLiteral" || n.arguments[0].type === "Literal" && typeof n.arguments[0].value === "string") &&
(n.arguments[1].type === "FunctionExpression" || n.arguments[1].type === "ArrowFunctionExpression") &&
n.arguments[1].params.length <= 1)
) {
return concat$2([
path.call(print, "callee"),
concat$2(["(", join$2(", ", path.map(print, "arguments")), ")"])
]);
}
// We detect calls on member lookups and possibly print them in a
// special chain format. See `printMemberChain` for more info.
if (n.callee.type === "MemberExpression") {
@ -11291,9 +11377,12 @@ function genericPrintNoParens(path, options, print) {
? concat$2([
path.call(print, "id"),
" =",
hasLeadingOwnLineComment(options.originalText, n.init) ?
indent$2(options.tabWidth, concat$2([hardline$2, path.call(print, "init")])) :
concat$2([" ", path.call(print, "init")]),
hasLeadingOwnLineComment(options.originalText, n.init)
? indent$2(
options.tabWidth,
concat$2([hardline$2, path.call(print, "init")])
)
: concat$2([" ", path.call(print, "init")])
])
: path.call(print, "id");
case "WithStatement":
@ -11466,8 +11555,7 @@ function genericPrintNoParens(path, options, print) {
return concat$2([
path.call(print, "label"),
":",
hardline$2,
": ",
path.call(print, "body")
]);
case "TryStatement":
@ -11649,10 +11737,7 @@ function genericPrintNoParens(path, options, print) {
case "JSXText":
throw new Error("JSXTest should be handled by JSXElement");
case "JSXEmptyExpression":
return concat$2([
comments$3.printDanglingComments(path, options, /* sameIndent */ true),
softline$1
]);
return comments$3.printDanglingComments(path, options, /* sameIndent */ true);
case "TypeAnnotatedIdentifier":
return concat$2([
path.call(print, "annotation"),
@ -11730,8 +11815,7 @@ function genericPrintNoParens(path, options, print) {
return docUtils$2.mapDoc(doc, d => {
if (d.type === "line" && !d.hard) {
return d.soft ? "" : " ";
}
else if(d.type === "if-break") {
} else if (d.type === "if-break") {
return d.flatContents || "";
}
return d;
@ -11944,12 +12028,19 @@ function genericPrintNoParens(path, options, print) {
return join$2(" & ", types);
}
const parent = path.getParentNode();
// If there's a leading comment, the parent is doing the indentation
const shouldIndent = !(parent.type === 'TypeAlias' &&
hasLeadingOwnLineComment(options.originalText, n));
const token = isIntersection ? "&" : "|";
return group$1(
indent$2(
options.tabWidth,
shouldIndent ? options.tabWidth : 0,
concat$2([
ifBreak$1(concat$2([line$1, isIntersection ? "&" : "|", " "])),
join$2(concat$2([line$1, isIntersection ? "&" : "|", " "]), types)
ifBreak$1(concat$2([shouldIndent ? line$1 : "", token, " "])),
join$2(concat$2([line$1, token, " "]), types)
])
)
);
@ -12032,8 +12123,13 @@ function genericPrintNoParens(path, options, print) {
"type ",
path.call(print, "id"),
path.call(print, "typeParameters"),
" = ",
path.call(print, "right"),
" =",
hasLeadingOwnLineComment(options.originalText, n.right)
? indent$2(
options.tabWidth,
concat$2([hardline$2, path.call(print, "right")])
)
: concat$2([" ", path.call(print, "right")]),
";"
);
@ -12236,20 +12332,10 @@ function printMethod(path, options, print) {
return concat$2(parts);
}
function printArgumentsList(path, options, print) {
var printed = path.map(print, "arguments");
if (printed.length === 0) {
return "()";
}
const args = path.getValue().arguments;
function shouldGroupLastArg(args) {
const lastArg = util$4.getLast(args);
const penultimateArg = util$4.getPenultimate(args);
// This is just an optimization; I think we could return the
// conditional group for all function calls, but it's more expensive
// so only do it for specific forms.
const groupLastArg = (!lastArg.comments || !lastArg.comments.length) &&
return (!lastArg.comments || !lastArg.comments.length) &&
(lastArg.type === "ObjectExpression" ||
lastArg.type === "ArrayExpression" ||
lastArg.type === "FunctionExpression" ||
@ -12259,12 +12345,24 @@ function printArgumentsList(path, options, print) {
lastArg.body.type === "ObjectExpression" ||
lastArg.body.type === "ArrayExpression" ||
lastArg.body.type === "CallExpression" ||
lastArg.body.type === "JSXElement"))) &&
// If the last two arguments are of the same type,
// disable last element expansion.
(!penultimateArg || penultimateArg.type !== lastArg.type);
lastArg.body.type === "JSXElement"))) &&
// If the last two arguments are of the same type,
// disable last element expansion.
(!penultimateArg || penultimateArg.type !== lastArg.type);
}
if (groupLastArg) {
function printArgumentsList(path, options, print) {
var printed = path.map(print, "arguments");
if (printed.length === 0) {
return "()";
}
const args = path.getValue().arguments;
// This is just an optimization; I think we could return the
// conditional group for all function calls, but it's more expensive
// so only do it for specific forms.
if (shouldGroupLastArg(args)) {
const shouldBreak = printed.slice(0, -1).some(willBreak$2);
return concat$2([
printed.some(willBreak$2) ? breakParent$2 : "",
@ -12340,7 +12438,7 @@ function printFunctionParams(path, print, options) {
"(",
comments$3.printDanglingComments(path, options, /* sameIndent */ true),
")"
])
]);
}
const lastParam = util$4.getLast(path.getValue().params);
@ -12348,6 +12446,23 @@ function printFunctionParams(path, print, options) {
lastParam.type === "RestElement") &&
!fun.rest;
// If the parent is a call with the last argument expansion and this is the
// params of the last argument, we dont want the arguments to break and instead
// want the whole expression to be on a new line.
//
// Good: Bad:
// verylongcall( verylongcall((
// (a, b) => { a,
// } b,
// }) ) => {
// })
const parent = path.getParentNode();
if ((parent.type === "CallExpression" || parent.type === "NewExpression") &&
util$4.getLast(parent.arguments) === path.getValue() &&
shouldGroupLastArg(parent.arguments)) {
return concat$2(["(", join$2(", ", printed), ")"]);
}
return concat$2([
"(",
indent$2(
@ -12727,10 +12842,12 @@ function printMemberChain(path, options, print) {
// If we only have a single `.`, we shouldn't do anything fancy and just
// render everything concatenated together.
if (groups.length <= (shouldMerge ? 3 : 2) &&
!hasComment &&
// (a || b).map() should be break before .map() instead of ||
groups[0][0].node.type !== "LogicalExpression") {
if (
groups.length <= (shouldMerge ? 3 : 2) &&
!hasComment &&
// (a || b).map() should be break before .map() instead of ||
groups[0][0].node.type !== "LogicalExpression"
) {
return group$1(oneLine);
}
@ -12815,6 +12932,7 @@ function printJSXChildren(path, options, print, jsxWhitespace) {
const beginSpace = /^\s+/.test(line);
if (beginSpace) {
children.push(jsxWhitespace);
children.push(softline$1);
}
const stripped = line.replace(/^\s+|\s+$/g, "");
@ -12824,6 +12942,7 @@ function printJSXChildren(path, options, print, jsxWhitespace) {
const endSpace = /\s+$/.test(line);
if (endSpace) {
children.push(softline$1);
children.push(jsxWhitespace);
}
});
@ -13001,6 +13120,7 @@ function maybeWrapJSXElementInParens(path, elem, options) {
const NO_WRAP_PARENTS = {
JSXElement: true,
JSXExpressionContainer: true,
ExpressionStatement: true,
CallExpression: true,
ConditionalExpression: true,
@ -13078,14 +13198,13 @@ function printBinaryishExpressions(path, parts, print, options, isNested) {
path.call(print, "right")
]);
// If there's only a single binary expression: everything except && and ||,
// we want to create a group in order to avoid having a small right part
// like -1 be on its own line.
// If there's only a single binary expression, we want to create a group
// in order to avoid having a small right part like -1 be on its own line.
const parent = path.getParentNode();
const shouldGroup = node.type === "BinaryExpression" &&
parent.type !== "BinaryExpression" &&
node.left.type !== "BinaryExpression" &&
node.right.type !== "BinaryExpression";
const shouldGroup =
parent.type !== node.type &&
node.left.type !== node.type &&
node.right.type !== node.type;
parts.push(" ", shouldGroup ? group$1(right) : right);
@ -13220,10 +13339,11 @@ function isLastStatement(path) {
function hasLeadingOwnLineComment(text, node) {
const res = node.comments &&
node.comments.some(comment =>
comment.leading &&
util$4.hasNewline(text, util$4.locStart(comment), { backwards: true }) &&
util$4.hasNewline(text, util$4.locEnd(comment))
node.comments.some(
comment =>
comment.leading &&
util$4.hasNewline(text, util$4.locStart(comment), { backwards: true }) &&
util$4.hasNewline(text, util$4.locEnd(comment))
);
return res;
}

View File

@ -1,6 +1,6 @@
{
"name": "prettier",
"version": "0.20.0",
"version": "0.21.0",
"description": "Prettier is an opinionated JavaScript formatter",
"bin": {
"prettier": "./bin/prettier.js"