printer.js 88 KB

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