Socket
Socket
Sign inDemoInstall

prettier

Package Overview
Dependencies
Maintainers
1
Versions
164
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

prettier - npm Package Compare versions

Comparing version 0.0.5 to 0.0.6

docs/index.html

33

bin/prettier.js
#!/usr/bin/env node
"use strict";
const fs = require("fs");

@@ -10,6 +9,11 @@ const getStdin = require("get-stdin");

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 }
});

@@ -23,12 +27,11 @@

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"
);

@@ -35,0 +38,0 @@ process.exit(1);

# 0.0.5
# 0.0.6
6f0743e fix italic in readme
1fe0833 add yarn.lock and tests to .npmignore and add yarn instructions to README
f1db144 docs: add globbing example
9ffbd32 Enable reading from stdin
ccf6f84 add travis config and add yarn support
24c3af8 Remove trailing whitespace in broken arrow function expressions.
00fad62 Regenerate snapshots
030a70f Fix misprinting of directives.
03414d6 Add newline to EOF.
d56365d Add semicolons to `export` declarations.
8fb6428 Add missing comma in API example
b8e6fc5 Do not fatal when formatting throws
0fdf14d Log the filename when --write is being used
[link](https://github.com/jlongster/prettier/compare/faed09ceea32fcdd58b525aa09b880afb9fa55b7...3af7da5748d64efaed781104ec198924c8c369f9)
* Format property names consistently
* remove node 0.10 from travis config, add travis badge to readme
* Update snapshots
* chore: link prettier package to its github project
* add gitter badge to readme
* add instructions for Visual Studio plugin
* Do not unquote string properties
* Add prettier-browser
* v0.0.5 -- Accidentally didn't push this commit out before others landed; 0.0.5 is actually based on commit faed09ceea32fcdd58b525aa09b880afb9fa55b7
* update yarn.lock
* remove recast (not used)
* Always use double quotes for JSX and properly escape
* remove unused recast ref
* Fix typo in README.
* Support type annotation for rest argument on babylon parser
* Use `setq' instead of `infc' and `decf'
* Add title and encoding to the REPL
* Fix old name reference in tests_config
* Minimize string escapes
* Support method generics on babylon parser
* Break long `exports` into multiple lines.
* Use group instead of conditionalGroup
* Fix misprinting of computed properties in method chains. (#157)
* treat shebang outside of parsing (#137)
* Break multiline imports (#167)
* Do not put spaces on empty for loop (#169)
* Add trailing comma support for multiline exports (#168)
* Update run_spec to support options
* Add tests for bracketSpacing option
* Add tests for quotes option
* Add tests for tabWiths option
* Add tests for trailingComma option
* Fix for Node 4
* Add test for shebang and move to index.js (#170)
* Numeric literal callees should keep parens (#141)
* Remove leftover `arrowParensAlways` option (#171)
* Wrap Stateless JSX Arrow Functions and Assignment in Parens (fixes part of #73)
* Break JSXOpeningElement between attributes (fixes #15)
* JSX maintains spaces that matter (fixes #30 and thus part of #73)
* Multiline JSX opening tag breaks children out too (for #73)
* Add regression tests for long JSX Expression contents
* include index.js in format:all script (#132)
* Wrap ForStatement in a block for const decls (#172)
* Reprint all the files!

@@ -8,50 +8,65 @@ "use strict";

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"
]
};
module.exports = {
format: function(text, opts) {
opts = opts || {};
let ast;
function format(text, opts) {
opts = opts || {};
let ast;
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) {
msg += " in file " + opts.filename;
}
throw new Error(msg);
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) {
msg += " in file " + opts.filename;
}
throw new Error(msg);
}
else {
ast = babylon.parse(text, babylonOptions);
}
} else {
ast = babylon.parse(text, babylonOptions);
}
// Interleave comment nodes
if(ast.comments) {
comments.attach(ast.comments, ast, text);
ast.comments = [];
}
ast.tokens = [];
opts.originalText = text;
// Interleave comment nodes
if (ast.comments) {
comments.attach(ast.comments, ast, text);
ast.comments = [];
}
ast.tokens = [];
opts.originalText = text;
const printer = new Printer(opts);
return printer.printGenerically(ast).code;
const printer = new Printer(opts);
return printer.printGenerically(ast).code;
}
function formatWithShebang(text, opts) {
if (!text.startsWith("#!")) {
return format(text, opts);
}
const index = text.indexOf("\n");
const shebang = text.slice(0, index + 1);
const programText = text.slice(index + 1);
return shebang + format(programText, opts);
}
module.exports = {
format: function(text, opts) {
return formatWithShebang(text, opts);
}
};
{
"name": "prettier",
"version": "0.0.5",
"version": "0.0.6",
"bin": {
"prettier": "./bin/prettier.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/jlongster/prettier.git"
},
"author": "James Long",
"bugs": {
"url": "https://github.com/jlongster/prettier/issues"
},
"main": "./index.js",

@@ -11,2 +19,3 @@ "dependencies": {

"babylon": "^6.15.0",
"esutils": "^2.0.2",
"flow-parser": "^0.37.0",

@@ -16,7 +25,11 @@ "get-stdin": "^5.0.1",

"private": "^0.1.6",
"recast": "^0.11.18",
"source-map": "^0.5.6"
},
"devDependencies": {
"jest": "^18.0.0"
"jest": "^18.0.0",
"rollup": "^0.41.1",
"rollup-plugin-commonjs": "^7.0.0",
"rollup-plugin-node-builtins": "^2.0.0",
"rollup-plugin-node-resolve": "^2.0.0",
"rollup-plugin-real-babili": "^1.0.0-alpha3"
},

@@ -27,3 +40,4 @@ "scripts": {

"format:single": "npm run format -- src/printer.js",
"format:all": "npm run format -- src/*.js bin/*.js"
"format:all": "npm run format -- index.js src/*.js bin/*.js",
"build:docs": "rollup -c docs/rollup.config.js"
},

@@ -30,0 +44,0 @@ "jest": {

@@ -1,3 +0,5 @@

# Prettier
# Prettier [![Build Status](https://travis-ci.org/jlongster/prettier.svg?branch=master)](https://travis-ci.org/jlongster/prettier)
[![Gitter](https://badges.gitter.im/gitterHQ/gitter.svg)](https://gitter.im/jlongster/prettier)
Prettier is an opinionated JavaScript formatter inspired by

@@ -174,2 +176,10 @@ [refmt](https://facebook.github.io/reason/tools.html) with advanced

### Visual Studio Code
Can be installed using the extension sidebar. Search for `Prettier - JavaScript formatter`
Can also be installed using `ext install prettier-vscode`
[Check repository for configuration and shortcuts](https://github.com/esbenp/prettier-vscode)
More editors are coming soon.

@@ -192,3 +202,3 @@

This printer is a fork of
[recast](https://github.com/benjamn/recast)'s printer with it's
[recast](https://github.com/benjamn/recast)'s printer with its
algorithm replaced by the one described by Wadler in "[A prettier

@@ -195,0 +205,0 @@ printer](http://homepages.inf.ed.ac.uk/wadler/papers/prettier/prettier.pdf)".

@@ -76,7 +76,9 @@ var assert = require("assert");

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.

@@ -150,3 +152,2 @@ comment.enclosingNode = child;

tiesToBreak.push(comment);
} else if (pn) {

@@ -156,3 +157,2 @@ // No contest: we have a trailing comment.

addTrailingComment(pn, comment);
} else if (fn) {

@@ -162,3 +162,2 @@ // No contest: we have a leading comment.

addLeadingComment(fn, comment);
} else if (en) {

@@ -169,6 +168,3 @@ // The enclosing node has no child nodes at all, so what we

addDanglingComment(en, comment);
} else {
// throw new Error("AST contains no nodes at all?");
}
} else {}
});

@@ -194,4 +190,4 @@

var pn = tiesToBreak[0].precedingNode;
var fn = tiesToBreak[0].followingNode;
var pn = tiesToBreak[(0)].precedingNode;
var fn = tiesToBreak[(0)].followingNode;
var gapEndPos = locStart(fn);

@@ -203,5 +199,7 @@

// 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];

@@ -228,3 +226,2 @@ assert.strictEqual(comment.precedingNode, pn);

// }
tiesToBreak.forEach(function(comment, i) {

@@ -267,3 +264,3 @@ if (i < indexOfFirstLeadingComment) {

n.Comment.assert(comment);
return concat([print(commentPath), hardline]);
return concat([ print(commentPath), hardline ]);
}

@@ -286,6 +283,4 @@

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;

@@ -297,26 +292,33 @@ if (!comments || comments.length === 0) {

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"
);

@@ -323,0 +325,0 @@ leadingParts.push.apply(leadingParts, trailingParts);

@@ -10,3 +10,3 @@ var assert = require("assert");

assert.ok(this instanceof FastPath);
this.stack = [value];
this.stack = [ value ];
}

@@ -28,4 +28,4 @@

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);

@@ -95,5 +95,5 @@ copy.stack = stack.reverse();

if (s.length % 2 === 0) {
return s[1];
return s[(1)];
}
return s[0];
return s[(0)];
};

@@ -106,3 +106,3 @@

// 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;

@@ -126,3 +126,3 @@ var origLen = s.length;

// element of the array.
FPp.each = function each(callback/*, name1, name2, ... */) {
FPp.each = function each(callback /*, name1, name2, ... */) {
var s = this.stack;

@@ -155,3 +155,3 @@ var origLen = s.length;

// the end of the iteration.
FPp.map = function map(callback/*, name1, name2, ... */) {
FPp.map = function map(callback /*, name1, name2, ... */) {
var s = this.stack;

@@ -217,5 +217,6 @@ var origLen = s.length;

// 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;

@@ -226,8 +227,9 @@ }

// 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;
}

@@ -239,5 +241,4 @@

case "SpreadProperty":
return parent.type === "MemberExpression"
&& name === "object"
&& parent.object === node;
return parent.type === "MemberExpression" && name === "object" &&
parent.object === node;

@@ -248,4 +249,3 @@ case "BinaryExpression":

case "CallExpression":
return name === "callee"
&& parent.callee === node;
return name === "callee" && parent.callee === node;

@@ -258,4 +258,3 @@ case "UnaryExpression":

case "MemberExpression":
return name === "object"
&& parent.object === node;
return name === "object" && parent.object === node;

@@ -338,7 +337,9 @@ case "BinaryExpression":

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";
case "AssignmentExpression":

@@ -355,23 +356,18 @@ case "ConditionalExpression":

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;
};
}

@@ -384,4 +380,3 @@ return isBinary(parent);

case "ObjectExpression":
if (parent.type === "ArrowFunctionExpression" &&
name === "body") {
if (parent.type === "ArrowFunctionExpression" && name === "body") {
return true;

@@ -391,5 +386,6 @@ }

default:
if (parent.type === "NewExpression" &&
name === "callee" &&
parent.callee === node) {
if (
parent.type === "NewExpression" && name === "callee" &&
parent.callee === node
) {
return containsCallExpression(node);

@@ -399,5 +395,6 @@ }

if (assumeExpressionContext !== true &&
!this.canBeFirstInStatement() &&
this.firstInStatement())
if (
assumeExpressionContext !== true && !this.canBeFirstInStatement() &&
this.firstInStatement()
)
return true;

@@ -409,25 +406,25 @@

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) {

@@ -459,7 +456,5 @@ tier.forEach(function(op) {

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));
};

@@ -484,11 +479,10 @@

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);

@@ -498,11 +492,11 @@ 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);

@@ -512,4 +506,3 @@ continue;

if (n.MemberExpression.check(parent) &&
childName === "object") {
if (n.MemberExpression.check(parent) && childName === "object") {
assert.strictEqual(parent.object, child);

@@ -519,4 +512,3 @@ continue;

if (n.ConditionalExpression.check(parent) &&
childName === "test") {
if (n.ConditionalExpression.check(parent) && childName === "test") {
assert.strictEqual(parent.test, child);

@@ -526,4 +518,3 @@ continue;

if (isBinary(parent) &&
childName === "left") {
if (isBinary(parent) && childName === "left") {
assert.strictEqual(parent.left, child);

@@ -533,5 +524,6 @@ continue;

if (n.UnaryExpression.check(parent) &&
!parent.prefix &&
childName === "argument") {
if (
n.UnaryExpression.check(parent) && !parent.prefix &&
childName === "argument"
) {
assert.strictEqual(parent.argument, child);

@@ -538,0 +530,0 @@ continue;

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

@@ -22,3 +18,3 @@ bracketSpacing: true

Object.keys(defaults).forEach(k => {
if(normalized[k] == null) {
if (normalized[k] == null) {
normalized[k] = defaults[k];

@@ -25,0 +21,0 @@ }

@@ -18,3 +18,3 @@ "use strict";

return {type: "concat", parts};
return { type: "concat", parts };
}

@@ -25,3 +25,3 @@

return {type: "indent", contents, n};
return { type: "indent", contents, n };
}

@@ -45,3 +45,3 @@

contents,
Object.assign(opts || {}, {shouldBreak: hasHardLine(contents)})
Object.assign(opts || {}, { shouldBreak: hasHardLine(contents) })
);

@@ -51,7 +51,10 @@ }

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 };
}

@@ -89,6 +92,6 @@

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 };

@@ -126,8 +129,8 @@ function isEmpty(n) {

switch (type) {
case "line":
if (doc.hard) {
return true;
}
case "line":
if (doc.hard) {
return true;
}
break;
break;
}

@@ -167,5 +170,5 @@ });

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)];

@@ -176,38 +179,38 @@ if (typeof doc === "string") {

switch (doc.type) {
case "concat":
for (var i = doc.parts.length - 1; i >= 0; i--) {
cmds.push([ ind, mode, doc.parts[i] ]);
}
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 "indent":
cmds.push([ ind + doc.n, mode, doc.contents ]);
break;
case "group":
cmds.push([ ind, doc.break ? MODE_BREAK : 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 "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 "line":
switch (mode) {
// fallthrough
case MODE_FLAT:
if (!doc.hard) {
if (!doc.soft) {
width -= 1;
}
break;
break;
}
case MODE_BREAK:
return true;
}
case MODE_BREAK:
return true;
}
break;
break;
}

@@ -229,5 +232,5 @@ }

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)];

@@ -240,53 +243,47 @@ if (typeof doc === "string") {

switch (doc.type) {
case "concat":
for (var i = doc.parts.length - 1; i >= 0; i--) {
cmds.push([ ind, mode, doc.parts[i] ]);
}
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 "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 "group":
switch (mode) {
// fallthrough
case MODE_FLAT:
if (!shouldRemeasure) {
cmds.push([
ind,
doc.break ? MODE_BREAK : MODE_FLAT,
doc.contents
]);
break;
}
break;
}
case MODE_BREAK:
shouldRemeasure = false;
case MODE_BREAK:
shouldRemeasure = false;
const next = [ ind, MODE_FLAT, doc.contents ];
let rem = w - pos;
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 && 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;
} else {
for (var i = 1; i < doc.expandedStates.length + 1; i++) {
if (i >= doc.expandedStates.length) {
if (doc.break) {
cmds.push([ ind, MODE_BREAK, mostExpanded ]);

@@ -296,72 +293,78 @@

} 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];
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 (lastString.match(/^\s*\n\s*$/)) {
out[out.length - 1] = "\n";
}
}
if (doc.literal) {
out.push("\n");
if (doc.literal) {
out.push("\n");
pos = 0;
} else {
out.push("\n" + _makeIndent(ind));
pos = 0;
} else {
out.push("\n" + _makeIndent(ind));
pos = ind;
}
pos = ind;
break;
}
break;
}
break;
default:
default:
}

@@ -368,0 +371,0 @@ }

@@ -28,2 +28,3 @@ "use strict";

var util = require("./util");
var isIdentifierName = require("esutils").keyword.isIdentifierNameES6;

@@ -78,3 +79,7 @@ function PrintResult(code, sourceMap) {

function printGenerically(path) {
return printComments(path, p => genericPrint(p, options, printGenerically), options);
return printComments(
path,
p => genericPrint(p, options, printGenerically),
options
);
}

@@ -197,63 +202,63 @@

switch (n.type) {
case "File":
return path.call(print, "program");
case "Program":
// Babel 6
if (n.directives) {
path.each(
function(childPath) {
parts.push(print(childPath), ";", hardline);
},
"directives"
case "File":
return path.call(print, "program");
case "Program":
// Babel 6
if (n.directives) {
path.each(
function(childPath) {
parts.push(print(childPath), ";", hardline);
},
"directives"
);
}
parts.push(
path.call(
function(bodyPath) {
return printStatementSequence(bodyPath, options, print);
},
"body"
)
);
}
parts.push(
path.call(
function(bodyPath) {
return printStatementSequence(bodyPath, options, print);
},
"body"
)
);
parts.push(hardline);
parts.push(hardline);
return concat(parts);
// Babel extension.
case "Noop":
case "EmptyStatement":
return fromString("");
case "ExpressionStatement":
return concat([ path.call(print, "expression"), ";" ]);
case // Babel extension.
"ParenthesizedExpression":
return concat([ "(", path.call(print, "expression"), ")" ]);
case "AssignmentExpression":
return group(
concat([
return concat(parts);
// Babel extension.
case "Noop":
case "EmptyStatement":
return fromString("");
case "ExpressionStatement":
return concat([ path.call(print, "expression"), ";" ]);
case // Babel extension.
"ParenthesizedExpression":
return concat([ "(", path.call(print, "expression"), ")" ]);
case "AssignmentExpression":
return group(
concat([
path.call(print, "left"),
" ",
n.operator,
" ",
path.call(print, "right")
])
);
case "BinaryExpression":
case "LogicalExpression":
return group(
concat([
path.call(print, "left"),
" ",
n.operator,
indent(options.tabWidth, concat([ line, path.call(print, "right") ]))
])
);
case "AssignmentPattern":
return concat([
path.call(print, "left"),
" ",
n.operator,
" ",
" = ",
path.call(print, "right")
])
);
case "BinaryExpression":
case "LogicalExpression":
return group(
concat([
path.call(print, "left"),
" ",
n.operator,
indent(options.tabWidth, concat([ line, path.call(print, "right") ]))
])
);
case "AssignmentPattern":
return concat([
path.call(print, "left"),
" = ",
path.call(print, "right")
]);
case "MemberExpression": {
]);
case "MemberExpression": {
return concat([

@@ -264,306 +269,325 @@ path.call(print, "object"),

}
case "MetaProperty":
return concat([
path.call(print, "meta"),
".",
path.call(print, "property")
]);
case "BindExpression":
if (n.object) {
parts.push(path.call(print, "object"));
}
case "MetaProperty":
return concat([
path.call(print, "meta"),
".",
path.call(print, "property")
]);
case "BindExpression":
if (n.object) {
parts.push(path.call(print, "object"));
}
parts.push("::", path.call(print, "callee"));
parts.push("::", path.call(print, "callee"));
return concat(parts);
case "Path":
return join(".", n.body);
case "Identifier":
return concat([
n.name,
n.optional ? "?" : "",
path.call(print, "typeAnnotation")
]);
case "SpreadElement":
case "SpreadElementPattern":
// Babel 6 for ObjectPattern
case "RestProperty":
case "SpreadProperty":
case "SpreadPropertyPattern":
case "RestElement":
return concat([ "...", path.call(print, "argument") ]);
case "FunctionDeclaration":
case "FunctionExpression":
if (n.async)
parts.push("async ");
return concat(parts);
case "Path":
return join(".", n.body);
case "Identifier":
return concat([
n.name,
n.optional ? "?" : "",
path.call(print, "typeAnnotation")
]);
case "SpreadElement":
case "SpreadElementPattern":
// Babel 6 for ObjectPattern
case "RestProperty":
case "SpreadProperty":
case "SpreadPropertyPattern":
case "RestElement":
return concat([
"...",
path.call(print, "argument"),
path.call(print, "typeAnnotation")
]);
case "FunctionDeclaration":
case "FunctionExpression":
if (n.async)
parts.push("async ");
parts.push("function");
parts.push("function");
if (n.generator)
parts.push("*");
if (n.generator)
parts.push("*");
if (n.id) {
parts.push(" ", path.call(print, "id"));
}
if (n.id) {
parts.push(" ", path.call(print, "id"));
}
parts.push(
path.call(print, "typeParameters"),
multilineGroup(concat([
printFunctionParams(path, print, options),
printReturnType(path, print)
])),
" ",
path.call(print, "body")
);
parts.push(
path.call(print, "typeParameters"),
multilineGroup(
concat([
printFunctionParams(path, print, options),
printReturnType(path, print)
])
),
" ",
path.call(print, "body")
);
return concat(parts);
case "ArrowFunctionExpression":
if (n.async)
parts.push("async ");
return concat(parts);
case "ArrowFunctionExpression":
if (n.async)
parts.push("async ");
if (n.typeParameters) {
parts.push(path.call(print, "typeParameters"));
}
if (n.typeParameters) {
parts.push(path.call(print, "typeParameters"));
}
if (
!options.arrowParensAlways && n.params.length === 1 && !n.rest &&
n.params[0].type === "Identifier" &&
!n.params[0].typeAnnotation &&
!n.predicate &&
!n.returnType
) {
parts.push(path.call(print, "params", 0));
} else {
parts.push(multilineGroup(concat([
printFunctionParams(path, print, options),
printReturnType(path, print)
])));
}
if (
n.params.length === 1 && !n.rest &&
n.params[(0)].type === "Identifier" &&
!n.params[(0)].typeAnnotation &&
!n.predicate &&
!n.returnType
) {
parts.push(path.call(print, "params", 0));
} else {
parts.push(
multilineGroup(
concat([
printFunctionParams(path, print, options),
printReturnType(path, print)
])
)
);
}
parts.push(" =>");
parts.push(" =>");
return conditionalGroup([
concat([ concat(parts), " ", path.call(print, "body") ]),
concat([ concat(parts),
indent(options.tabWidth,
concat([line, path.call(print, "body")]))])
])
case "MethodDefinition":
if (n.static) {
parts.push("static ");
}
const body = path.call(print, "body");
const collapsed = concat([ concat(parts), " ", body ]);
parts.push(printMethod(path, options, print));
if (n.body.type === "JSXElement") {
return group(collapsed);
}
return concat(parts);
case "YieldExpression":
parts.push("yield");
return conditionalGroup([
collapsed,
concat([
concat(parts),
indent(options.tabWidth, concat([ line, body ]))
])
]);
case "MethodDefinition":
if (n.static) {
parts.push("static ");
}
if (n.delegate)
parts.push("*");
parts.push(printMethod(path, options, print));
if (n.argument)
parts.push(" ", path.call(print, "argument"));
return concat(parts);
case "YieldExpression":
parts.push("yield");
return concat(parts);
case "AwaitExpression":
parts.push("await");
if (n.delegate)
parts.push("*");
if (n.all)
parts.push("*");
if (n.argument)
parts.push(" ", path.call(print, "argument"));
if (n.argument)
parts.push(" ", path.call(print, "argument"));
return concat(parts);
case "AwaitExpression":
parts.push("await");
return concat(parts);
case "ModuleDeclaration":
parts.push("module", path.call(print, "id"));
if (n.all)
parts.push("*");
if (n.source) {
assert.ok(!n.body);
if (n.argument)
parts.push(" ", path.call(print, "argument"));
parts.push("from", path.call(print, "source"));
} else {
parts.push(path.call(print, "body"));
}
return concat(parts);
case "ModuleDeclaration":
parts.push("module", path.call(print, "id"));
return join(" ", parts);
case "ImportSpecifier":
if (n.imported) {
parts.push(path.call(print, "imported"));
if (n.source) {
assert.ok(!n.body);
if (n.local && n.local.name !== n.imported.name) {
parts.push(" as ", path.call(print, "local"));
parts.push("from", path.call(print, "source"));
} else {
parts.push(path.call(print, "body"));
}
} else if (n.id) {
parts.push(path.call(print, "id"));
if (n.name) {
parts.push(" as ", path.call(print, "name"));
return join(" ", parts);
case "ImportSpecifier":
if (n.imported) {
parts.push(path.call(print, "imported"));
if (n.local && n.local.name !== n.imported.name) {
parts.push(" as ", path.call(print, "local"));
}
} else if (n.id) {
parts.push(path.call(print, "id"));
if (n.name) {
parts.push(" as ", path.call(print, "name"));
}
}
}
return concat(parts);
case "ExportSpecifier":
if (n.local) {
parts.push(path.call(print, "local"));
return concat(parts);
case "ExportSpecifier":
if (n.local) {
parts.push(path.call(print, "local"));
if (n.exported && n.exported.name !== n.local.name) {
parts.push(" as ", path.call(print, "exported"));
if (n.exported && n.exported.name !== n.local.name) {
parts.push(" as ", path.call(print, "exported"));
}
} else if (n.id) {
parts.push(path.call(print, "id"));
if (n.name) {
parts.push(" as ", path.call(print, "name"));
}
}
} else if (n.id) {
parts.push(path.call(print, "id"));
if (n.name) {
parts.push(" as ", path.call(print, "name"));
return concat(parts);
case "ExportBatchSpecifier":
return fromString("*");
case "ImportNamespaceSpecifier":
parts.push("* as ");
if (n.local) {
parts.push(path.call(print, "local"));
} else if (n.id) {
parts.push(path.call(print, "id"));
}
}
return concat(parts);
case "ExportBatchSpecifier":
return fromString("*");
case "ImportNamespaceSpecifier":
parts.push("* as ");
return concat(parts);
case "ImportDefaultSpecifier":
if (n.local) {
return path.call(print, "local");
}
if (n.local) {
parts.push(path.call(print, "local"));
} else if (n.id) {
parts.push(path.call(print, "id"));
}
return path.call(print, "id");
case "ExportDeclaration":
case "ExportDefaultDeclaration":
case "ExportNamedDeclaration":
return printExportDeclaration(path, options, print);
case "ExportAllDeclaration":
parts.push("export *");
return concat(parts);
case "ImportDefaultSpecifier":
if (n.local) {
return path.call(print, "local");
}
if (n.exported) {
parts.push(" as ", path.call(print, "exported"));
}
return path.call(print, "id");
case "ExportDeclaration":
case "ExportDefaultDeclaration":
case "ExportNamedDeclaration":
return printExportDeclaration(path, options, print);
case "ExportAllDeclaration":
parts.push("export *");
parts.push(" from ", path.call(print, "source"), ";");
if (n.exported) {
parts.push(" as ", path.call(print, "exported"));
}
return concat(parts);
case "ExportNamespaceSpecifier":
return concat([ "* as ", path.call(print, "exported") ]);
case "ExportDefaultSpecifier":
return path.call(print, "exported");
case "ImportDeclaration":
parts.push("import ");
parts.push(" from ", path.call(print, "source"), ";");
if (n.importKind && n.importKind !== "value") {
parts.push(n.importKind + " ");
}
return concat(parts);
case "ExportNamespaceSpecifier":
return concat([ "* as ", path.call(print, "exported") ]);
case "ExportDefaultSpecifier":
return path.call(print, "exported");
case "ImportDeclaration":
parts.push("import ");
if (n.specifiers && n.specifiers.length > 0) {
var standalones = [];
var grouped = [];
if (n.importKind && n.importKind !== "value") {
parts.push(n.importKind + " ");
}
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 (n.specifiers && n.specifiers.length > 0) {
var foundImportSpecifier = false;
assert.ok(standalones.length <= 1);
path.each(
function(specifierPath) {
var i = specifierPath.getName();
if (standalones.length > 0) {
parts.push(standalones[(0)]);
}
if (i > 0) {
parts.push(", ");
}
if (standalones.length > 0 && grouped.length > 0) {
parts.push(", ");
}
var value = specifierPath.getValue();
if (grouped.length > 0) {
parts.push(
group(
concat([
"{",
indent(
options.tabWidth,
concat([
options.bracketSpacing ? line : softline,
join(
concat([ ",", options.bracketSpacing ? line : softline ]),
grouped
)
])
),
ifBreak(options.trailingComma ? "," : ""),
options.bracketSpacing ? line : softline,
"}"
])
)
);
}
if (
namedTypes.ImportDefaultSpecifier.check(value) ||
namedTypes.ImportNamespaceSpecifier.check(value)
) {
assert.strictEqual(foundImportSpecifier, false);
} else {
namedTypes.ImportSpecifier.assert(value);
parts.push(" from ");
}
if (!foundImportSpecifier) {
foundImportSpecifier = true;
parts.push(path.call(print, "source"), ";");
parts.push(options.bracketSpacing ? "{ " : "{");
}
}
parts.push(print(specifierPath));
return concat(parts);
case "BlockStatement":
var naked = path.call(
function(bodyPath) {
return printStatementSequence(bodyPath, options, print);
},
"specifiers"
"body"
);
if (foundImportSpecifier) {
parts.push(options.bracketSpacing ? " }" : "}");
// If there are no contents, return a simple block
if (!getFirstString(naked)) {
return "{}";
}
parts.push(" from ");
}
parts.push("{");
parts.push(path.call(print, "source"), ";");
// Babel 6
if (n.directives) {
path.each(
function(childPath) {
parts.push(
indent(
options.tabWidth,
concat([ hardline, print(childPath), ";", hardline ])
)
);
},
"directives"
);
}
return concat(parts);
case "BlockStatement":
var naked = path.call(
function(bodyPath) {
return printStatementSequence(bodyPath, options, print);
},
"body"
);
parts.push(indent(options.tabWidth, concat([ hardline, naked ])));
// If there are no contents, return a simple block
if (!getFirstString(naked)) {
return "{}";
}
parts.push(hardline, "}");
parts.push("{");
return concat(parts);
case "ReturnStatement":
parts.push("return");
// Babel 6
if (n.directives) {
path.each(
function(childPath) {
parts.push(
indent(
options.tabWidth,
concat([ hardline, print(childPath), ";", hardline ])
)
);
},
"directives"
);
}
parts.push(indent(options.tabWidth, concat([ hardline, naked ])));
parts.push(hardline, "}");
return concat(parts);
case "ReturnStatement":
parts.push("return");
var arg = path.call(print, "argument");
if (n.argument) {
if (
namedTypes.JSXElement && namedTypes.JSXElement.check(n.argument) &&
hasHardLine(arg)
) {
parts.push(
" (",
indent(options.tabWidth, concat([ hardline, arg ])),
hardline,
")"
);
} else {
parts.push(" ", arg);
if (n.argument) {
parts.push(" ", path.call(print, "argument"));
}
}
parts.push(";");
parts.push(";");
return concat(parts);
case "CallExpression": {
return concat(parts);
case "CallExpression": {
const parent = path.getParentNode();

@@ -585,101 +609,38 @@ // We detect calls on member lookups and possibly print them in a

case "ObjectExpression":
case "ObjectPattern":
case "ObjectTypeAnnotation":
var allowBreak = false;
var isTypeAnnotation = n.type === "ObjectTypeAnnotation";
// Leave this here because we *might* want to make this
// configurable later -- flow accepts ";" for type separators
var separator = isTypeAnnotation ? "," : ",";
var fields = [];
var leftBrace = n.exact ? "{|" : "{";
var rightBrace = n.exact ? "|}" : "}";
case "ObjectExpression":
case "ObjectPattern":
case "ObjectTypeAnnotation":
var allowBreak = false;
var isTypeAnnotation = n.type === "ObjectTypeAnnotation";
// Leave this here because we *might* want to make this
// configurable later -- flow accepts ";" for type separators
var separator = isTypeAnnotation ? "," : ",";
var fields = [];
var leftBrace = n.exact ? "{|" : "{";
var rightBrace = n.exact ? "|}" : "}";
if (isTypeAnnotation) {
fields.push("indexers", "callProperties");
}
if (isTypeAnnotation) {
fields.push("indexers", "callProperties");
}
fields.push("properties");
fields.push("properties");
var i = 0;
var props = [];
var i = 0;
var props = [];
fields.forEach(function(field) {
path.each(
function(childPath) {
props.push(group(print(childPath)));
},
field
);
});
fields.forEach(function(field) {
path.each(
function(childPath) {
props.push(group(print(childPath)));
},
field
);
});
if (props.length === 0) {
return "{}";
} else {
return multilineGroup(
concat([
leftBrace,
indent(
options.tabWidth,
concat([
options.bracketSpacing ? line : softline,
join(concat([ separator, line ]), props)
])
),
ifBreak(options.trailingComma ? "," : ""),
options.bracketSpacing ? line : softline,
rightBrace,
path.call(print, "typeAnnotation")
])
);
}
case "PropertyPattern":
return concat([
path.call(print, "key"),
": ",
path.call(print, "pattern")
]);
// Babel 6
case "ObjectProperty":
case // Non-standard AST node type.
"Property":
if (n.method || n.kind === "get" || n.kind === "set") {
return printMethod(path, options, print);
}
if (n.computed) {
parts.push("[", path.call(print, "key"), "]");
} else {
parts.push(path.call(print, n.shorthand ? "value" : "key"));
}
if (!n.shorthand) {
parts.push(": ", path.call(print, "value"));
}
return concat(parts);
case // Babel 6
"ClassMethod":
if (n.static) {
parts.push("static ");
}
parts = parts.concat(printObjectMethod(path, options, print));
return concat(parts);
case // Babel 6
"ObjectMethod":
return printObjectMethod(path, options, print);
case "Decorator":
return concat([ "@", path.call(print, "expression") ]);
case "ArrayExpression":
case "ArrayPattern":
if (n.elements.length === 0) {
parts.push("[]");
} else {
parts.push(
multilineGroup(
if (props.length === 0) {
return "{}";
} else {
return multilineGroup(
concat([
"[",
leftBrace,
indent(

@@ -689,3 +650,3 @@ options.tabWidth,

options.bracketSpacing ? line : softline,
join(concat([ ",", line ]), path.map(print, "elements"))
join(concat([ separator, line ]), props)
])

@@ -695,776 +656,841 @@ ),

options.bracketSpacing ? line : softline,
"]"
rightBrace,
path.call(print, "typeAnnotation")
])
)
);
}
);
}
if (n.typeAnnotation)
parts.push(path.call(print, "typeAnnotation"));
case "PropertyPattern":
return concat([
path.call(print, "key"),
": ",
path.call(print, "pattern")
]);
// Babel 6
case "ObjectProperty":
case // Non-standard AST node type.
"Property":
if (n.method || n.kind === "get" || n.kind === "set") {
return printMethod(path, options, print);
}
return concat(parts);
case "SequenceExpression":
return join(", ", path.map(print, "expressions"));
case "ThisExpression":
return fromString("this");
case "Super":
return fromString("super");
case // Babel 6 Literal split
"NullLiteral":
return fromString("null");
case // Babel 6 Literal split
"RegExpLiteral":
return fromString(n.extra.raw);
// Babel 6 Literal split
case "BooleanLiteral":
// Babel 6 Literal split
case "NumericLiteral":
// Babel 6 Literal split
case "StringLiteral":
case "Literal":
if (typeof n.value !== "string")
return fromString(n.value, options);
if (n.shorthand) {
parts.push(path.call(print, "value"));
} else {
if (n.computed) {
parts.push("[", path.call(print, "key"), "]");
} else {
parts.push(printPropertyKey(path, print));
}
parts.push(": ", path.call(print, "value"));
}
return nodeStr(n.value, options);
case // Babel 6
"Directive":
return path.call(print, "value");
case // Babel 6
"DirectiveLiteral":
return fromString(nodeStr(n.value, options));
case "ModuleSpecifier":
if (n.local) {
throw new Error("The ESTree ModuleSpecifier type should be abstract");
}
return concat(parts);
case // Babel 6
"ClassMethod":
if (n.static) {
parts.push("static ");
}
// The Esprima ModuleSpecifier type is just a string-valued
// Literal identifying the imported-from module.
return fromString(nodeStr(n.value, options), options);
case "UnaryExpression":
parts.push(n.operator);
parts = parts.concat(printObjectMethod(path, options, print));
if (/[a-z]$/.test(n.operator))
parts.push(" ");
return concat(parts);
case // Babel 6
"ObjectMethod":
return printObjectMethod(path, options, print);
case "Decorator":
return concat([ "@", path.call(print, "expression") ]);
case "ArrayExpression":
case "ArrayPattern":
if (n.elements.length === 0) {
parts.push("[]");
} else {
parts.push(
multilineGroup(
concat([
"[",
indent(
options.tabWidth,
concat([
options.bracketSpacing ? line : softline,
join(concat([ ",", line ]), path.map(print, "elements"))
])
),
ifBreak(options.trailingComma ? "," : ""),
options.bracketSpacing ? line : softline,
"]"
])
)
);
}
parts.push(path.call(print, "argument"));
if (n.typeAnnotation)
parts.push(path.call(print, "typeAnnotation"));
return concat(parts);
case "UpdateExpression":
parts.push(path.call(print, "argument"), n.operator);
return concat(parts);
case "SequenceExpression":
return join(", ", path.map(print, "expressions"));
case "ThisExpression":
return fromString("this");
case "Super":
return fromString("super");
case // Babel 6 Literal split
"NullLiteral":
return fromString("null");
case // Babel 6 Literal split
"RegExpLiteral":
return fromString(n.extra.raw);
// Babel 6 Literal split
case "BooleanLiteral":
// Babel 6 Literal split
case "NumericLiteral":
// Babel 6 Literal split
case "StringLiteral":
case "Literal":
if (typeof n.value !== "string")
return fromString(n.value, options);
if (n.prefix)
parts.reverse();
return nodeStr(n.value, options);
case // Babel 6
"Directive":
return path.call(print, "value");
case // Babel 6
"DirectiveLiteral":
return fromString(nodeStr(n.value, options));
case "ModuleSpecifier":
if (n.local) {
throw new Error("The ESTree ModuleSpecifier type should be abstract");
}
return concat(parts);
case "ConditionalExpression":
return group(
concat([
path.call(print, "test"),
indent(
options.tabWidth,
concat([
line,
"? ",
path.call(print, "consequent"),
line,
": ",
path.call(print, "alternate")
])
)
])
);
case "NewExpression":
parts.push("new ", path.call(print, "callee"));
// The Esprima ModuleSpecifier type is just a string-valued
// Literal identifying the imported-from module.
return fromString(nodeStr(n.value, options), options);
case "UnaryExpression":
parts.push(n.operator);
var args = n.arguments;
if (/[a-z]$/.test(n.operator))
parts.push(" ");
if (args) {
parts.push(printArgumentsList(path, options, print));
}
parts.push(path.call(print, "argument"));
return concat(parts);
case "VariableDeclaration":
var printed = path.map(
function(childPath) {
return print(childPath);
},
"declarations"
);
return concat(parts);
case "UpdateExpression":
parts.push(path.call(print, "argument"), n.operator);
parts = [
n.kind,
" ",
printed[0],
indent(
options.tabWidth,
concat(printed.slice(1).map(p => concat([ ",", line, p ])))
)
];
if (n.prefix)
parts.reverse();
// We generally want to terminate all variable declarations with a
// semicolon, except when they are children of for loops.
var parentNode = path.getParentNode();
if (
!namedTypes.ForStatement.check(parentNode) &&
!namedTypes.ForInStatement.check(parentNode) &&
!(namedTypes.ForOfStatement &&
namedTypes.ForOfStatement.check(parentNode)) &&
!(namedTypes.ForAwaitStatement &&
namedTypes.ForAwaitStatement.check(parentNode))
) {
parts.push(";");
}
return multilineGroup(concat(parts));
case "VariableDeclarator":
return n.init
? concat([ path.call(print, "id"), " = ", path.call(print, "init") ])
: path.call(print, "id");
case "WithStatement":
return concat([
"with (",
path.call(print, "object"),
") ",
path.call(print, "body")
]);
case "IfStatement":
const con = adjustClause(path.call(print, "consequent"), options);
parts = [
"if (",
group(
return concat(parts);
case "ConditionalExpression":
return group(
concat([
path.call(print, "test"),
indent(
options.tabWidth,
concat([ softline, path.call(print, "test") ])
),
softline
concat([
line,
"? ",
path.call(print, "consequent"),
line,
": ",
path.call(print, "alternate")
])
)
])
),
")",
con
];
);
case "NewExpression":
parts.push("new ", path.call(print, "callee"));
if (n.alternate) {
const hasBraces = isCurlyBracket(con);
const isEmpty = isEmptyBlock(con);
var args = n.arguments;
if (hasBraces && !isEmpty) {
parts.push(" else");
} else {
parts.push(concat([ hardline, "else" ]));
if (args) {
parts.push(printArgumentsList(path, options, print));
}
parts.push(
adjustClause(
path.call(print, "alternate"),
options,
n.alternate.type === "IfStatement"
)
return concat(parts);
case "VariableDeclaration":
var printed = path.map(
function(childPath) {
return print(childPath);
},
"declarations"
);
}
return group(concat(parts));
case "ForStatement":
// TODO Get the for (;;) case right.
return concat([
"for (",
group(
concat([
indent(
options.tabWidth,
concat([
softline,
path.call(print, "init"),
";",
line,
path.call(print, "test"),
";",
line,
path.call(print, "update")
])
),
softline
])
),
")",
adjustClause(path.call(print, "body"), options)
]);
case "WhileStatement":
return concat([
"while (",
path.call(print, "test"),
")",
adjustClause(path.call(print, "body"), options)
]);
case "ForInStatement":
// Note: esprima can't actually parse "for each (".
return concat([
n.each ? "for each (" : "for (",
path.call(print, "left"),
" in ",
path.call(print, "right"),
")",
adjustClause(path.call(print, "body"), options)
]);
case "ForOfStatement":
return concat([
"for (",
path.call(print, "left"),
" of ",
path.call(print, "right"),
")",
adjustClause(path.call(print, "body"), options)
]);
case "ForAwaitStatement":
return concat([
"for await (",
path.call(print, "left"),
" of ",
path.call(print, "right"),
")",
adjustClause(path.call(print, "body"), options)
]);
case "DoWhileStatement":
var clause = adjustClause(path.call(print, "body"), options);
var doBody = concat([ "do", clause ]);
var parts = [ doBody ];
const hasBraces = isCurlyBracket(clause);
parts = [
n.kind,
" ",
printed[(0)],
indent(
options.tabWidth,
concat(printed.slice(1).map(p => concat([ ",", line, p ])))
)
];
if (hasBraces)
parts.push(" while");
else
parts.push(concat([ line, "while" ]));
// We generally want to terminate all variable declarations with a
// semicolon, except when they are children of for loops.
var parentNode = path.getParentNode();
parts.push(" (", path.call(print, "test"), ");");
if (
!namedTypes.ForStatement.check(parentNode) &&
!namedTypes.ForInStatement.check(parentNode) &&
!(namedTypes.ForOfStatement &&
namedTypes.ForOfStatement.check(parentNode)) &&
!(namedTypes.ForAwaitStatement &&
namedTypes.ForAwaitStatement.check(parentNode))
) {
parts.push(";");
}
return concat(parts);
case "DoExpression":
var statements = path.call(
function(bodyPath) {
return printStatementSequence(bodyPath, options, print);
},
"body"
);
return concat([ "do {\n", statements.indent(options.tabWidth), "\n}" ]);
case "BreakStatement":
parts.push("break");
return multilineGroup(concat(parts));
case "VariableDeclarator":
return n.init
? concat([ path.call(print, "id"), " = ", path.call(print, "init") ])
: path.call(print, "id");
case "WithStatement":
return concat([
"with (",
path.call(print, "object"),
") ",
path.call(print, "body")
]);
case "IfStatement":
const con = adjustClause(path.call(print, "consequent"), options);
if (n.label)
parts.push(" ", path.call(print, "label"));
parts = [
"if (",
group(
concat([
indent(
options.tabWidth,
concat([ softline, path.call(print, "test") ])
),
softline
])
),
")",
con
];
parts.push(";");
if (n.alternate) {
const hasBraces = isCurlyBracket(con);
const isEmpty = isEmptyBlock(con);
return concat(parts);
case "ContinueStatement":
parts.push("continue");
if (hasBraces && !isEmpty) {
parts.push(" else");
} else {
parts.push(concat([ hardline, "else" ]));
}
if (n.label)
parts.push(" ", path.call(print, "label"));
parts.push(
adjustClause(
path.call(print, "alternate"),
options,
n.alternate.type === "IfStatement"
)
);
}
parts.push(";");
return group(concat(parts));
case "ForStatement": {
const body = adjustClause(path.call(print, "body"), options);
return concat(parts);
case "LabeledStatement":
return concat([
path.call(print, "label"),
":",
hardline,
path.call(print, "body")
]);
case "TryStatement":
parts.push("try ", path.call(print, "block"));
if (!n.init && !n.test && !n.update) {
return concat([ "for (;;)", body ]);
}
if (n.handler) {
parts.push(" ", path.call(print, "handler"));
} else if (n.handlers) {
path.each(
function(handlerPath) {
parts.push(" ", print(handlerPath));
return concat([
"for (",
group(
concat([
indent(
options.tabWidth,
concat([
softline,
path.call(print, "init"),
";",
line,
path.call(print, "test"),
";",
line,
path.call(print, "update")
])
),
softline
])
),
")",
body
]);
}
case "WhileStatement":
return concat([
"while (",
path.call(print, "test"),
")",
adjustClause(path.call(print, "body"), options)
]);
case "ForInStatement":
// Note: esprima can't actually parse "for each (".
return concat([
n.each ? "for each (" : "for (",
path.call(print, "left"),
" in ",
path.call(print, "right"),
")",
adjustClause(path.call(print, "body"), options)
]);
case "ForOfStatement":
return concat([
"for (",
path.call(print, "left"),
" of ",
path.call(print, "right"),
")",
adjustClause(path.call(print, "body"), options)
]);
case "ForAwaitStatement":
return concat([
"for await (",
path.call(print, "left"),
" of ",
path.call(print, "right"),
")",
adjustClause(path.call(print, "body"), options)
]);
case "DoWhileStatement":
var clause = adjustClause(path.call(print, "body"), options);
var doBody = concat([ "do", clause ]);
var parts = [ doBody ];
const hasBraces = isCurlyBracket(clause);
if (hasBraces)
parts.push(" while");
else
parts.push(concat([ line, "while" ]));
parts.push(" (", path.call(print, "test"), ");");
return concat(parts);
case "DoExpression":
var statements = path.call(
function(bodyPath) {
return printStatementSequence(bodyPath, options, print);
},
"handlers"
"body"
);
}
return concat([ "do {\n", statements.indent(options.tabWidth), "\n}" ]);
case "BreakStatement":
parts.push("break");
if (n.finalizer) {
parts.push(" finally ", path.call(print, "finalizer"));
}
if (n.label)
parts.push(" ", path.call(print, "label"));
return concat(parts);
case "CatchClause":
parts.push("catch (", path.call(print, "param"));
parts.push(";");
if (n.guard)
// Note: esprima does not recognize conditional catch clauses.
parts.push(" if ", path.call(print, "guard"));
return concat(parts);
case "ContinueStatement":
parts.push("continue");
parts.push(") ", path.call(print, "body"));
if (n.label)
parts.push(" ", path.call(print, "label"));
return concat(parts);
case "ThrowStatement":
return concat([ "throw ", path.call(print, "argument"), ";" ]);
// Note: ignoring n.lexical because it has no printing consequences.
case "SwitchStatement":
return concat([
"switch (",
path.call(print, "discriminant"),
") {",
indent(
options.tabWidth,
concat([ hardline, join(hardline, path.map(print, "cases"))])
),
hardline,
"}"
]);
case "SwitchCase":
if (n.test)
parts.push("case ", path.call(print, "test"), ":");
else
parts.push("default:");
parts.push(";");
if (n.consequent.length > 0) {
const cons = path.call(
function(consequentPath) {
return printStatementSequence(consequentPath, options, print);
},
"consequent"
);
return concat(parts);
case "LabeledStatement":
return concat([
path.call(print, "label"),
":",
hardline,
path.call(print, "body")
]);
case "TryStatement":
parts.push("try ", path.call(print, "block"));
parts.push(
isCurlyBracket(cons)
? concat([ " ", cons ])
: indent(options.tabWidth, concat([ hardline, cons ]))
);
}
if (n.handler) {
parts.push(" ", path.call(print, "handler"));
} else if (n.handlers) {
path.each(
function(handlerPath) {
parts.push(" ", print(handlerPath));
},
"handlers"
);
}
return concat(parts);
// JSX extensions below.
case "DebuggerStatement":
return fromString("debugger;");
case "JSXAttribute":
parts.push(path.call(print, "name"));
if (n.finalizer) {
parts.push(" finally ", path.call(print, "finalizer"));
}
if (n.value)
parts.push("=", path.call(print, "value"));
return concat(parts);
case "CatchClause":
parts.push("catch (", path.call(print, "param"));
return concat(parts);
case "JSXIdentifier":
return fromString(n.name, options);
case "JSXNamespacedName":
return join(":", [ path.call(print, "namespace"), path.call(print, "name") ]);
case "JSXMemberExpression":
return join(".", [ path.call(print, "object"), path.call(print, "property") ]);
case "JSXSpreadAttribute":
return concat([ "{...", path.call(print, "argument"), "}" ]);
case "JSXExpressionContainer":
return group(concat([
"{",
indent(options.tabWidth,
concat([softline, path.call(print, "expression")])),
softline,
"}"
]));
case "JSXElement":
var openingLines = path.call(print, "openingElement");
if (n.guard)
// Note: esprima does not recognize conditional catch clauses.
parts.push(" if ", path.call(print, "guard"));
if (n.openingElement.selfClosing) {
assert.ok(!n.closingElement);
parts.push(") ", path.call(print, "body"));
return openingLines;
}
return concat(parts);
case "ThrowStatement":
return concat([ "throw ", path.call(print, "argument"), ";" ]);
// Note: ignoring n.lexical because it has no printing consequences.
case "SwitchStatement":
return concat([
"switch (",
path.call(print, "discriminant"),
") {",
indent(
options.tabWidth,
concat([ hardline, join(hardline, path.map(print, "cases")) ])
),
hardline,
"}"
]);
case "SwitchCase":
if (n.test)
parts.push("case ", path.call(print, "test"), ":");
else
parts.push("default:");
var children = [];
if (n.consequent.length > 0) {
const cons = path.call(
function(consequentPath) {
return printStatementSequence(consequentPath, options, print);
},
"consequent"
);
path.map(
function(childPath) {
var child = childPath.getValue();
parts.push(
isCurlyBracket(cons)
? concat([ " ", cons ])
: indent(options.tabWidth, concat([ hardline, cons ]))
);
}
return concat(parts);
// JSX extensions below.
case "DebuggerStatement":
return fromString("debugger;");
case "JSXAttribute":
parts.push(path.call(print, "name"));
if (n.value) {
let res;
if (
namedTypes.Literal.check(child) && typeof child.value === "string"
(n.value.type === "StringLiteral" || n.value.type === "Literal") &&
typeof n.value.value === "string"
) {
if (/\S/.test(child.value)) {
const beginBreak = child.value.match(/^\s*\n/);
const endBreak = child.value.match(/\n\s*$/);
children.push(
beginBreak ? hardline : "",
child.value.replace(/^\s+|\s+$/g, ""),
endBreak ? hardline : ""
);
} else if (/\n/.test(child.value)) {
children.push(hardline);
}
res = '"' + util.htmlEscapeInsideDoubleQuote(n.value.value) + '"';
} else {
children.push(print(childPath));
res = path.call(print, "value");
}
},
"children"
);
parts.push("=", res);
}
var mostChildren = children.slice(0, -1);
var closingLines = path.call(print, "closingElement");
return concat([
openingLines,
indent(options.tabWidth, concat(mostChildren)),
util.getLast(children) || "",
closingLines
]);
case "JSXOpeningElement":
return group(
concat([
"<",
path.call(print, "name"),
concat(path.map(attr => concat([" ", print(attr)]), "attributes")),
n.selfClosing ? " />" : ">"
])
);
case "JSXClosingElement":
return concat([ "</", path.call(print, "name"), ">" ]);
case "JSXText":
throw new Error("JSXTest should be handled by JSXElement");
case "JSXEmptyExpression":
return "";
case "TypeAnnotatedIdentifier":
return concat([
path.call(print, "annotation"),
" ",
path.call(print, "identifier")
]);
case "ClassBody":
if (n.body.length === 0) {
return fromString("{}");
}
return concat([
"{",
indent(
options.tabWidth,
return concat(parts);
case "JSXIdentifier":
return fromString(n.name, options);
case "JSXNamespacedName":
return join(":", [
path.call(print, "namespace"),
path.call(print, "name")
]);
case "JSXMemberExpression":
return join(".", [
path.call(print, "object"),
path.call(print, "property")
]);
case "JSXSpreadAttribute":
return concat([ "{...", path.call(print, "argument"), "}" ]);
case "JSXExpressionContainer":
return group(
concat([
hardline,
path.call(
function(bodyPath) {
return printStatementSequence(bodyPath, options, print);
},
"body"
)
"{",
indent(
options.tabWidth,
concat([ softline, path.call(print, "expression") ])
),
softline,
"}"
])
),
hardline,
"}"
]);
case "ClassPropertyDefinition":
parts.push("static ", path.call(print, "definition"));
);
case "JSXElement":
return printJSXElement(path, options, print);
case "JSXOpeningElement":
return group(
concat([
"<",
path.call(print, "name"),
multilineGroup(
concat([
indent(
options.tabWidth,
concat(
path.map(attr => concat([ line, print(attr) ]), "attributes")
)
),
n.selfClosing ? line : softline
])
),
n.selfClosing ? "/>" : ">"
])
);
case "JSXClosingElement":
return concat([ "</", path.call(print, "name"), ">" ]);
case "JSXText":
throw new Error("JSXTest should be handled by JSXElement");
case "JSXEmptyExpression":
return "";
case "TypeAnnotatedIdentifier":
return concat([
path.call(print, "annotation"),
" ",
path.call(print, "identifier")
]);
case "ClassBody":
if (n.body.length === 0) {
return fromString("{}");
}
if (!namedTypes.MethodDefinition.check(n.definition))
parts.push(";");
return concat([
"{",
indent(
options.tabWidth,
concat([
hardline,
path.call(
function(bodyPath) {
return printStatementSequence(bodyPath, options, print);
},
"body"
)
])
),
hardline,
"}"
]);
case "ClassPropertyDefinition":
parts.push("static ", path.call(print, "definition"));
return concat(parts);
case "ClassProperty":
if (n.static)
parts.push("static ");
if (!namedTypes.MethodDefinition.check(n.definition))
parts.push(";");
var key = path.call(print, "key");
return concat(parts);
case "ClassProperty":
if (n.static)
parts.push("static ");
if (n.computed) {
key = concat([ "[", key, "]" ]);
} else if (n.variance === "plus") {
key = concat([ "+", key ]);
} else if (n.variance === "minus") {
key = concat([ "-", key ]);
}
var key;
parts.push(key);
if (n.computed) {
key = concat([ "[", path.call(print, "key"), "]" ]);
} else {
key = printPropertyKey(path, print);
if (n.variance === "plus") {
key = concat([ "+", key ]);
} else if (n.variance === "minus") {
key = concat([ "-", key ]);
}
}
if (n.typeAnnotation)
parts.push(path.call(print, "typeAnnotation"));
parts.push(key);
if (n.value)
parts.push(" = ", path.call(print, "value"));
if (n.typeAnnotation)
parts.push(path.call(print, "typeAnnotation"));
parts.push(";");
if (n.value)
parts.push(" = ", path.call(print, "value"));
return concat(parts);
case "ClassDeclaration":
case "ClassExpression":
return concat(printClass(path, print));
case "TemplateElement":
return join(literalline, n.value.raw.split("\n"));
case "TemplateLiteral":
var expressions = path.map(print, "expressions");
parts.push(";");
parts.push("`");
return concat(parts);
case "ClassDeclaration":
case "ClassExpression":
return concat(printClass(path, print));
case "TemplateElement":
return join(literalline, n.value.raw.split("\n"));
case "TemplateLiteral":
var expressions = path.map(print, "expressions");
path.each(
function(childPath) {
var i = childPath.getName();
parts.push("`");
parts.push(print(childPath));
path.each(
function(childPath) {
var i = childPath.getName();
if (i < expressions.length) {
parts.push("${", expressions[i], "}");
parts.push(print(childPath));
if (i < expressions.length) {
parts.push("${", expressions[i], "}");
}
},
"quasis"
);
parts.push("`");
return concat(parts);
// These types are unprintable because they serve as abstract
// supertypes for other (printable) types.
case "TaggedTemplateExpression":
return concat([ path.call(print, "tag"), path.call(print, "quasi") ]);
case "Node":
case "Printable":
case "SourceLocation":
case "Position":
case "Statement":
case "Function":
case "Pattern":
case "Expression":
case "Declaration":
case "Specifier":
case "NamedSpecifier":
// Supertype of Block and Line.
case "Comment":
// Flow
case "MemberTypeAnnotation":
case // Flow
"Type":
throw new Error("unprintable type: " + JSON.stringify(n.type));
// Babel block comment.
case "CommentBlock":
case // Esprima block comment.
"Block":
return concat([ "/*", n.value, "*/" ]);
// Babel line comment.
case "CommentLine":
case // Esprima line comment.
"Line":
return concat([ "//", n.value ]);
// Type Annotations for Facebook Flow, typically stripped out or
// transformed away before printing.
case "TypeAnnotation":
if (n.typeAnnotation) {
if (n.typeAnnotation.type !== "FunctionTypeAnnotation") {
parts.push(": ");
}
},
"quasis"
);
parts.push("`");
parts.push(path.call(print, "typeAnnotation"));
return concat(parts);
// These types are unprintable because they serve as abstract
// supertypes for other (printable) types.
case "TaggedTemplateExpression":
return concat([ path.call(print, "tag"), path.call(print, "quasi") ]);
case "Node":
case "Printable":
case "SourceLocation":
case "Position":
case "Statement":
case "Function":
case "Pattern":
case "Expression":
case "Declaration":
case "Specifier":
case "NamedSpecifier":
// Supertype of Block and Line.
case "Comment":
// Flow
case "MemberTypeAnnotation":
case // Flow
"Type":
throw new Error("unprintable type: " + JSON.stringify(n.type));
// Babel block comment.
case "CommentBlock":
case // Esprima block comment.
"Block":
return concat([ "/*", n.value, "*/" ]);
// Babel line comment.
case "CommentLine":
case // Esprima line comment.
"Line":
return concat([ "//", n.value ]);
// Type Annotations for Facebook Flow, typically stripped out or
// transformed away before printing.
case "TypeAnnotation":
if (n.typeAnnotation) {
if (n.typeAnnotation.type !== "FunctionTypeAnnotation") {
parts.push(": ");
return concat(parts);
}
parts.push(path.call(print, "typeAnnotation"));
return "";
case "TupleTypeAnnotation":
return concat([ "[", join(", ", path.map(print, "types")), "]" ]);
case "ExistentialTypeParam":
case "ExistsTypeAnnotation":
return fromString("*", options);
case "EmptyTypeAnnotation":
return fromString("empty", options);
case "AnyTypeAnnotation":
return fromString("any", options);
case "MixedTypeAnnotation":
return fromString("mixed", options);
case "ArrayTypeAnnotation":
return concat([ path.call(print, "elementType"), "[]" ]);
case "BooleanTypeAnnotation":
return fromString("boolean", options);
case "NumericLiteralTypeAnnotation":
case "BooleanLiteralTypeAnnotation":
return "" + n.value;
case "DeclareClass":
return printFlowDeclaration(path, printClass(path, print));
case "DeclareFunction":
return printFlowDeclaration(path, [
"function ",
path.call(print, "id"),
n.predicate ? " " : "",
path.call(print, "predicate"),
";"
]);
case "DeclareModule":
return printFlowDeclaration(path, [
"module ",
path.call(print, "id"),
" ",
path.call(print, "body")
]);
case "DeclareModuleExports":
return printFlowDeclaration(path, [
"module.exports",
path.call(print, "typeAnnotation"),
";"
]);
case "DeclareVariable":
return printFlowDeclaration(path, [
"var ",
path.call(print, "id"),
";"
]);
case "DeclareExportAllDeclaration":
return concat([ "declare export * from ", path.call(print, "source") ]);
case "DeclareExportDeclaration":
return concat([
"declare ",
printExportDeclaration(path, options, print)
]);
case "FunctionTypeAnnotation":
// FunctionTypeAnnotation is ambiguous:
// declare function foo(a: B): void; OR
// var A: (a: B) => void;
var parent = path.getParentNode(0);
var isArrowFunctionTypeAnnotation = !(!parent.variance &&
!parent.optional &&
namedTypes.ObjectTypeProperty.check(parent) ||
namedTypes.ObjectTypeCallProperty.check(parent) ||
namedTypes.DeclareFunction.check(path.getParentNode(2)));
var needsColon = isArrowFunctionTypeAnnotation &&
namedTypes.TypeAnnotation.check(parent);
return concat(parts);
}
if (needsColon) {
parts.push(": ");
}
return "";
case "TupleTypeAnnotation":
return concat([ "[", join(", ", path.map(print, "types")), "]" ]);
case "ExistentialTypeParam":
case "ExistsTypeAnnotation":
return fromString("*", options);
case "EmptyTypeAnnotation":
return fromString("empty", options);
case "AnyTypeAnnotation":
return fromString("any", options);
case "MixedTypeAnnotation":
return fromString("mixed", options);
case "ArrayTypeAnnotation":
return concat([ path.call(print, "elementType"), "[]" ]);
case "BooleanTypeAnnotation":
return fromString("boolean", options);
case "NumericLiteralTypeAnnotation":
case "BooleanLiteralTypeAnnotation":
return "" + n.value;
case "DeclareClass":
return printFlowDeclaration(path, printClass(path, print));
case "DeclareFunction":
return printFlowDeclaration(path, [
"function ",
path.call(print, "id"),
n.predicate ? " " : "",
path.call(print, "predicate"),
";"
]);
case "DeclareModule":
return printFlowDeclaration(path, [
"module ",
path.call(print, "id"),
" ",
path.call(print, "body")
]);
case "DeclareModuleExports":
return printFlowDeclaration(path, [
"module.exports",
path.call(print, "typeAnnotation"),
";"
]);
case "DeclareVariable":
return printFlowDeclaration(path, [ "var ", path.call(print, "id"), ";" ]);
case "DeclareExportAllDeclaration":
return concat([ "declare export * from ", path.call(print, "source") ]);
case "DeclareExportDeclaration":
return concat([ "declare ", printExportDeclaration(path, options, print) ]);
case "FunctionTypeAnnotation":
// FunctionTypeAnnotation is ambiguous:
// declare function foo(a: B): void; OR
// var A: (a: B) => void;
var parent = path.getParentNode(0);
var isArrowFunctionTypeAnnotation = !(!parent.variance &&
!parent.optional &&
namedTypes.ObjectTypeProperty.check(parent) ||
namedTypes.ObjectTypeCallProperty.check(parent) ||
namedTypes.DeclareFunction.check(path.getParentNode(2)));
var needsColon = isArrowFunctionTypeAnnotation &&
namedTypes.TypeAnnotation.check(parent);
parts.push(path.call(print, "typeParameters"));
if (needsColon) {
parts.push(": ");
}
parts.push(multilineGroup(printFunctionParams(path, print, options)));
parts.push(path.call(print, "typeParameters"));
// The returnType is not wrapped in a TypeAnnotation, so the colon
// needs to be added separately.
if (n.returnType || n.predicate) {
parts.push(
isArrowFunctionTypeAnnotation ? " => " : ": ",
path.call(print, "returnType"),
path.call(print, "predicate")
);
}
parts.push(multilineGroup(printFunctionParams(path, print, options)));
return concat(parts);
case "FunctionTypeParam":
return concat([
path.call(print, "name"),
n.optional ? "?" : "",
n.name ? ": " : "",
path.call(print, "typeAnnotation")
]);
case "GenericTypeAnnotation":
return concat([
path.call(print, "id"),
path.call(print, "typeParameters")
]);
case "DeclareInterface":
parts.push("declare ");
// The returnType is not wrapped in a TypeAnnotation, so the colon
// needs to be added separately.
if (n.returnType || n.predicate) {
case "InterfaceDeclaration":
parts.push(
isArrowFunctionTypeAnnotation ? " => " : ": ",
path.call(print, "returnType"),
path.call(print, "predicate")
fromString("interface ", options),
path.call(print, "id"),
path.call(print, "typeParameters"),
" "
);
}
return concat(parts);
case "FunctionTypeParam":
return concat([
path.call(print, "name"),
n.optional ? "?" : "",
n.name ? ": " : "",
path.call(print, "typeAnnotation")
]);
case "GenericTypeAnnotation":
return concat([
path.call(print, "id"),
path.call(print, "typeParameters")
]);
case "DeclareInterface":
parts.push("declare ");
if (n["extends"].length > 0) {
parts.push("extends ", join(", ", path.map(print, "extends")));
}
case "InterfaceDeclaration":
parts.push(
fromString("interface ", options),
path.call(print, "id"),
path.call(print, "typeParameters"),
" "
);
parts.push(" ", path.call(print, "body"));
if (n["extends"].length > 0) {
parts.push("extends ", join(", ", path.map(print, "extends")));
}
parts.push(" ", path.call(print, "body"));
return concat(parts);
case "ClassImplements":
case "InterfaceExtends":
return concat([
path.call(print, "id"),
path.call(print, "typeParameters")
]);
case "IntersectionTypeAnnotation":
case "UnionTypeAnnotation": {
return concat(parts);
case "ClassImplements":
case "InterfaceExtends":
return concat([
path.call(print, "id"),
path.call(print, "typeParameters")
]);
case "IntersectionTypeAnnotation":
case "UnionTypeAnnotation": {
const types = path.map(print, "types");
const op = n.type === "IntersectionTypeAnnotation" ? "&" : "|";
return conditionalGroup(
[
// single-line variation
// A | B | C
concat([
indent(
options.tabWidth,
concat([
types[0],
indent(
options.tabWidth,
concat(types.slice(1).map(t => concat([ " ", op, line, t ])))
)
])
)
]),
// multi-line variation
// | A
// | B
// | C
concat([
indent(
options.tabWidth,
concat(types.map(t => concat([ line, op, " ", t ])))
)
])
]
);
return conditionalGroup([
// single-line variation
// A | B | C
concat([
indent(
options.tabWidth,
concat([
types[(0)],
indent(
options.tabWidth,
concat(types.slice(1).map(t => concat([ " ", op, line, t ])))
)
])
)
]),
// multi-line variation
// | A
// | B
// | C
concat([
indent(
options.tabWidth,
concat(types.map(t => concat([ line, op, " ", t ])))
)
])
]);
}
case "NullableTypeAnnotation":
return concat([ "?", path.call(print, "typeAnnotation") ]);
case "NullLiteralTypeAnnotation":
return fromString("null", options);
case "ThisTypeAnnotation":
return fromString("this", options);
case "NumberTypeAnnotation":
return fromString("number", options);
case "ObjectTypeCallProperty":
if (n.static) {
parts.push("static ");
}
case "NullableTypeAnnotation":
return concat([ "?", path.call(print, "typeAnnotation") ]);
case "NullLiteralTypeAnnotation":
return fromString("null", options);
case "ThisTypeAnnotation":
return fromString("this", options);
case "NumberTypeAnnotation":
return fromString("number", options);
case "ObjectTypeCallProperty":
if (n.static) {
parts.push("static ");
}
parts.push(path.call(print, "value"));
parts.push(path.call(print, "value"));
return concat(parts);
case "ObjectTypeIndexer":
var variance = n.variance === "plus"
? "+"
: n.variance === "minus" ? "-" : "";
return concat([
variance,
"[",
path.call(print, "id"),
n.id ? ": " : "",
path.call(print, "key"),
"]: ",
path.call(print, "value")
]);
case "ObjectTypeProperty":
var variance = n.variance === "plus"
? "+"
: n.variance === "minus" ? "-" : "";
// TODO: This is a bad hack and we need a better way to know
// when to emit an arrow function or not.
var isFunction = !n.variance && !n.optional &&
n.value.type === "FunctionTypeAnnotation";
return concat([
n.static ? "static " : "",
variance,
path.call(print, "key"),
n.optional ? "?" : "",
isFunction ? "" : ": ",
path.call(print, "value")
]);
case "QualifiedTypeIdentifier":
return concat([
path.call(print, "qualification"),
".",
path.call(print, "id")
]);
case "StringLiteralTypeAnnotation":
return fromString(nodeStr(n.value, options), options);
case "NumberLiteralTypeAnnotation":
assert.strictEqual(typeof n.value, "number");
return concat(parts);
case "ObjectTypeIndexer":
var variance = n.variance === "plus"
? "+"
: n.variance === "minus" ? "-" : "";
return concat([
variance,
"[",
path.call(print, "id"),
n.id ? ": " : "",
path.call(print, "key"),
"]: ",
path.call(print, "value")
]);
case "ObjectTypeProperty":
var variance = n.variance === "plus"
? "+"
: n.variance === "minus" ? "-" : "";
// TODO: This is a bad hack and we need a better way to know
// when to emit an arrow function or not.
var isFunction = !n.variance && !n.optional &&
n.value.type === "FunctionTypeAnnotation";
return concat([
n.static ? "static " : "",
variance,
path.call(print, "key"),
n.optional ? "?" : "",
isFunction ? "" : ": ",
path.call(print, "value")
]);
case "QualifiedTypeIdentifier":
return concat([
path.call(print, "qualification"),
".",
path.call(print, "id")
]);
case "StringLiteralTypeAnnotation":
return fromString(nodeStr(n.value, options), options);
case "NumberLiteralTypeAnnotation":
assert.strictEqual(typeof n.value, "number");
return fromString("" + n.value, options);
case "StringTypeAnnotation":
return fromString("string", options);
case "DeclareTypeAlias":
case "TypeAlias": {
return fromString("" + n.value, options);
case "StringTypeAnnotation":
return fromString("string", options);
case "DeclareTypeAlias":
case "TypeAlias": {
const parent = path.getParentNode(1);

@@ -1490,93 +1516,93 @@

}
case "TypeCastExpression":
return concat([
"(",
path.call(print, "expression"),
path.call(print, "typeAnnotation"),
")"
]);
case "TypeParameterDeclaration":
case "TypeParameterInstantiation":
return concat([ "<", join(", ", path.map(print, "params")), ">" ]);
case "TypeParameter":
switch (n.variance) {
case "plus":
parts.push("+");
case "TypeCastExpression":
return concat([
"(",
path.call(print, "expression"),
path.call(print, "typeAnnotation"),
")"
]);
case "TypeParameterDeclaration":
case "TypeParameterInstantiation":
return concat([ "<", join(", ", path.map(print, "params")), ">" ]);
case "TypeParameter":
switch (n.variance) {
case "plus":
parts.push("+");
break;
case "minus":
parts.push("-");
break;
case "minus":
parts.push("-");
break;
default:
}
break;
default:
}
parts.push(path.call(print, "name"));
parts.push(path.call(print, "name"));
if (n.bound) {
parts.push(path.call(print, "bound"));
}
if (n.bound) {
parts.push(path.call(print, "bound"));
}
if (n["default"]) {
parts.push("=", path.call(print, "default"));
}
if (n["default"]) {
parts.push("=", path.call(print, "default"));
}
return concat(parts);
case "TypeofTypeAnnotation":
return concat([
fromString("typeof ", options),
path.call(print, "argument")
]);
case "VoidTypeAnnotation":
return "void";
case "NullTypeAnnotation":
return "null";
case "InferredPredicate":
return "%checks";
// Unhandled types below. If encountered, nodes of these types should
// be either left alone or desugared into AST types that are fully
// supported by the pretty-printer.
case "DeclaredPredicate":
return concat([ "%checks(", path.call(print, "value"), ")" ]);
// 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 "GraphIndexExpression":
case "XMLDefaultDeclaration":
case "XMLAnyName":
case "XMLQualifiedIdentifier":
case "XMLFunctionQualifiedIdentifier":
case "XMLAttributeSelector":
case "XMLFilterExpression":
case "XML":
case "XMLElement":
case "XMLList":
case "XMLEscape":
case "XMLText":
case "XMLStartTag":
case "XMLEndTag":
case "XMLPointTag":
case "XMLName":
case "XMLAttribute":
case "XMLCdata":
case "XMLComment":
case "XMLProcessingInstruction":
default:
debugger;
throw new Error("unknown type: " + JSON.stringify(n.type));
return concat(parts);
case "TypeofTypeAnnotation":
return concat([
fromString("typeof ", options),
path.call(print, "argument")
]);
case "VoidTypeAnnotation":
return "void";
case "NullTypeAnnotation":
return "null";
case "InferredPredicate":
return "%checks";
// Unhandled types below. If encountered, nodes of these types should
// be either left alone or desugared into AST types that are fully
// supported by the pretty-printer.
case "DeclaredPredicate":
return concat([ "%checks(", path.call(print, "value"), ")" ]);
// 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 "GraphIndexExpression":
case "XMLDefaultDeclaration":
case "XMLAnyName":
case "XMLQualifiedIdentifier":
case "XMLFunctionQualifiedIdentifier":
case "XMLAttributeSelector":
case "XMLFilterExpression":
case "XML":
case "XMLElement":
case "XMLList":
case "XMLEscape":
case "XMLText":
case "XMLStartTag":
case "XMLEndTag":
case "XMLPointTag":
case "XMLName":
case "XMLAttribute":
case "XMLCdata":
case "XMLComment":
case "XMLProcessingInstruction":
default:
debugger;
throw new Error("unknown type: " + JSON.stringify(n.type));
}

@@ -1610,4 +1636,6 @@ return p;

if (util.newlineExistsAfter(text, util.locEnd(stmt)) &&
!isLastStatement(stmtPath)) {
if (
util.newlineExistsAfter(text, util.locEnd(stmt)) &&
!isLastStatement(stmtPath)
) {
parts.push(hardline);

@@ -1622,2 +1650,11 @@ }

function printPropertyKey(path, print) {
var node = path.getNode().key;
if (node.type === "StringLiteral" && isIdentifierName(node.value)) {
// 'a' -> a
return node.value;
}
return path.call(print, "key");
}
function printMethod(path, options, print) {

@@ -1648,3 +1685,3 @@ var node = path.getNode();

var key = path.call(print, "key");
var key = printPropertyKey(path, print);

@@ -1658,11 +1695,13 @@ if (node.computed) {

path.call(print, "value", "typeParameters"),
multilineGroup(concat([
path.call(
function(valuePath) {
return printFunctionParams(valuePath, print, options);
},
"value"
),
path.call(p => printReturnType(p, print), "value")
])),
multilineGroup(
concat([
path.call(
function(valuePath) {
return printFunctionParams(valuePath, print, options);
},
"value"
),
path.call(p => printReturnType(p, print), "value")
])
),
" ",

@@ -1690,5 +1729,5 @@ path.call(print, "value", "body")

lastArg.type === "FunctionExpression" ||
(lastArg.type === "ArrowFunctionExpression" &&
(lastArg.body.type === "BlockStatement" ||
lastArg.body.type === "ArrowFunctionExpression")) ||
lastArg.type === "ArrowFunctionExpression" &&
(lastArg.body.type === "BlockStatement" ||
lastArg.body.type === "ArrowFunctionExpression") ||
lastArg.type === "NewExpression";

@@ -1705,3 +1744,3 @@

printed.length > 1 ? ", " : "",
group(util.getLast(printed), {shouldBreak: true}),
group(util.getLast(printed), { shouldBreak: true }),
")"

@@ -1720,6 +1759,6 @@ ]),

]),
{shouldBreak: true}
{ shouldBreak: true }
)
],
{shouldBreak}
{ shouldBreak }
);

@@ -1793,3 +1832,3 @@ }

var key = path.call(print, "key");
var key = printPropertyKey(path, print);

@@ -1802,7 +1841,13 @@ if (objMethod.computed) {

if (objMethod.typeParameters) {
parts.push(path.call(print, "typeParameters"));
}
parts.push(
multilineGroup(concat([
printFunctionParams(path, print, options),
printReturnType(path, print)
])),
multilineGroup(
concat([
printFunctionParams(path, print, options),
printReturnType(path, print)
])
),
" ",

@@ -1842,3 +1887,6 @@ path.call(print, "body")

if (decl.type === "ExportDefaultDeclaration" && decl.declaration.type == "Identifier") {
if (
decl.type === "ExportDefaultDeclaration" &&
decl.declaration.type == "Identifier"
) {
parts.push(";");

@@ -1849,3 +1897,3 @@ }

decl.specifiers.length === 1 &&
decl.specifiers[0].type === "ExportBatchSpecifier"
decl.specifiers[(0)].type === "ExportBatchSpecifier"
) {

@@ -1856,5 +1904,20 @@ parts.push("*");

decl.exportKind === "type" ? "type " : "",
shouldPrintSpaces ? "{ " : "{",
join(", ", path.map(print, "specifiers")),
shouldPrintSpaces ? " }" : "}"
group(
concat([
"{",
indent(
options.tabWidth,
concat([
options.bracketSpacing ? line : softline,
join(
concat([ ",", options.bracketSpacing ? line : softline ]),
path.map(print, "specifiers")
)
])
),
ifBreak(options.trailingComma ? "," : ""),
options.bracketSpacing ? line : softline,
"}"
])
)
);

@@ -1867,3 +1930,3 @@ }

parts.push(';');
parts.push(";");
}

@@ -1908,6 +1971,3 @@

if (n["implements"] && n["implements"].length > 0) {
parts.push(
" implements ",
join(", ", path.map(print, "implements"))
);
parts.push(" implements ", join(", ", path.map(print, "implements")));
}

@@ -1951,3 +2011,3 @@

curr.callee.type === "MemberExpression") {
nodes.push({property: curr.callee.property, call: curr});
nodes.push({ member: curr.callee, call: curr });
curr = curr.callee.object;

@@ -1965,3 +2025,3 @@ }

if (call.arguments.length > 0) {
const type = call.arguments[0].type;
const type = call.arguments[(0)].type;
return type === "FunctionExpression" ||

@@ -1979,6 +2039,9 @@ type === "ArrowFunctionExpression" ||

const currPrinted = print(FastPath.from(curr));
const nodesPrinted = nodes.map(node => ({
property: print(FastPath.from(node.property)),
args: printArgumentsList(FastPath.from(node.call), options, print)
}));
const nodesPrinted = nodes.map(
node =>
({
property: printMemberLookup(FastPath.from(node.member), print),
args: printArgumentsList(FastPath.from(node.call), options, print)
})
);
const fullyExpanded = concat([

@@ -1990,3 +2053,3 @@ currPrinted,

options.tabWidth,
concat([ hardline, ".", node.property, node.args ])
concat([ hardline, node.property, node.args ])
);

@@ -2013,3 +2076,3 @@ })

nodesPrinted.map(node => {
return concat([ ".", node.property, node.args ]);
return concat([ node.property, node.args ]);
})

@@ -2024,2 +2087,80 @@ )

function printJSXElement(path, options, print) {
const n = path.getValue();
var openingLines = path.call(print, "openingElement");
let elem;
if (n.openingElement.selfClosing) {
assert.ok(!n.closingElement);
elem = openingLines;
} else {
var children = [];
path.map(
function(childPath) {
var child = childPath.getValue();
if (
namedTypes.Literal.check(child) && typeof child.value === "string"
) {
if (/\S/.test(child.value)) {
const beginBreak = child.value.match(/^\s*\n/);
const endBreak = child.value.match(/\n\s*$/);
children.push(
beginBreak ? hardline : "",
child.value.replace(/^\s+|\s+$/g, endBreak ? "" : " "),
endBreak ? hardline : ""
);
} else if (/\n/.test(child.value)) {
children.push(hardline);
}
} else {
children.push(print(childPath));
}
},
"children"
);
var mostChildren = children.slice(0, -1);
var closingLines = path.call(print, "closingElement");
const firstChild = children[(0)];
const lastChild = util.getLast(children);
const beginBreak = firstChild && firstChild.type === "line";
const endBreak = lastChild && lastChild.type === "line";
elem = multilineGroup(
concat([
openingLines,
indent(
options.tabWidth,
concat([ beginBreak ? "" : softline ].concat(mostChildren))
),
lastChild || "",
endBreak ? "" : softline,
closingLines
])
);
}
const parent = path.getParentNode();
if (
!parent || parent.type === "JSXElement" ||
parent.type === "ExpressionStatement"
) {
return elem;
}
return multilineGroup(
concat([
ifBreak("("),
indent(options.tabWidth, concat([ softline, elem ])),
softline,
ifBreak(")")
])
);
}
function adjustClause(clause, options, forceSpace) {

@@ -2055,3 +2196,3 @@ if (isCurlyBracket(clause) || forceSpace) {

return str.replace(/['"]/g, function(m) {
return m === "\"" ? "'" : "\"";
return m === '"' ? "'" : '"';
});

@@ -2063,3 +2204,14 @@ }

if (options.singleQuote) {
const containsSingleQuote = str.indexOf("'") !== -1;
const containsDoubleQuote = str.indexOf('"') !== -1;
let shouldUseSingleQuote = options.singleQuote;
if (options.singleQuote && containsSingleQuote && !containsDoubleQuote) {
shouldUseSingleQuote = false;
}
if (!options.singleQuote && !containsSingleQuote && containsDoubleQuote) {
shouldUseSingleQuote = true;
}
if (shouldUseSingleQuote) {
return swapQuotes(JSON.stringify(swapQuotes(str)));

@@ -2075,3 +2227,3 @@ } else {

const body = parent.body;
return body && body[0] === node;
return body && body[(0)] === node;
}

@@ -2078,0 +2230,0 @@

@@ -27,3 +27,3 @@ "use strict";

function comparePos(pos1, pos2) {
return (pos1.line - pos2.line) || (pos1.column - pos2.column);
return pos1.line - pos2.line || pos1.column - pos2.column;
}

@@ -33,6 +33,3 @@ util.comparePos = comparePos;

function copyPos(pos) {
return {
line: pos.line,
column: pos.column
};
return { line: pos.line, column: pos.column };
}

@@ -103,7 +100,6 @@ util.copyPos = copyPos;

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);

@@ -116,8 +112,10 @@ });

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)) {

@@ -134,3 +132,3 @@ // FunctionExpression method values should be anonymous,

if ((end = skipSpaces(text, end - 1, true)) !== false) {
setLocEnd(node, end)
setLocEnd(node, end);
}

@@ -154,3 +152,3 @@ }

assert.ok(afterLeftBackTickPos < text.length);
var firstQuasi = node.quasis[0];
var firstQuasi = node.quasis[(0)];
if (locStart(firstQuasi) - afterLeftBackTickPos < 0) {

@@ -172,3 +170,3 @@ setLocStart(firstQuasi, afterLeftBackTickPos);

// 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

@@ -180,6 +178,7 @@ // precedes the expression. The position of the $ should be the

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];

@@ -205,12 +204,13 @@ if (dollarCurlyPos - locEnd(quasiBefore) < 0) {

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;
}

@@ -220,6 +220,7 @@ 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;

@@ -240,11 +241,11 @@ }

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

@@ -267,11 +268,11 @@ // by scanning up/back to the next non-indentation character.

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

@@ -292,4 +293,4 @@ // by scanning up/back to the next non-indentation character.

function locStart(node) {
if(node.range) {
return node.range[0];
if (node.range) {
return node.range[(0)];
}

@@ -301,4 +302,4 @@ return node.start;

function locEnd(node) {
if(node.range) {
return node.range[1];
if (node.range) {
return node.range[(1)];
}

@@ -310,6 +311,5 @@ return node.end;

function setLocStart(node, index) {
if(node.range) {
node.range[0] = index;
}
else {
if (node.range) {
node.range[(0)] = index;
} else {
node.start = index;

@@ -321,6 +321,5 @@ }

function setLocEnd(node, index) {
if(node.range) {
node.range[1] = index;
}
else {
if (node.range) {
node.range[(1)] = index;
} else {
node.end = index;

@@ -330,1 +329,12 @@ }

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;');
}
util.htmlEscapeInsideDoubleQuote = htmlEscapeInsideDoubleQuote;

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc