You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2262 lines
87 KiB

4 years ago
  1. "use strict";
  2. var __importDefault = (this && this.__importDefault) || function (mod) {
  3. return (mod && mod.__esModule) ? mod : { "default": mod };
  4. };
  5. var __importStar = (this && this.__importStar) || function (mod) {
  6. if (mod && mod.__esModule) return mod;
  7. var result = {};
  8. if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
  9. result["default"] = mod;
  10. return result;
  11. };
  12. Object.defineProperty(exports, "__esModule", { value: true });
  13. var assert_1 = __importDefault(require("assert"));
  14. var comments_1 = require("./comments");
  15. var lines_1 = require("./lines");
  16. var options_1 = require("./options");
  17. var patcher_1 = require("./patcher");
  18. var types = __importStar(require("ast-types"));
  19. var namedTypes = types.namedTypes;
  20. var isString = types.builtInTypes.string;
  21. var isObject = types.builtInTypes.object;
  22. var fast_path_1 = __importDefault(require("./fast-path"));
  23. var util = __importStar(require("./util"));
  24. var PrintResult = function PrintResult(code, sourceMap) {
  25. assert_1.default.ok(this instanceof PrintResult);
  26. isString.assert(code);
  27. this.code = code;
  28. if (sourceMap) {
  29. isObject.assert(sourceMap);
  30. this.map = sourceMap;
  31. }
  32. };
  33. var PRp = PrintResult.prototype;
  34. var warnedAboutToString = false;
  35. PRp.toString = function () {
  36. if (!warnedAboutToString) {
  37. console.warn("Deprecation warning: recast.print now returns an object with " +
  38. "a .code property. You appear to be treating the object as a " +
  39. "string, which might still work but is strongly discouraged.");
  40. warnedAboutToString = true;
  41. }
  42. return this.code;
  43. };
  44. var emptyPrintResult = new PrintResult("");
  45. var Printer = function Printer(config) {
  46. assert_1.default.ok(this instanceof Printer);
  47. var explicitTabWidth = config && config.tabWidth;
  48. config = options_1.normalize(config);
  49. // It's common for client code to pass the same options into both
  50. // recast.parse and recast.print, but the Printer doesn't need (and
  51. // can be confused by) config.sourceFileName, so we null it out.
  52. config.sourceFileName = null;
  53. // Non-destructively modifies options with overrides, and returns a
  54. // new print function that uses the modified options.
  55. function makePrintFunctionWith(options, overrides) {
  56. options = Object.assign({}, options, overrides);
  57. return function (path) {
  58. return print(path, options);
  59. };
  60. }
  61. function print(path, options) {
  62. assert_1.default.ok(path instanceof fast_path_1.default);
  63. options = options || {};
  64. if (options.includeComments) {
  65. return comments_1.printComments(path, makePrintFunctionWith(options, {
  66. includeComments: false
  67. }));
  68. }
  69. var oldTabWidth = config.tabWidth;
  70. if (!explicitTabWidth) {
  71. var loc = path.getNode().loc;
  72. if (loc && loc.lines && loc.lines.guessTabWidth) {
  73. config.tabWidth = loc.lines.guessTabWidth();
  74. }
  75. }
  76. var reprinter = patcher_1.getReprinter(path);
  77. var lines = reprinter
  78. // Since the print function that we pass to the reprinter will
  79. // be used to print "new" nodes, it's tempting to think we
  80. // should pass printRootGenerically instead of print, to avoid
  81. // calling maybeReprint again, but that would be a mistake
  82. // because the new nodes might not be entirely new, but merely
  83. // moved from elsewhere in the AST. The print function is the
  84. // right choice because it gives us the opportunity to reprint
  85. // such nodes using their original source.
  86. ? reprinter(print)
  87. : genericPrint(path, config, options, makePrintFunctionWith(options, {
  88. includeComments: true,
  89. avoidRootParens: false
  90. }));
  91. config.tabWidth = oldTabWidth;
  92. return lines;
  93. }
  94. this.print = function (ast) {
  95. if (!ast) {
  96. return emptyPrintResult;
  97. }
  98. var lines = print(fast_path_1.default.from(ast), {
  99. includeComments: true,
  100. avoidRootParens: false
  101. });
  102. return new PrintResult(lines.toString(config), util.composeSourceMaps(config.inputSourceMap, lines.getSourceMap(config.sourceMapName, config.sourceRoot)));
  103. };
  104. this.printGenerically = function (ast) {
  105. if (!ast) {
  106. return emptyPrintResult;
  107. }
  108. // Print the entire AST generically.
  109. function printGenerically(path) {
  110. return comments_1.printComments(path, function (path) {
  111. return genericPrint(path, config, {
  112. includeComments: true,
  113. avoidRootParens: false
  114. }, printGenerically);
  115. });
  116. }
  117. var path = fast_path_1.default.from(ast);
  118. var oldReuseWhitespace = config.reuseWhitespace;
  119. // Do not reuse whitespace (or anything else, for that matter)
  120. // when printing generically.
  121. config.reuseWhitespace = false;
  122. // TODO Allow printing of comments?
  123. var pr = new PrintResult(printGenerically(path).toString(config));
  124. config.reuseWhitespace = oldReuseWhitespace;
  125. return pr;
  126. };
  127. };
  128. exports.Printer = Printer;
  129. function genericPrint(path, config, options, printPath) {
  130. assert_1.default.ok(path instanceof fast_path_1.default);
  131. var node = path.getValue();
  132. var parts = [];
  133. var linesWithoutParens = genericPrintNoParens(path, config, printPath);
  134. if (!node || linesWithoutParens.isEmpty()) {
  135. return linesWithoutParens;
  136. }
  137. var shouldAddParens = false;
  138. var decoratorsLines = printDecorators(path, printPath);
  139. if (decoratorsLines.isEmpty()) {
  140. // Nodes with decorators can't have parentheses, so we can avoid
  141. // computing path.needsParens() except in this case.
  142. if (!options.avoidRootParens) {
  143. shouldAddParens = path.needsParens();
  144. }
  145. }
  146. else {
  147. parts.push(decoratorsLines);
  148. }
  149. if (shouldAddParens) {
  150. parts.unshift("(");
  151. }
  152. parts.push(linesWithoutParens);
  153. if (shouldAddParens) {
  154. parts.push(")");
  155. }
  156. return lines_1.concat(parts);
  157. }
  158. // Note that the `options` parameter of this function is what other
  159. // functions in this file call the `config` object (that is, the
  160. // configuration object originally passed into the Printer constructor).
  161. // Its properties are documented in lib/options.js.
  162. function genericPrintNoParens(path, options, print) {
  163. var n = path.getValue();
  164. if (!n) {
  165. return lines_1.fromString("");
  166. }
  167. if (typeof n === "string") {
  168. return lines_1.fromString(n, options);
  169. }
  170. namedTypes.Printable.assert(n);
  171. var parts = [];
  172. switch (n.type) {
  173. case "File":
  174. return path.call(print, "program");
  175. case "Program":
  176. // Babel 6
  177. if (n.directives) {
  178. path.each(function (childPath) {
  179. parts.push(print(childPath), ";\n");
  180. }, "directives");
  181. }
  182. if (n.interpreter) {
  183. parts.push(path.call(print, "interpreter"));
  184. }
  185. parts.push(path.call(function (bodyPath) {
  186. return printStatementSequence(bodyPath, options, print);
  187. }, "body"));
  188. return lines_1.concat(parts);
  189. case "Noop": // Babel extension.
  190. case "EmptyStatement":
  191. return lines_1.fromString("");
  192. case "ExpressionStatement":
  193. return lines_1.concat([path.call(print, "expression"), ";"]);
  194. case "ParenthesizedExpression": // Babel extension.
  195. return lines_1.concat(["(", path.call(print, "expression"), ")"]);
  196. case "BinaryExpression":
  197. case "LogicalExpression":
  198. case "AssignmentExpression":
  199. return lines_1.fromString(" ").join([
  200. path.call(print, "left"),
  201. n.operator,
  202. path.call(print, "right")
  203. ]);
  204. case "AssignmentPattern":
  205. return lines_1.concat([
  206. path.call(print, "left"),
  207. " = ",
  208. path.call(print, "right")
  209. ]);
  210. case "MemberExpression":
  211. case "OptionalMemberExpression":
  212. parts.push(path.call(print, "object"));
  213. var property = path.call(print, "property");
  214. var optional = n.type === "OptionalMemberExpression" && n.optional;
  215. if (n.computed) {
  216. parts.push(optional ? "?.[" : "[", property, "]");
  217. }
  218. else {
  219. parts.push(optional ? "?." : ".", property);
  220. }
  221. return lines_1.concat(parts);
  222. case "MetaProperty":
  223. return lines_1.concat([
  224. path.call(print, "meta"),
  225. ".",
  226. path.call(print, "property")
  227. ]);
  228. case "BindExpression":
  229. if (n.object) {
  230. parts.push(path.call(print, "object"));
  231. }
  232. parts.push("::", path.call(print, "callee"));
  233. return lines_1.concat(parts);
  234. case "Path":
  235. return lines_1.fromString(".").join(n.body);
  236. case "Identifier":
  237. return lines_1.concat([
  238. lines_1.fromString(n.name, options),
  239. n.optional ? "?" : "",
  240. path.call(print, "typeAnnotation")
  241. ]);
  242. case "SpreadElement":
  243. case "SpreadElementPattern":
  244. case "RestProperty": // Babel 6 for ObjectPattern
  245. case "SpreadProperty":
  246. case "SpreadPropertyPattern":
  247. case "ObjectTypeSpreadProperty":
  248. case "RestElement":
  249. return lines_1.concat([
  250. "...",
  251. path.call(print, "argument"),
  252. path.call(print, "typeAnnotation")
  253. ]);
  254. case "FunctionDeclaration":
  255. case "FunctionExpression":
  256. case "TSDeclareFunction":
  257. if (n.declare) {
  258. parts.push("declare ");
  259. }
  260. if (n.async) {
  261. parts.push("async ");
  262. }
  263. parts.push("function");
  264. if (n.generator)
  265. parts.push("*");
  266. if (n.id) {
  267. parts.push(" ", path.call(print, "id"), path.call(print, "typeParameters"));
  268. }
  269. else {
  270. if (n.typeParameters) {
  271. parts.push(path.call(print, "typeParameters"));
  272. }
  273. }
  274. parts.push("(", printFunctionParams(path, options, print), ")", path.call(print, "returnType"));
  275. if (n.body) {
  276. parts.push(" ", path.call(print, "body"));
  277. }
  278. return lines_1.concat(parts);
  279. case "ArrowFunctionExpression":
  280. if (n.async) {
  281. parts.push("async ");
  282. }
  283. if (n.typeParameters) {
  284. parts.push(path.call(print, "typeParameters"));
  285. }
  286. if (!options.arrowParensAlways &&
  287. n.params.length === 1 &&
  288. !n.rest &&
  289. n.params[0].type === 'Identifier' &&
  290. !n.params[0].typeAnnotation &&
  291. !n.returnType) {
  292. parts.push(path.call(print, "params", 0));
  293. }
  294. else {
  295. parts.push("(", printFunctionParams(path, options, print), ")", path.call(print, "returnType"));
  296. }
  297. parts.push(" => ", path.call(print, "body"));
  298. return lines_1.concat(parts);
  299. case "MethodDefinition":
  300. return printMethod(path, options, print);
  301. case "YieldExpression":
  302. parts.push("yield");
  303. if (n.delegate)
  304. parts.push("*");
  305. if (n.argument)
  306. parts.push(" ", path.call(print, "argument"));
  307. return lines_1.concat(parts);
  308. case "AwaitExpression":
  309. parts.push("await");
  310. if (n.all)
  311. parts.push("*");
  312. if (n.argument)
  313. parts.push(" ", path.call(print, "argument"));
  314. return lines_1.concat(parts);
  315. case "ModuleDeclaration":
  316. parts.push("module", path.call(print, "id"));
  317. if (n.source) {
  318. assert_1.default.ok(!n.body);
  319. parts.push("from", path.call(print, "source"));
  320. }
  321. else {
  322. parts.push(path.call(print, "body"));
  323. }
  324. return lines_1.fromString(" ").join(parts);
  325. case "ImportSpecifier":
  326. if (n.importKind && n.importKind !== "value") {
  327. parts.push(n.importKind + " ");
  328. }
  329. if (n.imported) {
  330. parts.push(path.call(print, "imported"));
  331. if (n.local &&
  332. n.local.name !== n.imported.name) {
  333. parts.push(" as ", path.call(print, "local"));
  334. }
  335. }
  336. else if (n.id) {
  337. parts.push(path.call(print, "id"));
  338. if (n.name) {
  339. parts.push(" as ", path.call(print, "name"));
  340. }
  341. }
  342. return lines_1.concat(parts);
  343. case "ExportSpecifier":
  344. if (n.local) {
  345. parts.push(path.call(print, "local"));
  346. if (n.exported &&
  347. n.exported.name !== n.local.name) {
  348. parts.push(" as ", path.call(print, "exported"));
  349. }
  350. }
  351. else if (n.id) {
  352. parts.push(path.call(print, "id"));
  353. if (n.name) {
  354. parts.push(" as ", path.call(print, "name"));
  355. }
  356. }
  357. return lines_1.concat(parts);
  358. case "ExportBatchSpecifier":
  359. return lines_1.fromString("*");
  360. case "ImportNamespaceSpecifier":
  361. parts.push("* as ");
  362. if (n.local) {
  363. parts.push(path.call(print, "local"));
  364. }
  365. else if (n.id) {
  366. parts.push(path.call(print, "id"));
  367. }
  368. return lines_1.concat(parts);
  369. case "ImportDefaultSpecifier":
  370. if (n.local) {
  371. return path.call(print, "local");
  372. }
  373. return path.call(print, "id");
  374. case "TSExportAssignment":
  375. return lines_1.concat(["export = ", path.call(print, "expression")]);
  376. case "ExportDeclaration":
  377. case "ExportDefaultDeclaration":
  378. case "ExportNamedDeclaration":
  379. return printExportDeclaration(path, options, print);
  380. case "ExportAllDeclaration":
  381. parts.push("export *");
  382. if (n.exported) {
  383. parts.push(" as ", path.call(print, "exported"));
  384. }
  385. parts.push(" from ", path.call(print, "source"), ";");
  386. return lines_1.concat(parts);
  387. case "TSNamespaceExportDeclaration":
  388. parts.push("export as namespace ", path.call(print, "id"));
  389. return maybeAddSemicolon(lines_1.concat(parts));
  390. case "ExportNamespaceSpecifier":
  391. return lines_1.concat(["* as ", path.call(print, "exported")]);
  392. case "ExportDefaultSpecifier":
  393. return path.call(print, "exported");
  394. case "Import":
  395. return lines_1.fromString("import", options);
  396. case "ImportDeclaration": {
  397. parts.push("import ");
  398. if (n.importKind && n.importKind !== "value") {
  399. parts.push(n.importKind + " ");
  400. }
  401. if (n.specifiers &&
  402. n.specifiers.length > 0) {
  403. var unbracedSpecifiers_1 = [];
  404. var bracedSpecifiers_1 = [];
  405. path.each(function (specifierPath) {
  406. var spec = specifierPath.getValue();
  407. if (spec.type === "ImportSpecifier") {
  408. bracedSpecifiers_1.push(print(specifierPath));
  409. }
  410. else if (spec.type === "ImportDefaultSpecifier" ||
  411. spec.type === "ImportNamespaceSpecifier") {
  412. unbracedSpecifiers_1.push(print(specifierPath));
  413. }
  414. }, "specifiers");
  415. unbracedSpecifiers_1.forEach(function (lines, i) {
  416. if (i > 0) {
  417. parts.push(", ");
  418. }
  419. parts.push(lines);
  420. });
  421. if (bracedSpecifiers_1.length > 0) {
  422. var lines_2 = lines_1.fromString(", ").join(bracedSpecifiers_1);
  423. if (lines_2.getLineLength(1) > options.wrapColumn) {
  424. lines_2 = lines_1.concat([
  425. lines_1.fromString(",\n").join(bracedSpecifiers_1).indent(options.tabWidth),
  426. ","
  427. ]);
  428. }
  429. if (unbracedSpecifiers_1.length > 0) {
  430. parts.push(", ");
  431. }
  432. if (lines_2.length > 1) {
  433. parts.push("{\n", lines_2, "\n}");
  434. }
  435. else if (options.objectCurlySpacing) {
  436. parts.push("{ ", lines_2, " }");
  437. }
  438. else {
  439. parts.push("{", lines_2, "}");
  440. }
  441. }
  442. parts.push(" from ");
  443. }
  444. parts.push(path.call(print, "source"), ";");
  445. return lines_1.concat(parts);
  446. }
  447. case "BlockStatement":
  448. var naked = path.call(function (bodyPath) {
  449. return printStatementSequence(bodyPath, options, print);
  450. }, "body");
  451. if (naked.isEmpty()) {
  452. if (!n.directives || n.directives.length === 0) {
  453. return lines_1.fromString("{}");
  454. }
  455. }
  456. parts.push("{\n");
  457. // Babel 6
  458. if (n.directives) {
  459. path.each(function (childPath) {
  460. parts.push(maybeAddSemicolon(print(childPath).indent(options.tabWidth)), n.directives.length > 1 || !naked.isEmpty() ? "\n" : "");
  461. }, "directives");
  462. }
  463. parts.push(naked.indent(options.tabWidth));
  464. parts.push("\n}");
  465. return lines_1.concat(parts);
  466. case "ReturnStatement":
  467. parts.push("return");
  468. if (n.argument) {
  469. var argLines = path.call(print, "argument");
  470. if (argLines.startsWithComment() ||
  471. (argLines.length > 1 &&
  472. namedTypes.JSXElement &&
  473. namedTypes.JSXElement.check(n.argument))) {
  474. parts.push(" (\n", argLines.indent(options.tabWidth), "\n)");
  475. }
  476. else {
  477. parts.push(" ", argLines);
  478. }
  479. }
  480. parts.push(";");
  481. return lines_1.concat(parts);
  482. case "CallExpression":
  483. case "OptionalCallExpression":
  484. parts.push(path.call(print, "callee"));
  485. if (n.typeParameters) {
  486. parts.push(path.call(print, "typeParameters"));
  487. }
  488. if (n.typeArguments) {
  489. parts.push(path.call(print, "typeArguments"));
  490. }
  491. if (n.type === "OptionalCallExpression" &&
  492. n.callee.type !== "OptionalMemberExpression") {
  493. parts.push("?.");
  494. }
  495. parts.push(printArgumentsList(path, options, print));
  496. return lines_1.concat(parts);
  497. case "ObjectExpression":
  498. case "ObjectPattern":
  499. case "ObjectTypeAnnotation":
  500. var allowBreak = false;
  501. var isTypeAnnotation = n.type === "ObjectTypeAnnotation";
  502. var separator = options.flowObjectCommas ? "," : (isTypeAnnotation ? ";" : ",");
  503. var fields = [];
  504. if (isTypeAnnotation) {
  505. fields.push("indexers", "callProperties");
  506. if (n.internalSlots != null) {
  507. fields.push("internalSlots");
  508. }
  509. }
  510. fields.push("properties");
  511. var len = 0;
  512. fields.forEach(function (field) {
  513. len += n[field].length;
  514. });
  515. var oneLine = (isTypeAnnotation && len === 1) || len === 0;
  516. var leftBrace = n.exact ? "{|" : "{";
  517. var rightBrace = n.exact ? "|}" : "}";
  518. parts.push(oneLine ? leftBrace : leftBrace + "\n");
  519. var leftBraceIndex = parts.length - 1;
  520. var i = 0;
  521. fields.forEach(function (field) {
  522. path.each(function (childPath) {
  523. var lines = print(childPath);
  524. if (!oneLine) {
  525. lines = lines.indent(options.tabWidth);
  526. }
  527. var multiLine = !isTypeAnnotation && lines.length > 1;
  528. if (multiLine && allowBreak) {
  529. // Similar to the logic for BlockStatement.
  530. parts.push("\n");
  531. }
  532. parts.push(lines);
  533. if (i < len - 1) {
  534. // Add an extra line break if the previous object property
  535. // had a multi-line value.
  536. parts.push(separator + (multiLine ? "\n\n" : "\n"));
  537. allowBreak = !multiLine;
  538. }
  539. else if (len !== 1 && isTypeAnnotation) {
  540. parts.push(separator);
  541. }
  542. else if (!oneLine && util.isTrailingCommaEnabled(options, "objects")) {
  543. parts.push(separator);
  544. }
  545. i++;
  546. }, field);
  547. });
  548. if (n.inexact) {
  549. var line = lines_1.fromString("...", options);
  550. if (oneLine) {
  551. if (len > 0) {
  552. parts.push(separator, " ");
  553. }
  554. parts.push(line);
  555. }
  556. else {
  557. // No trailing separator after ... to maintain parity with prettier.
  558. parts.push("\n", line.indent(options.tabWidth));
  559. }
  560. }
  561. parts.push(oneLine ? rightBrace : "\n" + rightBrace);
  562. if (i !== 0 && oneLine && options.objectCurlySpacing) {
  563. parts[leftBraceIndex] = leftBrace + " ";
  564. parts[parts.length - 1] = " " + rightBrace;
  565. }
  566. if (n.typeAnnotation) {
  567. parts.push(path.call(print, "typeAnnotation"));
  568. }
  569. return lines_1.concat(parts);
  570. case "PropertyPattern":
  571. return lines_1.concat([
  572. path.call(print, "key"),
  573. ": ",
  574. path.call(print, "pattern")
  575. ]);
  576. case "ObjectProperty": // Babel 6
  577. case "Property": // Non-standard AST node type.
  578. if (n.method || n.kind === "get" || n.kind === "set") {
  579. return printMethod(path, options, print);
  580. }
  581. if (n.shorthand && n.value.type === "AssignmentPattern") {
  582. return path.call(print, "value");
  583. }
  584. var key = path.call(print, "key");
  585. if (n.computed) {
  586. parts.push("[", key, "]");
  587. }
  588. else {
  589. parts.push(key);
  590. }
  591. if (!n.shorthand) {
  592. parts.push(": ", path.call(print, "value"));
  593. }
  594. return lines_1.concat(parts);
  595. case "ClassMethod": // Babel 6
  596. case "ObjectMethod": // Babel 6
  597. case "ClassPrivateMethod":
  598. case "TSDeclareMethod":
  599. return printMethod(path, options, print);
  600. case "PrivateName":
  601. return lines_1.concat(["#", path.call(print, "id")]);
  602. case "Decorator":
  603. return lines_1.concat(["@", path.call(print, "expression")]);
  604. case "ArrayExpression":
  605. case "ArrayPattern":
  606. var elems = n.elements, len = elems.length;
  607. var printed = path.map(print, "elements");
  608. var joined = lines_1.fromString(", ").join(printed);
  609. var oneLine = joined.getLineLength(1) <= options.wrapColumn;
  610. if (oneLine) {
  611. if (options.arrayBracketSpacing) {
  612. parts.push("[ ");
  613. }
  614. else {
  615. parts.push("[");
  616. }
  617. }
  618. else {
  619. parts.push("[\n");
  620. }
  621. path.each(function (elemPath) {
  622. var i = elemPath.getName();
  623. var elem = elemPath.getValue();
  624. if (!elem) {
  625. // If the array expression ends with a hole, that hole
  626. // will be ignored by the interpreter, but if it ends with
  627. // two (or more) holes, we need to write out two (or more)
  628. // commas so that the resulting code is interpreted with
  629. // both (all) of the holes.
  630. parts.push(",");
  631. }
  632. else {
  633. var lines = printed[i];
  634. if (oneLine) {
  635. if (i > 0)
  636. parts.push(" ");
  637. }
  638. else {
  639. lines = lines.indent(options.tabWidth);
  640. }
  641. parts.push(lines);
  642. if (i < len - 1 || (!oneLine && util.isTrailingCommaEnabled(options, "arrays")))
  643. parts.push(",");
  644. if (!oneLine)
  645. parts.push("\n");
  646. }
  647. }, "elements");
  648. if (oneLine && options.arrayBracketSpacing) {
  649. parts.push(" ]");
  650. }
  651. else {
  652. parts.push("]");
  653. }
  654. if (n.typeAnnotation) {
  655. parts.push(path.call(print, "typeAnnotation"));
  656. }
  657. return lines_1.concat(parts);
  658. case "SequenceExpression":
  659. return lines_1.fromString(", ").join(path.map(print, "expressions"));
  660. case "ThisExpression":
  661. return lines_1.fromString("this");
  662. case "Super":
  663. return lines_1.fromString("super");
  664. case "NullLiteral": // Babel 6 Literal split
  665. return lines_1.fromString("null");
  666. case "RegExpLiteral": // Babel 6 Literal split
  667. return lines_1.fromString(n.extra.raw);
  668. case "BigIntLiteral": // Babel 7 Literal split
  669. return lines_1.fromString(n.value + "n");
  670. case "NumericLiteral": // Babel 6 Literal Split
  671. // Keep original representation for numeric values not in base 10.
  672. if (n.extra &&
  673. typeof n.extra.raw === "string" &&
  674. Number(n.extra.raw) === n.value) {
  675. return lines_1.fromString(n.extra.raw, options);
  676. }
  677. return lines_1.fromString(n.value, options);
  678. case "BooleanLiteral": // Babel 6 Literal split
  679. case "StringLiteral": // Babel 6 Literal split
  680. case "Literal":
  681. // Numeric values may be in bases other than 10. Use their raw
  682. // representation if equivalent.
  683. if (typeof n.value === "number" &&
  684. typeof n.raw === "string" &&
  685. Number(n.raw) === n.value) {
  686. return lines_1.fromString(n.raw, options);
  687. }
  688. if (typeof n.value !== "string") {
  689. return lines_1.fromString(n.value, options);
  690. }
  691. return lines_1.fromString(nodeStr(n.value, options), options);
  692. case "Directive": // Babel 6
  693. return path.call(print, "value");
  694. case "DirectiveLiteral": // Babel 6
  695. return lines_1.fromString(nodeStr(n.value, options));
  696. case "InterpreterDirective":
  697. return lines_1.fromString("#!" + n.value + "\n", options);
  698. case "ModuleSpecifier":
  699. if (n.local) {
  700. throw new Error("The ESTree ModuleSpecifier type should be abstract");
  701. }
  702. // The Esprima ModuleSpecifier type is just a string-valued
  703. // Literal identifying the imported-from module.
  704. return lines_1.fromString(nodeStr(n.value, options), options);
  705. case "UnaryExpression":
  706. parts.push(n.operator);
  707. if (/[a-z]$/.test(n.operator))
  708. parts.push(" ");
  709. parts.push(path.call(print, "argument"));
  710. return lines_1.concat(parts);
  711. case "UpdateExpression":
  712. parts.push(path.call(print, "argument"), n.operator);
  713. if (n.prefix)
  714. parts.reverse();
  715. return lines_1.concat(parts);
  716. case "ConditionalExpression":
  717. return lines_1.concat([
  718. path.call(print, "test"),
  719. " ? ", path.call(print, "consequent"),
  720. " : ", path.call(print, "alternate")
  721. ]);
  722. case "NewExpression":
  723. parts.push("new ", path.call(print, "callee"));
  724. if (n.typeParameters) {
  725. parts.push(path.call(print, "typeParameters"));
  726. }
  727. if (n.typeArguments) {
  728. parts.push(path.call(print, "typeArguments"));
  729. }
  730. var args = n.arguments;
  731. if (args) {
  732. parts.push(printArgumentsList(path, options, print));
  733. }
  734. return lines_1.concat(parts);
  735. case "VariableDeclaration":
  736. if (n.declare) {
  737. parts.push("declare ");
  738. }
  739. parts.push(n.kind, " ");
  740. var maxLen = 0;
  741. var printed = path.map(function (childPath) {
  742. var lines = print(childPath);
  743. maxLen = Math.max(lines.length, maxLen);
  744. return lines;
  745. }, "declarations");
  746. if (maxLen === 1) {
  747. parts.push(lines_1.fromString(", ").join(printed));
  748. }
  749. else if (printed.length > 1) {
  750. parts.push(lines_1.fromString(",\n").join(printed)
  751. .indentTail(n.kind.length + 1));
  752. }
  753. else {
  754. parts.push(printed[0]);
  755. }
  756. // We generally want to terminate all variable declarations with a
  757. // semicolon, except when they are children of for loops.
  758. var parentNode = path.getParentNode();
  759. if (!namedTypes.ForStatement.check(parentNode) &&
  760. !namedTypes.ForInStatement.check(parentNode) &&
  761. !(namedTypes.ForOfStatement &&
  762. namedTypes.ForOfStatement.check(parentNode)) &&
  763. !(namedTypes.ForAwaitStatement &&
  764. namedTypes.ForAwaitStatement.check(parentNode))) {
  765. parts.push(";");
  766. }
  767. return lines_1.concat(parts);
  768. case "VariableDeclarator":
  769. return n.init ? lines_1.fromString(" = ").join([
  770. path.call(print, "id"),
  771. path.call(print, "init")
  772. ]) : path.call(print, "id");
  773. case "WithStatement":
  774. return lines_1.concat([
  775. "with (",
  776. path.call(print, "object"),
  777. ") ",
  778. path.call(print, "body")
  779. ]);
  780. case "IfStatement":
  781. var con = adjustClause(path.call(print, "consequent"), options);
  782. parts.push("if (", path.call(print, "test"), ")", con);
  783. if (n.alternate)
  784. parts.push(endsWithBrace(con) ? " else" : "\nelse", adjustClause(path.call(print, "alternate"), options));
  785. return lines_1.concat(parts);
  786. case "ForStatement":
  787. // TODO Get the for (;;) case right.
  788. var init = path.call(print, "init"), sep = init.length > 1 ? ";\n" : "; ", forParen = "for (", indented = lines_1.fromString(sep).join([
  789. init,
  790. path.call(print, "test"),
  791. path.call(print, "update")
  792. ]).indentTail(forParen.length), head = lines_1.concat([forParen, indented, ")"]), clause = adjustClause(path.call(print, "body"), options);
  793. parts.push(head);
  794. if (head.length > 1) {
  795. parts.push("\n");
  796. clause = clause.trimLeft();
  797. }
  798. parts.push(clause);
  799. return lines_1.concat(parts);
  800. case "WhileStatement":
  801. return lines_1.concat([
  802. "while (",
  803. path.call(print, "test"),
  804. ")",
  805. adjustClause(path.call(print, "body"), options)
  806. ]);
  807. case "ForInStatement":
  808. // Note: esprima can't actually parse "for each (".
  809. return lines_1.concat([
  810. n.each ? "for each (" : "for (",
  811. path.call(print, "left"),
  812. " in ",
  813. path.call(print, "right"),
  814. ")",
  815. adjustClause(path.call(print, "body"), options)
  816. ]);
  817. case "ForOfStatement":
  818. case "ForAwaitStatement":
  819. parts.push("for ");
  820. if (n.await || n.type === "ForAwaitStatement") {
  821. parts.push("await ");
  822. }
  823. parts.push("(", path.call(print, "left"), " of ", path.call(print, "right"), ")", adjustClause(path.call(print, "body"), options));
  824. return lines_1.concat(parts);
  825. case "DoWhileStatement":
  826. var doBody = lines_1.concat([
  827. "do",
  828. adjustClause(path.call(print, "body"), options)
  829. ]);
  830. parts.push(doBody);
  831. if (endsWithBrace(doBody))
  832. parts.push(" while");
  833. else
  834. parts.push("\nwhile");
  835. parts.push(" (", path.call(print, "test"), ");");
  836. return lines_1.concat(parts);
  837. case "DoExpression":
  838. var statements = path.call(function (bodyPath) {
  839. return printStatementSequence(bodyPath, options, print);
  840. }, "body");
  841. return lines_1.concat([
  842. "do {\n",
  843. statements.indent(options.tabWidth),
  844. "\n}"
  845. ]);
  846. case "BreakStatement":
  847. parts.push("break");
  848. if (n.label)
  849. parts.push(" ", path.call(print, "label"));
  850. parts.push(";");
  851. return lines_1.concat(parts);
  852. case "ContinueStatement":
  853. parts.push("continue");
  854. if (n.label)
  855. parts.push(" ", path.call(print, "label"));
  856. parts.push(";");
  857. return lines_1.concat(parts);
  858. case "LabeledStatement":
  859. return lines_1.concat([
  860. path.call(print, "label"),
  861. ":\n",
  862. path.call(print, "body")
  863. ]);
  864. case "TryStatement":
  865. parts.push("try ", path.call(print, "block"));
  866. if (n.handler) {
  867. parts.push(" ", path.call(print, "handler"));
  868. }
  869. else if (n.handlers) {
  870. path.each(function (handlerPath) {
  871. parts.push(" ", print(handlerPath));
  872. }, "handlers");
  873. }
  874. if (n.finalizer) {
  875. parts.push(" finally ", path.call(print, "finalizer"));
  876. }
  877. return lines_1.concat(parts);
  878. case "CatchClause":
  879. parts.push("catch ");
  880. if (n.param) {
  881. parts.push("(", path.call(print, "param"));
  882. }
  883. if (n.guard) {
  884. // Note: esprima does not recognize conditional catch clauses.
  885. parts.push(" if ", path.call(print, "guard"));
  886. }
  887. if (n.param) {
  888. parts.push(") ");
  889. }
  890. parts.push(path.call(print, "body"));
  891. return lines_1.concat(parts);
  892. case "ThrowStatement":
  893. return lines_1.concat(["throw ", path.call(print, "argument"), ";"]);
  894. case "SwitchStatement":
  895. return lines_1.concat([
  896. "switch (",
  897. path.call(print, "discriminant"),
  898. ") {\n",
  899. lines_1.fromString("\n").join(path.map(print, "cases")),
  900. "\n}"
  901. ]);
  902. // Note: ignoring n.lexical because it has no printing consequences.
  903. case "SwitchCase":
  904. if (n.test)
  905. parts.push("case ", path.call(print, "test"), ":");
  906. else
  907. parts.push("default:");
  908. if (n.consequent.length > 0) {
  909. parts.push("\n", path.call(function (consequentPath) {
  910. return printStatementSequence(consequentPath, options, print);
  911. }, "consequent").indent(options.tabWidth));
  912. }
  913. return lines_1.concat(parts);
  914. case "DebuggerStatement":
  915. return lines_1.fromString("debugger;");
  916. // JSX extensions below.
  917. case "JSXAttribute":
  918. parts.push(path.call(print, "name"));
  919. if (n.value)
  920. parts.push("=", path.call(print, "value"));
  921. return lines_1.concat(parts);
  922. case "JSXIdentifier":
  923. return lines_1.fromString(n.name, options);
  924. case "JSXNamespacedName":
  925. return lines_1.fromString(":").join([
  926. path.call(print, "namespace"),
  927. path.call(print, "name")
  928. ]);
  929. case "JSXMemberExpression":
  930. return lines_1.fromString(".").join([
  931. path.call(print, "object"),
  932. path.call(print, "property")
  933. ]);
  934. case "JSXSpreadAttribute":
  935. return lines_1.concat(["{...", path.call(print, "argument"), "}"]);
  936. case "JSXSpreadChild":
  937. return lines_1.concat(["{...", path.call(print, "expression"), "}"]);
  938. case "JSXExpressionContainer":
  939. return lines_1.concat(["{", path.call(print, "expression"), "}"]);
  940. case "JSXElement":
  941. case "JSXFragment":
  942. var openingPropName = "opening" + (n.type === "JSXElement" ? "Element" : "Fragment");
  943. var closingPropName = "closing" + (n.type === "JSXElement" ? "Element" : "Fragment");
  944. var openingLines = path.call(print, openingPropName);
  945. if (n[openingPropName].selfClosing) {
  946. assert_1.default.ok(!n[closingPropName], "unexpected " + closingPropName + " element in self-closing " + n.type);
  947. return openingLines;
  948. }
  949. var childLines = lines_1.concat(path.map(function (childPath) {
  950. var child = childPath.getValue();
  951. if (namedTypes.Literal.check(child) &&
  952. typeof child.value === "string") {
  953. if (/\S/.test(child.value)) {
  954. return child.value.replace(/^\s+|\s+$/g, "");
  955. }
  956. else if (/\n/.test(child.value)) {
  957. return "\n";
  958. }
  959. }
  960. return print(childPath);
  961. }, "children")).indentTail(options.tabWidth);
  962. var closingLines = path.call(print, closingPropName);
  963. return lines_1.concat([
  964. openingLines,
  965. childLines,
  966. closingLines
  967. ]);
  968. case "JSXOpeningElement":
  969. parts.push("<", path.call(print, "name"));
  970. var attrParts = [];
  971. path.each(function (attrPath) {
  972. attrParts.push(" ", print(attrPath));
  973. }, "attributes");
  974. var attrLines = lines_1.concat(attrParts);
  975. var needLineWrap = (attrLines.length > 1 ||
  976. attrLines.getLineLength(1) > options.wrapColumn);
  977. if (needLineWrap) {
  978. attrParts.forEach(function (part, i) {
  979. if (part === " ") {
  980. assert_1.default.strictEqual(i % 2, 0);
  981. attrParts[i] = "\n";
  982. }
  983. });
  984. attrLines = lines_1.concat(attrParts).indentTail(options.tabWidth);
  985. }
  986. parts.push(attrLines, n.selfClosing ? " />" : ">");
  987. return lines_1.concat(parts);
  988. case "JSXClosingElement":
  989. return lines_1.concat(["</", path.call(print, "name"), ">"]);
  990. case "JSXOpeningFragment":
  991. return lines_1.fromString("<>");
  992. case "JSXClosingFragment":
  993. return lines_1.fromString("</>");
  994. case "JSXText":
  995. return lines_1.fromString(n.value, options);
  996. case "JSXEmptyExpression":
  997. return lines_1.fromString("");
  998. case "TypeAnnotatedIdentifier":
  999. return lines_1.concat([
  1000. path.call(print, "annotation"),
  1001. " ",
  1002. path.call(print, "identifier")
  1003. ]);
  1004. case "ClassBody":
  1005. if (n.body.length === 0) {
  1006. return lines_1.fromString("{}");
  1007. }
  1008. return lines_1.concat([
  1009. "{\n",
  1010. path.call(function (bodyPath) {
  1011. return printStatementSequence(bodyPath, options, print);
  1012. }, "body").indent(options.tabWidth),
  1013. "\n}"
  1014. ]);
  1015. case "ClassPropertyDefinition":
  1016. parts.push("static ", path.call(print, "definition"));
  1017. if (!namedTypes.MethodDefinition.check(n.definition))
  1018. parts.push(";");
  1019. return lines_1.concat(parts);
  1020. case "ClassProperty":
  1021. var access = n.accessibility || n.access;
  1022. if (typeof access === "string") {
  1023. parts.push(access, " ");
  1024. }
  1025. if (n.static) {
  1026. parts.push("static ");
  1027. }
  1028. if (n.abstract) {
  1029. parts.push("abstract ");
  1030. }
  1031. if (n.readonly) {
  1032. parts.push("readonly ");
  1033. }
  1034. var key = path.call(print, "key");
  1035. if (n.computed) {
  1036. key = lines_1.concat(["[", key, "]"]);
  1037. }
  1038. if (n.variance) {
  1039. key = lines_1.concat([printVariance(path, print), key]);
  1040. }
  1041. parts.push(key);
  1042. if (n.optional) {
  1043. parts.push("?");
  1044. }
  1045. if (n.typeAnnotation) {
  1046. parts.push(path.call(print, "typeAnnotation"));
  1047. }
  1048. if (n.value) {
  1049. parts.push(" = ", path.call(print, "value"));
  1050. }
  1051. parts.push(";");
  1052. return lines_1.concat(parts);
  1053. case "ClassPrivateProperty":
  1054. if (n.static) {
  1055. parts.push("static ");
  1056. }
  1057. parts.push(path.call(print, "key"));
  1058. if (n.typeAnnotation) {
  1059. parts.push(path.call(print, "typeAnnotation"));
  1060. }
  1061. if (n.value) {
  1062. parts.push(" = ", path.call(print, "value"));
  1063. }
  1064. parts.push(";");
  1065. return lines_1.concat(parts);
  1066. case "ClassDeclaration":
  1067. case "ClassExpression":
  1068. if (n.declare) {
  1069. parts.push("declare ");
  1070. }
  1071. if (n.abstract) {
  1072. parts.push("abstract ");
  1073. }
  1074. parts.push("class");
  1075. if (n.id) {
  1076. parts.push(" ", path.call(print, "id"));
  1077. }
  1078. if (n.typeParameters) {
  1079. parts.push(path.call(print, "typeParameters"));
  1080. }
  1081. if (n.superClass) {
  1082. parts.push(" extends ", path.call(print, "superClass"), path.call(print, "superTypeParameters"));
  1083. }
  1084. if (n["implements"] && n['implements'].length > 0) {
  1085. parts.push(" implements ", lines_1.fromString(", ").join(path.map(print, "implements")));
  1086. }
  1087. parts.push(" ", path.call(print, "body"));
  1088. return lines_1.concat(parts);
  1089. case "TemplateElement":
  1090. return lines_1.fromString(n.value.raw, options).lockIndentTail();
  1091. case "TemplateLiteral":
  1092. var expressions = path.map(print, "expressions");
  1093. parts.push("`");
  1094. path.each(function (childPath) {
  1095. var i = childPath.getName();
  1096. parts.push(print(childPath));
  1097. if (i < expressions.length) {
  1098. parts.push("${", expressions[i], "}");
  1099. }
  1100. }, "quasis");
  1101. parts.push("`");
  1102. return lines_1.concat(parts).lockIndentTail();
  1103. case "TaggedTemplateExpression":
  1104. return lines_1.concat([
  1105. path.call(print, "tag"),
  1106. path.call(print, "quasi")
  1107. ]);
  1108. // These types are unprintable because they serve as abstract
  1109. // supertypes for other (printable) types.
  1110. case "Node":
  1111. case "Printable":
  1112. case "SourceLocation":
  1113. case "Position":
  1114. case "Statement":
  1115. case "Function":
  1116. case "Pattern":
  1117. case "Expression":
  1118. case "Declaration":
  1119. case "Specifier":
  1120. case "NamedSpecifier":
  1121. case "Comment": // Supertype of Block and Line
  1122. case "Flow": // Supertype of all Flow AST node types
  1123. case "FlowType": // Supertype of all Flow types
  1124. case "FlowPredicate": // Supertype of InferredPredicate and DeclaredPredicate
  1125. case "MemberTypeAnnotation": // Flow
  1126. case "Type": // Flow
  1127. case "TSHasOptionalTypeParameterInstantiation":
  1128. case "TSHasOptionalTypeParameters":
  1129. case "TSHasOptionalTypeAnnotation":
  1130. throw new Error("unprintable type: " + JSON.stringify(n.type));
  1131. case "CommentBlock": // Babel block comment.
  1132. case "Block": // Esprima block comment.
  1133. return lines_1.concat(["/*", lines_1.fromString(n.value, options), "*/"]);
  1134. case "CommentLine": // Babel line comment.
  1135. case "Line": // Esprima line comment.
  1136. return lines_1.concat(["//", lines_1.fromString(n.value, options)]);
  1137. // Type Annotations for Facebook Flow, typically stripped out or
  1138. // transformed away before printing.
  1139. case "TypeAnnotation":
  1140. if (n.typeAnnotation) {
  1141. if (n.typeAnnotation.type !== "FunctionTypeAnnotation") {
  1142. parts.push(": ");
  1143. }
  1144. parts.push(path.call(print, "typeAnnotation"));
  1145. return lines_1.concat(parts);
  1146. }
  1147. return lines_1.fromString("");
  1148. case "ExistentialTypeParam":
  1149. case "ExistsTypeAnnotation":
  1150. return lines_1.fromString("*", options);
  1151. case "EmptyTypeAnnotation":
  1152. return lines_1.fromString("empty", options);
  1153. case "AnyTypeAnnotation":
  1154. return lines_1.fromString("any", options);
  1155. case "MixedTypeAnnotation":
  1156. return lines_1.fromString("mixed", options);
  1157. case "ArrayTypeAnnotation":
  1158. return lines_1.concat([
  1159. path.call(print, "elementType"),
  1160. "[]"
  1161. ]);
  1162. case "TupleTypeAnnotation":
  1163. var printed = path.map(print, "types");
  1164. var joined = lines_1.fromString(", ").join(printed);
  1165. var oneLine = joined.getLineLength(1) <= options.wrapColumn;
  1166. if (oneLine) {
  1167. if (options.arrayBracketSpacing) {
  1168. parts.push("[ ");
  1169. }
  1170. else {
  1171. parts.push("[");
  1172. }
  1173. }
  1174. else {
  1175. parts.push("[\n");
  1176. }
  1177. path.each(function (elemPath) {
  1178. var i = elemPath.getName();
  1179. var elem = elemPath.getValue();
  1180. if (!elem) {
  1181. // If the array expression ends with a hole, that hole
  1182. // will be ignored by the interpreter, but if it ends with
  1183. // two (or more) holes, we need to write out two (or more)
  1184. // commas so that the resulting code is interpreted with
  1185. // both (all) of the holes.
  1186. parts.push(",");
  1187. }
  1188. else {
  1189. var lines = printed[i];
  1190. if (oneLine) {
  1191. if (i > 0)
  1192. parts.push(" ");
  1193. }
  1194. else {
  1195. lines = lines.indent(options.tabWidth);
  1196. }
  1197. parts.push(lines);
  1198. if (i < n.types.length - 1 || (!oneLine && util.isTrailingCommaEnabled(options, "arrays")))
  1199. parts.push(",");
  1200. if (!oneLine)
  1201. parts.push("\n");
  1202. }
  1203. }, "types");
  1204. if (oneLine && options.arrayBracketSpacing) {
  1205. parts.push(" ]");
  1206. }
  1207. else {
  1208. parts.push("]");
  1209. }
  1210. return lines_1.concat(parts);
  1211. case "BooleanTypeAnnotation":
  1212. return lines_1.fromString("boolean", options);
  1213. case "BooleanLiteralTypeAnnotation":
  1214. assert_1.default.strictEqual(typeof n.value, "boolean");
  1215. return lines_1.fromString("" + n.value, options);
  1216. case "InterfaceTypeAnnotation":
  1217. parts.push("interface");
  1218. if (n.extends && n.extends.length > 0) {
  1219. parts.push(" extends ", lines_1.fromString(", ").join(path.map(print, "extends")));
  1220. }
  1221. parts.push(" ", path.call(print, "body"));
  1222. return lines_1.concat(parts);
  1223. case "DeclareClass":
  1224. return printFlowDeclaration(path, [
  1225. "class ",
  1226. path.call(print, "id"),
  1227. " ",
  1228. path.call(print, "body"),
  1229. ]);
  1230. case "DeclareFunction":
  1231. return printFlowDeclaration(path, [
  1232. "function ",
  1233. path.call(print, "id"),
  1234. ";"
  1235. ]);
  1236. case "DeclareModule":
  1237. return printFlowDeclaration(path, [
  1238. "module ",
  1239. path.call(print, "id"),
  1240. " ",
  1241. path.call(print, "body"),
  1242. ]);
  1243. case "DeclareModuleExports":
  1244. return printFlowDeclaration(path, [
  1245. "module.exports",
  1246. path.call(print, "typeAnnotation"),
  1247. ]);
  1248. case "DeclareVariable":
  1249. return printFlowDeclaration(path, [
  1250. "var ",
  1251. path.call(print, "id"),
  1252. ";"
  1253. ]);
  1254. case "DeclareExportDeclaration":
  1255. case "DeclareExportAllDeclaration":
  1256. return lines_1.concat([
  1257. "declare ",
  1258. printExportDeclaration(path, options, print)
  1259. ]);
  1260. case "InferredPredicate":
  1261. return lines_1.fromString("%checks", options);
  1262. case "DeclaredPredicate":
  1263. return lines_1.concat([
  1264. "%checks(",
  1265. path.call(print, "value"),
  1266. ")"
  1267. ]);
  1268. case "FunctionTypeAnnotation":
  1269. // FunctionTypeAnnotation is ambiguous:
  1270. // declare function(a: B): void; OR
  1271. // var A: (a: B) => void;
  1272. var parent = path.getParentNode(0);
  1273. var isArrowFunctionTypeAnnotation = !(namedTypes.ObjectTypeCallProperty.check(parent) ||
  1274. (namedTypes.ObjectTypeInternalSlot.check(parent) && parent.method) ||
  1275. namedTypes.DeclareFunction.check(path.getParentNode(2)));
  1276. var needsColon = isArrowFunctionTypeAnnotation &&
  1277. !namedTypes.FunctionTypeParam.check(parent);
  1278. if (needsColon) {
  1279. parts.push(": ");
  1280. }
  1281. parts.push("(", printFunctionParams(path, options, print), ")");
  1282. // The returnType is not wrapped in a TypeAnnotation, so the colon
  1283. // needs to be added separately.
  1284. if (n.returnType) {
  1285. parts.push(isArrowFunctionTypeAnnotation ? " => " : ": ", path.call(print, "returnType"));
  1286. }
  1287. return lines_1.concat(parts);
  1288. case "FunctionTypeParam":
  1289. return lines_1.concat([
  1290. path.call(print, "name"),
  1291. n.optional ? '?' : '',
  1292. ": ",
  1293. path.call(print, "typeAnnotation"),
  1294. ]);
  1295. case "GenericTypeAnnotation":
  1296. return lines_1.concat([
  1297. path.call(print, "id"),
  1298. path.call(print, "typeParameters")
  1299. ]);
  1300. case "DeclareInterface":
  1301. parts.push("declare ");
  1302. // Fall through to InterfaceDeclaration...
  1303. case "InterfaceDeclaration":
  1304. case "TSInterfaceDeclaration":
  1305. if (n.declare) {
  1306. parts.push("declare ");
  1307. }
  1308. parts.push("interface ", path.call(print, "id"), path.call(print, "typeParameters"), " ");
  1309. if (n["extends"] && n["extends"].length > 0) {
  1310. parts.push("extends ", lines_1.fromString(", ").join(path.map(print, "extends")), " ");
  1311. }
  1312. if (n.body) {
  1313. parts.push(path.call(print, "body"));
  1314. }
  1315. return lines_1.concat(parts);
  1316. case "ClassImplements":
  1317. case "InterfaceExtends":
  1318. return lines_1.concat([
  1319. path.call(print, "id"),
  1320. path.call(print, "typeParameters")
  1321. ]);
  1322. case "IntersectionTypeAnnotation":
  1323. return lines_1.fromString(" & ").join(path.map(print, "types"));
  1324. case "NullableTypeAnnotation":
  1325. return lines_1.concat([
  1326. "?",
  1327. path.call(print, "typeAnnotation")
  1328. ]);
  1329. case "NullLiteralTypeAnnotation":
  1330. return lines_1.fromString("null", options);
  1331. case "ThisTypeAnnotation":
  1332. return lines_1.fromString("this", options);
  1333. case "NumberTypeAnnotation":
  1334. return lines_1.fromString("number", options);
  1335. case "ObjectTypeCallProperty":
  1336. return path.call(print, "value");
  1337. case "ObjectTypeIndexer":
  1338. return lines_1.concat([
  1339. printVariance(path, print),
  1340. "[",
  1341. path.call(print, "id"),
  1342. ": ",
  1343. path.call(print, "key"),
  1344. "]: ",
  1345. path.call(print, "value")
  1346. ]);
  1347. case "ObjectTypeProperty":
  1348. return lines_1.concat([
  1349. printVariance(path, print),
  1350. path.call(print, "key"),
  1351. n.optional ? "?" : "",
  1352. ": ",
  1353. path.call(print, "value")
  1354. ]);
  1355. case "ObjectTypeInternalSlot":
  1356. return lines_1.concat([
  1357. n.static ? "static " : "",
  1358. "[[",
  1359. path.call(print, "id"),
  1360. "]]",
  1361. n.optional ? "?" : "",
  1362. n.value.type !== "FunctionTypeAnnotation" ? ": " : "",
  1363. path.call(print, "value")
  1364. ]);
  1365. case "QualifiedTypeIdentifier":
  1366. return lines_1.concat([
  1367. path.call(print, "qualification"),
  1368. ".",
  1369. path.call(print, "id")
  1370. ]);
  1371. case "StringLiteralTypeAnnotation":
  1372. return lines_1.fromString(nodeStr(n.value, options), options);
  1373. case "NumberLiteralTypeAnnotation":
  1374. case "NumericLiteralTypeAnnotation":
  1375. assert_1.default.strictEqual(typeof n.value, "number");
  1376. return lines_1.fromString(JSON.stringify(n.value), options);
  1377. case "StringTypeAnnotation":
  1378. return lines_1.fromString("string", options);
  1379. case "DeclareTypeAlias":
  1380. parts.push("declare ");
  1381. // Fall through to TypeAlias...
  1382. case "TypeAlias":
  1383. return lines_1.concat([
  1384. "type ",
  1385. path.call(print, "id"),
  1386. path.call(print, "typeParameters"),
  1387. " = ",
  1388. path.call(print, "right"),
  1389. ";"
  1390. ]);
  1391. case "DeclareOpaqueType":
  1392. parts.push("declare ");
  1393. // Fall through to OpaqueType...
  1394. case "OpaqueType":
  1395. parts.push("opaque type ", path.call(print, "id"), path.call(print, "typeParameters"));
  1396. if (n["supertype"]) {
  1397. parts.push(": ", path.call(print, "supertype"));
  1398. }
  1399. if (n["impltype"]) {
  1400. parts.push(" = ", path.call(print, "impltype"));
  1401. }
  1402. parts.push(";");
  1403. return lines_1.concat(parts);
  1404. case "TypeCastExpression":
  1405. return lines_1.concat([
  1406. "(",
  1407. path.call(print, "expression"),
  1408. path.call(print, "typeAnnotation"),
  1409. ")"
  1410. ]);
  1411. case "TypeParameterDeclaration":
  1412. case "TypeParameterInstantiation":
  1413. return lines_1.concat([
  1414. "<",
  1415. lines_1.fromString(", ").join(path.map(print, "params")),
  1416. ">"
  1417. ]);
  1418. case "Variance":
  1419. if (n.kind === "plus") {
  1420. return lines_1.fromString("+");
  1421. }
  1422. if (n.kind === "minus") {
  1423. return lines_1.fromString("-");
  1424. }
  1425. return lines_1.fromString("");
  1426. case "TypeParameter":
  1427. if (n.variance) {
  1428. parts.push(printVariance(path, print));
  1429. }
  1430. parts.push(path.call(print, 'name'));
  1431. if (n.bound) {
  1432. parts.push(path.call(print, 'bound'));
  1433. }
  1434. if (n['default']) {
  1435. parts.push('=', path.call(print, 'default'));
  1436. }
  1437. return lines_1.concat(parts);
  1438. case "TypeofTypeAnnotation":
  1439. return lines_1.concat([
  1440. lines_1.fromString("typeof ", options),
  1441. path.call(print, "argument")
  1442. ]);
  1443. case "UnionTypeAnnotation":
  1444. return lines_1.fromString(" | ").join(path.map(print, "types"));
  1445. case "VoidTypeAnnotation":
  1446. return lines_1.fromString("void", options);
  1447. case "NullTypeAnnotation":
  1448. return lines_1.fromString("null", options);
  1449. // Type Annotations for TypeScript (when using Babylon as parser)
  1450. case "TSType":
  1451. throw new Error("unprintable type: " + JSON.stringify(n.type));
  1452. case "TSNumberKeyword":
  1453. return lines_1.fromString("number", options);
  1454. case "TSBigIntKeyword":
  1455. return lines_1.fromString("bigint", options);
  1456. case "TSObjectKeyword":
  1457. return lines_1.fromString("object", options);
  1458. case "TSBooleanKeyword":
  1459. return lines_1.fromString("boolean", options);
  1460. case "TSStringKeyword":
  1461. return lines_1.fromString("string", options);
  1462. case "TSSymbolKeyword":
  1463. return lines_1.fromString("symbol", options);
  1464. case "TSAnyKeyword":
  1465. return lines_1.fromString("any", options);
  1466. case "TSVoidKeyword":
  1467. return lines_1.fromString("void", options);
  1468. case "TSThisType":
  1469. return lines_1.fromString("this", options);
  1470. case "TSNullKeyword":
  1471. return lines_1.fromString("null", options);
  1472. case "TSUndefinedKeyword":
  1473. return lines_1.fromString("undefined", options);
  1474. case "TSUnknownKeyword":
  1475. return lines_1.fromString("unknown", options);
  1476. case "TSNeverKeyword":
  1477. return lines_1.fromString("never", options);
  1478. case "TSArrayType":
  1479. return lines_1.concat([
  1480. path.call(print, "elementType"),
  1481. "[]"
  1482. ]);
  1483. case "TSLiteralType":
  1484. return path.call(print, "literal");
  1485. case "TSUnionType":
  1486. return lines_1.fromString(" | ").join(path.map(print, "types"));
  1487. case "TSIntersectionType":
  1488. return lines_1.fromString(" & ").join(path.map(print, "types"));
  1489. case "TSConditionalType":
  1490. parts.push(path.call(print, "checkType"), " extends ", path.call(print, "extendsType"), " ? ", path.call(print, "trueType"), " : ", path.call(print, "falseType"));
  1491. return lines_1.concat(parts);
  1492. case "TSInferType":
  1493. parts.push("infer ", path.call(print, "typeParameter"));
  1494. return lines_1.concat(parts);
  1495. case "TSParenthesizedType":
  1496. return lines_1.concat([
  1497. "(",
  1498. path.call(print, "typeAnnotation"),
  1499. ")"
  1500. ]);
  1501. case "TSFunctionType":
  1502. return lines_1.concat([
  1503. path.call(print, "typeParameters"),
  1504. "(",
  1505. printFunctionParams(path, options, print),
  1506. ")",
  1507. path.call(print, "typeAnnotation")
  1508. ]);
  1509. case "TSConstructorType":
  1510. return lines_1.concat([
  1511. "new ",
  1512. path.call(print, 'typeParameters'),
  1513. "(",
  1514. printFunctionParams(path, options, print),
  1515. ")",
  1516. path.call(print, "typeAnnotation")
  1517. ]);
  1518. case "TSMappedType": {
  1519. parts.push(n.readonly ? "readonly " : "", "[", path.call(print, "typeParameter"), "]", n.optional ? "?" : "");
  1520. if (n.typeAnnotation) {
  1521. parts.push(": ", path.call(print, "typeAnnotation"), ";");
  1522. }
  1523. return lines_1.concat([
  1524. "{\n",
  1525. lines_1.concat(parts).indent(options.tabWidth),
  1526. "\n}",
  1527. ]);
  1528. }
  1529. case "TSTupleType":
  1530. return lines_1.concat([
  1531. "[",
  1532. lines_1.fromString(", ").join(path.map(print, "elementTypes")),
  1533. "]"
  1534. ]);
  1535. case "TSRestType":
  1536. return lines_1.concat([
  1537. "...",
  1538. path.call(print, "typeAnnotation"),
  1539. "[]"
  1540. ]);
  1541. case "TSOptionalType":
  1542. return lines_1.concat([
  1543. path.call(print, "typeAnnotation"),
  1544. "?"
  1545. ]);
  1546. case "TSIndexedAccessType":
  1547. return lines_1.concat([
  1548. path.call(print, "objectType"),
  1549. "[",
  1550. path.call(print, "indexType"),
  1551. "]"
  1552. ]);
  1553. case "TSTypeOperator":
  1554. return lines_1.concat([
  1555. path.call(print, "operator"),
  1556. " ",
  1557. path.call(print, "typeAnnotation")
  1558. ]);
  1559. case "TSTypeLiteral": {
  1560. var memberLines_1 = lines_1.fromString(",\n").join(path.map(print, "members"));
  1561. if (memberLines_1.isEmpty()) {
  1562. return lines_1.fromString("{}", options);
  1563. }
  1564. parts.push("{\n", memberLines_1.indent(options.tabWidth), "\n}");
  1565. return lines_1.concat(parts);
  1566. }
  1567. case "TSEnumMember":
  1568. parts.push(path.call(print, "id"));
  1569. if (n.initializer) {
  1570. parts.push(" = ", path.call(print, "initializer"));
  1571. }
  1572. return lines_1.concat(parts);
  1573. case "TSTypeQuery":
  1574. return lines_1.concat([
  1575. "typeof ",
  1576. path.call(print, "exprName"),
  1577. ]);
  1578. case "TSParameterProperty":
  1579. if (n.accessibility) {
  1580. parts.push(n.accessibility, " ");
  1581. }
  1582. if (n.export) {
  1583. parts.push("export ");
  1584. }
  1585. if (n.static) {
  1586. parts.push("static ");
  1587. }
  1588. if (n.readonly) {
  1589. parts.push("readonly ");
  1590. }
  1591. parts.push(path.call(print, "parameter"));
  1592. return lines_1.concat(parts);
  1593. case "TSTypeReference":
  1594. return lines_1.concat([
  1595. path.call(print, "typeName"),
  1596. path.call(print, "typeParameters")
  1597. ]);
  1598. case "TSQualifiedName":
  1599. return lines_1.concat([
  1600. path.call(print, "left"),
  1601. ".",
  1602. path.call(print, "right")
  1603. ]);
  1604. case "TSAsExpression": {
  1605. var withParens = n.extra && n.extra.parenthesized === true;
  1606. if (withParens)
  1607. parts.push("(");
  1608. parts.push(path.call(print, "expression"), lines_1.fromString(" as "), path.call(print, "typeAnnotation"));
  1609. if (withParens)
  1610. parts.push(")");
  1611. return lines_1.concat(parts);
  1612. }
  1613. case "TSNonNullExpression":
  1614. return lines_1.concat([
  1615. path.call(print, "expression"),
  1616. "!"
  1617. ]);
  1618. case "TSTypeAnnotation": {
  1619. // similar to flow's FunctionTypeAnnotation, this can be
  1620. // ambiguous: it can be prefixed by => or :
  1621. // in a type predicate, it takes the for u is U
  1622. var parent = path.getParentNode(0);
  1623. var prefix = ": ";
  1624. if (namedTypes.TSFunctionType.check(parent) || namedTypes.TSConstructorType.check(parent)) {
  1625. prefix = " => ";
  1626. }
  1627. if (namedTypes.TSTypePredicate.check(parent)) {
  1628. prefix = " is ";
  1629. }
  1630. return lines_1.concat([
  1631. prefix,
  1632. path.call(print, "typeAnnotation")
  1633. ]);
  1634. }
  1635. case "TSIndexSignature":
  1636. return lines_1.concat([
  1637. n.readonly ? "readonly " : "",
  1638. "[",
  1639. path.map(print, "parameters"),
  1640. "]",
  1641. path.call(print, "typeAnnotation")
  1642. ]);
  1643. case "TSPropertySignature":
  1644. parts.push(printVariance(path, print), n.readonly ? "readonly " : "");
  1645. if (n.computed) {
  1646. parts.push("[", path.call(print, "key"), "]");
  1647. }
  1648. else {
  1649. parts.push(path.call(print, "key"));
  1650. }
  1651. parts.push(n.optional ? "?" : "", path.call(print, "typeAnnotation"));
  1652. return lines_1.concat(parts);
  1653. case "TSMethodSignature":
  1654. if (n.computed) {
  1655. parts.push("[", path.call(print, "key"), "]");
  1656. }
  1657. else {
  1658. parts.push(path.call(print, "key"));
  1659. }
  1660. if (n.optional) {
  1661. parts.push("?");
  1662. }
  1663. parts.push(path.call(print, "typeParameters"), "(", printFunctionParams(path, options, print), ")", path.call(print, "typeAnnotation"));
  1664. return lines_1.concat(parts);
  1665. case "TSTypePredicate":
  1666. return lines_1.concat([
  1667. path.call(print, "parameterName"),
  1668. path.call(print, "typeAnnotation")
  1669. ]);
  1670. case "TSCallSignatureDeclaration":
  1671. return lines_1.concat([
  1672. path.call(print, "typeParameters"),
  1673. "(",
  1674. printFunctionParams(path, options, print),
  1675. ")",
  1676. path.call(print, "typeAnnotation")
  1677. ]);
  1678. case "TSConstructSignatureDeclaration":
  1679. if (n.typeParameters) {
  1680. parts.push("new", path.call(print, "typeParameters"));
  1681. }
  1682. else {
  1683. parts.push("new ");
  1684. }
  1685. parts.push("(", printFunctionParams(path, options, print), ")", path.call(print, "typeAnnotation"));
  1686. return lines_1.concat(parts);
  1687. case "TSTypeAliasDeclaration":
  1688. return lines_1.concat([
  1689. n.declare ? "declare " : "",
  1690. "type ",
  1691. path.call(print, "id"),
  1692. path.call(print, "typeParameters"),
  1693. " = ",
  1694. path.call(print, "typeAnnotation"),
  1695. ";"
  1696. ]);
  1697. case "TSTypeParameter":
  1698. parts.push(path.call(print, "name"));
  1699. // ambiguous because of TSMappedType
  1700. var parent = path.getParentNode(0);
  1701. var isInMappedType = namedTypes.TSMappedType.check(parent);
  1702. if (n.constraint) {
  1703. parts.push(isInMappedType ? " in " : " extends ", path.call(print, "constraint"));
  1704. }
  1705. if (n["default"]) {
  1706. parts.push(" = ", path.call(print, "default"));
  1707. }
  1708. return lines_1.concat(parts);
  1709. case "TSTypeAssertion":
  1710. var withParens = n.extra && n.extra.parenthesized === true;
  1711. if (withParens) {
  1712. parts.push("(");
  1713. }
  1714. parts.push("<", path.call(print, "typeAnnotation"), "> ", path.call(print, "expression"));
  1715. if (withParens) {
  1716. parts.push(")");
  1717. }
  1718. return lines_1.concat(parts);
  1719. case "TSTypeParameterDeclaration":
  1720. case "TSTypeParameterInstantiation":
  1721. return lines_1.concat([
  1722. "<",
  1723. lines_1.fromString(", ").join(path.map(print, "params")),
  1724. ">"
  1725. ]);
  1726. case "TSEnumDeclaration":
  1727. parts.push(n.declare ? "declare " : "", n.const ? "const " : "", "enum ", path.call(print, "id"));
  1728. var memberLines = lines_1.fromString(",\n").join(path.map(print, "members"));
  1729. if (memberLines.isEmpty()) {
  1730. parts.push(" {}");
  1731. }
  1732. else {
  1733. parts.push(" {\n", memberLines.indent(options.tabWidth), "\n}");
  1734. }
  1735. return lines_1.concat(parts);
  1736. case "TSExpressionWithTypeArguments":
  1737. return lines_1.concat([
  1738. path.call(print, "expression"),
  1739. path.call(print, "typeParameters")
  1740. ]);
  1741. case "TSInterfaceBody":
  1742. var lines = lines_1.fromString(";\n").join(path.map(print, "body"));
  1743. if (lines.isEmpty()) {
  1744. return lines_1.fromString("{}", options);
  1745. }
  1746. return lines_1.concat([
  1747. "{\n",
  1748. lines.indent(options.tabWidth), ";",
  1749. "\n}",
  1750. ]);
  1751. case "TSImportType":
  1752. parts.push("import(", path.call(print, "argument"), ")");
  1753. if (n.qualifier) {
  1754. parts.push(".", path.call(print, "qualifier"));
  1755. }
  1756. if (n.typeParameters) {
  1757. parts.push(path.call(print, "typeParameters"));
  1758. }
  1759. return lines_1.concat(parts);
  1760. case "TSImportEqualsDeclaration":
  1761. if (n.isExport) {
  1762. parts.push("export ");
  1763. }
  1764. parts.push("import ", path.call(print, "id"), " = ", path.call(print, "moduleReference"));
  1765. return maybeAddSemicolon(lines_1.concat(parts));
  1766. case "TSExternalModuleReference":
  1767. return lines_1.concat(["require(", path.call(print, "expression"), ")"]);
  1768. case "TSModuleDeclaration": {
  1769. var parent_1 = path.getParentNode();
  1770. if (parent_1.type === "TSModuleDeclaration") {
  1771. parts.push(".");
  1772. }
  1773. else {
  1774. if (n.declare) {
  1775. parts.push("declare ");
  1776. }
  1777. if (!n.global) {
  1778. var isExternal = n.id.type === "StringLiteral" ||
  1779. (n.id.type === "Literal" &&
  1780. typeof n.id.value === "string");
  1781. if (isExternal) {
  1782. parts.push("module ");
  1783. }
  1784. else if (n.loc &&
  1785. n.loc.lines &&
  1786. n.id.loc) {
  1787. var prefix_1 = n.loc.lines.sliceString(n.loc.start, n.id.loc.start);
  1788. // These keywords are fundamentally ambiguous in the
  1789. // Babylon parser, and not reflected in the AST, so
  1790. // the best we can do is to match the original code,
  1791. // when possible.
  1792. if (prefix_1.indexOf("module") >= 0) {
  1793. parts.push("module ");
  1794. }
  1795. else {
  1796. parts.push("namespace ");
  1797. }
  1798. }
  1799. else {
  1800. parts.push("namespace ");
  1801. }
  1802. }
  1803. }
  1804. parts.push(path.call(print, "id"));
  1805. if (n.body && n.body.type === "TSModuleDeclaration") {
  1806. parts.push(path.call(print, "body"));
  1807. }
  1808. else if (n.body) {
  1809. var bodyLines = path.call(print, "body");
  1810. if (bodyLines.isEmpty()) {
  1811. parts.push(" {}");
  1812. }
  1813. else {
  1814. parts.push(" {\n", bodyLines.indent(options.tabWidth), "\n}");
  1815. }
  1816. }
  1817. return lines_1.concat(parts);
  1818. }
  1819. case "TSModuleBlock":
  1820. return path.call(function (bodyPath) {
  1821. return printStatementSequence(bodyPath, options, print);
  1822. }, "body");
  1823. // Unhandled types below. If encountered, nodes of these types should
  1824. // be either left alone or desugared into AST types that are fully
  1825. // supported by the pretty-printer.
  1826. case "ClassHeritage": // TODO
  1827. case "ComprehensionBlock": // TODO
  1828. case "ComprehensionExpression": // TODO
  1829. case "Glob": // TODO
  1830. case "GeneratorExpression": // TODO
  1831. case "LetStatement": // TODO
  1832. case "LetExpression": // TODO
  1833. case "GraphExpression": // TODO
  1834. case "GraphIndexExpression": // TODO
  1835. // XML types that nobody cares about or needs to print.
  1836. case "XMLDefaultDeclaration":
  1837. case "XMLAnyName":
  1838. case "XMLQualifiedIdentifier":
  1839. case "XMLFunctionQualifiedIdentifier":
  1840. case "XMLAttributeSelector":
  1841. case "XMLFilterExpression":
  1842. case "XML":
  1843. case "XMLElement":
  1844. case "XMLList":
  1845. case "XMLEscape":
  1846. case "XMLText":
  1847. case "XMLStartTag":
  1848. case "XMLEndTag":
  1849. case "XMLPointTag":
  1850. case "XMLName":
  1851. case "XMLAttribute":
  1852. case "XMLCdata":
  1853. case "XMLComment":
  1854. case "XMLProcessingInstruction":
  1855. default:
  1856. debugger;
  1857. throw new Error("unknown type: " + JSON.stringify(n.type));
  1858. }
  1859. }
  1860. function printDecorators(path, printPath) {
  1861. var parts = [];
  1862. var node = path.getValue();
  1863. if (node.decorators &&
  1864. node.decorators.length > 0 &&
  1865. // If the parent node is an export declaration, it will be
  1866. // responsible for printing node.decorators.
  1867. !util.getParentExportDeclaration(path)) {
  1868. path.each(function (decoratorPath) {
  1869. parts.push(printPath(decoratorPath), "\n");
  1870. }, "decorators");
  1871. }
  1872. else if (util.isExportDeclaration(node) &&
  1873. node.declaration &&
  1874. node.declaration.decorators) {
  1875. // Export declarations are responsible for printing any decorators
  1876. // that logically apply to node.declaration.
  1877. path.each(function (decoratorPath) {
  1878. parts.push(printPath(decoratorPath), "\n");
  1879. }, "declaration", "decorators");
  1880. }
  1881. return lines_1.concat(parts);
  1882. }
  1883. function printStatementSequence(path, options, print) {
  1884. var filtered = [];
  1885. var sawComment = false;
  1886. var sawStatement = false;
  1887. path.each(function (stmtPath) {
  1888. var stmt = stmtPath.getValue();
  1889. // Just in case the AST has been modified to contain falsy
  1890. // "statements," it's safer simply to skip them.
  1891. if (!stmt) {
  1892. return;
  1893. }
  1894. // Skip printing EmptyStatement nodes to avoid leaving stray
  1895. // semicolons lying around.
  1896. if (stmt.type === "EmptyStatement" &&
  1897. !(stmt.comments && stmt.comments.length > 0)) {
  1898. return;
  1899. }
  1900. if (namedTypes.Comment.check(stmt)) {
  1901. // The pretty printer allows a dangling Comment node to act as
  1902. // a Statement when the Comment can't be attached to any other
  1903. // non-Comment node in the tree.
  1904. sawComment = true;
  1905. }
  1906. else if (namedTypes.Statement.check(stmt)) {
  1907. sawStatement = true;
  1908. }
  1909. else {
  1910. // When the pretty printer encounters a string instead of an
  1911. // AST node, it just prints the string. This behavior can be
  1912. // useful for fine-grained formatting decisions like inserting
  1913. // blank lines.
  1914. isString.assert(stmt);
  1915. }
  1916. // We can't hang onto stmtPath outside of this function, because
  1917. // it's just a reference to a mutable FastPath object, so we have
  1918. // to go ahead and print it here.
  1919. filtered.push({
  1920. node: stmt,
  1921. printed: print(stmtPath)
  1922. });
  1923. });
  1924. if (sawComment) {
  1925. assert_1.default.strictEqual(sawStatement, false, "Comments may appear as statements in otherwise empty statement " +
  1926. "lists, but may not coexist with non-Comment nodes.");
  1927. }
  1928. var prevTrailingSpace = null;
  1929. var len = filtered.length;
  1930. var parts = [];
  1931. filtered.forEach(function (info, i) {
  1932. var printed = info.printed;
  1933. var stmt = info.node;
  1934. var multiLine = printed.length > 1;
  1935. var notFirst = i > 0;
  1936. var notLast = i < len - 1;
  1937. var leadingSpace;
  1938. var trailingSpace;
  1939. var lines = stmt && stmt.loc && stmt.loc.lines;
  1940. var trueLoc = lines && options.reuseWhitespace &&
  1941. util.getTrueLoc(stmt, lines);
  1942. if (notFirst) {
  1943. if (trueLoc) {
  1944. var beforeStart = lines.skipSpaces(trueLoc.start, true);
  1945. var beforeStartLine = beforeStart ? beforeStart.line : 1;
  1946. var leadingGap = trueLoc.start.line - beforeStartLine;
  1947. leadingSpace = Array(leadingGap + 1).join("\n");
  1948. }
  1949. else {
  1950. leadingSpace = multiLine ? "\n\n" : "\n";
  1951. }
  1952. }
  1953. else {
  1954. leadingSpace = "";
  1955. }
  1956. if (notLast) {
  1957. if (trueLoc) {
  1958. var afterEnd = lines.skipSpaces(trueLoc.end);
  1959. var afterEndLine = afterEnd ? afterEnd.line : lines.length;
  1960. var trailingGap = afterEndLine - trueLoc.end.line;
  1961. trailingSpace = Array(trailingGap + 1).join("\n");
  1962. }
  1963. else {
  1964. trailingSpace = multiLine ? "\n\n" : "\n";
  1965. }
  1966. }
  1967. else {
  1968. trailingSpace = "";
  1969. }
  1970. parts.push(maxSpace(prevTrailingSpace, leadingSpace), printed);
  1971. if (notLast) {
  1972. prevTrailingSpace = trailingSpace;
  1973. }
  1974. else if (trailingSpace) {
  1975. parts.push(trailingSpace);
  1976. }
  1977. });
  1978. return lines_1.concat(parts);
  1979. }
  1980. function maxSpace(s1, s2) {
  1981. if (!s1 && !s2) {
  1982. return lines_1.fromString("");
  1983. }
  1984. if (!s1) {
  1985. return lines_1.fromString(s2);
  1986. }
  1987. if (!s2) {
  1988. return lines_1.fromString(s1);
  1989. }
  1990. var spaceLines1 = lines_1.fromString(s1);
  1991. var spaceLines2 = lines_1.fromString(s2);
  1992. if (spaceLines2.length > spaceLines1.length) {
  1993. return spaceLines2;
  1994. }
  1995. return spaceLines1;
  1996. }
  1997. function printMethod(path, options, print) {
  1998. var node = path.getNode();
  1999. var kind = node.kind;
  2000. var parts = [];
  2001. var nodeValue = node.value;
  2002. if (!namedTypes.FunctionExpression.check(nodeValue)) {
  2003. nodeValue = node;
  2004. }
  2005. var access = node.accessibility || node.access;
  2006. if (typeof access === "string") {
  2007. parts.push(access, " ");
  2008. }
  2009. if (node.static) {
  2010. parts.push("static ");
  2011. }
  2012. if (node.abstract) {
  2013. parts.push("abstract ");
  2014. }
  2015. if (node.readonly) {
  2016. parts.push("readonly ");
  2017. }
  2018. if (nodeValue.async) {
  2019. parts.push("async ");
  2020. }
  2021. if (nodeValue.generator) {
  2022. parts.push("*");
  2023. }
  2024. if (kind === "get" || kind === "set") {
  2025. parts.push(kind, " ");
  2026. }
  2027. var key = path.call(print, "key");
  2028. if (node.computed) {
  2029. key = lines_1.concat(["[", key, "]"]);
  2030. }
  2031. parts.push(key);
  2032. if (node.optional) {
  2033. parts.push("?");
  2034. }
  2035. if (node === nodeValue) {
  2036. parts.push(path.call(print, "typeParameters"), "(", printFunctionParams(path, options, print), ")", path.call(print, "returnType"));
  2037. if (node.body) {
  2038. parts.push(" ", path.call(print, "body"));
  2039. }
  2040. else {
  2041. parts.push(";");
  2042. }
  2043. }
  2044. else {
  2045. parts.push(path.call(print, "value", "typeParameters"), "(", path.call(function (valuePath) {
  2046. return printFunctionParams(valuePath, options, print);
  2047. }, "value"), ")", path.call(print, "value", "returnType"));
  2048. if (nodeValue.body) {
  2049. parts.push(" ", path.call(print, "value", "body"));
  2050. }
  2051. else {
  2052. parts.push(";");
  2053. }
  2054. }
  2055. return lines_1.concat(parts);
  2056. }
  2057. function printArgumentsList(path, options, print) {
  2058. var printed = path.map(print, "arguments");
  2059. var trailingComma = util.isTrailingCommaEnabled(options, "parameters");
  2060. var joined = lines_1.fromString(", ").join(printed);
  2061. if (joined.getLineLength(1) > options.wrapColumn) {
  2062. joined = lines_1.fromString(",\n").join(printed);
  2063. return lines_1.concat([
  2064. "(\n",
  2065. joined.indent(options.tabWidth),
  2066. trailingComma ? ",\n)" : "\n)"
  2067. ]);
  2068. }
  2069. return lines_1.concat(["(", joined, ")"]);
  2070. }
  2071. function printFunctionParams(path, options, print) {
  2072. var fun = path.getValue();
  2073. if (fun.params) {
  2074. var params = fun.params;
  2075. var printed = path.map(print, "params");
  2076. }
  2077. else if (fun.parameters) {
  2078. params = fun.parameters;
  2079. printed = path.map(print, "parameters");
  2080. }
  2081. if (fun.defaults) {
  2082. path.each(function (defExprPath) {
  2083. var i = defExprPath.getName();
  2084. var p = printed[i];
  2085. if (p && defExprPath.getValue()) {
  2086. printed[i] = lines_1.concat([p, " = ", print(defExprPath)]);
  2087. }
  2088. }, "defaults");
  2089. }
  2090. if (fun.rest) {
  2091. printed.push(lines_1.concat(["...", path.call(print, "rest")]));
  2092. }
  2093. var joined = lines_1.fromString(", ").join(printed);
  2094. if (joined.length > 1 ||
  2095. joined.getLineLength(1) > options.wrapColumn) {
  2096. joined = lines_1.fromString(",\n").join(printed);
  2097. if (util.isTrailingCommaEnabled(options, "parameters") &&
  2098. !fun.rest &&
  2099. params[params.length - 1].type !== 'RestElement') {
  2100. joined = lines_1.concat([joined, ",\n"]);
  2101. }
  2102. else {
  2103. joined = lines_1.concat([joined, "\n"]);
  2104. }
  2105. return lines_1.concat(["\n", joined.indent(options.tabWidth)]);
  2106. }
  2107. return joined;
  2108. }
  2109. function printExportDeclaration(path, options, print) {
  2110. var decl = path.getValue();
  2111. var parts = ["export "];
  2112. if (decl.exportKind && decl.exportKind !== "value") {
  2113. parts.push(decl.exportKind + " ");
  2114. }
  2115. var shouldPrintSpaces = options.objectCurlySpacing;
  2116. namedTypes.Declaration.assert(decl);
  2117. if (decl["default"] ||
  2118. decl.type === "ExportDefaultDeclaration") {
  2119. parts.push("default ");
  2120. }
  2121. if (decl.declaration) {
  2122. parts.push(path.call(print, "declaration"));
  2123. }
  2124. else if (decl.specifiers) {
  2125. if (decl.specifiers.length === 1 &&
  2126. decl.specifiers[0].type === "ExportBatchSpecifier") {
  2127. parts.push("*");
  2128. }
  2129. else if (decl.specifiers.length === 0) {
  2130. parts.push("{}");
  2131. }
  2132. else if (decl.specifiers[0].type === 'ExportDefaultSpecifier') {
  2133. var unbracedSpecifiers_2 = [];
  2134. var bracedSpecifiers_2 = [];
  2135. path.each(function (specifierPath) {
  2136. var spec = specifierPath.getValue();
  2137. if (spec.type === "ExportDefaultSpecifier") {
  2138. unbracedSpecifiers_2.push(print(specifierPath));
  2139. }
  2140. else {
  2141. bracedSpecifiers_2.push(print(specifierPath));
  2142. }
  2143. }, "specifiers");
  2144. unbracedSpecifiers_2.forEach(function (lines, i) {
  2145. if (i > 0) {
  2146. parts.push(", ");
  2147. }
  2148. parts.push(lines);
  2149. });
  2150. if (bracedSpecifiers_2.length > 0) {
  2151. var lines_3 = lines_1.fromString(", ").join(bracedSpecifiers_2);
  2152. if (lines_3.getLineLength(1) > options.wrapColumn) {
  2153. lines_3 = lines_1.concat([
  2154. lines_1.fromString(",\n").join(bracedSpecifiers_2).indent(options.tabWidth),
  2155. ","
  2156. ]);
  2157. }
  2158. if (unbracedSpecifiers_2.length > 0) {
  2159. parts.push(", ");
  2160. }
  2161. if (lines_3.length > 1) {
  2162. parts.push("{\n", lines_3, "\n}");
  2163. }
  2164. else if (options.objectCurlySpacing) {
  2165. parts.push("{ ", lines_3, " }");
  2166. }
  2167. else {
  2168. parts.push("{", lines_3, "}");
  2169. }
  2170. }
  2171. }
  2172. else {
  2173. parts.push(shouldPrintSpaces ? "{ " : "{", lines_1.fromString(", ").join(path.map(print, "specifiers")), shouldPrintSpaces ? " }" : "}");
  2174. }
  2175. if (decl.source) {
  2176. parts.push(" from ", path.call(print, "source"));
  2177. }
  2178. }
  2179. var lines = lines_1.concat(parts);
  2180. if (lastNonSpaceCharacter(lines) !== ";" &&
  2181. !(decl.declaration &&
  2182. (decl.declaration.type === "FunctionDeclaration" ||
  2183. decl.declaration.type === "ClassDeclaration" ||
  2184. decl.declaration.type === "TSModuleDeclaration" ||
  2185. decl.declaration.type === "TSInterfaceDeclaration" ||
  2186. decl.declaration.type === "TSEnumDeclaration"))) {
  2187. lines = lines_1.concat([lines, ";"]);
  2188. }
  2189. return lines;
  2190. }
  2191. function printFlowDeclaration(path, parts) {
  2192. var parentExportDecl = util.getParentExportDeclaration(path);
  2193. if (parentExportDecl) {
  2194. assert_1.default.strictEqual(parentExportDecl.type, "DeclareExportDeclaration");
  2195. }
  2196. else {
  2197. // If the parent node has type DeclareExportDeclaration, then it
  2198. // will be responsible for printing the "declare" token. Otherwise
  2199. // it needs to be printed with this non-exported declaration node.
  2200. parts.unshift("declare ");
  2201. }
  2202. return lines_1.concat(parts);
  2203. }
  2204. function printVariance(path, print) {
  2205. return path.call(function (variancePath) {
  2206. var value = variancePath.getValue();
  2207. if (value) {
  2208. if (value === "plus") {
  2209. return lines_1.fromString("+");
  2210. }
  2211. if (value === "minus") {
  2212. return lines_1.fromString("-");
  2213. }
  2214. return print(variancePath);
  2215. }
  2216. return lines_1.fromString("");
  2217. }, "variance");
  2218. }
  2219. function adjustClause(clause, options) {
  2220. if (clause.length > 1)
  2221. return lines_1.concat([" ", clause]);
  2222. return lines_1.concat([
  2223. "\n",
  2224. maybeAddSemicolon(clause).indent(options.tabWidth)
  2225. ]);
  2226. }
  2227. function lastNonSpaceCharacter(lines) {
  2228. var pos = lines.lastPos();
  2229. do {
  2230. var ch = lines.charAt(pos);
  2231. if (/\S/.test(ch))
  2232. return ch;
  2233. } while (lines.prevPos(pos));
  2234. }
  2235. function endsWithBrace(lines) {
  2236. return lastNonSpaceCharacter(lines) === "}";
  2237. }
  2238. function swapQuotes(str) {
  2239. return str.replace(/['"]/g, function (m) {
  2240. return m === '"' ? '\'' : '"';
  2241. });
  2242. }
  2243. function nodeStr(str, options) {
  2244. isString.assert(str);
  2245. switch (options.quote) {
  2246. case "auto":
  2247. var double = JSON.stringify(str);
  2248. var single = swapQuotes(JSON.stringify(swapQuotes(str)));
  2249. return double.length > single.length ? single : double;
  2250. case "single":
  2251. return swapQuotes(JSON.stringify(swapQuotes(str)));
  2252. case "double":
  2253. default:
  2254. return JSON.stringify(str);
  2255. }
  2256. }
  2257. function maybeAddSemicolon(lines) {
  2258. var eoc = lastNonSpaceCharacter(lines);
  2259. if (!eoc || "\n};".indexOf(eoc) < 0)
  2260. return lines_1.concat([lines, ";"]);
  2261. return lines;
  2262. }