Improve ESLint setup and fix errors (#1656)

* Improve ESLint setup

- Uses `eslint:recommended` + a handful more rules.
- Uses .eslintignore so that editors can understand which files to lint.
- Uses .eslintrc<strong>.js</strong> so more editors get syntax highlighting.

* Fix ESLint errors

About half of them were fixed by `eslint . --fix`.
master
Simon Lydell 2017-05-21 21:11:09 +02:00 committed by Christopher Chedeau
parent d7aaaee0dd
commit 378682350f
20 changed files with 164 additions and 131 deletions

5
.eslintignore Normal file
View File

@ -0,0 +1,5 @@
!/*.js
/docs/
/tests/**/*.js
!/tests/**/jsfmt.spec.js
!/**/.eslintrc.js

View File

@ -1,11 +0,0 @@
{
"parserOptions": {
"ecmaVersion": "2015"
},
"plugins": [
"prettier"
],
"rules": {
"prettier/prettier": "error"
}
}

19
.eslintrc.js Normal file
View File

@ -0,0 +1,19 @@
"use strict";
module.exports = {
env: {
es6: true,
node: true
},
extends: ["eslint:recommended"],
plugins: ["prettier"],
rules: {
"no-console": "off",
"no-inner-declarations": "off",
"no-var": "error",
"prefer-arrow-callback": "error",
"prefer-const": "error",
"prettier/prettier": "error",
strict: "error"
}
};

View File

@ -9,5 +9,5 @@ cache:
directories:
- node_modules
script:
- npm run lint
- npm test -- --runInBand
- yarn lint
- yarn test -- --runInBand

View File

@ -454,6 +454,7 @@ To get up and running, install the dependencies and run the tests:
```
yarn
yarn lint
yarn test
```
@ -478,6 +479,8 @@ Here's what you need to know about the tests:
interactive `docs` REPL locally. The easiest way to debug it in node, is to
create a local test file and run it in an editor like VS Code.
Run `yarn lint -- --fix` to automatically format files.
If you can, take look at [commands.md](commands.md) and check out [Wadler's
paper](http://homepages.inf.ed.ac.uk/wadler/papers/prettier/prettier.pdf) to
understand how Prettier works.

View File

@ -129,6 +129,7 @@ function getTrailingComma() {
"Warning: `--trailing-comma` was used without an argument. This is deprecated. " +
'Specify "none", "es5", or "all".'
);
return "es5";
case "es5":
return "es5";
case "all":

View File

@ -40,10 +40,7 @@
},
"scripts": {
"test": "jest",
"format": "./bin/prettier.js --write",
"format:single": "npm run format -- src/printer.js",
"format:all": "npm run lint -- --fix",
"lint": "eslint index.js \"{src,bin,tests_config,scripts}/*.js\" \"tests/**/jsfmt.spec.js\"",
"lint": "eslint .",
"build:docs": "rollup -c docs/rollup.config.js"
},
"jest": {

View File

@ -1,3 +1,5 @@
"use strict";
/**
* There's an issue with this script's assumption that each run of prettier
* will result in one output to stderr or stdout.
@ -18,7 +20,6 @@ const spawn = require("child_process").spawn;
const rimraf = require("rimraf");
const tsRoot = path.resolve(__dirname, "../../TypeScript");
const packageJson = path.resolve(tsRoot, "package.json");
const testsDir = path.relative(process.cwd(), path.join(tsRoot, "tests"));
const errorsPath = "./errors/";
const fileGlob = path.join(testsDir, "**/*.ts");
@ -43,7 +44,7 @@ const cp = spawn("node", [
fileGlob
]);
cp.stdout.on("data", out => {
cp.stdout.on("data", () => {
good++;
printStatus();
});
@ -60,7 +61,7 @@ cp.stderr.on("data", err => {
printStatus();
});
cp.on("close", code => {
cp.on("close", () => {
const total = badFiles.length + good + skipped;
const percentNoError = (100 * (good + skipped) / total).toFixed(0);
console.log(

View File

@ -1,3 +1,5 @@
"use strict";
const fs = require("fs");
const flowParser = require("flow-parser");
const glob = require("glob");

View File

@ -284,7 +284,7 @@ function attach(comments, ast, text) {
breakTies(tiesToBreak, text);
comments.forEach(function(comment) {
comments.forEach(comment => {
// These node references were useful for breaking ties, but we
// don't need them anymore, and they create cycles in the AST that
// may lead to infinite recursion if we don't delete them here.
@ -327,7 +327,7 @@ function breakTies(tiesToBreak, text) {
gapEndPos = locStart(comment);
}
tiesToBreak.forEach(function(comment, i) {
tiesToBreak.forEach((comment, i) => {
if (i < indexOfFirstLeadingComment) {
addTrailingComment(precedingNode, comment);
} else {
@ -917,7 +917,7 @@ function printComments(path, print, options, needsSemi) {
const leadingParts = [];
const trailingParts = [needsSemi ? ";" : "", printed];
path.each(function(commentPath) {
path.each(commentPath => {
const comment = commentPath.getValue();
const leading = types.getFieldValue(comment, "leading");
const trailing = types.getFieldValue(comment, "trailing");

View File

@ -2,10 +2,7 @@
const docBuilders = require("./doc-builders");
const concat = docBuilders.concat;
const line = docBuilders.line;
const softline = docBuilders.softline;
const fill = docBuilders.fill;
const ifBreak = docBuilders.ifBreak;
const MODE_BREAK = 1;
const MODE_FLAT = 2;
@ -123,6 +120,7 @@ function fits(next, restCommands, width, mustBeFlat) {
break;
}
return true;
case MODE_BREAK:
return true;
@ -135,14 +133,14 @@ function fits(next, restCommands, width, mustBeFlat) {
}
function printDocToString(doc, options) {
let width = options.printWidth;
let newLine = options.newLine || "\n";
const width = options.printWidth;
const newLine = options.newLine || "\n";
let pos = 0;
// cmds is basically a stack. We've turned a recursive call into a
// while loop which is much faster. The while loop below adds new
// cmds to the array instead of recursively calling `print`.
let cmds = [[rootIndent(), MODE_BREAK, doc]];
let out = [];
const cmds = [[rootIndent(), MODE_BREAK, doc]];
const out = [];
let shouldRemeasure = false;
let lineSuffix = [];
@ -174,7 +172,6 @@ function printDocToString(doc, options) {
break;
case "group":
switch (mode) {
// fallthrough
case MODE_FLAT:
if (!shouldRemeasure) {
cmds.push([
@ -185,12 +182,14 @@ function printDocToString(doc, options) {
break;
}
// fallthrough
case MODE_BREAK:
case MODE_BREAK: {
shouldRemeasure = false;
const next = [ind, MODE_FLAT, doc.contents];
let rem = width - pos;
const rem = width - pos;
if (!doc.break && fits(next, cmds, rem)) {
cmds.push(next);
@ -234,6 +233,7 @@ function printDocToString(doc, options) {
}
break;
}
}
break;
// Fills each line with as much code as possible before moving to a new
@ -257,7 +257,7 @@ function printDocToString(doc, options) {
// * Neither content item fits on the line without breaking
// -> output the first content item and the whitespace with "break".
case "fill": {
let rem = width - pos;
const rem = width - pos;
const parts = doc.parts;
if (parts.length === 0) {
@ -347,7 +347,6 @@ function printDocToString(doc, options) {
break;
case "line":
switch (mode) {
// fallthrough
case MODE_FLAT:
if (!doc.hard) {
if (!doc.soft) {
@ -366,6 +365,8 @@ function printDocToString(doc, options) {
// for nested groups)
shouldRemeasure = true;
}
// fallthrough
case MODE_BREAK:
if (lineSuffix.length) {
@ -396,8 +397,8 @@ function printDocToString(doc, options) {
}
}
let length = ind.indent * options.tabWidth + ind.align.spaces;
let indentString = options.useTabs
const length = ind.indent * options.tabWidth + ind.align.spaces;
const indentString = options.useTabs
? "\t".repeat(ind.indent + ind.align.tabs)
: " ".repeat(length);
out.push(newLine + indentString);

View File

@ -62,7 +62,7 @@ function mapDoc(doc, func) {
function findInDoc(doc, fn, defaultValue) {
let result = defaultValue;
let hasStopped = false;
traverseDoc(doc, function(doc) {
traverseDoc(doc, doc => {
const maybeResult = fn(doc);
if (maybeResult !== undefined) {
hasStopped = true;

View File

@ -268,7 +268,7 @@ FPp.needsParens = function() {
(node.operator === "--" && parent.operator === "-"))
);
}
// else fall through
// else fallthrough
case "UnaryExpression":
switch (parent.type) {
case "UnaryExpression":
@ -294,11 +294,11 @@ FPp.needsParens = function() {
return false;
}
case "BinaryExpression":
case "BinaryExpression": {
const isLeftOfAForStatement = node => {
let i = 0;
while (node) {
let parent = this.getParentNode(i++);
const parent = this.getParentNode(i++);
if (!parent) {
return false;
}
@ -312,7 +312,8 @@ FPp.needsParens = function() {
if (node.operator === "in" && isLeftOfAForStatement(node)) {
return true;
}
// else fall through
}
// fallthrough
case "TSTypeAssertionExpression":
case "TSAsExpression":
case "LogicalExpression":
@ -333,7 +334,7 @@ FPp.needsParens = function() {
return name === "object" && parent.object === node;
case "BinaryExpression":
case "LogicalExpression":
case "LogicalExpression": {
const po = parent.operator;
const pp = util.getPrecedence(po);
const no = node.operator;
@ -362,6 +363,9 @@ FPp.needsParens = function() {
return true;
}
return false;
}
default:
return false;
}
@ -394,7 +398,7 @@ FPp.needsParens = function() {
) {
return true;
}
// else fall through
// else fallthrough
case "AwaitExpression":
switch (parent.type) {
case "TaggedTemplateExpression":
@ -577,7 +581,7 @@ function containsCallExpression(node) {
}
if (n.Node.check(node)) {
return types.someField(node, function(name, child) {
return types.someField(node, (name, child) => {
return containsCallExpression(child);
});
}

View File

@ -40,10 +40,12 @@ function shouldPrintComma(options, level) {
if (level === "all") {
return true;
}
// fallthrough
case "es5":
if (level === "es5") {
return true;
}
// fallthrough
case "none":
default:
return false;
@ -90,7 +92,7 @@ function genericPrint(path, options, printPath, args) {
node.decorators[0].expression.type === "MemberExpression")
? " "
: hardline;
path.each(function(decoratorPath) {
path.each(decoratorPath => {
parts.push(printPath(decoratorPath), separator);
}, "decorators");
} else if (
@ -101,7 +103,7 @@ function genericPrint(path, options, printPath, args) {
// Export declarations are responsible for printing any decorators
// that logically apply to node.declaration.
path.each(
function(decoratorPath) {
decoratorPath => {
parts.push(printPath(decoratorPath), line);
},
"declaration",
@ -157,7 +159,7 @@ function genericPrintNoParens(path, options, print, args) {
case "Program":
// Babel 6
if (n.directives) {
path.each(function(childPath) {
path.each(childPath => {
parts.push(print(childPath), semi, hardline);
if (
util.isNextLineEmpty(options.originalText, childPath.getValue())
@ -168,7 +170,7 @@ function genericPrintNoParens(path, options, print, args) {
}
parts.push(
path.call(function(bodyPath) {
path.call(bodyPath => {
return printStatementSequence(bodyPath, options, print);
}, "body")
);
@ -338,7 +340,6 @@ function genericPrintNoParens(path, options, print, args) {
}
case "SpreadElement":
case "SpreadElementPattern":
// Babel 6 for ObjectPattern
case "RestProperty":
case "SpreadProperty":
case "SpreadPropertyPattern":
@ -560,7 +561,7 @@ function genericPrintNoParens(path, options, print, args) {
case "ExportNamespaceSpecifier":
case "ExportDefaultSpecifier":
return path.call(print, "exported");
case "ImportDeclaration":
case "ImportDeclaration": {
parts.push("import ");
const fromParts = [];
@ -572,7 +573,7 @@ function genericPrintNoParens(path, options, print, args) {
const standalones = [];
const grouped = [];
if (n.specifiers && n.specifiers.length > 0) {
path.each(function(specifierPath) {
path.each(specifierPath => {
const value = specifierPath.getValue();
if (
namedTypes.ImportDefaultSpecifier.check(value) ||
@ -630,12 +631,12 @@ function genericPrintNoParens(path, options, print, args) {
}
return concat([concat(parts), concat(fromParts)]);
case "Import": {
return "import";
}
case "Import":
return "import";
case "BlockStatement": {
const naked = path.call(function(bodyPath) {
const naked = path.call(bodyPath => {
return printStatementSequence(bodyPath, options, print);
}, "body");
@ -662,7 +663,7 @@ function genericPrintNoParens(path, options, print, args) {
// Babel 6
if (hasDirectives) {
path.each(function(childPath) {
path.each(childPath => {
parts.push(indent(concat([hardline, print(childPath), semi])));
}, "directives");
}
@ -781,10 +782,7 @@ function genericPrintNoParens(path, options, print, args) {
case "ObjectTypeAnnotation":
case "TSTypeLiteral": {
const isTypeAnnotation = n.type === "ObjectTypeAnnotation";
const isTypeScriptTypeAnnotation = n.type === "TSTypeLiteral";
const isTypeScriptInterfaceBody = n.type === "TSInterfaceBody";
const isTypeScriptType =
isTypeScriptTypeAnnotation || isTypeScriptInterfaceBody;
// Leave this here because we *might* want to make this
// configurable later -- flow accepts ";" for type separators,
// typescript accepts ";" and newlines
@ -793,7 +791,6 @@ function genericPrintNoParens(path, options, print, args) {
separator = semi;
}
const fields = [];
const prefix = [];
const leftBrace = n.exact ? "{|" : "{";
const rightBrace = n.exact ? "|}" : "}";
const parent = path.getParentNode(0);
@ -817,8 +814,8 @@ function genericPrintNoParens(path, options, print, args) {
// interleaved in the source code. So we need to reorder them before
// printing them.
const propsAndLoc = [];
fields.forEach(function(field) {
path.each(function(childPath) {
fields.forEach(field => {
path.each(childPath => {
const node = childPath.getValue();
propsAndLoc.push({
node: node,
@ -1022,19 +1019,14 @@ function genericPrintNoParens(path, options, print, args) {
return "this";
case "Super":
return "super";
// Babel 6 Literal split
case "NullLiteral":
case "NullLiteral": // Babel 6 Literal split
return "null";
// Babel 6 Literal split
case "RegExpLiteral":
case "RegExpLiteral": // Babel 6 Literal split
return printRegex(n);
// Babel 6 Literal split
case "NumericLiteral":
case "NumericLiteral": // Babel 6 Literal split
return printNumber(n.extra.raw);
// Babel 6 Literal split
case "BooleanLiteral":
// Babel 6 Literal split
case "StringLiteral":
case "BooleanLiteral": // Babel 6 Literal split
case "StringLiteral": // Babel 6 Literal split
case "Literal":
if (n.regex) {
return printRegex(n.regex);
@ -1111,7 +1103,7 @@ function genericPrintNoParens(path, options, print, args) {
return concat(parts);
case "VariableDeclaration": {
const printed = path.map(function(childPath) {
const printed = path.map(childPath => {
return print(childPath);
}, "declarations");
@ -1158,7 +1150,7 @@ function genericPrintNoParens(path, options, print, args) {
adjustClause(n.body, path.call(print, "body"))
])
);
case "IfStatement":
case "IfStatement": {
const con = adjustClause(n.consequent, path.call(print, "consequent"));
const opening = group(
concat([
@ -1195,6 +1187,7 @@ function genericPrintNoParens(path, options, print, args) {
}
return concat(parts);
}
case "ForStatement": {
const body = adjustClause(n.body, path.call(print, "body"));
@ -1268,7 +1261,7 @@ function genericPrintNoParens(path, options, print, args) {
);
case "ForOfStatement":
case "ForAwaitStatement":
case "ForAwaitStatement": {
// Babylon 7 removed ForAwaitStatement in favor of ForOfStatement
// with `"await": true`:
// https://github.com/estree/estree/pull/138
@ -1286,8 +1279,9 @@ function genericPrintNoParens(path, options, print, args) {
adjustClause(n.body, path.call(print, "body"))
])
);
}
case "DoWhileStatement":
case "DoWhileStatement": {
const clause = adjustClause(n.body, path.call(print, "body"));
const doBody = group(concat(["do", clause]));
parts = [doBody];
@ -1306,6 +1300,7 @@ function genericPrintNoParens(path, options, print, args) {
);
return concat(parts);
}
case "DoExpression":
return concat(["do ", path.call(print, "body")]);
case "BreakStatement":
@ -1344,7 +1339,7 @@ function genericPrintNoParens(path, options, print, args) {
if (n.handler) {
parts.push(" ", path.call(print, "handler"));
} else if (n.handlers) {
path.each(function(handlerPath) {
path.each(handlerPath => {
parts.push(" ", print(handlerPath));
}, "handlers");
}
@ -1378,7 +1373,7 @@ function genericPrintNoParens(path, options, print, args) {
hardline,
"}"
]);
case "SwitchCase":
case "SwitchCase": {
if (n.test) {
parts.push("case ", path.call(print, "test"), ":");
} else {
@ -1419,6 +1414,7 @@ function genericPrintNoParens(path, options, print, args) {
}
return concat(parts);
}
// JSX extensions below.
case "DebuggerStatement":
return concat(["debugger", semi]);
@ -1540,7 +1536,7 @@ function genericPrintNoParens(path, options, print, args) {
return concat(["</", path.call(print, "name"), ">"]);
case "JSXText":
throw new Error("JSXTest should be handled by JSXElement");
case "JSXEmptyExpression":
case "JSXEmptyExpression": {
const requiresHardline =
n.comments && !n.comments.every(util.isBlockComment);
@ -1552,6 +1548,7 @@ function genericPrintNoParens(path, options, print, args) {
),
requiresHardline ? hardline : ""
]);
}
case "TypeAnnotatedIdentifier":
return concat([
path.call(print, "annotation"),
@ -1569,7 +1566,7 @@ function genericPrintNoParens(path, options, print, args) {
? indent(
concat([
hardline,
path.call(function(bodyPath) {
path.call(bodyPath => {
return printStatementSequence(bodyPath, options, print);
}, "body")
])
@ -1642,12 +1639,12 @@ function genericPrintNoParens(path, options, print, args) {
]);
case "TemplateElement":
return join(literalline, n.value.raw.split(/\r?\n/g));
case "TemplateLiteral":
case "TemplateLiteral": {
const expressions = path.map(print, "expressions");
parts.push("`");
path.each(function(childPath) {
path.each(childPath => {
const i = childPath.getName();
parts.push(print(childPath));
@ -1672,7 +1669,7 @@ function genericPrintNoParens(path, options, print, args) {
size = util.getAlignmentSize(value, tabWidth, index + 1);
}
let aligned = addAlignmentToDoc(
const aligned = addAlignmentToDoc(
removeLines(expressions[i]),
size,
tabWidth
@ -1685,6 +1682,7 @@ function genericPrintNoParens(path, options, print, args) {
parts.push("`");
return concat(parts);
}
// These types are unprintable because they serve as abstract
// supertypes for other (printable) types.
case "TaggedTemplateExpression":
@ -1700,9 +1698,7 @@ function genericPrintNoParens(path, options, print, args) {
case "Declaration":
case "Specifier":
case "NamedSpecifier":
// Supertype of Block and Line.
case "Comment":
// Flow
case "MemberTypeAnnotation": // Flow
case "Type":
throw new Error("unprintable type: " + JSON.stringify(n.type));
@ -1715,8 +1711,8 @@ function genericPrintNoParens(path, options, print, args) {
return "";
case "TSTupleType":
case "TupleTypeAnnotation":
let typesField = n.type === "TSTupleType" ? "elementTypes" : "types";
case "TupleTypeAnnotation": {
const typesField = n.type === "TSTupleType" ? "elementTypes" : "types";
return group(
concat([
"[",
@ -1732,6 +1728,7 @@ function genericPrintNoParens(path, options, print, args) {
"]"
])
);
}
case "ExistsTypeAnnotation":
return "*";
@ -2118,7 +2115,7 @@ function genericPrintNoParens(path, options, print, args) {
]);
case "TSArrayType":
return concat([path.call(print, "elementType"), "[]"]);
case "TSPropertySignature":
case "TSPropertySignature": {
const computed =
!namedTypes.Identifier.check(n.name) &&
!namedTypes.Literal.check(n.name);
@ -2150,6 +2147,7 @@ function genericPrintNoParens(path, options, print, args) {
}
return concat(parts);
}
case "TSParameterProperty":
if (n.accessibility) {
parts.push(n.accessibility + " ");
@ -2201,7 +2199,7 @@ function genericPrintNoParens(path, options, print, args) {
]);
case "TSConstructSignature":
case "TSConstructorType":
case "TSCallSignature":
case "TSCallSignature": {
if (n.type !== "TSCallSignature") {
parts.push("new ");
}
@ -2216,6 +2214,7 @@ function genericPrintNoParens(path, options, print, args) {
parts.push(isType ? " => " : ": ", path.call(print, "typeAnnotation"));
}
return concat(parts);
}
case "TSTypeOperator":
return concat(["keyof ", path.call(print, "typeAnnotation")]);
case "TSMappedType":
@ -2380,27 +2379,18 @@ function genericPrintNoParens(path, options, print, args) {
return concat(parts);
}
case "TSModuleBlock":
return path.call(function(bodyPath) {
return path.call(bodyPath => {
return printStatementSequence(bodyPath, options, print);
}, "body");
// TODO
case "ClassHeritage":
// TODO
case "ComprehensionBlock":
// TODO
case "ComprehensionExpression":
// TODO
case "Glob":
// TODO
case "GeneratorExpression":
// TODO
case "LetStatement":
// TODO
case "LetExpression":
// TODO
case "GraphExpression":
// TODO
// XML types that nobody cares about or needs to print.
case "ClassHeritage": // TODO
case "ComprehensionBlock": // TODO
case "ComprehensionExpression": // TODO
case "Glob": // TODO
case "GeneratorExpression": // TODO
case "LetStatement": // TODO
case "LetExpression": // TODO
case "GraphExpression": // TODO
// XML types that nobody cares about or needs to print. (fallthrough)
case "GraphIndexExpression":
case "XMLDefaultDeclaration":
case "XMLAnyName":
@ -2427,7 +2417,7 @@ function genericPrintNoParens(path, options, print, args) {
}
function printStatementSequence(path, options, print) {
let printed = [];
const printed = [];
const bodyNode = path.getNode();
const isClass = bodyNode.type === "ClassBody";
@ -2608,7 +2598,6 @@ function shouldGroupFirstArg(args) {
function printArgumentsList(path, options, print) {
const printed = path.map(print, "arguments");
const n = path.getValue();
if (printed.length === 0) {
return concat([
"(",
@ -2631,7 +2620,7 @@ function printArgumentsList(path, options, print) {
// We want to print the last argument with a special flag
let printedExpanded;
let i = 0;
path.each(function(argPath) {
path.each(argPath => {
if (shouldGroupFirst && i === 0) {
printedExpanded = [
argPath.call(p => print(p, { expandFirstArg: true }))
@ -2723,7 +2712,7 @@ function printFunctionParams(path, print, options, expandArg) {
const printed = path.map(print, paramsField);
if (fun.defaults) {
path.each(function(defExprPath) {
path.each(defExprPath => {
const i = defExprPath.getName();
const p = printed[i];
@ -2929,7 +2918,7 @@ function printReturnType(path, print) {
function printExportDeclaration(path, options, print) {
const decl = path.getValue();
const semi = options.semi ? ";" : "";
let parts = ["export "];
const parts = ["export "];
namedTypes.Declaration.assert(decl);
@ -2959,9 +2948,9 @@ function printExportDeclaration(path, options, print) {
) {
parts.push("*");
} else {
let specifiers = [];
let defaultSpecifiers = [];
let namespaceSpecifiers = [];
const specifiers = [];
const defaultSpecifiers = [];
const namespaceSpecifiers = [];
path.map(specifierPath => {
const specifierType = path.getValue().type;
@ -3414,7 +3403,7 @@ function printJSXChildren(path, options, print, jsxWhitespace) {
const children = [];
// using `map` instead of `each` because it provides `i`
path.map(function(childPath, i) {
path.map((childPath, i) => {
const child = childPath.getValue();
const isLiteral = namedTypes.Literal.check(child);
@ -3491,7 +3480,7 @@ function printJSXChildren(path, options, print, jsxWhitespace) {
// add a softline where we have two adjacent elements that are not
// literals
let next = n.children[i + 1];
const next = n.children[i + 1];
const followedByJSXElement = next && !namedTypes.Literal.check(next);
if (followedByJSXElement) {
children.push(softline);
@ -3588,7 +3577,7 @@ function printJSXElement(path, options, print) {
// Tweak how we format children if outputting this element over multiple lines.
// Also detect whether we will force this element to output over multiple lines.
let multilineChildren = [];
const multilineChildren = [];
children.forEach((child, i) => {
// Ensure that we display leading, trailing, and solitary whitespace as
// `{" "}` when outputting this element over multiple lines.
@ -3702,7 +3691,7 @@ function printBinaryishExpressions(
isInsideParenthesis
) {
let parts = [];
let node = path.getValue();
const node = path.getValue();
// We treat BinaryExpression and LogicalExpression nodes the same.
if (isBinaryish(node)) {
@ -4060,12 +4049,10 @@ function classChildNeedsASIProtection(node) {
case "ClassProperty":
case "TSAbstractClassProperty":
return node.computed;
// flow
case "MethodDefinition":
// typescript
case "TSAbstractMethodDefinition":
// babylon
case "MethodDefinition": // Flow
case "TSAbstractMethodDefinition": // TypeScript
case "ClassMethod": {
// Babylon
const isAsync = node.value ? node.value.async : node.async;
const isGenerator = node.value ? node.value.generator : node.generator;
if (
@ -4079,6 +4066,7 @@ function classChildNeedsASIProtection(node) {
if (node.computed || isGenerator) {
return true;
}
return false;
}
default:
@ -4204,7 +4192,7 @@ function printArrayItems(path, options, printPath, print) {
const printedElements = [];
let separatorParts = [];
path.each(function(childPath) {
path.each(childPath => {
printedElements.push(concat(separatorParts));
printedElements.push(group(print(childPath)));

View File

@ -1,3 +1,5 @@
"use strict";
module.exports = function(fork) {
fork.use(require("ast-types/def/es7"));

View File

@ -247,8 +247,8 @@ const PRECEDENCE = {};
["+", "-"],
["*", "/", "%"],
["**"]
].forEach(function(tier, i) {
tier.forEach(function(op) {
].forEach((tier, i) => {
tier.forEach(op => {
PRECEDENCE[op] = i;
});
});

13
tests/.eslintrc.js Normal file
View File

@ -0,0 +1,13 @@
"use strict";
module.exports = {
env: {
jest: true
},
rules: {
strict: "off"
},
globals: {
run_spec: false
}
};

View File

@ -0,0 +1,7 @@
"use strict";
module.exports = {
env: {
jest: true
}
};

View File

@ -1,3 +1,5 @@
"use strict";
const RAW = Symbol.for("raw");
module.exports = {

View File

@ -3,7 +3,6 @@
const fs = require("fs");
const extname = require("path").extname;
const prettier = require("../");
const types = require("../src/ast-types");
const parser = require("../src/parser");
const massageAST = require("../src/clean-ast.js").massageAST;
@ -76,7 +75,7 @@ function stripLocation(ast) {
}
if (typeof ast === "object") {
const newObj = {};
for (var key in ast) {
for (const key in ast) {
if (
key === "loc" ||
key === "range" ||