diff --git a/bin/prettier.js b/bin/prettier.js index 71ecac36..a0c284c4 100755 --- a/bin/prettier.js +++ b/bin/prettier.js @@ -221,7 +221,7 @@ if (stdin) { let input; try { input = fs.readFileSync(filename, "utf8"); - } catch(e) { + } catch (e) { // Add newline to split errors from filename line. process.stdout.write("\n"); diff --git a/index.js b/index.js index 449a821d..9874a247 100644 --- a/index.js +++ b/index.js @@ -20,9 +20,9 @@ function guessLineEnding(text) { function parse(text, opts) { let parseFunction; - if (opts.parser === 'flow') { + if (opts.parser === "flow") { parseFunction = parser.parseWithFlow; - } else if (opts.parser === 'typescript') { + } else if (opts.parser === "typescript") { parseFunction = parser.parseWithTypeScript; } else { parseFunction = parser.parseWithBabylon; diff --git a/src/comments.js b/src/comments.js index 875cc66a..314b3d3e 100644 --- a/src/comments.js +++ b/src/comments.js @@ -19,7 +19,8 @@ var comparePos = util.comparePos; var childNodesCacheKey = Symbol("child-nodes"); var locStart = util.locStart; var locEnd = util.locEnd; -var getNextNonSpaceNonCommentCharacter = util.getNextNonSpaceNonCommentCharacter; +var getNextNonSpaceNonCommentCharacter = + util.getNextNonSpaceNonCommentCharacter; // TODO Move a non-caching implementation of this function into ast-types, // and implement a caching wrapper function here. @@ -38,8 +39,10 @@ function getSortedChildNodes(node, text, resultArray) { // time because we almost always (maybe always?) append the // nodes in order anyway. for (var i = resultArray.length - 1; i >= 0; --i) { - if (locStart(resultArray[i]) <= locStart(node) && - locEnd(resultArray[i]) <= locEnd(node)) { + if ( + locStart(resultArray[i]) <= locStart(node) && + locEnd(resultArray[i]) <= locEnd(node) + ) { break; } } @@ -82,7 +85,7 @@ function decorateComment(node, comment, text) { // Time to dust off the old binary search robes and wizard hat. var left = 0, right = childNodes.length; while (left < right) { - var middle = left + right >> 1; + var middle = (left + right) >> 1; var child = childNodes[middle]; if ( @@ -155,7 +158,12 @@ function attach(comments, ast, text, options) { comment ) || handleMemberExpressionComments(enclosingNode, followingNode, comment) || - handleIfStatementComments(text, enclosingNode, followingNode, comment) || + handleIfStatementComments( + text, + enclosingNode, + followingNode, + comment + ) || handleTryStatementComments(enclosingNode, followingNode, comment) || handleClassComments(enclosingNode, comment) || handleImportSpecifierComments(enclosingNode, comment) || @@ -168,7 +176,11 @@ function attach(comments, ast, text, options) { comment ) || handleOnlyComments(enclosingNode, ast, comment, isLastComment) || - handleImportDeclarationComments(enclosingNode, precedingNode, comment) || + handleImportDeclarationComments( + enclosingNode, + precedingNode, + comment + ) || handleAssignmentPatternComments(enclosingNode, comment) ) { // We're good @@ -194,7 +206,12 @@ function attach(comments, ast, text, options) { ) || handleImportSpecifierComments(enclosingNode, comment) || handleTemplateLiteralComments(enclosingNode, comment) || - handleIfStatementComments(text, enclosingNode, followingNode, comment) || + handleIfStatementComments( + text, + enclosingNode, + followingNode, + comment + ) || handleClassComments(enclosingNode, comment) || handleLabeledStatementComments(enclosingNode, comment) || handleCallExpressionComments(precedingNode, enclosingNode, comment) || @@ -219,7 +236,12 @@ function attach(comments, ast, text, options) { } } else { if ( - handleIfStatementComments(text, enclosingNode, followingNode, comment) || + handleIfStatementComments( + text, + enclosingNode, + followingNode, + comment + ) || handleObjectPropertyAssignment(enclosingNode, precedingNode, comment) || handleTemplateLiteralComments(enclosingNode, comment) || handleCommentInEmptyParens(enclosingNode, comment) || @@ -365,11 +387,14 @@ function addBlockOrNotComment(node, comment) { // // comment // ... // } -function handleIfStatementComments(text, enclosingNode, followingNode, comment) { +function handleIfStatementComments( + text, + enclosingNode, + followingNode, + comment +) { if ( - !enclosingNode || - enclosingNode.type !== "IfStatement" || - !followingNode + !enclosingNode || enclosingNode.type !== "IfStatement" || !followingNode ) { return false; } @@ -444,7 +469,8 @@ function handleConditionalExpressionComments( comment, text ) { - const isSameLineAsPrecedingNode = precedingNode && + const isSameLineAsPrecedingNode = + precedingNode && !util.hasNewlineInRange(text, locEnd(precedingNode), locStart(comment)); if ( @@ -498,16 +524,18 @@ function handleCommentInEmptyParens(enclosingNode, comment) { enclosingNode.type === "ArrowFunctionExpression" || enclosingNode.type === "ClassMethod" || enclosingNode.type === "ObjectMethod") && - enclosingNode.params.length === 0) || - (enclosingNode.type === "CallExpression" && - enclosingNode.arguments.length === 0)) + enclosingNode.params.length === 0) || + (enclosingNode.type === "CallExpression" && + enclosingNode.arguments.length === 0)) ) { addDanglingComment(enclosingNode, comment); return true; } - if (enclosingNode && + if ( + enclosingNode && (enclosingNode.type === "MethodDefinition" && - enclosingNode.value.params.length === 0)) { + enclosingNode.value.params.length === 0) + ) { addDanglingComment(enclosingNode.value, comment); return true; } @@ -607,10 +635,7 @@ function handleUnionTypeComments( followingNode, comment ) { - if ( - enclosingNode && - enclosingNode.type === "UnionTypeAnnotation" - ) { + if (enclosingNode && enclosingNode.type === "UnionTypeAnnotation") { addTrailingComment(precedingNode, comment); return true; } @@ -619,10 +644,9 @@ function handleUnionTypeComments( function handlePropertyComments(enclosingNode, comment) { if ( - enclosingNode && ( - enclosingNode.type === "Property" || - enclosingNode.type === "ObjectProperty" - ) + enclosingNode && + (enclosingNode.type === "Property" || + enclosingNode.type === "ObjectProperty") ) { addLeadingComment(enclosingNode, comment); return true; @@ -648,8 +672,10 @@ function handleOnlyComments(enclosingNode, ast, comment, isLastComment) { } return true; } else if ( - enclosingNode && enclosingNode.type === 'Program' && - enclosingNode.body.length === 0 && enclosingNode.directives && + enclosingNode && + enclosingNode.type === "Program" && + enclosingNode.body.length === 0 && + enclosingNode.directives && enclosingNode.directives.length === 0 ) { if (isLastComment) { @@ -663,9 +689,10 @@ function handleOnlyComments(enclosingNode, ast, comment, isLastComment) { } function handleForComments(enclosingNode, precedingNode, comment) { - if (enclosingNode && ( - enclosingNode.type === "ForInStatement" || - enclosingNode.type === "ForOfStatement") + if ( + enclosingNode && + (enclosingNode.type === "ForInStatement" || + enclosingNode.type === "ForOfStatement") ) { addLeadingComment(enclosingNode, comment); return true; @@ -673,11 +700,17 @@ function handleForComments(enclosingNode, precedingNode, comment) { return false; } -function handleImportDeclarationComments(enclosingNode, precedingNode, comment) { +function handleImportDeclarationComments( + enclosingNode, + precedingNode, + comment +) { if ( precedingNode && - enclosingNode && enclosingNode.type === "ImportDeclaration" && - comment.type !== "CommentBlock" && comment.type !== "Block" + enclosingNode && + enclosingNode.type === "ImportDeclaration" && + comment.type !== "CommentBlock" && + comment.type !== "Block" ) { addTrailingComment(precedingNode, comment); return true; @@ -701,12 +734,16 @@ function handleClassMethodComments(enclosingNode, comment) { return false; } -function handleVariableDeclaratorComments(enclosingNode, followingNode, comment) { +function handleVariableDeclaratorComments( + enclosingNode, + followingNode, + comment +) { if ( enclosingNode && enclosingNode.type === "VariableDeclarator" && - followingNode && ( - followingNode.type === "ObjectExpression" || + followingNode && + (followingNode.type === "ObjectExpression" || followingNode.type === "ArrayExpression") ) { addLeadingComment(followingNode, comment); @@ -825,15 +862,12 @@ function printDanglingComments(path, options, sameIndent) { return ""; } - path.each( - commentPath => { - const comment = commentPath.getValue(); - if (!comment.leading && !comment.trailing) { - parts.push(printComment(commentPath)); - } - }, - "comments" - ); + path.each(commentPath => { + const comment = commentPath.getValue(); + if (!comment.leading && !comment.trailing) { + parts.push(printComment(commentPath)); + } + }, "comments"); if (parts.length === 0) { return ""; @@ -858,29 +892,24 @@ function printComments(path, print, options) { var leadingParts = []; var trailingParts = [printed]; - path.each( - function(commentPath) { - var comment = commentPath.getValue(); - var leading = types.getFieldValue(comment, "leading"); - var trailing = types.getFieldValue(comment, "trailing"); + path.each(function(commentPath) { + var comment = commentPath.getValue(); + var leading = types.getFieldValue(comment, "leading"); + var trailing = types.getFieldValue(comment, "trailing"); - if (leading) { - leadingParts.push(printLeadingComment(commentPath, print, options)); + if (leading) { + leadingParts.push(printLeadingComment(commentPath, print, options)); - const text = options.originalText; - if ( - util.hasNewline(text, util.skipNewline(text, util.locEnd(comment))) - ) { - leadingParts.push(hardline); - } - } else if (trailing) { - trailingParts.push( - printTrailingComment(commentPath, print, options, parent) - ); + const text = options.originalText; + if (util.hasNewline(text, util.skipNewline(text, util.locEnd(comment)))) { + leadingParts.push(hardline); } - }, - "comments" - ); + } else if (trailing) { + trailingParts.push( + printTrailingComment(commentPath, print, options, parent) + ); + } + }, "comments"); return concat(leadingParts.concat(trailingParts)); } diff --git a/src/doc-debug.js b/src/doc-debug.js index 0c6aada3..df3dd279 100644 --- a/src/doc-debug.js +++ b/src/doc-debug.js @@ -75,24 +75,30 @@ function printDoc(doc) { } if (doc.type === "if-break") { - return "ifBreak(" + + return ( + "ifBreak(" + printDoc(doc.breakContents) + (doc.flatContents ? ", " + printDoc(doc.flatContents) : "") + - ")"; + ")" + ); } if (doc.type === "group") { if (doc.expandedStates) { - return "conditionalGroup(" + + return ( + "conditionalGroup(" + "[" + doc.expandedStates.map(printDoc).join(",") + - "])"; + "])" + ); } - return (doc.break ? "wrappedGroup" : "group") + + return ( + (doc.break ? "wrappedGroup" : "group") + "(" + printDoc(doc.contents) + - ")"; + ")" + ); } if (doc.type === "line-suffix") { diff --git a/src/doc-printer.js b/src/doc-printer.js index b058c0bd..5f69e5a9 100644 --- a/src/doc-printer.js +++ b/src/doc-printer.js @@ -177,9 +177,8 @@ function printDocToString(doc, options) { // group has these, we need to manually go through // these states and find the first one that fits. if (doc.expandedStates) { - const mostExpanded = doc.expandedStates[ - doc.expandedStates.length - 1 - ]; + const mostExpanded = + doc.expandedStates[doc.expandedStates.length - 1]; if (doc.break) { cmds.push([ind, MODE_BREAK, mostExpanded]); diff --git a/src/fast-path.js b/src/fast-path.js index 799e5b76..ad009a98 100644 --- a/src/fast-path.js +++ b/src/fast-path.js @@ -235,8 +235,11 @@ FPp.needsParens = function(assumeExpressionContext) { } if ( - parent.type === "ArrowFunctionExpression" && parent.body === node && startsWithNoLookaheadToken(node, /* forbidFunctionAndClass */ false) - || parent.type === "ExpressionStatement" && startsWithNoLookaheadToken(node, /* forbidFunctionAndClass */ true) + (parent.type === "ArrowFunctionExpression" && + parent.body === node && + startsWithNoLookaheadToken(node, /* forbidFunctionAndClass */ false)) || + (parent.type === "ExpressionStatement" && + startsWithNoLookaheadToken(node, /* forbidFunctionAndClass */ true)) ) { return true; } @@ -250,22 +253,28 @@ FPp.needsParens = function(assumeExpressionContext) { case "SpreadElement": case "SpreadProperty": - return parent.type === "MemberExpression" && + return ( + parent.type === "MemberExpression" && name === "object" && - parent.object === node; + parent.object === node + ); case "UpdateExpression": if (parent.type === "UnaryExpression") { - return node.prefix && + return ( + node.prefix && ((node.operator === "++" && parent.operator === "+") || - (node.operator === "--" && parent.operator === "-")); + (node.operator === "--" && parent.operator === "-")) + ); } - // else fall through + // else fall through case "UnaryExpression": switch (parent.type) { case "UnaryExpression": - return node.operator === parent.operator && - (node.operator === "+" || node.operator === "-"); + return ( + node.operator === parent.operator && + (node.operator === "+" || node.operator === "-") + ); case "MemberExpression": return name === "object" && parent.object === node; @@ -302,7 +311,7 @@ FPp.needsParens = function(assumeExpressionContext) { if (node.operator === "in" && isLeftOfAForStatement(node)) { return true; } - // else fall through + // else fall through case "LogicalExpression": switch (parent.type) { case "CallExpression": @@ -377,7 +386,7 @@ FPp.needsParens = function(assumeExpressionContext) { if (parent.type === "UnaryExpression") { return true; } - // else fall through + // else fall through case "AwaitExpression": switch (parent.type) { case "TaggedTemplateExpression": @@ -404,24 +413,30 @@ FPp.needsParens = function(assumeExpressionContext) { case "IntersectionTypeAnnotation": case "UnionTypeAnnotation": - return parent.type === "ArrayTypeAnnotation" || + return ( + parent.type === "ArrayTypeAnnotation" || parent.type === "NullableTypeAnnotation" || parent.type === "IntersectionTypeAnnotation" || - parent.type === "UnionTypeAnnotation"; + parent.type === "UnionTypeAnnotation" + ); case "NullableTypeAnnotation": return parent.type === "ArrayTypeAnnotation"; case "FunctionTypeAnnotation": - return parent.type === "UnionTypeAnnotation" || - parent.type === "IntersectionTypeAnnotation"; + return ( + parent.type === "UnionTypeAnnotation" || + parent.type === "IntersectionTypeAnnotation" + ); case "NumericLiteral": case "Literal": - return parent.type === "MemberExpression" && + return ( + parent.type === "MemberExpression" && isNumber.check(node.value) && name === "object" && - parent.object === node; + parent.object === node + ); case "AssignmentExpression": if (parent.type === "ArrowFunctionExpression" && parent.body === node) { @@ -570,11 +585,20 @@ function startsWithNoLookaheadToken(node, forbidFunctionAndClass) { case "ConditionalExpression": return startsWithNoLookaheadToken(node.test, forbidFunctionAndClass); case "UpdateExpression": - return !node.prefix && startsWithNoLookaheadToken(node.argument, forbidFunctionAndClass); + return ( + !node.prefix && + startsWithNoLookaheadToken(node.argument, forbidFunctionAndClass) + ); case "BindExpression": - return node.object && startsWithNoLookaheadToken(node.object, forbidFunctionAndClass); + return ( + node.object && + startsWithNoLookaheadToken(node.object, forbidFunctionAndClass) + ); case "SequenceExpression": - return startsWithNoLookaheadToken(node.expressions[0], forbidFunctionAndClass) + return startsWithNoLookaheadToken( + node.expressions[0], + forbidFunctionAndClass + ); default: return false; } diff --git a/src/parser.js b/src/parser.js index 8f07d189..c55c4592 100644 --- a/src/parser.js +++ b/src/parser.js @@ -16,12 +16,8 @@ function parseWithFlow(text) { line: ast.errors[0].loc.start.line, column: ast.errors[0].loc.start.column }; - const msg = ast.errors[0].message + - " (" + - loc.line + - ":" + - loc.column + - ")"; + const msg = + ast.errors[0].message + " (" + loc.line + ":" + loc.column + ")"; const error = new SyntaxError(msg); error.loc = loc; throw error; @@ -58,16 +54,16 @@ function parseWithTypeScript(text) { // While we are working on typescript, we are putting it in devDependencies // so it shouldn't be picked up by static analysis const r = require; - const parser = r('typescript-eslint-parser') + const parser = r("typescript-eslint-parser"); return parser.parse(text, { loc: true, range: true, tokens: true, attachComment: true, ecmaFeatures: { - jsx: true, + jsx: true } - }) + }); } module.exports = { parseWithFlow, parseWithBabylon, parseWithTypeScript }; diff --git a/src/printer.js b/src/printer.js index 1f65cf37..3b509184 100644 --- a/src/printer.js +++ b/src/printer.js @@ -80,15 +80,12 @@ function genericPrint(path, options, printPath, args) { ) { const separator = node.decorators.length === 1 && (node.decorators[0].expression.type === "Identifier" || - node.decorators[0].expression.type === "MemberExpression") + node.decorators[0].expression.type === "MemberExpression") ? " " : hardline; - path.each( - function(decoratorPath) { - parts.push(printPath(decoratorPath), separator); - }, - "decorators" - ); + path.each(function(decoratorPath) { + parts.push(printPath(decoratorPath), separator); + }, "decorators"); } else if ( util.isExportDeclaration(node) && node.declaration && @@ -132,9 +129,7 @@ function genericPrint(path, options, printPath, args) { function genericPrintNoParens(path, options, print, args) { var n = path.getValue(); - const semi = options.semi - ? ";" - : ""; + const semi = options.semi ? ";" : ""; if (!n) { return ""; @@ -155,26 +150,20 @@ function genericPrintNoParens(path, options, print, args) { case "Program": // Babel 6 if (n.directives) { - path.each( - function(childPath) { - parts.push(print(childPath), semi, hardline); - if ( - util.isNextLineEmpty(options.originalText, childPath.getValue()) - ) { - parts.push(hardline); - } - }, - "directives" - ); + path.each(function(childPath) { + parts.push(print(childPath), semi, hardline); + if ( + util.isNextLineEmpty(options.originalText, childPath.getValue()) + ) { + parts.push(hardline); + } + }, "directives"); } parts.push( - path.call( - function(bodyPath) { - return printStatementSequence(bodyPath, options, print); - }, - "body" - ) + path.call(function(bodyPath) { + return printStatementSequence(bodyPath, options, print); + }, "body") ); parts.push( @@ -298,7 +287,7 @@ function genericPrintNoParens(path, options, print, args) { ]); case "FunctionDeclaration": case "FunctionExpression": - return printFunctionDeclaration(path, print, options) + return printFunctionDeclaration(path, print, options); case "ArrowFunctionExpression": { if (n.async) parts.push("async "); @@ -355,9 +344,9 @@ function genericPrintNoParens(path, options, print, args) { ifBreak(shouldPrintComma(options, "all") ? "," : ""), softline ]) - : '' + : "" ]) - ), + ) ]) ); } @@ -480,20 +469,17 @@ function genericPrintNoParens(path, options, print, args) { var standalones = []; var grouped = []; if (n.specifiers && n.specifiers.length > 0) { - path.each( - function(specifierPath) { - var value = specifierPath.getValue(); - if ( - namedTypes.ImportDefaultSpecifier.check(value) || - namedTypes.ImportNamespaceSpecifier.check(value) - ) { - standalones.push(print(specifierPath)); - } else { - grouped.push(print(specifierPath)); - } - }, - "specifiers" - ); + path.each(function(specifierPath) { + var value = specifierPath.getValue(); + if ( + namedTypes.ImportDefaultSpecifier.check(value) || + namedTypes.ImportNamespaceSpecifier.check(value) + ) { + standalones.push(print(specifierPath)); + } else { + grouped.push(print(specifierPath)); + } + }, "specifiers"); if (standalones.length > 0) { parts.push(join(", ", standalones)); @@ -537,9 +523,7 @@ function genericPrintNoParens(path, options, print, args) { // In case there are grouped elements, they will already break the way // we want and this break would take precedence instead. if (grouped.length === 0) { - return group( - concat([concat(parts), indent(concat(fromParts))]) - ); + return group(concat([concat(parts), indent(concat(fromParts))])); } return concat([concat(parts), concat(fromParts)]); @@ -548,12 +532,9 @@ function genericPrintNoParens(path, options, print, args) { return "import"; } case "BlockStatement": { - var naked = path.call( - function(bodyPath) { - return printStatementSequence(bodyPath, options, print); - }, - "body" - ); + var naked = path.call(function(bodyPath) { + return printStatementSequence(bodyPath, options, print); + }, "body"); const hasContent = getFirstString(naked); const hasDirectives = n.directives && n.directives.length > 0; @@ -578,16 +559,9 @@ function genericPrintNoParens(path, options, print, args) { // Babel 6 if (hasDirectives) { - path.each( - function(childPath) { - parts.push( - indent( - concat([hardline, print(childPath), semi]) - ) - ); - }, - "directives" - ); + path.each(function(childPath) { + parts.push(indent(concat([hardline, print(childPath), semi]))); + }, "directives"); } if (hasContent) { @@ -607,26 +581,24 @@ function genericPrintNoParens(path, options, print, args) { parts.push( concat([ " (", - indent( - concat([softline, path.call(print, "argument")]) - ), + indent(concat([softline, path.call(print, "argument")])), line, ")" ]) ); } else if ( - n.argument.type === 'LogicalExpression' || - n.argument.type === 'BinaryExpression' + n.argument.type === "LogicalExpression" || + n.argument.type === "BinaryExpression" ) { parts.push( - group(concat([ - ifBreak(" (", " "), - indent( - concat([softline, path.call(print, "argument")]) - ), - softline, - ifBreak(")") - ])) + group( + concat([ + ifBreak(" (", " "), + indent(concat([softline, path.call(print, "argument")])), + softline, + ifBreak(")") + ]) + ) ); } else { parts.push(" ", path.call(print, "argument")); @@ -640,11 +612,7 @@ function genericPrintNoParens(path, options, print, args) { if (hasDanglingComments) { parts.push( " ", - comments.printDanglingComments( - path, - options, - /* sameIndent */ true - ) + comments.printDanglingComments(path, options, /* sameIndent */ true) ); } @@ -705,7 +673,9 @@ function genericPrintNoParens(path, options, print, args) { var rightBrace = n.exact ? "|}" : "}"; var parent = path.getParentNode(0); var parentIsUnionTypeAnnotation = parent.type === "UnionTypeAnnotation"; - var propertiesField = isTypeScriptTypeAnnotaion ? "members" : "properties"; + var propertiesField = isTypeScriptTypeAnnotaion + ? "members" + : "properties"; if (isTypeAnnotation) { fields.push("indexers", "callProperties"); @@ -717,27 +687,25 @@ function genericPrintNoParens(path, options, print, args) { let separatorParts = []; fields.forEach(function(field) { - path.each( - function(childPath) { - props.push(concat(separatorParts)); - props.push(group(print(childPath))); + path.each(function(childPath) { + props.push(concat(separatorParts)); + props.push(group(print(childPath))); - separatorParts = [separator, line]; - if ( - util.isNextLineEmpty(options.originalText, childPath.getValue()) - ) { - separatorParts.push(hardline); - } - }, - field - ); + separatorParts = [separator, line]; + if ( + util.isNextLineEmpty(options.originalText, childPath.getValue()) + ) { + separatorParts.push(hardline); + } + }, field); }); const lastElem = util.getLast(n[propertiesField]); const canHaveTrailingComma = !(lastElem && lastElem.type === "RestProperty"); - const shouldBreak = n.type !== "ObjectPattern" && + const shouldBreak = + n.type !== "ObjectPattern" && util.hasNewlineInRange( options.originalText, util.locStart(n), @@ -844,8 +812,8 @@ function genericPrintNoParens(path, options, print, args) { // // Note that util.getLast returns null if the array is empty, but // we already check for an empty array just above so we are safe - const needsForcedTrailingComma = canHaveTrailingComma && - lastElem === null; + const needsForcedTrailingComma = + canHaveTrailingComma && lastElem === null; parts.push( group( @@ -948,7 +916,7 @@ function genericPrintNoParens(path, options, print, args) { parts.push("new ", path.call(print, "callee")); if (n.typeParameters) { - parts.push(path.call(print, "typeParameters")) + parts.push(path.call(print, "typeParameters")); } var args = n.arguments; @@ -959,27 +927,23 @@ function genericPrintNoParens(path, options, print, args) { return concat(parts); case "VariableDeclaration": - var printed = path.map( - function(childPath) { - return print(childPath); - }, - "declarations" - ); + var printed = path.map(function(childPath) { + return print(childPath); + }, "declarations"); parts = [ n.kind, " ", printed[0], - indent( - concat(printed.slice(1).map(p => concat([",", line, p]))) - ) + indent(concat(printed.slice(1).map(p => concat([",", line, p])))) ]; // We generally want to terminate all variable declarations with a // semicolon, except when they in the () part of for loops. var parentNode = path.getParentNode(); - var isParentForLoop = namedTypes.ForStatement.check(parentNode) || + var isParentForLoop = + namedTypes.ForStatement.check(parentNode) || namedTypes.ForInStatement.check(parentNode) || (namedTypes.ForOfStatement && namedTypes.ForOfStatement.check(parentNode)) || @@ -1008,17 +972,19 @@ function genericPrintNoParens(path, options, print, args) { ]); case "IfStatement": const con = adjustClause(path.call(print, "consequent"), options); - const opening = group(concat([ - "if (", - group(concat([ - indent( - concat([softline, path.call(print, "test")]) + const opening = group( + concat([ + "if (", + group( + concat([ + indent(concat([softline, path.call(print, "test")])), + softline + ]) ), - softline - ])), - ")", - con - ])); + ")", + con + ]) + ); parts.push(opening); @@ -1033,11 +999,13 @@ function genericPrintNoParens(path, options, print, args) { } parts.push( - group(adjustClause( - path.call(print, "alternate"), - options, - n.alternate.type === "IfStatement" - )) + group( + adjustClause( + path.call(print, "alternate"), + options, + n.alternate.type === "IfStatement" + ) + ) ); } @@ -1088,9 +1056,7 @@ function genericPrintNoParens(path, options, print, args) { "while (", group( concat([ - indent( - concat([softline, path.call(print, "test")]) - ), + indent(concat([softline, path.call(print, "test")])), softline ]) ), @@ -1113,7 +1079,7 @@ function genericPrintNoParens(path, options, print, args) { // Babylon 7 removed ForAwaitStatement in favor of ForOfStatement // with `"await": true`: // https://github.com/estree/estree/pull/138 - const isAwait = (n.type === "ForAwaitStatement" || n.await); + const isAwait = n.type === "ForAwaitStatement" || n.await; return concat([ "for", @@ -1172,12 +1138,9 @@ function genericPrintNoParens(path, options, print, args) { if (n.handler) { parts.push(" ", path.call(print, "handler")); } else if (n.handlers) { - path.each( - function(handlerPath) { - parts.push(" ", print(handlerPath)); - }, - "handlers" - ); + path.each(function(handlerPath) { + parts.push(" ", print(handlerPath)); + }, "handlers"); } if (n.finalizer) { @@ -1204,9 +1167,7 @@ function genericPrintNoParens(path, options, print, args) { path.call(print, "discriminant"), ") {", n.cases.length > 0 - ? indent( - concat([hardline, join(hardline, path.map(print, "cases"))]) - ) + ? indent(concat([hardline, join(hardline, path.map(print, "cases"))])) : "", hardline, "}" @@ -1217,17 +1178,24 @@ function genericPrintNoParens(path, options, print, args) { const isFirstCase = path.getNode() === path.getParentNode().cases[0]; - if (!isFirstCase && util.isPreviousLineEmpty(options.originalText, path.getValue())) { + if ( + !isFirstCase && + util.isPreviousLineEmpty(options.originalText, path.getValue()) + ) { parts.unshift(hardline); } if (n.consequent.find(node => node.type !== "EmptyStatement")) { const cons = path.call(consequentPath => { - return join(hardline, consequentPath.map((p, i) => { - const shouldAddLine = i !== n.consequent.length - 1 && - util.isNextLineEmpty(options.originalText, p.getValue()); - return concat([print(p), shouldAddLine ? hardline : ""]); - })); + return join( + hardline, + consequentPath.map((p, i) => { + const shouldAddLine = + i !== n.consequent.length - 1 && + util.isNextLineEmpty(options.originalText, p.getValue()); + return concat([print(p), shouldAddLine ? hardline : ""]); + }) + ); }, "consequent"); parts.push( isCurlyBracket(cons) @@ -1250,7 +1218,8 @@ function genericPrintNoParens(path, options, print, args) { typeof n.value.value === "string" ) { const value = n.value.extra ? n.value.extra.raw : n.value.raw; - res = '"' + + res = + '"' + value.slice(1, value.length - 1).replace(/"/g, """) + '"'; } else { @@ -1277,7 +1246,8 @@ function genericPrintNoParens(path, options, print, args) { case "JSXExpressionContainer": { const parent = path.getParentNode(0); - const shouldInline = n.expression.type === "ArrayExpression" || + const shouldInline = + n.expression.type === "ArrayExpression" || n.expression.type === "ObjectExpression" || n.expression.type === "ArrowFunctionExpression" || n.expression.type === "CallExpression" || @@ -1298,9 +1268,7 @@ function genericPrintNoParens(path, options, print, args) { return group( concat([ "{", - indent( - concat([softline, path.call(print, "expression")]) - ), + indent(concat([softline, path.call(print, "expression")])), softline, lineSuffixBoundary, "}" @@ -1382,12 +1350,9 @@ function genericPrintNoParens(path, options, print, args) { ? indent( concat([ hardline, - path.call( - function(bodyPath) { - return printStatementSequence(bodyPath, options, print); - }, - "body" - ) + path.call(function(bodyPath) { + return printStatementSequence(bodyPath, options, print); + }, "body") ]) ) : comments.printDanglingComments(path, options), @@ -1457,23 +1422,20 @@ function genericPrintNoParens(path, options, print, args) { parts.push("`"); - path.each( - function(childPath) { - var i = childPath.getName(); + path.each(function(childPath) { + var i = childPath.getName(); - parts.push(print(childPath)); + parts.push(print(childPath)); - if (i < expressions.length) { - parts.push( - "${", - removeLines(expressions[i]), - lineSuffixBoundary, - "}" - ); - } - }, - "quasis" - ); + if (i < expressions.length) { + parts.push( + "${", + removeLines(expressions[i]), + lineSuffixBoundary, + "}" + ); + } + }, "quasis"); parts.push("`"); @@ -1499,7 +1461,6 @@ function genericPrintNoParens(path, options, print, args) { case "MemberTypeAnnotation": // Flow case "Type": throw new Error("unprintable type: " + JSON.stringify(n.type)); - // Type Annotations for Facebook Flow, typically stripped out or // transformed away before printing. case "TypeAnnotation": @@ -1522,7 +1483,7 @@ function genericPrintNoParens(path, options, print, args) { return ""; case "TSTupleType": case "TupleTypeAnnotation": - let typesField = n.type === "TSTupleType" ? "elementTypes" : "types" + let typesField = n.type === "TSTupleType" ? "elementTypes" : "types"; return group( concat([ "[", @@ -1533,11 +1494,7 @@ function genericPrintNoParens(path, options, print, args) { ]) ), ifBreak(shouldPrintComma(options) ? "," : ""), - comments.printDanglingComments( - path, - options, - /* sameIndent */ true - ), + comments.printDanglingComments(path, options, /* sameIndent */ true), softline, "]" ]) @@ -1565,8 +1522,8 @@ function genericPrintNoParens(path, options, print, args) { if (n.params) { return concat([ "declare ", - printFunctionDeclaration(path, print, options), - ]) + printFunctionDeclaration(path, print, options) + ]); } return printFlowDeclaration(path, [ "function ", @@ -1601,19 +1558,23 @@ function genericPrintNoParens(path, options, print, args) { // var A: (a: B) => void; var parent = path.getParentNode(0); var parentParent = path.getParentNode(1); - var isArrowFunctionTypeAnnotation = n.type === "TSFunctionType" || !((!getFlowVariance(parent, options) && - !parent.optional && - namedTypes.ObjectTypeProperty.check(parent)) || - namedTypes.ObjectTypeCallProperty.check(parent) || - namedTypes.DeclareFunction.check(path.getParentNode(2))); + var isArrowFunctionTypeAnnotation = + n.type === "TSFunctionType" || + !((!getFlowVariance(parent, options) && + !parent.optional && + namedTypes.ObjectTypeProperty.check(parent)) || + namedTypes.ObjectTypeCallProperty.check(parent) || + namedTypes.DeclareFunction.check(path.getParentNode(2))); - var needsColon = isArrowFunctionTypeAnnotation && + var needsColon = + isArrowFunctionTypeAnnotation && namedTypes.TypeAnnotation.check(parent); // Sadly we can't put it inside of FastPath::needsColon because we are // printing ":" as part of the expression and it would put parenthesis // around :( - const needsParens = needsColon && + const needsParens = + needsColon && isArrowFunctionTypeAnnotation && parent.type === "TypeAnnotation" && parentParent.type === "ArrowFunctionExpression"; @@ -1680,11 +1641,7 @@ function genericPrintNoParens(path, options, print, args) { parts.push( group( indent( - concat([ - line, - "extends ", - join(", ", path.map(print, "extends")), - ]) + concat([line, "extends ", join(", ", path.map(print, "extends"))]) ) ) ); @@ -1741,9 +1698,7 @@ function genericPrintNoParens(path, options, print, args) { join(concat([line, "| "]), path.map(print, "types")) ]); - return group( - shouldIndent ? indent(code) : code - ); + return group(shouldIndent ? indent(code) : code); } case "NullableTypeAnnotation": return concat(["?", path.call(print, "typeAnnotation")]); @@ -1776,9 +1731,8 @@ function genericPrintNoParens(path, options, print, args) { var variance = getFlowVariance(n, options); // TODO: This is a bad hack and we need a better way to know // when to emit an arrow function or not. - var isFunction = !variance && - !n.optional && - n.value.type === "FunctionTypeAnnotation"; + var isFunction = + !variance && !n.optional && n.value.type === "FunctionTypeAnnotation"; if (isObjectTypePropertyAFunction(n)) { isFunction = true; @@ -1825,9 +1779,7 @@ function genericPrintNoParens(path, options, print, args) { path.call(print, "typeParameters"), " =", hasLeadingOwnLineComment(options.originalText, n.right) - ? indent( - concat([hardline, path.call(print, "right")]) - ) + ? indent(concat([hardline, path.call(print, "right")])) : concat([" ", path.call(print, "right")]), semi ); @@ -1844,24 +1796,25 @@ function genericPrintNoParens(path, options, print, args) { case "TypeParameterDeclaration": case "TypeParameterInstantiation": { const shouldInline = - n.params.length === 1 && - n.params[0].type === "ObjectTypeAnnotation"; + n.params.length === 1 && n.params[0].type === "ObjectTypeAnnotation"; if (shouldInline) { return concat(["<", join(", ", path.map(print, "params")), ">"]); } - return group(concat([ - "<", - indent( - concat([ - softline, - join(concat([",", line]), path.map(print, "params")), - ]) - ), - softline, - ">" - ])); + return group( + concat([ + "<", + indent( + concat([ + softline, + join(concat([",", line]), path.map(print, "params")) + ]) + ), + softline, + ">" + ]) + ); } case "TypeParameter": var variance = getFlowVariance(n, options); @@ -1914,8 +1867,8 @@ function genericPrintNoParens(path, options, print, args) { return concat([ path.call(print, "expression"), " as ", - path.call(print, "typeAnnotation"), - ]) + path.call(print, "typeAnnotation") + ]); case "TSArrayType": return concat([path.call(print, "elementType"), "[]"]); case "TSPropertySignature": @@ -1930,14 +1883,14 @@ function genericPrintNoParens(path, options, print, args) { "(", join(", ", path.map(print, "parameters")), "): ", - path.call(print, "typeAnnotation"), + path.call(print, "typeAnnotation") ]); case "TSConstructSignature": return concat([ "new (", join(", ", path.map(print, "parameters")), "): ", - path.call(print, "typeAnnotation"), + path.call(print, "typeAnnotation") ]); case "TSTypeQuery": return concat(["typeof ", path.call(print, "exprName")]); @@ -1950,7 +1903,7 @@ function genericPrintNoParens(path, options, print, args) { // it using parseDelimitedList that uses commas as delimiter. join(", ", path.map(print, "parameters")), "]: ", - path.call(print, "typeAnnotation"), + path.call(print, "typeAnnotation") ]); // TODO case "ClassHeritage": @@ -2107,12 +2060,9 @@ function printMethod(path, options, print) { path.call(print, "value", "typeParameters"), group( concat([ - path.call( - function(valuePath) { - return printFunctionParams(valuePath, print, options); - }, - "value" - ), + path.call(function(valuePath) { + return printFunctionParams(valuePath, print, options); + }, "value"), path.call(p => printReturnType(p, print), "value") ]) ), @@ -2124,26 +2074,30 @@ function printMethod(path, options, print) { } function couldGroupArg(arg) { - return ((arg.type === "ObjectExpression" && arg.properties.length > 0) || - (arg.type === "ArrayExpression" && arg.elements.length > 0) || - arg.type === "FunctionExpression" || - (arg.type === "ArrowFunctionExpression" && - (arg.body.type === "BlockStatement" || - arg.body.type === "ArrowFunctionExpression" || - arg.body.type === "ObjectExpression" || - arg.body.type === "ArrayExpression" || - arg.body.type === "CallExpression" || - arg.body.type === "JSXElement"))); + return ( + (arg.type === "ObjectExpression" && arg.properties.length > 0) || + (arg.type === "ArrayExpression" && arg.elements.length > 0) || + arg.type === "FunctionExpression" || + (arg.type === "ArrowFunctionExpression" && + (arg.body.type === "BlockStatement" || + arg.body.type === "ArrowFunctionExpression" || + arg.body.type === "ObjectExpression" || + arg.body.type === "ArrayExpression" || + arg.body.type === "CallExpression" || + arg.body.type === "JSXElement")) + ); } function shouldGroupLastArg(args) { const lastArg = util.getLast(args); const penultimateArg = util.getPenultimate(args); - return (!lastArg.comments || !lastArg.comments.length) && + return ( + (!lastArg.comments || !lastArg.comments.length) && couldGroupArg(lastArg) && // If the last two arguments are of the same type, // disable last element expansion. - (!penultimateArg || penultimateArg.type !== lastArg.type); + (!penultimateArg || penultimateArg.type !== lastArg.type) + ); } function shouldGroupFirstArg(args) { @@ -2153,11 +2107,13 @@ function shouldGroupFirstArg(args) { const firstArg = args[0]; const secondArg = args[1]; - return (!firstArg.comments || !firstArg.comments.length) && - (firstArg.type === 'FunctionExpression' || - (firstArg.type === 'ArrowFunctionExpression' && - firstArg.body.type === 'BlockStatement')) && - !couldGroupArg(secondArg); + return ( + (!firstArg.comments || !firstArg.comments.length) && + (firstArg.type === "FunctionExpression" || + (firstArg.type === "ArrowFunctionExpression" && + firstArg.body.type === "BlockStatement")) && + !couldGroupArg(secondArg) + ); } function printArgumentsList(path, options, print) { @@ -2191,9 +2147,7 @@ function printArgumentsList(path, options, print) { if (i++ === args.length - 1) { printedLastArgExpanded = printed .slice(0, -1) - .concat(argPath.call( - p => print(p, { expandLastArg: true }) - )); + .concat(argPath.call(p => print(p, { expandLastArg: true }))); } }, "arguments"); } @@ -2215,18 +2169,15 @@ function printArgumentsList(path, options, print) { "(", join(concat([",", line]), printed.slice(0, -1)), printed.length > 1 ? ", " : "", - group( - util.getLast(printedLastArgExpanded), - { shouldBreak: true } - ), + group(util.getLast(printedLastArgExpanded), { + shouldBreak: true + }), ")" ]), group( concat([ "(", - indent( - concat([line, join(concat([",", line]), printed)]) - ), + indent(concat([line, join(concat([",", line]), printed)])), shouldPrintComma(options, "all") ? "," : "", line, ")" @@ -2242,9 +2193,7 @@ function printArgumentsList(path, options, print) { return group( concat([ "(", - indent( - concat([softline, join(concat([",", line]), printed)]) - ), + indent(concat([softline, join(concat([",", line]), printed)])), ifBreak(shouldPrintComma(options, "all") ? "," : ""), softline, ")" @@ -2260,17 +2209,14 @@ function printFunctionParams(path, print, options) { var printed = path.map(print, paramsField); if (fun.defaults) { - path.each( - function(defExprPath) { - var i = defExprPath.getName(); - var p = printed[i]; + path.each(function(defExprPath) { + var i = defExprPath.getName(); + var p = printed[i]; - if (p && defExprPath.getValue()) { - printed[i] = concat([p, " = ", print(defExprPath)]); - } - }, - "defaults" - ); + if (p && defExprPath.getValue()) { + printed[i] = concat([p, " = ", print(defExprPath)]); + } + }, "defaults"); } if (fun.rest) { @@ -2286,8 +2232,8 @@ function printFunctionParams(path, print, options) { } const lastParam = util.getLast(fun[paramsField]); - const canHaveTrailingComma = !(lastParam && - lastParam.type === "RestElement") && !fun.rest; + const canHaveTrailingComma = + !(lastParam && lastParam.type === "RestElement") && !fun.rest; // If the parent is a call with the first/last argument expansion and this is the // params of the first/last argument, we dont want the arguments to break and instead @@ -2317,25 +2263,29 @@ function printFunctionParams(path, print, options) { // b, // c // }) {} - if (fun.params && + if ( + fun.params && fun.params.length === 1 && !fun.params[0].comments && (fun.params[0].type === "ObjectPattern" || - fun.params[0].type === "FunctionTypeParam" && - fun.params[0].typeAnnotation.type === "ObjectTypeAnnotation") && - !fun.rest) { + (fun.params[0].type === "FunctionTypeParam" && + fun.params[0].typeAnnotation.type === "ObjectTypeAnnotation")) && + !fun.rest + ) { return concat(["(", join(", ", printed), ")"]); } - const isFlowShorthandWithOneArg = (isObjectTypePropertyAFunction(parent) || - isTypeAnnotationAFunction(parent) || parent.type === "TypeAlias") && - fun[paramsField].length === 1 && fun[paramsField][0].name === null && !fun.rest; + const isFlowShorthandWithOneArg = + (isObjectTypePropertyAFunction(parent) || + isTypeAnnotationAFunction(parent) || + parent.type === "TypeAlias") && + fun[paramsField].length === 1 && + fun[paramsField][0].name === null && + !fun.rest; return concat([ isFlowShorthandWithOneArg ? "" : "(", - indent( - concat([softline, join(concat([",", line]), printed)]) - ), + indent(concat([softline, join(concat([",", line]), printed)])), ifBreak( canHaveTrailingComma && shouldPrintComma(options, "all") ? "," : "" ), @@ -2441,9 +2391,11 @@ function printReturnType(path, print) { } function typeIsFunction(type) { - return type === "FunctionExpression" || + return ( + type === "FunctionExpression" || type === "ArrowFunctionExpression" || - type === "NewExpression"; + type === "NewExpression" + ); } function printExportDeclaration(path, options, print) { @@ -2467,7 +2419,7 @@ function printExportDeclaration(path, options, print) { if ( decl.type === "ExportDefaultDeclaration" && (decl.declaration.type !== "ClassDeclaration" && - decl.declaration.type !== "FunctionDeclaration") + decl.declaration.type !== "FunctionDeclaration") ) { parts.push(semi); } @@ -2494,10 +2446,11 @@ function printExportDeclaration(path, options, print) { } }, "specifiers"); - const isNamespaceFollowed = namespaceSpecifiers.length !== 0 && + const isNamespaceFollowed = + namespaceSpecifiers.length !== 0 && (specifiers.length !== 0 || defaultSpecifiers.length !== 0); - const isDefaultFollowed = defaultSpecifiers.length !== 0 && - specifiers.length !== 0; + const isDefaultFollowed = + defaultSpecifiers.length !== 0 && specifiers.length !== 0; parts.push( decl.exportKind === "type" ? "type " : "", @@ -2507,20 +2460,20 @@ function printExportDeclaration(path, options, print) { concat([isDefaultFollowed ? ", " : ""]), specifiers.length !== 0 ? group( - concat([ - "{", - indent( - concat([ - options.bracketSpacing ? line : softline, - join(concat([",", line]), specifiers) - ]) - ), - ifBreak(shouldPrintComma(options) ? "," : ""), - options.bracketSpacing ? line : softline, - "}" - ]) - ) - : "" + concat([ + "{", + indent( + concat([ + options.bracketSpacing ? line : softline, + join(concat([",", line]), specifiers) + ]) + ), + ifBreak(shouldPrintComma(options) ? "," : ""), + options.bracketSpacing ? line : softline, + "}" + ]) + ) + : "" ); } } else { @@ -2619,12 +2572,7 @@ function printMemberLookup(path, options, print) { n.computed ? [ "[", - group( - concat([ - indent(concat([softline, property])), - softline - ]) - ), + group(concat([indent(concat([softline, property])), softline])), "]" ] : [".", property] @@ -2777,7 +2725,8 @@ function printMemberChain(path, options, print) { // node is just an identifier with the name starting with a capital // letter, just a sequence of _$ or this. The rationale is that they are // likely to be factories. - const shouldMerge = groups[0].length === 1 && + const shouldMerge = + groups[0].length === 1 && (groups[0][0].node.type === "ThisExpression" || (groups[0][0].node.type === "Identifier" && groups[0][0].node.name.match(/(^[A-Z])|^[_$]+$/))) && @@ -2833,7 +2782,7 @@ function printMemberChain(path, options, print) { // naturally willBreak(oneLine) ? breakParent : "", conditionalGroup([oneLine, expanded]) - ]) + ]); } function isEmptyJSXElement(node) { @@ -2864,82 +2813,79 @@ function printJSXChildren(path, options, print, jsxWhitespace) { const children = []; // using `map` instead of `each` because it provides `i` - path.map( - function(childPath, i) { - const child = childPath.getValue(); - const isLiteral = namedTypes.Literal.check(child); + path.map(function(childPath, i) { + const child = childPath.getValue(); + const isLiteral = namedTypes.Literal.check(child); - if (isLiteral && typeof child.value === "string") { - // There's a bug in the flow parser where it doesn't unescape the - // value field. To workaround this, we can use rawValue which is - // correctly escaped (since it parsed). - // We really want to use value and re-escape it ourself when possible - // though. - const partiallyEscapedValue = options.parser === "flow" - ? child.raw - : util.htmlEscapeInsideAngleBracket(child.value); - const value = partiallyEscapedValue.replace(/\u00a0/g, " "); + if (isLiteral && typeof child.value === "string") { + // There's a bug in the flow parser where it doesn't unescape the + // value field. To workaround this, we can use rawValue which is + // correctly escaped (since it parsed). + // We really want to use value and re-escape it ourself when possible + // though. + const partiallyEscapedValue = options.parser === "flow" + ? child.raw + : util.htmlEscapeInsideAngleBracket(child.value); + const value = partiallyEscapedValue.replace(/\u00a0/g, " "); - if (/\S/.test(value)) { - // treat each line of text as its own entity - value.split(/(\r?\n\s*)/).forEach(line => { - const newlines = line.match(/\n/g); - if (newlines) { + if (/\S/.test(value)) { + // treat each line of text as its own entity + value.split(/(\r?\n\s*)/).forEach(line => { + const newlines = line.match(/\n/g); + if (newlines) { + children.push(hardline); + + // allow one extra newline + if (newlines.length > 1) { children.push(hardline); - - // allow one extra newline - if (newlines.length > 1) { - children.push(hardline); - } - return; } + return; + } - const beginSpace = /^\s+/.test(line); - if (beginSpace) { - children.push(jsxWhitespace); - children.push(softline); - } - - const stripped = line.replace(/^\s+|\s+$/g, ""); - if (stripped) { - children.push(stripped); - } - - const endSpace = /\s+$/.test(line); - if (endSpace) { - children.push(softline); - children.push(jsxWhitespace); - } - }); - - if (!isLineNext(util.getLast(children))) { + const beginSpace = /^\s+/.test(line); + if (beginSpace) { + children.push(jsxWhitespace); children.push(softline); } - } else if (/\n/.test(value)) { - children.push(hardline); - // allow one extra newline - if (value.match(/\n/g).length > 1) { - children.push(hardline); + const stripped = line.replace(/^\s+|\s+$/g, ""); + if (stripped) { + children.push(stripped); } - } else if (/\s/.test(value)) { - // whitespace-only without newlines, - // eg; a single space separating two elements - children.push(jsxWhitespace); - children.push(softline); - } - } else { - children.push(print(childPath)); - // add a line unless it's followed by a JSX newline - let next = n.children[i + 1]; - if (!(next && /^\s*\n/.test(next.value))) { + const endSpace = /\s+$/.test(line); + if (endSpace) { + children.push(softline); + children.push(jsxWhitespace); + } + }); + + if (!isLineNext(util.getLast(children))) { children.push(softline); } + } else if (/\n/.test(value)) { + children.push(hardline); + + // allow one extra newline + if (value.match(/\n/g).length > 1) { + children.push(hardline); + } + } else if (/\s/.test(value)) { + // whitespace-only without newlines, + // eg; a single space separating two elements + children.push(jsxWhitespace); + children.push(softline); } - }, - "children" - ); + } else { + children.push(print(childPath)); + + // add a line unless it's followed by a JSX newline + let next = n.children[i + 1]; + if (!(next && /^\s*\n/.test(next.value))) { + children.push(softline); + } + } + }, "children"); return children; } @@ -3064,9 +3010,9 @@ function printJSXElement(path, options, print) { concat( groups.map( contents => - Array.isArray(contents) + (Array.isArray(contents) ? conditionalGroup([concat(contents)]) - : contents + : contents) ) ) ]; @@ -3074,9 +3020,7 @@ function printJSXElement(path, options, print) { const multiLineElem = group( concat([ openingLines, - indent( - group(concat(childrenGroupedByLine), { shouldBreak: true }) - ), + indent(group(concat(childrenGroupedByLine), { shouldBreak: true })), hardline, closingLines ]) @@ -3124,9 +3068,11 @@ function isBinaryish(node) { } function shouldInlineLogicalExpression(node) { - return node.type === "LogicalExpression" && + return ( + node.type === "LogicalExpression" && (node.right.type === "ObjectExpression" || - node.right.type === "ArrayExpression"); + node.right.type === "ArrayExpression") + ); } // For binary expressions to be consistent, we need to group @@ -3154,20 +3100,21 @@ function printBinaryishExpressions(path, print, options, isNested) { // which is unique in that it is right-associative.) if ( util.getPrecedence(node.left.operator) === - util.getPrecedence(node.operator) - && node.operator !== "**" + util.getPrecedence(node.operator) && node.operator !== "**" ) { // Flatten them out by recursively calling this function. - parts = parts.concat(path.call( - left => - printBinaryishExpressions( - left, - print, - options, - /* isNested */ true - ), - "left" - )); + parts = parts.concat( + path.call( + left => + printBinaryishExpressions( + left, + print, + options, + /* isNested */ true + ), + "left" + ) + ); } else { parts.push(path.call(print, "left")); } @@ -3181,7 +3128,8 @@ function printBinaryishExpressions(path, print, options, isNested) { // 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 = parent.type !== node.type && + const shouldGroup = + parent.type !== node.type && node.left.type !== node.type && node.right.type !== node.type; @@ -3201,36 +3149,32 @@ function printBinaryishExpressions(path, print, options, isNested) { return parts; } -function printAssignment(printedLeft, operator, rightNode, printedRight, options) { +function printAssignment( + printedLeft, + operator, + rightNode, + printedRight, + options +) { if (!rightNode) { return printedLeft; } let printed; if (hasLeadingOwnLineComment(options.originalText, rightNode)) { - printed = indent( - concat([hardline, printedRight]) - ); + printed = indent(concat([hardline, printedRight])); } else if ( (isBinaryish(rightNode) && !shouldInlineLogicalExpression(rightNode)) || rightNode.type === "StringLiteral" || - (rightNode.type === "Literal" && - typeof rightNode.value === "string") || + (rightNode.type === "Literal" && typeof rightNode.value === "string") || isMemberExpressionChain(rightNode) ) { - printed = indent( - concat([line, printedRight]) - ); + printed = indent(concat([line, printedRight])); } else { printed = concat([" ", printedRight]); } - return group(concat([ - printedLeft, - " ", - operator, - printed, - ])); + return group(concat([printedLeft, " ", operator, printed])); } function adjustClause(clause, options, forceSpace) { @@ -3255,11 +3199,10 @@ function isEmptyBlock(doc) { return str === "{}"; } - function shouldTypeScriptTypeAvoidColon(path) { // As the special TS nodes isn't returned by the node helpers, // we use the stack directly to get the parent node. - const parent = path.stack[path.stack.length - 3] + const parent = path.stack[path.stack.length - 3]; switch (parent.type) { case "TSFunctionType": @@ -3268,10 +3211,9 @@ function shouldTypeScriptTypeAvoidColon(path) { case "TSCallSignature": case "TSConstructSignature": case "TSAsExpression": - return true + return true; default: - return false - + return false; } } @@ -3351,16 +3293,18 @@ function makeString(rawContent, enclosingQuote) { } function printNumber(rawNumber) { - return rawNumber - .toLowerCase() - // Remove unnecessary plus and zeroes from scientific notation. - .replace(/^([\d.]+e)(?:\+|(-))?0*(\d)/, "$1$2$3") - // Remove unnecessary scientific notation (1e0). - .replace(/^([\d.]+)e[+-]?0+$/, "$1") - // Make sure numbers always start with a digit. - .replace(/^\./, "0.") - // Remove trailing dot. - .replace(/\.(?=e|$)/, ""); + return ( + rawNumber + .toLowerCase() + // Remove unnecessary plus and zeroes from scientific notation. + .replace(/^([\d.]+e)(?:\+|(-))?0*(\d)/, "$1$2$3") + // Remove unnecessary scientific notation (1e0). + .replace(/^([\d.]+)e[+-]?0+$/, "$1") + // Make sure numbers always start with a digit. + .replace(/^\./, "0.") + // Remove trailing dot. + .replace(/\.(?=e|$)/, "") + ); } function isFirstStatement(path) { @@ -3378,11 +3322,10 @@ function isLastStatement(path) { } function hasLeadingOwnLineComment(text, node) { - const res = node.comments && + const res = + node.comments && node.comments.some( - comment => - comment.leading && - util.hasNewline(text, util.locEnd(comment)) + comment => comment.leading && util.hasNewline(text, util.locEnd(comment)) ); return res; } @@ -3410,7 +3353,8 @@ function getLeftSide(node) { function exprNeedsASIProtection(node) { // HACK: node.needsParens is added in `genericPrint()` for the sole purpose // of being used here. It'd be preferable to find a cleaner way to do this. - const maybeASIProblem = node.needsParens || + const maybeASIProblem = + node.needsParens || node.type === "ParenthesizedExpression" || node.type === "TypeCastExpression" || (node.type === "ArrowFunctionExpression" && @@ -3475,18 +3419,15 @@ function classChildNeedsASIProtection(node) { switch (node.type) { case "ClassProperty": return node.computed; - // flow case "MethodDefinition": // babylon case "ClassMethod": { - const isAsync = node.value - ? node.value.async - : node.async; - const isGenerator = node.value - ? node.value.generator - : node.generator; - if (isAsync || node.static || node.kind === "get" || node.kind === "set") { + const isAsync = node.value ? node.value.async : node.async; + const isGenerator = node.value ? node.value.generator : node.generator; + if ( + isAsync || node.static || node.kind === "get" || node.kind === "set" + ) { return false; } if (node.computed || isGenerator) { @@ -3510,7 +3451,7 @@ function returnArgumentHasLeadingComment(options, argument) { if (hasNakedLeftSide(argument)) { let leftMost = argument; let newLeftMost; - while (newLeftMost = getLeftSide(leftMost)) { + while ((newLeftMost = getLeftSide(leftMost))) { leftMost = newLeftMost; if (hasLeadingOwnLineComment(options.originalText, leftMost)) { @@ -3536,20 +3477,24 @@ function isMemberExpressionChain(node) { // type T = { method: () => void }; // type T = { method(): void }; function isObjectTypePropertyAFunction(node) { - return node.type === "ObjectTypeProperty" && + return ( + node.type === "ObjectTypeProperty" && node.value.type === "FunctionTypeAnnotation" && !node.static && - util.locStart(node.key) !== util.locStart(node.value); + util.locStart(node.key) !== util.locStart(node.value) + ); } // Hack to differentiate between the following two which have the same ast // declare function f(a): void; // var f: (a) => void; function isTypeAnnotationAFunction(node) { - return node.type === "TypeAnnotation" && + return ( + node.type === "TypeAnnotation" && node.typeAnnotation.type === "FunctionTypeAnnotation" && !node.static && util.locStart(node) !== util.locStart(node.typeAnnotation) + ); } function isFlowNodeStartingWithDeclare(node, options) { @@ -3566,26 +3511,22 @@ function printArrayItems(path, options, printPath, print) { const printedElements = []; let separatorParts = []; - path.each( - function(childPath) { - printedElements.push(concat(separatorParts)); - printedElements.push(group(print(childPath))); + path.each(function(childPath) { + printedElements.push(concat(separatorParts)); + printedElements.push(group(print(childPath))); - separatorParts = [",", line]; - if ( - childPath.getValue() && - util.isNextLineEmpty(options.originalText, childPath.getValue()) - ) { - separatorParts.push(softline); - } - }, - printPath - ); + separatorParts = [",", line]; + if ( + childPath.getValue() && + util.isNextLineEmpty(options.originalText, childPath.getValue()) + ) { + separatorParts.push(softline); + } + }, printPath); return concat(printedElements); } - function printAstToDoc(ast, options) { function printGenerically(path, args) { return comments.printComments( diff --git a/src/util.js b/src/util.js index ec173f41..7bca29f8 100644 --- a/src/util.js +++ b/src/util.js @@ -170,7 +170,12 @@ function skipNewline(text, index, opts) { const atIndex = text.charAt(index); if (backwards) { - if (atIndex === "\n" || atIndex === "\r" || atIndex === "\u2028" || atIndex === "\u2029") { + if ( + atIndex === "\n" || + atIndex === "\r" || + atIndex === "\u2028" || + atIndex === "\u2029" + ) { return index - 1; } if (text.charAt(index - 1) === "\r" && atIndex === "\n") { @@ -180,7 +185,12 @@ function skipNewline(text, index, opts) { if (atIndex === "\r" && text.charAt(index + 1) === "\n") { return index + 2; } - if (atIndex === "\n" || atIndex === "\r" || atIndex === "\u2028" || atIndex === "\u2029") { + if ( + atIndex === "\n" || + atIndex === "\r" || + atIndex === "\u2028" || + atIndex === "\u2029" + ) { return index + 1; } }