Reprint all the files!

master
James Long 2017-01-13 15:03:53 -05:00
parent 6be89286bb
commit 3af7da5748
8 changed files with 1735 additions and 1688 deletions

View File

@ -1,16 +1,20 @@
#!/usr/bin/env node
"use strict";
const fs = require("fs");
const getStdin = require("get-stdin");
const minimist = require("minimist");
const jscodefmt = require("../index");
const argv = minimist(process.argv.slice(2), {
boolean: ["write", "stdin", "flow-parser", "bracket-spacing", "single-quote", "trailing-comma"],
default: {
"bracket-spacing": true
}
boolean: [
"write",
"stdin",
"flow-parser",
"bracket-spacing",
"single-quote",
"trailing-comma"
],
default: { "bracket-spacing": true }
});
const filenames = argv["_"];
@ -19,16 +23,15 @@ const stdin = argv["stdin"];
if (!filenames.length && !stdin) {
console.log(
"Usage: prettier [opts] [filename ...]\n\n" +
"Available options:\n" +
" --write Edit the file in-place (beware!)\n" +
" --stdin Read input from stdin\n" +
" --print-width <int> Specify the length of line that the printer will wrap on. Defaults to 80.\n" +
" --tab-width <int> Specify the number of spaces per indentation-level. Defaults to 2.\n" +
" --flow-parser Use the flow parser instead of babylon\n" +
" --single-quote Use single quotes instead of double\n" +
" --trailing-comma Print trailing commas wherever possible\n" +
" --bracket-spacing Put spaces between brackets. Defaults to true, set false to turn off"
"Usage: prettier [opts] [filename ...]\n\n" + "Available options:\n" +
" --write Edit the file in-place (beware!)\n" +
" --stdin Read input from stdin\n" +
" --print-width <int> Specify the length of line that the printer will wrap on. Defaults to 80.\n" +
" --tab-width <int> Specify the number of spaces per indentation-level. Defaults to 2.\n" +
" --flow-parser Use the flow parser instead of babylon\n" +
" --single-quote Use single quotes instead of double\n" +
" --trailing-comma Print trailing commas wherever possible\n" +
" --bracket-spacing Put spaces between brackets. Defaults to true, set false to turn off"
);
process.exit(1);
}

View File

@ -5,21 +5,21 @@ const flowParser = require("flow-parser");
const comments = require("./src/comments");
var babylonOptions = {
sourceType: 'module',
sourceType: "module",
allowImportExportEverywhere: false,
allowReturnOutsideFunction: false,
plugins: [
'jsx',
'flow',
'doExpressions',
'objectRestSpread',
'decorators',
'classProperties',
'exportExtensions',
'asyncGenerators',
'functionBind',
'functionSent',
'dynamicImport'
"jsx",
"flow",
"doExpressions",
"objectRestSpread",
"decorators",
"classProperties",
"exportExtensions",
"asyncGenerators",
"functionBind",
"functionSent",
"dynamicImport"
]
};
@ -27,22 +27,22 @@ function format(text, opts) {
opts = opts || {};
let ast;
if(opts.useFlowParser) {
if (opts.useFlowParser) {
ast = flowParser.parse(text);
if(ast.errors.length > 0) {
let msg = ast.errors[0].message + " on line " + ast.errors[0].loc.start.line
if(opts.filename) {
if (ast.errors.length > 0) {
let msg = ast.errors[(0)].message + " on line " +
ast.errors[(0)].loc.start.line;
if (opts.filename) {
msg += " in file " + opts.filename;
}
throw new Error(msg);
}
}
else {
} else {
ast = babylon.parse(text, babylonOptions);
}
// Interleave comment nodes
if(ast.comments) {
if (ast.comments) {
comments.attach(ast.comments, ast, text);
ast.comments = [];
}

View File

@ -73,11 +73,13 @@ 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 (locStart(child) - locStart(comment) <= 0 &&
locEnd(comment) - locEnd(child) <= 0) {
if (
locStart(child) - locStart(comment) <= 0 &&
locEnd(comment) - locEnd(child) <= 0
) {
// The comment is completely contained by this child node.
comment.enclosingNode = child;
decorateComment(child, comment, text);
@ -146,26 +148,20 @@ exports.attach = function(comments, ast, text) {
}
tiesToBreak.push(comment);
} else if (pn) {
// No contest: we have a trailing comment.
breakTies(tiesToBreak, text);
addTrailingComment(pn, comment);
} else if (fn) {
// No contest: we have a leading comment.
breakTies(tiesToBreak, text);
addLeadingComment(fn, comment);
} else if (en) {
// The enclosing node has no child nodes at all, so what we
// have here is a dangling comment, e.g. [/* crickets */].
breakTies(tiesToBreak, text);
addDanglingComment(en, comment);
} else {
// throw new Error("AST contains no nodes at all?");
}
} else {}
});
breakTies(tiesToBreak, text);
@ -186,17 +182,19 @@ function breakTies(tiesToBreak, text) {
return;
}
var pn = tiesToBreak[0].precedingNode;
var fn = tiesToBreak[0].followingNode;
var pn = tiesToBreak[(0)].precedingNode;
var fn = tiesToBreak[(0)].followingNode;
var gapEndPos = locStart(fn);
// Iterate backwards through tiesToBreak, examining the gaps
// between the tied comments. In order to qualify as leading, a
// comment must be separated from fn by an unbroken series of
// whitespace-only gaps (or other comments).
for (var indexOfFirstLeadingComment = tieCount;
indexOfFirstLeadingComment > 0;
--indexOfFirstLeadingComment) {
for (
var indexOfFirstLeadingComment = tieCount;
indexOfFirstLeadingComment > 0;
--indexOfFirstLeadingComment
) {
var comment = tiesToBreak[indexOfFirstLeadingComment - 1];
assert.strictEqual(comment.precedingNode, pn);
assert.strictEqual(comment.followingNode, fn);
@ -218,7 +216,6 @@ function breakTies(tiesToBreak, text) {
// comment.loc.start.column > fn.loc.start.column) {
// ++indexOfFirstLeadingComment;
// }
tiesToBreak.forEach(function(comment, i) {
if (i < indexOfFirstLeadingComment) {
addTrailingComment(pn, comment);
@ -256,7 +253,7 @@ function addTrailingComment(node, comment) {
function printLeadingComment(commentPath, print) {
var comment = commentPath.getValue();
n.Comment.assert(comment);
return concat([print(commentPath), hardline]);
return concat([ print(commentPath), hardline ]);
}
function printTrailingComment(commentPath, print, options) {
@ -274,40 +271,45 @@ exports.printComments = function(path, print, options) {
var value = path.getValue();
var parent = path.getParentNode();
var printed = print(path);
var comments = n.Node.check(value) &&
types.getFieldValue(value, "comments");
var isFirstInProgram = n.Program.check(parent) &&
parent.body[0] === value;
var comments = n.Node.check(value) && types.getFieldValue(value, "comments");
var isFirstInProgram = n.Program.check(parent) && parent.body[(0)] === value;
if (!comments || comments.length === 0) {
return printed;
}
var leadingParts = [];
var trailingParts = [printed];
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 || (trailing && !(n.Statement.check(value) ||
comment.type === "Block" ||
comment.type === "CommentBlock"))) {
leadingParts.push(printLeadingComment(commentPath, print));
if (
leading ||
trailing &&
!(n.Statement.check(value) || comment.type === "Block" ||
comment.type === "CommentBlock")
) {
leadingParts.push(printLeadingComment(commentPath, print));
// Support a special case where a comment exists at the very top
// of the file. Allow the user to add spacing between that file
// and any code beneath it.
if(isFirstInProgram &&
util.newlineExistsAfter(options.originalText, util.locEnd(comment))) {
leadingParts.push(hardline);
// Support a special case where a comment exists at the very top
// of the file. Allow the user to add spacing between that file
// and any code beneath it.
if (
isFirstInProgram &&
util.newlineExistsAfter(options.originalText, util.locEnd(comment))
) {
leadingParts.push(hardline);
}
} else if (trailing) {
trailingParts.push(printTrailingComment(commentPath, print, options));
}
} else if (trailing) {
trailingParts.push(printTrailingComment(commentPath, print, options));
}
}, "comments");
},
"comments"
);
leadingParts.push.apply(leadingParts, trailingParts);
return concat(leadingParts);

View File

@ -7,7 +7,7 @@ var isNumber = types.builtInTypes.number;
function FastPath(value) {
assert.ok(this instanceof FastPath);
this.stack = [value];
this.stack = [ value ];
}
var FPp = FastPath.prototype;
@ -24,8 +24,8 @@ FastPath.from = function(obj) {
// For backwards compatibility, unroll NodePath instances into
// lightweight FastPath [..., name, value] stacks.
var copy = Object.create(FastPath.prototype);
var stack = [obj.value];
for (var pp; (pp = obj.parentPath); obj = pp)
var stack = [ obj.value ];
for (var pp; pp = obj.parentPath; obj = pp)
stack.push(obj.name, pp.value);
copy.stack = stack.reverse();
return copy;
@ -90,9 +90,9 @@ FPp.getParentNode = function getParentNode(count) {
FPp.getRootValue = function getRootValue() {
var s = this.stack;
if (s.length % 2 === 0) {
return s[1];
return s[(1)];
}
return s[0];
return s[(0)];
};
// Temporarily push properties named by string arguments given after the
@ -100,7 +100,7 @@ FPp.getRootValue = function getRootValue() {
// reference to this (modified) FastPath object. Note that the stack will
// be restored to its original state after the callback is finished, so it
// is probably a mistake to retain a reference to the path.
FPp.call = function call(callback/*, name1, name2, ... */) {
FPp.call = function call(callback /*, name1, name2, ... */) {
var s = this.stack;
var origLen = s.length;
var value = s[origLen - 1];
@ -119,7 +119,7 @@ FPp.call = function call(callback/*, name1, name2, ... */) {
// accessing this.getValue()[name1][name2]... should be array-like. The
// callback will be called with a reference to this path object for each
// element of the array.
FPp.each = function each(callback/*, name1, name2, ... */) {
FPp.each = function each(callback /*, name1, name2, ... */) {
var s = this.stack;
var origLen = s.length;
var value = s[origLen - 1];
@ -147,7 +147,7 @@ FPp.each = function each(callback/*, name1, name2, ... */) {
// Similar to FastPath.prototype.each, except that the results of the
// callback function invocations are stored in an array and returned at
// the end of the iteration.
FPp.map = function map(callback/*, name1, name2, ... */) {
FPp.map = function map(callback /*, name1, name2, ... */) {
var s = this.stack;
var origLen = s.length;
var value = s[origLen - 1];
@ -208,36 +208,36 @@ FPp.needsParens = function(assumeExpressionContext) {
// Add parens around a `class` that extends an expression (it should
// parse correctly, even if it's invalid)
if(parent.type === "ClassDeclaration" &&
parent.superClass === node &&
node.type === "AwaitExpression") {
if (
parent.type === "ClassDeclaration" && parent.superClass === node &&
node.type === "AwaitExpression"
) {
return true;
}
// The left-hand side of the ** exponentiation operator must always
// be parenthesized unless it's an ident or literal
if(parent.type === "BinaryExpression" &&
parent.operator === "**" &&
parent.left === node &&
node.type !== "Identifier" &&
node.type !== "Literal") {
return true
if (
parent.type === "BinaryExpression" && parent.operator === "**" &&
parent.left === node &&
node.type !== "Identifier" &&
node.type !== "Literal"
) {
return true;
}
switch (node.type) {
case "UnaryExpression":
case "SpreadElement":
case "SpreadProperty":
return parent.type === "MemberExpression"
&& name === "object"
&& parent.object === node;
return parent.type === "MemberExpression" && name === "object" &&
parent.object === node;
case "BinaryExpression":
case "LogicalExpression":
switch (parent.type) {
case "CallExpression":
return name === "callee"
&& parent.callee === node;
return name === "callee" && parent.callee === node;
case "UnaryExpression":
case "SpreadElement":
@ -245,8 +245,7 @@ FPp.needsParens = function(assumeExpressionContext) {
return true;
case "MemberExpression":
return name === "object"
&& parent.object === node;
return name === "object" && parent.object === node;
case "BinaryExpression":
case "LogicalExpression":
@ -324,10 +323,9 @@ FPp.needsParens = function(assumeExpressionContext) {
parent.type === "IntersectionTypeAnnotation";
case "Literal":
return parent.type === "MemberExpression"
&& isNumber.check(node.value)
&& name === "object"
&& parent.object === node;
return parent.type === "MemberExpression" && isNumber.check(node.value) &&
name === "object" &&
parent.object === node;
case "NumericLiteral":
return parent.type === "MemberExpression";
@ -343,27 +341,22 @@ FPp.needsParens = function(assumeExpressionContext) {
return true;
case "CallExpression":
return name === "callee"
&& parent.callee === node;
return name === "callee" && parent.callee === node;
case "ConditionalExpression":
return name === "test"
&& parent.test === node;
return name === "test" && parent.test === node;
case "MemberExpression":
return name === "object"
&& parent.object === node;
return name === "object" && parent.object === node;
default:
return n.ObjectPattern.check(node.left) &&
this.firstInStatement();
return n.ObjectPattern.check(node.left) && this.firstInStatement();
}
case "ArrowFunctionExpression":
if(parent.type === 'CallExpression' &&
name === 'callee') {
if (parent.type === "CallExpression" && name === "callee") {
return true;
};
}
return isBinary(parent);
@ -371,51 +364,52 @@ FPp.needsParens = function(assumeExpressionContext) {
return parent.type === "ExpressionStatement";
case "ObjectExpression":
if (parent.type === "ArrowFunctionExpression" &&
name === "body") {
if (parent.type === "ArrowFunctionExpression" && name === "body") {
return true;
}
default:
if (parent.type === "NewExpression" &&
name === "callee" &&
parent.callee === node) {
if (
parent.type === "NewExpression" && name === "callee" &&
parent.callee === node
) {
return containsCallExpression(node);
}
}
if (assumeExpressionContext !== true &&
!this.canBeFirstInStatement() &&
this.firstInStatement())
if (
assumeExpressionContext !== true && !this.canBeFirstInStatement() &&
this.firstInStatement()
)
return true;
return false;
};
function isBinary(node) {
return n.BinaryExpression.check(node)
|| n.LogicalExpression.check(node);
return n.BinaryExpression.check(node) || n.LogicalExpression.check(node);
}
function isUnaryLike(node) {
return n.UnaryExpression.check(node)
// I considered making SpreadElement and SpreadProperty subtypes
return // I considered making SpreadElement and SpreadProperty subtypes
// of UnaryExpression, but they're not really Expression nodes.
|| (n.SpreadElement && n.SpreadElement.check(node))
|| (n.SpreadProperty && n.SpreadProperty.check(node));
n.UnaryExpression.check(
node
) || n.SpreadElement && n.SpreadElement.check(node) || n.SpreadProperty && n.SpreadProperty.check(node);
}
var PRECEDENCE = {};
[["||"],
["&&"],
["|"],
["^"],
["&"],
["==", "===", "!=", "!=="],
["<", ">", "<=", ">=", "in", "instanceof"],
[">>", "<<", ">>>"],
["+", "-"],
["*", "/", "%", "**"]
[
[ "||" ],
[ "&&" ],
[ "|" ],
[ "^" ],
[ "&" ],
[ "==", "===", "!=", "!==" ],
[ "<", ">", "<=", ">=", "in", "instanceof" ],
[ ">>", "<<", ">>>" ],
[ "+", "-" ],
[ "*", "/", "%", "**" ]
].forEach(function(tier, i) {
tier.forEach(function(op) {
PRECEDENCE[op] = i;
@ -442,11 +436,9 @@ function containsCallExpression(node) {
FPp.canBeFirstInStatement = function() {
var node = this.getNode();
return !n.FunctionExpression.check(node)
&& !n.ObjectExpression.check(node)
&& !n.ClassExpression.check(node)
&& !(n.AssignmentExpression.check(node) &&
n.ObjectPattern.check(node.left));
return !n.FunctionExpression.check(node) && !n.ObjectExpression.check(node) &&
!n.ClassExpression.check(node) &&
!(n.AssignmentExpression.check(node) && n.ObjectPattern.check(node.left));
};
FPp.firstInStatement = function() {
@ -466,53 +458,50 @@ FPp.firstInStatement = function() {
continue;
}
if (n.BlockStatement.check(parent) &&
parentName === "body" &&
childName === 0) {
assert.strictEqual(parent.body[0], child);
if (
n.BlockStatement.check(parent) && parentName === "body" && childName === 0
) {
assert.strictEqual(parent.body[(0)], child);
return true;
}
if (n.ExpressionStatement.check(parent) &&
childName === "expression") {
if (n.ExpressionStatement.check(parent) && childName === "expression") {
assert.strictEqual(parent.expression, child);
return true;
}
if (n.SequenceExpression.check(parent) &&
parentName === "expressions" &&
childName === 0) {
assert.strictEqual(parent.expressions[0], child);
if (
n.SequenceExpression.check(parent) && parentName === "expressions" &&
childName === 0
) {
assert.strictEqual(parent.expressions[(0)], child);
continue;
}
if (n.CallExpression.check(parent) &&
childName === "callee") {
if (n.CallExpression.check(parent) && childName === "callee") {
assert.strictEqual(parent.callee, child);
continue;
}
if (n.MemberExpression.check(parent) &&
childName === "object") {
if (n.MemberExpression.check(parent) && childName === "object") {
assert.strictEqual(parent.object, child);
continue;
}
if (n.ConditionalExpression.check(parent) &&
childName === "test") {
if (n.ConditionalExpression.check(parent) && childName === "test") {
assert.strictEqual(parent.test, child);
continue;
}
if (isBinary(parent) &&
childName === "left") {
if (isBinary(parent) && childName === "left") {
assert.strictEqual(parent.left, child);
continue;
}
if (n.UnaryExpression.check(parent) &&
!parent.prefix &&
childName === "argument") {
if (
n.UnaryExpression.check(parent) && !parent.prefix &&
childName === "argument"
) {
assert.strictEqual(parent.argument, child);
continue;
}

View File

@ -1,16 +1,12 @@
var defaults = {
// Number of spaces the pretty-printer should use per tab
tabWidth: 2,
// Fit code within this line limit
printWidth: 80,
// If true, will use single instead of double quotes
singleQuote: false,
// Controls the printing of trailing commas wherever possible
trailingComma: false,
// Controls the printing of spaces inside array and objects
bracketSpacing: true
};
@ -19,7 +15,7 @@ var defaults = {
exports.normalize = function(options) {
const normalized = Object.assign({}, options);
Object.keys(defaults).forEach(k => {
if(normalized[k] == null) {
if (normalized[k] == null) {
normalized[k] = defaults[k];
}
});

313
src/pp.js
View File

@ -15,13 +15,13 @@ function fromString(text) {
function concat(parts) {
parts.forEach(assertDoc);
return {type: "concat", parts};
return { type: "concat", parts };
}
function indent(n, contents) {
assertDoc(contents);
return {type: "indent", contents, n};
return { type: "indent", contents, n };
}
function group(contents, opts) {
@ -40,16 +40,19 @@ function group(contents, opts) {
function multilineGroup(contents, opts) {
return group(
contents,
Object.assign(opts || {}, {shouldBreak: hasHardLine(contents)})
Object.assign(opts || {}, { shouldBreak: hasHardLine(contents) })
);
}
function conditionalGroup(states, opts) {
return group(states[0], Object.assign(opts || {}, {expandedStates: states}));
return group(
states[(0)],
Object.assign(opts || {}, { expandedStates: states })
);
}
function ifBreak(contents) {
return {type: "if-break", contents};
return { type: "if-break", contents };
}
function iterDoc(topDoc, func) {
@ -82,10 +85,10 @@ function iterDoc(topDoc, func) {
}
}
const line = {type: "line"};
const softline = {type: "line", soft: true};
const hardline = {type: "line", hard: true};
const literalline = {type: "line", hard: true, literal: true};
const line = { type: "line" };
const softline = { type: "line", soft: true };
const hardline = { type: "line", hard: true };
const literalline = { type: "line", hard: true, literal: true };
function isEmpty(n) {
return typeof n === "string" && n.length === 0;
@ -118,12 +121,12 @@ function hasHardLine(doc) {
// multiline group because they should be marked bottom-up.
return !!iterDoc(doc, (type, doc) => {
switch (type) {
case "line":
if (doc.hard) {
return true;
}
case "line":
if (doc.hard) {
return true;
}
break;
break;
}
});
}
@ -158,50 +161,50 @@ function fits(next, restCommands, width) {
}
const x = cmds.pop();
const ind = x[0];
const mode = x[1];
const doc = x[2];
const ind = x[(0)];
const mode = x[(1)];
const doc = x[(2)];
if (typeof doc === "string") {
width -= doc.length;
} else {
switch (doc.type) {
case "concat":
for (var i = doc.parts.length - 1; i >= 0; i--) {
cmds.push([ ind, mode, doc.parts[i] ]);
}
break;
case "indent":
cmds.push([ ind + doc.n, mode, doc.contents ]);
break;
case "group":
cmds.push([ ind, doc.break ? MODE_BREAK : mode, doc.contents ]);
break;
case "if-break":
if (mode === MODE_BREAK) {
cmds.push([ ind, mode, doc.contents ]);
}
break;
case "line":
switch (mode) {
// fallthrough
case MODE_FLAT:
if (!doc.hard) {
if (!doc.soft) {
width -= 1;
}
break;
case "concat":
for (var i = doc.parts.length - 1; i >= 0; i--) {
cmds.push([ ind, mode, doc.parts[i] ]);
}
case MODE_BREAK:
return true;
}
break;
break;
case "indent":
cmds.push([ ind + doc.n, mode, doc.contents ]);
break;
case "group":
cmds.push([ ind, doc.break ? MODE_BREAK : mode, doc.contents ]);
break;
case "if-break":
if (mode === MODE_BREAK) {
cmds.push([ ind, mode, doc.contents ]);
}
break;
case "line":
switch (mode) {
// fallthrough
case MODE_FLAT:
if (!doc.hard) {
if (!doc.soft) {
width -= 1;
}
break;
}
case MODE_BREAK:
return true;
}
break;
}
}
}
@ -218,9 +221,9 @@ function print(w, doc) {
let shouldRemeasure = false;
while (cmds.length !== 0) {
const x = cmds.pop();
const ind = x[0];
const mode = x[1];
const doc = x[2];
const ind = x[(0)];
const mode = x[(1)];
const doc = x[(2)];
if (typeof doc === "string") {
out.push(doc);
@ -228,131 +231,131 @@ function print(w, doc) {
pos += doc.length;
} else {
switch (doc.type) {
case "concat":
for (var i = doc.parts.length - 1; i >= 0; i--) {
cmds.push([ ind, mode, doc.parts[i] ]);
}
break;
case "indent":
cmds.push([ ind + doc.n, mode, doc.contents ]);
break;
case "group":
switch (mode) {
// fallthrough
case MODE_FLAT:
if (!shouldRemeasure) {
cmds.push([
ind,
doc.break ? MODE_BREAK : MODE_FLAT,
doc.contents
]);
break;
case "concat":
for (var i = doc.parts.length - 1; i >= 0; i--) {
cmds.push([ ind, mode, doc.parts[i] ]);
}
case MODE_BREAK:
shouldRemeasure = false;
break;
case "indent":
cmds.push([ ind + doc.n, mode, doc.contents ]);
const next = [ ind, MODE_FLAT, doc.contents ];
let rem = w - pos;
if (!doc.break && fits(next, cmds, rem)) {
cmds.push(next);
} else {
// Expanded states are a rare case where a document
// can manually provide multiple representations of
// itself. It provides an array of documents
// going from the least expanded (most flattened)
// representation first to the most expanded. If a
// 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];
if (doc.break) {
cmds.push([ ind, MODE_BREAK, mostExpanded ]);
break;
case "group":
switch (mode) {
// fallthrough
case MODE_FLAT:
if (!shouldRemeasure) {
cmds.push([
ind,
doc.break ? MODE_BREAK : MODE_FLAT,
doc.contents
]);
break;
}
case MODE_BREAK:
shouldRemeasure = false;
const next = [ ind, MODE_FLAT, doc.contents ];
let rem = w - pos;
if (!doc.break && fits(next, cmds, rem)) {
cmds.push(next);
} else {
for (var i = 1; i < doc.expandedStates.length + 1; i++) {
if (i >= doc.expandedStates.length) {
// Expanded states are a rare case where a document
// can manually provide multiple representations of
// itself. It provides an array of documents
// going from the least expanded (most flattened)
// representation first to the most expanded. If a
// 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];
if (doc.break) {
cmds.push([ ind, MODE_BREAK, mostExpanded ]);
break;
} else {
const state = doc.expandedStates[i];
const cmd = [ ind, MODE_FLAT, state ];
for (var i = 1; i < doc.expandedStates.length + 1; i++) {
if (i >= doc.expandedStates.length) {
cmds.push([ ind, MODE_BREAK, mostExpanded ]);
if (fits(cmd, cmds, rem)) {
cmds.push(cmd);
break;
} else {
const state = doc.expandedStates[i];
const cmd = [ ind, MODE_FLAT, state ];
break;
if (fits(cmd, cmds, rem)) {
cmds.push(cmd);
break;
}
}
}
}
} else {
cmds.push([ ind, MODE_BREAK, doc.contents ]);
}
}
} else {
cmds.push([ ind, MODE_BREAK, doc.contents ]);
}
break;
}
break;
case "if-break":
if (mode === MODE_BREAK) {
cmds.push([ ind, MODE_BREAK, doc.contents ]);
}
break;
}
break;
case "if-break":
if (mode === MODE_BREAK) {
cmds.push([ ind, MODE_BREAK, doc.contents ]);
}
case "line":
switch (mode) {
// fallthrough
case MODE_FLAT:
if (!doc.hard) {
if (!doc.soft) {
out.push(" ");
break;
case "line":
switch (mode) {
// fallthrough
case MODE_FLAT:
if (!doc.hard) {
if (!doc.soft) {
out.push(" ");
pos += 1;
}
pos += 1;
}
break;
} else {
// This line was forced into the output even if we
// were in flattened mode, so we need to tell the next
// group that no matter what, it needs to remeasure
// because the previous measurement didn't accurately
// capture the entire expression (this is necessary
// for nested groups)
shouldRemeasure = true;
}
break;
} else {
// This line was forced into the output even if we
// were in flattened mode, so we need to tell the next
// group that no matter what, it needs to remeasure
// because the previous measurement didn't accurately
// capture the entire expression (this is necessary
// for nested groups)
shouldRemeasure = true;
case MODE_BREAK:
if (out.length > 0) {
const lastString = out[out.length - 1];
if (lastString.match(/^\s*\n\s*$/)) {
out[out.length - 1] = "\n";
}
}
if (doc.literal) {
out.push("\n");
pos = 0;
} else {
out.push("\n" + _makeIndent(ind));
pos = ind;
}
break;
}
case MODE_BREAK:
if (out.length > 0) {
const lastString = out[out.length - 1];
if (lastString.match(/^\s*\n\s*$/)) {
out[out.length - 1] = "\n";
}
}
if (doc.literal) {
out.push("\n");
pos = 0;
} else {
out.push("\n" + _makeIndent(ind));
pos = ind;
}
break;
}
break;
default:
default:
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -24,15 +24,12 @@ function getUnionOfKeys() {
util.getUnionOfKeys = getUnionOfKeys;
function comparePos(pos1, pos2) {
return (pos1.line - pos2.line) || (pos1.column - pos2.column);
return pos1.line - pos2.line || pos1.column - pos2.column;
}
util.comparePos = comparePos;
function copyPos(pos) {
return {
line: pos.line,
column: pos.column
};
return { line: pos.line, column: pos.column };
}
util.copyPos = copyPos;
@ -98,11 +95,10 @@ function expandLoc(parentNode, childNode) {
util.fixFaultyLocations = function(node, text) {
if (node.type === "TemplateLiteral") {
fixTemplateLiteral(node, text);
} else if (node.decorators) {
// Expand the loc of the node responsible for printing the decorators
// (here, the decorated node) so that it includes node.decorators.
node.decorators.forEach(function (decorator) {
node.decorators.forEach(function(decorator) {
expandLoc(node, decorator);
});
} else if (node.declaration && util.isExportDeclaration(node)) {
@ -110,12 +106,14 @@ util.fixFaultyLocations = function(node, text) {
// (here, the export declaration) so that it includes node.decorators.
var decorators = node.declaration.decorators;
if (decorators) {
decorators.forEach(function (decorator) {
decorators.forEach(function(decorator) {
expandLoc(node, decorator);
});
}
} else if ((n.MethodDefinition && n.MethodDefinition.check(node)) ||
(n.Property.check(node) && (node.method || node.shorthand))) {
} else if (
n.MethodDefinition && n.MethodDefinition.check(node) ||
n.Property.check(node) && (node.method || node.shorthand)
) {
if (n.FunctionExpression.check(node.value)) {
// FunctionExpression method values should be anonymous,
// because their .id fields are ignored anyway.
@ -127,7 +125,7 @@ util.fixFaultyLocations = function(node, text) {
// Some parsers accidentally include trailing commas in the
// end information for ObjectTypeProperty nodes.
if ((end = skipSpaces(text, end - 1, true)) !== false) {
setLocEnd(node, end)
setLocEnd(node, end);
}
}
}
@ -146,7 +144,7 @@ function fixTemplateLiteral(node, text) {
var afterLeftBackTickPos = locStart(node);
assert.strictEqual(text.charAt(afterLeftBackTickPos), "`");
assert.ok(afterLeftBackTickPos < text.length);
var firstQuasi = node.quasis[0];
var firstQuasi = node.quasis[(0)];
if (locStart(firstQuasi) - afterLeftBackTickPos < 0) {
setLocStart(firstQuasi, afterLeftBackTickPos);
}
@ -163,17 +161,18 @@ function fixTemplateLiteral(node, text) {
// Now we need to exclude ${ and } characters from the loc's of all
// quasi elements, since some parsers accidentally include them.
node.expressions.forEach(function (expr, i) {
node.expressions.forEach(function(expr, i) {
// Rewind from the start loc over any whitespace and the ${ that
// precedes the expression. The position of the $ should be the
// same as the end of the preceding quasi element, but some
// parsers accidentally include the ${ in the loc of the quasi
// element.
var dollarCurlyPos = skipSpaces(text, locStart(expr) - 1, true);
if (dollarCurlyPos - 1 >= 0 &&
text.charAt(dollarCurlyPos - 1) === "{" &&
if (
dollarCurlyPos - 1 >= 0 && text.charAt(dollarCurlyPos - 1) === "{" &&
dollarCurlyPos - 2 >= 0 &&
text.charAt(dollarCurlyPos - 2) === "$") {
text.charAt(dollarCurlyPos - 2) === "$"
) {
var quasiBefore = node.quasis[i];
if (dollarCurlyPos - locEnd(quasiBefore) < 0) {
setLocEnd(quasiBefore, dollarCurlyPos);
@ -194,24 +193,26 @@ function fixTemplateLiteral(node, text) {
});
}
util.isExportDeclaration = function (node) {
if (node) switch (node.type) {
case "ExportDeclaration":
case "ExportDefaultDeclaration":
case "ExportDefaultSpecifier":
case "DeclareExportDeclaration":
case "ExportNamedDeclaration":
case "ExportAllDeclaration":
return true;
}
util.isExportDeclaration = function(node) {
if (node)
switch (node.type) {
case "ExportDeclaration":
case "ExportDefaultDeclaration":
case "ExportDefaultSpecifier":
case "DeclareExportDeclaration":
case "ExportNamedDeclaration":
case "ExportAllDeclaration":
return true;
}
return false;
};
util.getParentExportDeclaration = function (path) {
util.getParentExportDeclaration = function(path) {
var parentNode = path.getParentNode();
if (path.getName() === "declaration" &&
util.isExportDeclaration(parentNode)) {
if (
path.getName() === "declaration" && util.isExportDeclaration(parentNode)
) {
return parentNode;
}
@ -227,15 +228,15 @@ util.isTrailingCommaEnabled = function(options, context) {
};
util.getLast = function(arr) {
if(arr.length > 0) {
if (arr.length > 0) {
return arr[arr.length - 1];
}
return null;
}
};
function _findNewline(text, index, backwards) {
const length = text.length;
let cursor = backwards ? (index - 1) : (index + 1);
let cursor = backwards ? index - 1 : index + 1;
// Look forward and see if there is a newline after/before this code
// by scanning up/back to the next non-indentation character.
while (cursor > 0 && cursor < length) {
@ -253,15 +254,15 @@ function _findNewline(text, index, backwards) {
util.newlineExistsBefore = function(text, index) {
return _findNewline(text, index, true);
}
};
util.newlineExistsAfter = function(text, index) {
return _findNewline(text, index);
}
};
function skipSpaces(text, index, backwards) {
const length = text.length;
let cursor = backwards ? (index - 1) : (index + 1);
let cursor = backwards ? index - 1 : index + 1;
// Look forward and see if there is a newline after/before this code
// by scanning up/back to the next non-indentation character.
while (cursor > 0 && cursor < length) {
@ -277,36 +278,34 @@ function skipSpaces(text, index, backwards) {
util.skipSpaces = skipSpaces;
function locStart(node) {
if(node.range) {
return node.range[0];
if (node.range) {
return node.range[(0)];
}
return node.start;
}
util.locStart = locStart;
function locEnd(node) {
if(node.range) {
return node.range[1];
if (node.range) {
return node.range[(1)];
}
return node.end;
}
util.locEnd = locEnd;
function setLocStart(node, index) {
if(node.range) {
node.range[0] = index;
}
else {
if (node.range) {
node.range[(0)] = index;
} else {
node.start = index;
}
}
util.setLocStart = setLocStart;
function setLocEnd(node, index) {
if(node.range) {
node.range[1] = index;
}
else {
if (node.range) {
node.range[(1)] = index;
} else {
node.end = index;
}
}
@ -314,13 +313,11 @@ util.setLocEnd = setLocEnd;
// http://stackoverflow.com/a/7124052
function htmlEscapeInsideDoubleQuote(str) {
return str
.replace(/&/g, '&amp;')
.replace(/"/g, '&quot;');
// Intentionally disable the following since it is safe inside of a
// double quote context
// .replace(/'/g, '&#39;')
// .replace(/</g, '&lt;')
// .replace(/>/g, '&gt;');
return str.replace(/&/g, "&amp;").replace(/"/g, "&quot;");
// Intentionally disable the following since it is safe inside of a
// double quote context
// .replace(/'/g, '&#39;')
// .replace(/</g, '&lt;')
// .replace(/>/g, '&gt;');
}
util.htmlEscapeInsideDoubleQuote = htmlEscapeInsideDoubleQuote;