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.

2248 lines
87 KiB

5 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(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. var key = path.call(print, "key");
  582. if (n.computed) {
  583. parts.push("[", key, "]");
  584. }
  585. else {
  586. parts.push(key);
  587. }
  588. if (!n.shorthand) {
  589. parts.push(": ", path.call(print, "value"));
  590. }
  591. return lines_1.concat(parts);
  592. case "ClassMethod": // Babel 6
  593. case "ObjectMethod": // Babel 6
  594. case "ClassPrivateMethod":
  595. case "TSDeclareMethod":
  596. return printMethod(path, options, print);
  597. case "PrivateName":
  598. return lines_1.concat(["#", path.call(print, "id")]);
  599. case "Decorator":
  600. return lines_1.concat(["@", path.call(print, "expression")]);
  601. case "ArrayExpression":
  602. case "ArrayPattern":
  603. var elems = n.elements, len = elems.length;
  604. var printed = path.map(print, "elements");
  605. var joined = lines_1.fromString(", ").join(printed);
  606. var oneLine = joined.getLineLength(1) <= options.wrapColumn;
  607. if (oneLine) {
  608. if (options.arrayBracketSpacing) {
  609. parts.push("[ ");
  610. }
  611. else {
  612. parts.push("[");
  613. }
  614. }
  615. else {
  616. parts.push("[\n");
  617. }
  618. path.each(function (elemPath) {
  619. var i = elemPath.getName();
  620. var elem = elemPath.getValue();
  621. if (!elem) {
  622. // If the array expression ends with a hole, that hole
  623. // will be ignored by the interpreter, but if it ends with
  624. // two (or more) holes, we need to write out two (or more)
  625. // commas so that the resulting code is interpreted with
  626. // both (all) of the holes.
  627. parts.push(",");
  628. }
  629. else {
  630. var lines = printed[i];
  631. if (oneLine) {
  632. if (i > 0)
  633. parts.push(" ");
  634. }
  635. else {
  636. lines = lines.indent(options.tabWidth);
  637. }
  638. parts.push(lines);
  639. if (i < len - 1 || (!oneLine && util.isTrailingCommaEnabled(options, "arrays")))
  640. parts.push(",");
  641. if (!oneLine)
  642. parts.push("\n");
  643. }
  644. }, "elements");
  645. if (oneLine && options.arrayBracketSpacing) {
  646. parts.push(" ]");
  647. }
  648. else {
  649. parts.push("]");
  650. }
  651. return lines_1.concat(parts);
  652. case "SequenceExpression":
  653. return lines_1.fromString(", ").join(path.map(print, "expressions"));
  654. case "ThisExpression":
  655. return lines_1.fromString("this");
  656. case "Super":
  657. return lines_1.fromString("super");
  658. case "NullLiteral": // Babel 6 Literal split
  659. return lines_1.fromString("null");
  660. case "RegExpLiteral": // Babel 6 Literal split
  661. return lines_1.fromString(n.extra.raw);
  662. case "BigIntLiteral": // Babel 7 Literal split
  663. return lines_1.fromString(n.value + "n");
  664. case "NumericLiteral": // Babel 6 Literal Split
  665. // Keep original representation for numeric values not in base 10.
  666. if (n.extra &&
  667. typeof n.extra.raw === "string" &&
  668. Number(n.extra.raw) === n.value) {
  669. return lines_1.fromString(n.extra.raw, options);
  670. }
  671. return lines_1.fromString(n.value, options);
  672. case "BooleanLiteral": // Babel 6 Literal split
  673. case "StringLiteral": // Babel 6 Literal split
  674. case "Literal":
  675. // Numeric values may be in bases other than 10. Use their raw
  676. // representation if equivalent.
  677. if (typeof n.value === "number" &&
  678. typeof n.raw === "string" &&
  679. Number(n.raw) === n.value) {
  680. return lines_1.fromString(n.raw, options);
  681. }
  682. if (typeof n.value !== "string") {
  683. return lines_1.fromString(n.value, options);
  684. }
  685. return lines_1.fromString(nodeStr(n.value, options), options);
  686. case "Directive": // Babel 6
  687. return path.call(print, "value");
  688. case "DirectiveLiteral": // Babel 6
  689. return lines_1.fromString(nodeStr(n.value, options));
  690. case "InterpreterDirective":
  691. return lines_1.fromString("#!" + n.value + "\n", options);
  692. case "ModuleSpecifier":
  693. if (n.local) {
  694. throw new Error("The ESTree ModuleSpecifier type should be abstract");
  695. }
  696. // The Esprima ModuleSpecifier type is just a string-valued
  697. // Literal identifying the imported-from module.
  698. return lines_1.fromString(nodeStr(n.value, options), options);
  699. case "UnaryExpression":
  700. parts.push(n.operator);
  701. if (/[a-z]$/.test(n.operator))
  702. parts.push(" ");
  703. parts.push(path.call(print, "argument"));
  704. return lines_1.concat(parts);
  705. case "UpdateExpression":
  706. parts.push(path.call(print, "argument"), n.operator);
  707. if (n.prefix)
  708. parts.reverse();
  709. return lines_1.concat(parts);
  710. case "ConditionalExpression":
  711. return lines_1.concat([
  712. path.call(print, "test"),
  713. " ? ", path.call(print, "consequent"),
  714. " : ", path.call(print, "alternate")
  715. ]);
  716. case "NewExpression":
  717. parts.push("new ", path.call(print, "callee"));
  718. if (n.typeParameters) {
  719. parts.push(path.call(print, "typeParameters"));
  720. }
  721. if (n.typeArguments) {
  722. parts.push(path.call(print, "typeArguments"));
  723. }
  724. var args = n.arguments;
  725. if (args) {
  726. parts.push(printArgumentsList(path, options, print));
  727. }
  728. return lines_1.concat(parts);
  729. case "VariableDeclaration":
  730. if (n.declare) {
  731. parts.push("declare ");
  732. }
  733. parts.push(n.kind, " ");
  734. var maxLen = 0;
  735. var printed = path.map(function (childPath) {
  736. var lines = print(childPath);
  737. maxLen = Math.max(lines.length, maxLen);
  738. return lines;
  739. }, "declarations");
  740. if (maxLen === 1) {
  741. parts.push(lines_1.fromString(", ").join(printed));
  742. }
  743. else if (printed.length > 1) {
  744. parts.push(lines_1.fromString(",\n").join(printed)
  745. .indentTail(n.kind.length + 1));
  746. }
  747. else {
  748. parts.push(printed[0]);
  749. }
  750. // We generally want to terminate all variable declarations with a
  751. // semicolon, except when they are children of for loops.
  752. var parentNode = path.getParentNode();
  753. if (!namedTypes.ForStatement.check(parentNode) &&
  754. !namedTypes.ForInStatement.check(parentNode) &&
  755. !(namedTypes.ForOfStatement &&
  756. namedTypes.ForOfStatement.check(parentNode)) &&
  757. !(namedTypes.ForAwaitStatement &&
  758. namedTypes.ForAwaitStatement.check(parentNode))) {
  759. parts.push(";");
  760. }
  761. return lines_1.concat(parts);
  762. case "VariableDeclarator":
  763. return n.init ? lines_1.fromString(" = ").join([
  764. path.call(print, "id"),
  765. path.call(print, "init")
  766. ]) : path.call(print, "id");
  767. case "WithStatement":
  768. return lines_1.concat([
  769. "with (",
  770. path.call(print, "object"),
  771. ") ",
  772. path.call(print, "body")
  773. ]);
  774. case "IfStatement":
  775. var con = adjustClause(path.call(print, "consequent"), options);
  776. parts.push("if (", path.call(print, "test"), ")", con);
  777. if (n.alternate)
  778. parts.push(endsWithBrace(con) ? " else" : "\nelse", adjustClause(path.call(print, "alternate"), options));
  779. return lines_1.concat(parts);
  780. case "ForStatement":
  781. // TODO Get the for (;;) case right.
  782. var init = path.call(print, "init"), sep = init.length > 1 ? ";\n" : "; ", forParen = "for (", indented = lines_1.fromString(sep).join([
  783. init,
  784. path.call(print, "test"),
  785. path.call(print, "update")
  786. ]).indentTail(forParen.length), head = lines_1.concat([forParen, indented, ")"]), clause = adjustClause(path.call(print, "body"), options);
  787. parts.push(head);
  788. if (head.length > 1) {
  789. parts.push("\n");
  790. clause = clause.trimLeft();
  791. }
  792. parts.push(clause);
  793. return lines_1.concat(parts);
  794. case "WhileStatement":
  795. return lines_1.concat([
  796. "while (",
  797. path.call(print, "test"),
  798. ")",
  799. adjustClause(path.call(print, "body"), options)
  800. ]);
  801. case "ForInStatement":
  802. // Note: esprima can't actually parse "for each (".
  803. return lines_1.concat([
  804. n.each ? "for each (" : "for (",
  805. path.call(print, "left"),
  806. " in ",
  807. path.call(print, "right"),
  808. ")",
  809. adjustClause(path.call(print, "body"), options)
  810. ]);
  811. case "ForOfStatement":
  812. case "ForAwaitStatement":
  813. parts.push("for ");
  814. if (n.await || n.type === "ForAwaitStatement") {
  815. parts.push("await ");
  816. }
  817. parts.push("(", path.call(print, "left"), " of ", path.call(print, "right"), ")", adjustClause(path.call(print, "body"), options));
  818. return lines_1.concat(parts);
  819. case "DoWhileStatement":
  820. var doBody = lines_1.concat([
  821. "do",
  822. adjustClause(path.call(print, "body"), options)
  823. ]);
  824. parts.push(doBody);
  825. if (endsWithBrace(doBody))
  826. parts.push(" while");
  827. else
  828. parts.push("\nwhile");
  829. parts.push(" (", path.call(print, "test"), ");");
  830. return lines_1.concat(parts);
  831. case "DoExpression":
  832. var statements = path.call(function (bodyPath) {
  833. return printStatementSequence(bodyPath, options, print);
  834. }, "body");
  835. return lines_1.concat([
  836. "do {\n",
  837. statements.indent(options.tabWidth),
  838. "\n}"
  839. ]);
  840. case "BreakStatement":
  841. parts.push("break");
  842. if (n.label)
  843. parts.push(" ", path.call(print, "label"));
  844. parts.push(";");
  845. return lines_1.concat(parts);
  846. case "ContinueStatement":
  847. parts.push("continue");
  848. if (n.label)
  849. parts.push(" ", path.call(print, "label"));
  850. parts.push(";");
  851. return lines_1.concat(parts);
  852. case "LabeledStatement":
  853. return lines_1.concat([
  854. path.call(print, "label"),
  855. ":\n",
  856. path.call(print, "body")
  857. ]);
  858. case "TryStatement":
  859. parts.push("try ", path.call(print, "block"));
  860. if (n.handler) {
  861. parts.push(" ", path.call(print, "handler"));
  862. }
  863. else if (n.handlers) {
  864. path.each(function (handlerPath) {
  865. parts.push(" ", print(handlerPath));
  866. }, "handlers");
  867. }
  868. if (n.finalizer) {
  869. parts.push(" finally ", path.call(print, "finalizer"));
  870. }
  871. return lines_1.concat(parts);
  872. case "CatchClause":
  873. parts.push("catch ");
  874. if (n.param) {
  875. parts.push("(", path.call(print, "param"));
  876. }
  877. if (n.guard) {
  878. // Note: esprima does not recognize conditional catch clauses.
  879. parts.push(" if ", path.call(print, "guard"));
  880. }
  881. if (n.param) {
  882. parts.push(") ");
  883. }
  884. parts.push(path.call(print, "body"));
  885. return lines_1.concat(parts);
  886. case "ThrowStatement":
  887. return lines_1.concat(["throw ", path.call(print, "argument"), ";"]);
  888. case "SwitchStatement":
  889. return lines_1.concat([
  890. "switch (",
  891. path.call(print, "discriminant"),
  892. ") {\n",
  893. lines_1.fromString("\n").join(path.map(print, "cases")),
  894. "\n}"
  895. ]);
  896. // Note: ignoring n.lexical because it has no printing consequences.
  897. case "SwitchCase":
  898. if (n.test)
  899. parts.push("case ", path.call(print, "test"), ":");
  900. else
  901. parts.push("default:");
  902. if (n.consequent.length > 0) {
  903. parts.push("\n", path.call(function (consequentPath) {
  904. return printStatementSequence(consequentPath, options, print);
  905. }, "consequent").indent(options.tabWidth));
  906. }
  907. return lines_1.concat(parts);
  908. case "DebuggerStatement":
  909. return lines_1.fromString("debugger;");
  910. // JSX extensions below.
  911. case "JSXAttribute":
  912. parts.push(path.call(print, "name"));
  913. if (n.value)
  914. parts.push("=", path.call(print, "value"));
  915. return lines_1.concat(parts);
  916. case "JSXIdentifier":
  917. return lines_1.fromString(n.name, options);
  918. case "JSXNamespacedName":
  919. return lines_1.fromString(":").join([
  920. path.call(print, "namespace"),
  921. path.call(print, "name")
  922. ]);
  923. case "JSXMemberExpression":
  924. return lines_1.fromString(".").join([
  925. path.call(print, "object"),
  926. path.call(print, "property")
  927. ]);
  928. case "JSXSpreadAttribute":
  929. return lines_1.concat(["{...", path.call(print, "argument"), "}"]);
  930. case "JSXSpreadChild":
  931. return lines_1.concat(["{...", path.call(print, "expression"), "}"]);
  932. case "JSXExpressionContainer":
  933. return lines_1.concat(["{", path.call(print, "expression"), "}"]);
  934. case "JSXElement":
  935. case "JSXFragment":
  936. var openingPropName = "opening" + (n.type === "JSXElement" ? "Element" : "Fragment");
  937. var closingPropName = "closing" + (n.type === "JSXElement" ? "Element" : "Fragment");
  938. var openingLines = path.call(print, openingPropName);
  939. if (n[openingPropName].selfClosing) {
  940. assert_1.default.ok(!n[closingPropName], "unexpected " + closingPropName + " element in self-closing " + n.type);
  941. return openingLines;
  942. }
  943. var childLines = lines_1.concat(path.map(function (childPath) {
  944. var child = childPath.getValue();
  945. if (namedTypes.Literal.check(child) &&
  946. typeof child.value === "string") {
  947. if (/\S/.test(child.value)) {
  948. return child.value.replace(/^\s+|\s+$/g, "");
  949. }
  950. else if (/\n/.test(child.value)) {
  951. return "\n";
  952. }
  953. }
  954. return print(childPath);
  955. }, "children")).indentTail(options.tabWidth);
  956. var closingLines = path.call(print, closingPropName);
  957. return lines_1.concat([
  958. openingLines,
  959. childLines,
  960. closingLines
  961. ]);
  962. case "JSXOpeningElement":
  963. parts.push("<", path.call(print, "name"));
  964. var attrParts = [];
  965. path.each(function (attrPath) {
  966. attrParts.push(" ", print(attrPath));
  967. }, "attributes");
  968. var attrLines = lines_1.concat(attrParts);
  969. var needLineWrap = (attrLines.length > 1 ||
  970. attrLines.getLineLength(1) > options.wrapColumn);
  971. if (needLineWrap) {
  972. attrParts.forEach(function (part, i) {
  973. if (part === " ") {
  974. assert_1.default.strictEqual(i % 2, 0);
  975. attrParts[i] = "\n";
  976. }
  977. });
  978. attrLines = lines_1.concat(attrParts).indentTail(options.tabWidth);
  979. }
  980. parts.push(attrLines, n.selfClosing ? " />" : ">");
  981. return lines_1.concat(parts);
  982. case "JSXClosingElement":
  983. return lines_1.concat(["</", path.call(print, "name"), ">"]);
  984. case "JSXOpeningFragment":
  985. return lines_1.fromString("<>");
  986. case "JSXClosingFragment":
  987. return lines_1.fromString("</>");
  988. case "JSXText":
  989. return lines_1.fromString(n.value, options);
  990. case "JSXEmptyExpression":
  991. return lines_1.fromString("");
  992. case "TypeAnnotatedIdentifier":
  993. return lines_1.concat([
  994. path.call(print, "annotation"),
  995. " ",
  996. path.call(print, "identifier")
  997. ]);
  998. case "ClassBody":
  999. if (n.body.length === 0) {
  1000. return lines_1.fromString("{}");
  1001. }
  1002. return lines_1.concat([
  1003. "{\n",
  1004. path.call(function (bodyPath) {
  1005. return printStatementSequence(bodyPath, options, print);
  1006. }, "body").indent(options.tabWidth),
  1007. "\n}"
  1008. ]);
  1009. case "ClassPropertyDefinition":
  1010. parts.push("static ", path.call(print, "definition"));
  1011. if (!namedTypes.MethodDefinition.check(n.definition))
  1012. parts.push(";");
  1013. return lines_1.concat(parts);
  1014. case "ClassProperty":
  1015. var access = n.accessibility || n.access;
  1016. if (typeof access === "string") {
  1017. parts.push(access, " ");
  1018. }
  1019. if (n.static) {
  1020. parts.push("static ");
  1021. }
  1022. if (n.abstract) {
  1023. parts.push("abstract ");
  1024. }
  1025. if (n.readonly) {
  1026. parts.push("readonly ");
  1027. }
  1028. var key = path.call(print, "key");
  1029. if (n.computed) {
  1030. key = lines_1.concat(["[", key, "]"]);
  1031. }
  1032. if (n.variance) {
  1033. key = lines_1.concat([printVariance(path, print), key]);
  1034. }
  1035. parts.push(key);
  1036. if (n.optional) {
  1037. parts.push("?");
  1038. }
  1039. if (n.typeAnnotation) {
  1040. parts.push(path.call(print, "typeAnnotation"));
  1041. }
  1042. if (n.value) {
  1043. parts.push(" = ", path.call(print, "value"));
  1044. }
  1045. parts.push(";");
  1046. return lines_1.concat(parts);
  1047. case "ClassPrivateProperty":
  1048. if (n.static) {
  1049. parts.push("static ");
  1050. }
  1051. parts.push(path.call(print, "key"));
  1052. if (n.typeAnnotation) {
  1053. parts.push(path.call(print, "typeAnnotation"));
  1054. }
  1055. if (n.value) {
  1056. parts.push(" = ", path.call(print, "value"));
  1057. }
  1058. parts.push(";");
  1059. return lines_1.concat(parts);
  1060. case "ClassDeclaration":
  1061. case "ClassExpression":
  1062. if (n.declare) {
  1063. parts.push("declare ");
  1064. }
  1065. if (n.abstract) {
  1066. parts.push("abstract ");
  1067. }
  1068. parts.push("class");
  1069. if (n.id) {
  1070. parts.push(" ", path.call(print, "id"));
  1071. }
  1072. if (n.typeParameters) {
  1073. parts.push(path.call(print, "typeParameters"));
  1074. }
  1075. if (n.superClass) {
  1076. parts.push(" extends ", path.call(print, "superClass"), path.call(print, "superTypeParameters"));
  1077. }
  1078. if (n["implements"] && n['implements'].length > 0) {
  1079. parts.push(" implements ", lines_1.fromString(", ").join(path.map(print, "implements")));
  1080. }
  1081. parts.push(" ", path.call(print, "body"));
  1082. return lines_1.concat(parts);
  1083. case "TemplateElement":
  1084. return lines_1.fromString(n.value.raw, options).lockIndentTail();
  1085. case "TemplateLiteral":
  1086. var expressions = path.map(print, "expressions");
  1087. parts.push("`");
  1088. path.each(function (childPath) {
  1089. var i = childPath.getName();
  1090. parts.push(print(childPath));
  1091. if (i < expressions.length) {
  1092. parts.push("${", expressions[i], "}");
  1093. }
  1094. }, "quasis");
  1095. parts.push("`");
  1096. return lines_1.concat(parts).lockIndentTail();
  1097. case "TaggedTemplateExpression":
  1098. return lines_1.concat([
  1099. path.call(print, "tag"),
  1100. path.call(print, "quasi")
  1101. ]);
  1102. // These types are unprintable because they serve as abstract
  1103. // supertypes for other (printable) types.
  1104. case "Node":
  1105. case "Printable":
  1106. case "SourceLocation":
  1107. case "Position":
  1108. case "Statement":
  1109. case "Function":
  1110. case "Pattern":
  1111. case "Expression":
  1112. case "Declaration":
  1113. case "Specifier":
  1114. case "NamedSpecifier":
  1115. case "Comment": // Supertype of Block and Line
  1116. case "Flow": // Supertype of all Flow AST node types
  1117. case "FlowType": // Supertype of all Flow types
  1118. case "FlowPredicate": // Supertype of InferredPredicate and DeclaredPredicate
  1119. case "MemberTypeAnnotation": // Flow
  1120. case "Type": // Flow
  1121. case "TSHasOptionalTypeParameterInstantiation":
  1122. case "TSHasOptionalTypeParameters":
  1123. case "TSHasOptionalTypeAnnotation":
  1124. throw new Error("unprintable type: " + JSON.stringify(n.type));
  1125. case "CommentBlock": // Babel block comment.
  1126. case "Block": // Esprima block comment.
  1127. return lines_1.concat(["/*", lines_1.fromString(n.value, options), "*/"]);
  1128. case "CommentLine": // Babel line comment.
  1129. case "Line": // Esprima line comment.
  1130. return lines_1.concat(["//", lines_1.fromString(n.value, options)]);
  1131. // Type Annotations for Facebook Flow, typically stripped out or
  1132. // transformed away before printing.
  1133. case "TypeAnnotation":
  1134. if (n.typeAnnotation) {
  1135. if (n.typeAnnotation.type !== "FunctionTypeAnnotation") {
  1136. parts.push(": ");
  1137. }
  1138. parts.push(path.call(print, "typeAnnotation"));
  1139. return lines_1.concat(parts);
  1140. }
  1141. return lines_1.fromString("");
  1142. case "ExistentialTypeParam":
  1143. case "ExistsTypeAnnotation":
  1144. return lines_1.fromString("*", options);
  1145. case "EmptyTypeAnnotation":
  1146. return lines_1.fromString("empty", options);
  1147. case "AnyTypeAnnotation":
  1148. return lines_1.fromString("any", options);
  1149. case "MixedTypeAnnotation":
  1150. return lines_1.fromString("mixed", options);
  1151. case "ArrayTypeAnnotation":
  1152. return lines_1.concat([
  1153. path.call(print, "elementType"),
  1154. "[]"
  1155. ]);
  1156. case "TupleTypeAnnotation":
  1157. var printed = path.map(print, "types");
  1158. var joined = lines_1.fromString(", ").join(printed);
  1159. var oneLine = joined.getLineLength(1) <= options.wrapColumn;
  1160. if (oneLine) {
  1161. if (options.arrayBracketSpacing) {
  1162. parts.push("[ ");
  1163. }
  1164. else {
  1165. parts.push("[");
  1166. }
  1167. }
  1168. else {
  1169. parts.push("[\n");
  1170. }
  1171. path.each(function (elemPath) {
  1172. var i = elemPath.getName();
  1173. var elem = elemPath.getValue();
  1174. if (!elem) {
  1175. // If the array expression ends with a hole, that hole
  1176. // will be ignored by the interpreter, but if it ends with
  1177. // two (or more) holes, we need to write out two (or more)
  1178. // commas so that the resulting code is interpreted with
  1179. // both (all) of the holes.
  1180. parts.push(",");
  1181. }
  1182. else {
  1183. var lines = printed[i];
  1184. if (oneLine) {
  1185. if (i > 0)
  1186. parts.push(" ");
  1187. }
  1188. else {
  1189. lines = lines.indent(options.tabWidth);
  1190. }
  1191. parts.push(lines);
  1192. if (i < n.types.length - 1 || (!oneLine && util.isTrailingCommaEnabled(options, "arrays")))
  1193. parts.push(",");
  1194. if (!oneLine)
  1195. parts.push("\n");
  1196. }
  1197. }, "types");
  1198. if (oneLine && options.arrayBracketSpacing) {
  1199. parts.push(" ]");
  1200. }
  1201. else {
  1202. parts.push("]");
  1203. }
  1204. return lines_1.concat(parts);
  1205. case "BooleanTypeAnnotation":
  1206. return lines_1.fromString("boolean", options);
  1207. case "BooleanLiteralTypeAnnotation":
  1208. assert_1.default.strictEqual(typeof n.value, "boolean");
  1209. return lines_1.fromString("" + n.value, options);
  1210. case "InterfaceTypeAnnotation":
  1211. parts.push("interface");
  1212. if (n.extends && n.extends.length > 0) {
  1213. parts.push(" extends ", lines_1.fromString(", ").join(path.map(print, "extends")));
  1214. }
  1215. parts.push(" ", path.call(print, "body"));
  1216. return lines_1.concat(parts);
  1217. case "DeclareClass":
  1218. return printFlowDeclaration(path, [
  1219. "class ",
  1220. path.call(print, "id"),
  1221. " ",
  1222. path.call(print, "body"),
  1223. ]);
  1224. case "DeclareFunction":
  1225. return printFlowDeclaration(path, [
  1226. "function ",
  1227. path.call(print, "id"),
  1228. ";"
  1229. ]);
  1230. case "DeclareModule":
  1231. return printFlowDeclaration(path, [
  1232. "module ",
  1233. path.call(print, "id"),
  1234. " ",
  1235. path.call(print, "body"),
  1236. ]);
  1237. case "DeclareModuleExports":
  1238. return printFlowDeclaration(path, [
  1239. "module.exports",
  1240. path.call(print, "typeAnnotation"),
  1241. ]);
  1242. case "DeclareVariable":
  1243. return printFlowDeclaration(path, [
  1244. "var ",
  1245. path.call(print, "id"),
  1246. ";"
  1247. ]);
  1248. case "DeclareExportDeclaration":
  1249. case "DeclareExportAllDeclaration":
  1250. return lines_1.concat([
  1251. "declare ",
  1252. printExportDeclaration(path, options, print)
  1253. ]);
  1254. case "InferredPredicate":
  1255. return lines_1.fromString("%checks", options);
  1256. case "DeclaredPredicate":
  1257. return lines_1.concat([
  1258. "%checks(",
  1259. path.call(print, "value"),
  1260. ")"
  1261. ]);
  1262. case "FunctionTypeAnnotation":
  1263. // FunctionTypeAnnotation is ambiguous:
  1264. // declare function(a: B): void; OR
  1265. // var A: (a: B) => void;
  1266. var parent = path.getParentNode(0);
  1267. var isArrowFunctionTypeAnnotation = !(namedTypes.ObjectTypeCallProperty.check(parent) ||
  1268. (namedTypes.ObjectTypeInternalSlot.check(parent) && parent.method) ||
  1269. namedTypes.DeclareFunction.check(path.getParentNode(2)));
  1270. var needsColon = isArrowFunctionTypeAnnotation &&
  1271. !namedTypes.FunctionTypeParam.check(parent);
  1272. if (needsColon) {
  1273. parts.push(": ");
  1274. }
  1275. parts.push("(", printFunctionParams(path, options, print), ")");
  1276. // The returnType is not wrapped in a TypeAnnotation, so the colon
  1277. // needs to be added separately.
  1278. if (n.returnType) {
  1279. parts.push(isArrowFunctionTypeAnnotation ? " => " : ": ", path.call(print, "returnType"));
  1280. }
  1281. return lines_1.concat(parts);
  1282. case "FunctionTypeParam":
  1283. return lines_1.concat([
  1284. path.call(print, "name"),
  1285. n.optional ? '?' : '',
  1286. ": ",
  1287. path.call(print, "typeAnnotation"),
  1288. ]);
  1289. case "GenericTypeAnnotation":
  1290. return lines_1.concat([
  1291. path.call(print, "id"),
  1292. path.call(print, "typeParameters")
  1293. ]);
  1294. case "DeclareInterface":
  1295. parts.push("declare ");
  1296. // Fall through to InterfaceDeclaration...
  1297. case "InterfaceDeclaration":
  1298. case "TSInterfaceDeclaration":
  1299. if (n.declare) {
  1300. parts.push("declare ");
  1301. }
  1302. parts.push("interface ", path.call(print, "id"), path.call(print, "typeParameters"), " ");
  1303. if (n["extends"] && n["extends"].length > 0) {
  1304. parts.push("extends ", lines_1.fromString(", ").join(path.map(print, "extends")), " ");
  1305. }
  1306. if (n.body) {
  1307. parts.push(path.call(print, "body"));
  1308. }
  1309. return lines_1.concat(parts);
  1310. case "ClassImplements":
  1311. case "InterfaceExtends":
  1312. return lines_1.concat([
  1313. path.call(print, "id"),
  1314. path.call(print, "typeParameters")
  1315. ]);
  1316. case "IntersectionTypeAnnotation":
  1317. return lines_1.fromString(" & ").join(path.map(print, "types"));
  1318. case "NullableTypeAnnotation":
  1319. return lines_1.concat([
  1320. "?",
  1321. path.call(print, "typeAnnotation")
  1322. ]);
  1323. case "NullLiteralTypeAnnotation":
  1324. return lines_1.fromString("null", options);
  1325. case "ThisTypeAnnotation":
  1326. return lines_1.fromString("this", options);
  1327. case "NumberTypeAnnotation":
  1328. return lines_1.fromString("number", options);
  1329. case "ObjectTypeCallProperty":
  1330. return path.call(print, "value");
  1331. case "ObjectTypeIndexer":
  1332. return lines_1.concat([
  1333. printVariance(path, print),
  1334. "[",
  1335. path.call(print, "id"),
  1336. ": ",
  1337. path.call(print, "key"),
  1338. "]: ",
  1339. path.call(print, "value")
  1340. ]);
  1341. case "ObjectTypeProperty":
  1342. return lines_1.concat([
  1343. printVariance(path, print),
  1344. path.call(print, "key"),
  1345. n.optional ? "?" : "",
  1346. ": ",
  1347. path.call(print, "value")
  1348. ]);
  1349. case "ObjectTypeInternalSlot":
  1350. return lines_1.concat([
  1351. n.static ? "static " : "",
  1352. "[[",
  1353. path.call(print, "id"),
  1354. "]]",
  1355. n.optional ? "?" : "",
  1356. n.value.type !== "FunctionTypeAnnotation" ? ": " : "",
  1357. path.call(print, "value")
  1358. ]);
  1359. case "QualifiedTypeIdentifier":
  1360. return lines_1.concat([
  1361. path.call(print, "qualification"),
  1362. ".",
  1363. path.call(print, "id")
  1364. ]);
  1365. case "StringLiteralTypeAnnotation":
  1366. return lines_1.fromString(nodeStr(n.value, options), options);
  1367. case "NumberLiteralTypeAnnotation":
  1368. case "NumericLiteralTypeAnnotation":
  1369. assert_1.default.strictEqual(typeof n.value, "number");
  1370. return lines_1.fromString(JSON.stringify(n.value), options);
  1371. case "StringTypeAnnotation":
  1372. return lines_1.fromString("string", options);
  1373. case "DeclareTypeAlias":
  1374. parts.push("declare ");
  1375. // Fall through to TypeAlias...
  1376. case "TypeAlias":
  1377. return lines_1.concat([
  1378. "type ",
  1379. path.call(print, "id"),
  1380. path.call(print, "typeParameters"),
  1381. " = ",
  1382. path.call(print, "right"),
  1383. ";"
  1384. ]);
  1385. case "DeclareOpaqueType":
  1386. parts.push("declare ");
  1387. // Fall through to OpaqueType...
  1388. case "OpaqueType":
  1389. parts.push("opaque type ", path.call(print, "id"), path.call(print, "typeParameters"));
  1390. if (n["supertype"]) {
  1391. parts.push(": ", path.call(print, "supertype"));
  1392. }
  1393. if (n["impltype"]) {
  1394. parts.push(" = ", path.call(print, "impltype"));
  1395. }
  1396. parts.push(";");
  1397. return lines_1.concat(parts);
  1398. case "TypeCastExpression":
  1399. return lines_1.concat([
  1400. "(",
  1401. path.call(print, "expression"),
  1402. path.call(print, "typeAnnotation"),
  1403. ")"
  1404. ]);
  1405. case "TypeParameterDeclaration":
  1406. case "TypeParameterInstantiation":
  1407. return lines_1.concat([
  1408. "<",
  1409. lines_1.fromString(", ").join(path.map(print, "params")),
  1410. ">"
  1411. ]);
  1412. case "Variance":
  1413. if (n.kind === "plus") {
  1414. return lines_1.fromString("+");
  1415. }
  1416. if (n.kind === "minus") {
  1417. return lines_1.fromString("-");
  1418. }
  1419. return lines_1.fromString("");
  1420. case "TypeParameter":
  1421. if (n.variance) {
  1422. parts.push(printVariance(path, print));
  1423. }
  1424. parts.push(path.call(print, 'name'));
  1425. if (n.bound) {
  1426. parts.push(path.call(print, 'bound'));
  1427. }
  1428. if (n['default']) {
  1429. parts.push('=', path.call(print, 'default'));
  1430. }
  1431. return lines_1.concat(parts);
  1432. case "TypeofTypeAnnotation":
  1433. return lines_1.concat([
  1434. lines_1.fromString("typeof ", options),
  1435. path.call(print, "argument")
  1436. ]);
  1437. case "UnionTypeAnnotation":
  1438. return lines_1.fromString(" | ").join(path.map(print, "types"));
  1439. case "VoidTypeAnnotation":
  1440. return lines_1.fromString("void", options);
  1441. case "NullTypeAnnotation":
  1442. return lines_1.fromString("null", options);
  1443. // Type Annotations for TypeScript (when using Babylon as parser)
  1444. case "TSType":
  1445. throw new Error("unprintable type: " + JSON.stringify(n.type));
  1446. case "TSNumberKeyword":
  1447. return lines_1.fromString("number", options);
  1448. case "TSBigIntKeyword":
  1449. return lines_1.fromString("bigint", options);
  1450. case "TSObjectKeyword":
  1451. return lines_1.fromString("object", options);
  1452. case "TSBooleanKeyword":
  1453. return lines_1.fromString("boolean", options);
  1454. case "TSStringKeyword":
  1455. return lines_1.fromString("string", options);
  1456. case "TSSymbolKeyword":
  1457. return lines_1.fromString("symbol", options);
  1458. case "TSAnyKeyword":
  1459. return lines_1.fromString("any", options);
  1460. case "TSVoidKeyword":
  1461. return lines_1.fromString("void", options);
  1462. case "TSThisType":
  1463. return lines_1.fromString("this", options);
  1464. case "TSNullKeyword":
  1465. return lines_1.fromString("null", options);
  1466. case "TSUndefinedKeyword":
  1467. return lines_1.fromString("undefined", options);
  1468. case "TSUnknownKeyword":
  1469. return lines_1.fromString("unknown", options);
  1470. case "TSNeverKeyword":
  1471. return lines_1.fromString("never", options);
  1472. case "TSArrayType":
  1473. return lines_1.concat([
  1474. path.call(print, "elementType"),
  1475. "[]"
  1476. ]);
  1477. case "TSLiteralType":
  1478. return path.call(print, "literal");
  1479. case "TSUnionType":
  1480. return lines_1.fromString(" | ").join(path.map(print, "types"));
  1481. case "TSIntersectionType":
  1482. return lines_1.fromString(" & ").join(path.map(print, "types"));
  1483. case "TSConditionalType":
  1484. parts.push(path.call(print, "checkType"), " extends ", path.call(print, "extendsType"), " ? ", path.call(print, "trueType"), " : ", path.call(print, "falseType"));
  1485. return lines_1.concat(parts);
  1486. case "TSInferType":
  1487. parts.push("infer ", path.call(print, "typeParameter"));
  1488. return lines_1.concat(parts);
  1489. case "TSParenthesizedType":
  1490. return lines_1.concat([
  1491. "(",
  1492. path.call(print, "typeAnnotation"),
  1493. ")"
  1494. ]);
  1495. case "TSFunctionType":
  1496. case "TSConstructorType":
  1497. return lines_1.concat([
  1498. path.call(print, "typeParameters"),
  1499. "(",
  1500. printFunctionParams(path, options, print),
  1501. ")",
  1502. path.call(print, "typeAnnotation")
  1503. ]);
  1504. case "TSMappedType": {
  1505. parts.push(n.readonly ? "readonly " : "", "[", path.call(print, "typeParameter"), "]", n.optional ? "?" : "");
  1506. if (n.typeAnnotation) {
  1507. parts.push(": ", path.call(print, "typeAnnotation"), ";");
  1508. }
  1509. return lines_1.concat([
  1510. "{\n",
  1511. lines_1.concat(parts).indent(options.tabWidth),
  1512. "\n}",
  1513. ]);
  1514. }
  1515. case "TSTupleType":
  1516. return lines_1.concat([
  1517. "[",
  1518. lines_1.fromString(", ").join(path.map(print, "elementTypes")),
  1519. "]"
  1520. ]);
  1521. case "TSRestType":
  1522. return lines_1.concat([
  1523. "...",
  1524. path.call(print, "typeAnnotation"),
  1525. "[]"
  1526. ]);
  1527. case "TSOptionalType":
  1528. return lines_1.concat([
  1529. path.call(print, "typeAnnotation"),
  1530. "?"
  1531. ]);
  1532. case "TSIndexedAccessType":
  1533. return lines_1.concat([
  1534. path.call(print, "objectType"),
  1535. "[",
  1536. path.call(print, "indexType"),
  1537. "]"
  1538. ]);
  1539. case "TSTypeOperator":
  1540. return lines_1.concat([
  1541. path.call(print, "operator"),
  1542. " ",
  1543. path.call(print, "typeAnnotation")
  1544. ]);
  1545. case "TSTypeLiteral": {
  1546. var memberLines_1 = lines_1.fromString(",\n").join(path.map(print, "members"));
  1547. if (memberLines_1.isEmpty()) {
  1548. return lines_1.fromString("{}", options);
  1549. }
  1550. parts.push("{\n", memberLines_1.indent(options.tabWidth), "\n}");
  1551. return lines_1.concat(parts);
  1552. }
  1553. case "TSEnumMember":
  1554. parts.push(path.call(print, "id"));
  1555. if (n.initializer) {
  1556. parts.push(" = ", path.call(print, "initializer"));
  1557. }
  1558. return lines_1.concat(parts);
  1559. case "TSTypeQuery":
  1560. return lines_1.concat([
  1561. "typeof ",
  1562. path.call(print, "exprName"),
  1563. ]);
  1564. case "TSParameterProperty":
  1565. if (n.accessibility) {
  1566. parts.push(n.accessibility, " ");
  1567. }
  1568. if (n.export) {
  1569. parts.push("export ");
  1570. }
  1571. if (n.static) {
  1572. parts.push("static ");
  1573. }
  1574. if (n.readonly) {
  1575. parts.push("readonly ");
  1576. }
  1577. parts.push(path.call(print, "parameter"));
  1578. return lines_1.concat(parts);
  1579. case "TSTypeReference":
  1580. return lines_1.concat([
  1581. path.call(print, "typeName"),
  1582. path.call(print, "typeParameters")
  1583. ]);
  1584. case "TSQualifiedName":
  1585. return lines_1.concat([
  1586. path.call(print, "left"),
  1587. ".",
  1588. path.call(print, "right")
  1589. ]);
  1590. case "TSAsExpression": {
  1591. var withParens = n.extra && n.extra.parenthesized === true;
  1592. if (withParens)
  1593. parts.push("(");
  1594. parts.push(path.call(print, "expression"), lines_1.fromString(" as "), path.call(print, "typeAnnotation"));
  1595. if (withParens)
  1596. parts.push(")");
  1597. return lines_1.concat(parts);
  1598. }
  1599. case "TSNonNullExpression":
  1600. return lines_1.concat([
  1601. path.call(print, "expression"),
  1602. "!"
  1603. ]);
  1604. case "TSTypeAnnotation": {
  1605. // similar to flow's FunctionTypeAnnotation, this can be
  1606. // ambiguous: it can be prefixed by => or :
  1607. // in a type predicate, it takes the for u is U
  1608. var parent = path.getParentNode(0);
  1609. var prefix = ": ";
  1610. if (namedTypes.TSFunctionType.check(parent)) {
  1611. prefix = " => ";
  1612. }
  1613. if (namedTypes.TSTypePredicate.check(parent)) {
  1614. prefix = " is ";
  1615. }
  1616. return lines_1.concat([
  1617. prefix,
  1618. path.call(print, "typeAnnotation")
  1619. ]);
  1620. }
  1621. case "TSIndexSignature":
  1622. return lines_1.concat([
  1623. n.readonly ? "readonly " : "",
  1624. "[",
  1625. path.map(print, "parameters"),
  1626. "]",
  1627. path.call(print, "typeAnnotation")
  1628. ]);
  1629. case "TSPropertySignature":
  1630. parts.push(printVariance(path, print), n.readonly ? "readonly " : "");
  1631. if (n.computed) {
  1632. parts.push("[", path.call(print, "key"), "]");
  1633. }
  1634. else {
  1635. parts.push(path.call(print, "key"));
  1636. }
  1637. parts.push(n.optional ? "?" : "", path.call(print, "typeAnnotation"));
  1638. return lines_1.concat(parts);
  1639. case "TSMethodSignature":
  1640. if (n.computed) {
  1641. parts.push("[", path.call(print, "key"), "]");
  1642. }
  1643. else {
  1644. parts.push(path.call(print, "key"));
  1645. }
  1646. if (n.optional) {
  1647. parts.push("?");
  1648. }
  1649. parts.push(path.call(print, "typeParameters"), "(", printFunctionParams(path, options, print), ")", path.call(print, "typeAnnotation"));
  1650. return lines_1.concat(parts);
  1651. case "TSTypePredicate":
  1652. return lines_1.concat([
  1653. path.call(print, "parameterName"),
  1654. path.call(print, "typeAnnotation")
  1655. ]);
  1656. case "TSCallSignatureDeclaration":
  1657. return lines_1.concat([
  1658. path.call(print, "typeParameters"),
  1659. "(",
  1660. printFunctionParams(path, options, print),
  1661. ")",
  1662. path.call(print, "typeAnnotation")
  1663. ]);
  1664. case "TSConstructSignatureDeclaration":
  1665. if (n.typeParameters) {
  1666. parts.push("new", path.call(print, "typeParameters"));
  1667. }
  1668. else {
  1669. parts.push("new ");
  1670. }
  1671. parts.push("(", printFunctionParams(path, options, print), ")", path.call(print, "typeAnnotation"));
  1672. return lines_1.concat(parts);
  1673. case "TSTypeAliasDeclaration":
  1674. return lines_1.concat([
  1675. n.declare ? "declare " : "",
  1676. "type ",
  1677. path.call(print, "id"),
  1678. path.call(print, "typeParameters"),
  1679. " = ",
  1680. path.call(print, "typeAnnotation"),
  1681. ";"
  1682. ]);
  1683. case "TSTypeParameter":
  1684. parts.push(path.call(print, "name"));
  1685. // ambiguous because of TSMappedType
  1686. var parent = path.getParentNode(0);
  1687. var isInMappedType = namedTypes.TSMappedType.check(parent);
  1688. if (n.constraint) {
  1689. parts.push(isInMappedType ? " in " : " extends ", path.call(print, "constraint"));
  1690. }
  1691. if (n["default"]) {
  1692. parts.push(" = ", path.call(print, "default"));
  1693. }
  1694. return lines_1.concat(parts);
  1695. case "TSTypeAssertion":
  1696. var withParens = n.extra && n.extra.parenthesized === true;
  1697. if (withParens) {
  1698. parts.push("(");
  1699. }
  1700. parts.push("<", path.call(print, "typeAnnotation"), "> ", path.call(print, "expression"));
  1701. if (withParens) {
  1702. parts.push(")");
  1703. }
  1704. return lines_1.concat(parts);
  1705. case "TSTypeParameterDeclaration":
  1706. case "TSTypeParameterInstantiation":
  1707. return lines_1.concat([
  1708. "<",
  1709. lines_1.fromString(", ").join(path.map(print, "params")),
  1710. ">"
  1711. ]);
  1712. case "TSEnumDeclaration":
  1713. parts.push(n.declare ? "declare " : "", n.const ? "const " : "", "enum ", path.call(print, "id"));
  1714. var memberLines = lines_1.fromString(",\n").join(path.map(print, "members"));
  1715. if (memberLines.isEmpty()) {
  1716. parts.push(" {}");
  1717. }
  1718. else {
  1719. parts.push(" {\n", memberLines.indent(options.tabWidth), "\n}");
  1720. }
  1721. return lines_1.concat(parts);
  1722. case "TSExpressionWithTypeArguments":
  1723. return lines_1.concat([
  1724. path.call(print, "expression"),
  1725. path.call(print, "typeParameters")
  1726. ]);
  1727. case "TSInterfaceBody":
  1728. var lines = lines_1.fromString(";\n").join(path.map(print, "body"));
  1729. if (lines.isEmpty()) {
  1730. return lines_1.fromString("{}", options);
  1731. }
  1732. return lines_1.concat([
  1733. "{\n",
  1734. lines.indent(options.tabWidth), ";",
  1735. "\n}",
  1736. ]);
  1737. case "TSImportType":
  1738. parts.push("import(", path.call(print, "argument"), ")");
  1739. if (n.qualifier) {
  1740. parts.push(".", path.call(print, "qualifier"));
  1741. }
  1742. if (n.typeParameters) {
  1743. parts.push(path.call(print, "typeParameters"));
  1744. }
  1745. return lines_1.concat(parts);
  1746. case "TSImportEqualsDeclaration":
  1747. if (n.isExport) {
  1748. parts.push("export ");
  1749. }
  1750. parts.push("import ", path.call(print, "id"), " = ", path.call(print, "moduleReference"));
  1751. return maybeAddSemicolon(lines_1.concat(parts));
  1752. case "TSExternalModuleReference":
  1753. return lines_1.concat(["require(", path.call(print, "expression"), ")"]);
  1754. case "TSModuleDeclaration": {
  1755. var parent_1 = path.getParentNode();
  1756. if (parent_1.type === "TSModuleDeclaration") {
  1757. parts.push(".");
  1758. }
  1759. else {
  1760. if (n.declare) {
  1761. parts.push("declare ");
  1762. }
  1763. if (!n.global) {
  1764. var isExternal = n.id.type === "StringLiteral" ||
  1765. (n.id.type === "Literal" &&
  1766. typeof n.id.value === "string");
  1767. if (isExternal) {
  1768. parts.push("module ");
  1769. }
  1770. else if (n.loc &&
  1771. n.loc.lines &&
  1772. n.id.loc) {
  1773. var prefix_1 = n.loc.lines.sliceString(n.loc.start, n.id.loc.start);
  1774. // These keywords are fundamentally ambiguous in the
  1775. // Babylon parser, and not reflected in the AST, so
  1776. // the best we can do is to match the original code,
  1777. // when possible.
  1778. if (prefix_1.indexOf("module") >= 0) {
  1779. parts.push("module ");
  1780. }
  1781. else {
  1782. parts.push("namespace ");
  1783. }
  1784. }
  1785. else {
  1786. parts.push("namespace ");
  1787. }
  1788. }
  1789. }
  1790. parts.push(path.call(print, "id"));
  1791. if (n.body && n.body.type === "TSModuleDeclaration") {
  1792. parts.push(path.call(print, "body"));
  1793. }
  1794. else if (n.body) {
  1795. var bodyLines = path.call(print, "body");
  1796. if (bodyLines.isEmpty()) {
  1797. parts.push(" {}");
  1798. }
  1799. else {
  1800. parts.push(" {\n", bodyLines.indent(options.tabWidth), "\n}");
  1801. }
  1802. }
  1803. return lines_1.concat(parts);
  1804. }
  1805. case "TSModuleBlock":
  1806. return path.call(function (bodyPath) {
  1807. return printStatementSequence(bodyPath, options, print);
  1808. }, "body");
  1809. // Unhandled types below. If encountered, nodes of these types should
  1810. // be either left alone or desugared into AST types that are fully
  1811. // supported by the pretty-printer.
  1812. case "ClassHeritage": // TODO
  1813. case "ComprehensionBlock": // TODO
  1814. case "ComprehensionExpression": // TODO
  1815. case "Glob": // TODO
  1816. case "GeneratorExpression": // TODO
  1817. case "LetStatement": // TODO
  1818. case "LetExpression": // TODO
  1819. case "GraphExpression": // TODO
  1820. case "GraphIndexExpression": // TODO
  1821. // XML types that nobody cares about or needs to print.
  1822. case "XMLDefaultDeclaration":
  1823. case "XMLAnyName":
  1824. case "XMLQualifiedIdentifier":
  1825. case "XMLFunctionQualifiedIdentifier":
  1826. case "XMLAttributeSelector":
  1827. case "XMLFilterExpression":
  1828. case "XML":
  1829. case "XMLElement":
  1830. case "XMLList":
  1831. case "XMLEscape":
  1832. case "XMLText":
  1833. case "XMLStartTag":
  1834. case "XMLEndTag":
  1835. case "XMLPointTag":
  1836. case "XMLName":
  1837. case "XMLAttribute":
  1838. case "XMLCdata":
  1839. case "XMLComment":
  1840. case "XMLProcessingInstruction":
  1841. default:
  1842. debugger;
  1843. throw new Error("unknown type: " + JSON.stringify(n.type));
  1844. }
  1845. }
  1846. function printDecorators(path, printPath) {
  1847. var parts = [];
  1848. var node = path.getValue();
  1849. if (node.decorators &&
  1850. node.decorators.length > 0 &&
  1851. // If the parent node is an export declaration, it will be
  1852. // responsible for printing node.decorators.
  1853. !util.getParentExportDeclaration(path)) {
  1854. path.each(function (decoratorPath) {
  1855. parts.push(printPath(decoratorPath), "\n");
  1856. }, "decorators");
  1857. }
  1858. else if (util.isExportDeclaration(node) &&
  1859. node.declaration &&
  1860. node.declaration.decorators) {
  1861. // Export declarations are responsible for printing any decorators
  1862. // that logically apply to node.declaration.
  1863. path.each(function (decoratorPath) {
  1864. parts.push(printPath(decoratorPath), "\n");
  1865. }, "declaration", "decorators");
  1866. }
  1867. return lines_1.concat(parts);
  1868. }
  1869. function printStatementSequence(path, options, print) {
  1870. var filtered = [];
  1871. var sawComment = false;
  1872. var sawStatement = false;
  1873. path.each(function (stmtPath) {
  1874. var stmt = stmtPath.getValue();
  1875. // Just in case the AST has been modified to contain falsy
  1876. // "statements," it's safer simply to skip them.
  1877. if (!stmt) {
  1878. return;
  1879. }
  1880. // Skip printing EmptyStatement nodes to avoid leaving stray
  1881. // semicolons lying around.
  1882. if (stmt.type === "EmptyStatement" &&
  1883. !(stmt.comments && stmt.comments.length > 0)) {
  1884. return;
  1885. }
  1886. if (namedTypes.Comment.check(stmt)) {
  1887. // The pretty printer allows a dangling Comment node to act as
  1888. // a Statement when the Comment can't be attached to any other
  1889. // non-Comment node in the tree.
  1890. sawComment = true;
  1891. }
  1892. else if (namedTypes.Statement.check(stmt)) {
  1893. sawStatement = true;
  1894. }
  1895. else {
  1896. // When the pretty printer encounters a string instead of an
  1897. // AST node, it just prints the string. This behavior can be
  1898. // useful for fine-grained formatting decisions like inserting
  1899. // blank lines.
  1900. isString.assert(stmt);
  1901. }
  1902. // We can't hang onto stmtPath outside of this function, because
  1903. // it's just a reference to a mutable FastPath object, so we have
  1904. // to go ahead and print it here.
  1905. filtered.push({
  1906. node: stmt,
  1907. printed: print(stmtPath)
  1908. });
  1909. });
  1910. if (sawComment) {
  1911. assert_1.default.strictEqual(sawStatement, false, "Comments may appear as statements in otherwise empty statement " +
  1912. "lists, but may not coexist with non-Comment nodes.");
  1913. }
  1914. var prevTrailingSpace = null;
  1915. var len = filtered.length;
  1916. var parts = [];
  1917. filtered.forEach(function (info, i) {
  1918. var printed = info.printed;
  1919. var stmt = info.node;
  1920. var multiLine = printed.length > 1;
  1921. var notFirst = i > 0;
  1922. var notLast = i < len - 1;
  1923. var leadingSpace;
  1924. var trailingSpace;
  1925. var lines = stmt && stmt.loc && stmt.loc.lines;
  1926. var trueLoc = lines && options.reuseWhitespace &&
  1927. util.getTrueLoc(stmt, lines);
  1928. if (notFirst) {
  1929. if (trueLoc) {
  1930. var beforeStart = lines.skipSpaces(trueLoc.start, true);
  1931. var beforeStartLine = beforeStart ? beforeStart.line : 1;
  1932. var leadingGap = trueLoc.start.line - beforeStartLine;
  1933. leadingSpace = Array(leadingGap + 1).join("\n");
  1934. }
  1935. else {
  1936. leadingSpace = multiLine ? "\n\n" : "\n";
  1937. }
  1938. }
  1939. else {
  1940. leadingSpace = "";
  1941. }
  1942. if (notLast) {
  1943. if (trueLoc) {
  1944. var afterEnd = lines.skipSpaces(trueLoc.end);
  1945. var afterEndLine = afterEnd ? afterEnd.line : lines.length;
  1946. var trailingGap = afterEndLine - trueLoc.end.line;
  1947. trailingSpace = Array(trailingGap + 1).join("\n");
  1948. }
  1949. else {
  1950. trailingSpace = multiLine ? "\n\n" : "\n";
  1951. }
  1952. }
  1953. else {
  1954. trailingSpace = "";
  1955. }
  1956. parts.push(maxSpace(prevTrailingSpace, leadingSpace), printed);
  1957. if (notLast) {
  1958. prevTrailingSpace = trailingSpace;
  1959. }
  1960. else if (trailingSpace) {
  1961. parts.push(trailingSpace);
  1962. }
  1963. });
  1964. return lines_1.concat(parts);
  1965. }
  1966. function maxSpace(s1, s2) {
  1967. if (!s1 && !s2) {
  1968. return lines_1.fromString("");
  1969. }
  1970. if (!s1) {
  1971. return lines_1.fromString(s2);
  1972. }
  1973. if (!s2) {
  1974. return lines_1.fromString(s1);
  1975. }
  1976. var spaceLines1 = lines_1.fromString(s1);
  1977. var spaceLines2 = lines_1.fromString(s2);
  1978. if (spaceLines2.length > spaceLines1.length) {
  1979. return spaceLines2;
  1980. }
  1981. return spaceLines1;
  1982. }
  1983. function printMethod(path, options, print) {
  1984. var node = path.getNode();
  1985. var kind = node.kind;
  1986. var parts = [];
  1987. var nodeValue = node.value;
  1988. if (!namedTypes.FunctionExpression.check(nodeValue)) {
  1989. nodeValue = node;
  1990. }
  1991. var access = node.accessibility || node.access;
  1992. if (typeof access === "string") {
  1993. parts.push(access, " ");
  1994. }
  1995. if (node.static) {
  1996. parts.push("static ");
  1997. }
  1998. if (node.abstract) {
  1999. parts.push("abstract ");
  2000. }
  2001. if (node.readonly) {
  2002. parts.push("readonly ");
  2003. }
  2004. if (nodeValue.async) {
  2005. parts.push("async ");
  2006. }
  2007. if (nodeValue.generator) {
  2008. parts.push("*");
  2009. }
  2010. if (kind === "get" || kind === "set") {
  2011. parts.push(kind, " ");
  2012. }
  2013. var key = path.call(print, "key");
  2014. if (node.computed) {
  2015. key = lines_1.concat(["[", key, "]"]);
  2016. }
  2017. parts.push(key);
  2018. if (node.optional) {
  2019. parts.push("?");
  2020. }
  2021. if (node === nodeValue) {
  2022. parts.push(path.call(print, "typeParameters"), "(", printFunctionParams(path, options, print), ")", path.call(print, "returnType"));
  2023. if (node.body) {
  2024. parts.push(" ", path.call(print, "body"));
  2025. }
  2026. else {
  2027. parts.push(";");
  2028. }
  2029. }
  2030. else {
  2031. parts.push(path.call(print, "value", "typeParameters"), "(", path.call(function (valuePath) {
  2032. return printFunctionParams(valuePath, options, print);
  2033. }, "value"), ")", path.call(print, "value", "returnType"));
  2034. if (nodeValue.body) {
  2035. parts.push(" ", path.call(print, "value", "body"));
  2036. }
  2037. else {
  2038. parts.push(";");
  2039. }
  2040. }
  2041. return lines_1.concat(parts);
  2042. }
  2043. function printArgumentsList(path, options, print) {
  2044. var printed = path.map(print, "arguments");
  2045. var trailingComma = util.isTrailingCommaEnabled(options, "parameters");
  2046. var joined = lines_1.fromString(", ").join(printed);
  2047. if (joined.getLineLength(1) > options.wrapColumn) {
  2048. joined = lines_1.fromString(",\n").join(printed);
  2049. return lines_1.concat([
  2050. "(\n",
  2051. joined.indent(options.tabWidth),
  2052. trailingComma ? ",\n)" : "\n)"
  2053. ]);
  2054. }
  2055. return lines_1.concat(["(", joined, ")"]);
  2056. }
  2057. function printFunctionParams(path, options, print) {
  2058. var fun = path.getValue();
  2059. if (fun.params) {
  2060. var params = fun.params;
  2061. var printed = path.map(print, "params");
  2062. }
  2063. else if (fun.parameters) {
  2064. params = fun.parameters;
  2065. printed = path.map(print, "parameters");
  2066. }
  2067. if (fun.defaults) {
  2068. path.each(function (defExprPath) {
  2069. var i = defExprPath.getName();
  2070. var p = printed[i];
  2071. if (p && defExprPath.getValue()) {
  2072. printed[i] = lines_1.concat([p, " = ", print(defExprPath)]);
  2073. }
  2074. }, "defaults");
  2075. }
  2076. if (fun.rest) {
  2077. printed.push(lines_1.concat(["...", path.call(print, "rest")]));
  2078. }
  2079. var joined = lines_1.fromString(", ").join(printed);
  2080. if (joined.length > 1 ||
  2081. joined.getLineLength(1) > options.wrapColumn) {
  2082. joined = lines_1.fromString(",\n").join(printed);
  2083. if (util.isTrailingCommaEnabled(options, "parameters") &&
  2084. !fun.rest &&
  2085. params[params.length - 1].type !== 'RestElement') {
  2086. joined = lines_1.concat([joined, ",\n"]);
  2087. }
  2088. else {
  2089. joined = lines_1.concat([joined, "\n"]);
  2090. }
  2091. return lines_1.concat(["\n", joined.indent(options.tabWidth)]);
  2092. }
  2093. return joined;
  2094. }
  2095. function printExportDeclaration(path, options, print) {
  2096. var decl = path.getValue();
  2097. var parts = ["export "];
  2098. if (decl.exportKind && decl.exportKind !== "value") {
  2099. parts.push(decl.exportKind + " ");
  2100. }
  2101. var shouldPrintSpaces = options.objectCurlySpacing;
  2102. namedTypes.Declaration.assert(decl);
  2103. if (decl["default"] ||
  2104. decl.type === "ExportDefaultDeclaration") {
  2105. parts.push("default ");
  2106. }
  2107. if (decl.declaration) {
  2108. parts.push(path.call(print, "declaration"));
  2109. }
  2110. else if (decl.specifiers) {
  2111. if (decl.specifiers.length === 1 &&
  2112. decl.specifiers[0].type === "ExportBatchSpecifier") {
  2113. parts.push("*");
  2114. }
  2115. else if (decl.specifiers.length === 0) {
  2116. parts.push("{}");
  2117. }
  2118. else if (decl.specifiers[0].type === 'ExportDefaultSpecifier') {
  2119. var unbracedSpecifiers_2 = [];
  2120. var bracedSpecifiers_2 = [];
  2121. path.each(function (specifierPath) {
  2122. var spec = specifierPath.getValue();
  2123. if (spec.type === "ExportDefaultSpecifier") {
  2124. unbracedSpecifiers_2.push(print(specifierPath));
  2125. }
  2126. else {
  2127. bracedSpecifiers_2.push(print(specifierPath));
  2128. }
  2129. }, "specifiers");
  2130. unbracedSpecifiers_2.forEach(function (lines, i) {
  2131. if (i > 0) {
  2132. parts.push(", ");
  2133. }
  2134. parts.push(lines);
  2135. });
  2136. if (bracedSpecifiers_2.length > 0) {
  2137. var lines_3 = lines_1.fromString(", ").join(bracedSpecifiers_2);
  2138. if (lines_3.getLineLength(1) > options.wrapColumn) {
  2139. lines_3 = lines_1.concat([
  2140. lines_1.fromString(",\n").join(bracedSpecifiers_2).indent(options.tabWidth),
  2141. ","
  2142. ]);
  2143. }
  2144. if (unbracedSpecifiers_2.length > 0) {
  2145. parts.push(", ");
  2146. }
  2147. if (lines_3.length > 1) {
  2148. parts.push("{\n", lines_3, "\n}");
  2149. }
  2150. else if (options.objectCurlySpacing) {
  2151. parts.push("{ ", lines_3, " }");
  2152. }
  2153. else {
  2154. parts.push("{", lines_3, "}");
  2155. }
  2156. }
  2157. }
  2158. else {
  2159. parts.push(shouldPrintSpaces ? "{ " : "{", lines_1.fromString(", ").join(path.map(print, "specifiers")), shouldPrintSpaces ? " }" : "}");
  2160. }
  2161. if (decl.source) {
  2162. parts.push(" from ", path.call(print, "source"));
  2163. }
  2164. }
  2165. var lines = lines_1.concat(parts);
  2166. if (lastNonSpaceCharacter(lines) !== ";" &&
  2167. !(decl.declaration &&
  2168. (decl.declaration.type === "FunctionDeclaration" ||
  2169. decl.declaration.type === "ClassDeclaration" ||
  2170. decl.declaration.type === "TSModuleDeclaration" ||
  2171. decl.declaration.type === "TSInterfaceDeclaration" ||
  2172. decl.declaration.type === "TSEnumDeclaration"))) {
  2173. lines = lines_1.concat([lines, ";"]);
  2174. }
  2175. return lines;
  2176. }
  2177. function printFlowDeclaration(path, parts) {
  2178. var parentExportDecl = util.getParentExportDeclaration(path);
  2179. if (parentExportDecl) {
  2180. assert_1.default.strictEqual(parentExportDecl.type, "DeclareExportDeclaration");
  2181. }
  2182. else {
  2183. // If the parent node has type DeclareExportDeclaration, then it
  2184. // will be responsible for printing the "declare" token. Otherwise
  2185. // it needs to be printed with this non-exported declaration node.
  2186. parts.unshift("declare ");
  2187. }
  2188. return lines_1.concat(parts);
  2189. }
  2190. function printVariance(path, print) {
  2191. return path.call(function (variancePath) {
  2192. var value = variancePath.getValue();
  2193. if (value) {
  2194. if (value === "plus") {
  2195. return lines_1.fromString("+");
  2196. }
  2197. if (value === "minus") {
  2198. return lines_1.fromString("-");
  2199. }
  2200. return print(variancePath);
  2201. }
  2202. return lines_1.fromString("");
  2203. }, "variance");
  2204. }
  2205. function adjustClause(clause, options) {
  2206. if (clause.length > 1)
  2207. return lines_1.concat([" ", clause]);
  2208. return lines_1.concat([
  2209. "\n",
  2210. maybeAddSemicolon(clause).indent(options.tabWidth)
  2211. ]);
  2212. }
  2213. function lastNonSpaceCharacter(lines) {
  2214. var pos = lines.lastPos();
  2215. do {
  2216. var ch = lines.charAt(pos);
  2217. if (/\S/.test(ch))
  2218. return ch;
  2219. } while (lines.prevPos(pos));
  2220. }
  2221. function endsWithBrace(lines) {
  2222. return lastNonSpaceCharacter(lines) === "}";
  2223. }
  2224. function swapQuotes(str) {
  2225. return str.replace(/['"]/g, function (m) {
  2226. return m === '"' ? '\'' : '"';
  2227. });
  2228. }
  2229. function nodeStr(str, options) {
  2230. isString.assert(str);
  2231. switch (options.quote) {
  2232. case "auto":
  2233. var double = JSON.stringify(str);
  2234. var single = swapQuotes(JSON.stringify(swapQuotes(str)));
  2235. return double.length > single.length ? single : double;
  2236. case "single":
  2237. return swapQuotes(JSON.stringify(swapQuotes(str)));
  2238. case "double":
  2239. default:
  2240. return JSON.stringify(str);
  2241. }
  2242. }
  2243. function maybeAddSemicolon(lines) {
  2244. var eoc = lastNonSpaceCharacter(lines);
  2245. if (!eoc || "\n};".indexOf(eoc) < 0)
  2246. return lines_1.concat([lines, ";"]);
  2247. return lines;
  2248. }