@ttsc/factory 0.15.9 → 0.15.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (541) hide show
  1. package/README.md +3 -2
  2. package/lib/TsPrinter.d.ts +51 -11
  3. package/lib/TsPrinter.js +555 -70
  4. package/lib/TsPrinter.js.map +1 -1
  5. package/lib/TsPrinter.mjs +1827 -0
  6. package/lib/TsPrinter.mjs.map +1 -0
  7. package/lib/comments.mjs +76 -0
  8. package/lib/comments.mjs.map +1 -0
  9. package/lib/factory/clauses/createHeritageClause.mjs +26 -0
  10. package/lib/factory/clauses/createHeritageClause.mjs.map +1 -0
  11. package/lib/factory/clauses/createParameterDeclaration.mjs +43 -0
  12. package/lib/factory/clauses/createParameterDeclaration.mjs.map +1 -0
  13. package/lib/factory/declarations/createClassDeclaration.mjs +44 -0
  14. package/lib/factory/declarations/createClassDeclaration.mjs.map +1 -0
  15. package/lib/factory/declarations/createClassStaticBlockDeclaration.mjs +25 -0
  16. package/lib/factory/declarations/createClassStaticBlockDeclaration.mjs.map +1 -0
  17. package/lib/factory/declarations/createConstructorDeclaration.mjs +28 -0
  18. package/lib/factory/declarations/createConstructorDeclaration.mjs.map +1 -0
  19. package/lib/factory/declarations/createEnumDeclaration.mjs +31 -0
  20. package/lib/factory/declarations/createEnumDeclaration.mjs.map +1 -0
  21. package/lib/factory/declarations/createEnumMember.mjs +26 -0
  22. package/lib/factory/declarations/createEnumMember.mjs.map +1 -0
  23. package/lib/factory/declarations/createExternalModuleReference.mjs +23 -0
  24. package/lib/factory/declarations/createExternalModuleReference.mjs.map +1 -0
  25. package/lib/factory/declarations/createFunctionDeclaration.mjs +48 -0
  26. package/lib/factory/declarations/createFunctionDeclaration.mjs.map +1 -0
  27. package/lib/factory/declarations/createGetAccessorDeclaration.mjs +39 -0
  28. package/lib/factory/declarations/createGetAccessorDeclaration.mjs.map +1 -0
  29. package/lib/factory/declarations/createImportEqualsDeclaration.mjs +35 -0
  30. package/lib/factory/declarations/createImportEqualsDeclaration.mjs.map +1 -0
  31. package/lib/factory/declarations/createInterfaceDeclaration.mjs +40 -0
  32. package/lib/factory/declarations/createInterfaceDeclaration.mjs.map +1 -0
  33. package/lib/factory/declarations/createMethodDeclaration.mjs +50 -0
  34. package/lib/factory/declarations/createMethodDeclaration.mjs.map +1 -0
  35. package/lib/factory/declarations/createModuleBlock.mjs +25 -0
  36. package/lib/factory/declarations/createModuleBlock.mjs.map +1 -0
  37. package/lib/factory/declarations/createModuleDeclaration.mjs +43 -0
  38. package/lib/factory/declarations/createModuleDeclaration.mjs.map +1 -0
  39. package/lib/factory/declarations/createNamespaceExportDeclaration.mjs +24 -0
  40. package/lib/factory/declarations/createNamespaceExportDeclaration.mjs.map +1 -0
  41. package/lib/factory/declarations/createPropertyDeclaration.mjs +41 -0
  42. package/lib/factory/declarations/createPropertyDeclaration.mjs.map +1 -0
  43. package/lib/factory/declarations/createSemicolonClassElement.mjs +20 -0
  44. package/lib/factory/declarations/createSemicolonClassElement.mjs.map +1 -0
  45. package/lib/factory/declarations/createSetAccessorDeclaration.mjs +37 -0
  46. package/lib/factory/declarations/createSetAccessorDeclaration.mjs.map +1 -0
  47. package/lib/factory/declarations/createTypeAliasDeclaration.mjs +35 -0
  48. package/lib/factory/declarations/createTypeAliasDeclaration.mjs.map +1 -0
  49. package/lib/factory/expressions/createAdd.mjs +26 -0
  50. package/lib/factory/expressions/createAdd.mjs.map +1 -0
  51. package/lib/factory/expressions/createArrayBindingPattern.mjs +23 -0
  52. package/lib/factory/expressions/createArrayBindingPattern.mjs.map +1 -0
  53. package/lib/factory/expressions/createArrayLiteralExpression.mjs +25 -0
  54. package/lib/factory/expressions/createArrayLiteralExpression.mjs.map +1 -0
  55. package/lib/factory/expressions/createArrowFunction.mjs +32 -0
  56. package/lib/factory/expressions/createArrowFunction.mjs.map +1 -0
  57. package/lib/factory/expressions/createAsExpression.mjs +23 -0
  58. package/lib/factory/expressions/createAsExpression.mjs.map +1 -0
  59. package/lib/factory/expressions/createAssignment.mjs +26 -0
  60. package/lib/factory/expressions/createAssignment.mjs.map +1 -0
  61. package/lib/factory/expressions/createAwaitExpression.mjs +22 -0
  62. package/lib/factory/expressions/createAwaitExpression.mjs.map +1 -0
  63. package/lib/factory/expressions/createBinaryExpression.mjs +33 -0
  64. package/lib/factory/expressions/createBinaryExpression.mjs.map +1 -0
  65. package/lib/factory/expressions/createBindingElement.mjs +39 -0
  66. package/lib/factory/expressions/createBindingElement.mjs.map +1 -0
  67. package/lib/factory/expressions/createBitwiseAnd.mjs +26 -0
  68. package/lib/factory/expressions/createBitwiseAnd.mjs.map +1 -0
  69. package/lib/factory/expressions/createBitwiseNot.mjs +25 -0
  70. package/lib/factory/expressions/createBitwiseNot.mjs.map +1 -0
  71. package/lib/factory/expressions/createBitwiseOr.mjs +25 -0
  72. package/lib/factory/expressions/createBitwiseOr.mjs.map +1 -0
  73. package/lib/factory/expressions/createBitwiseXor.mjs +25 -0
  74. package/lib/factory/expressions/createBitwiseXor.mjs.map +1 -0
  75. package/lib/factory/expressions/createCallChain.mjs +35 -0
  76. package/lib/factory/expressions/createCallChain.mjs.map +1 -0
  77. package/lib/factory/expressions/createCallExpression.mjs +29 -0
  78. package/lib/factory/expressions/createCallExpression.mjs.map +1 -0
  79. package/lib/factory/expressions/createClassExpression.mjs +34 -0
  80. package/lib/factory/expressions/createClassExpression.mjs.map +1 -0
  81. package/lib/factory/expressions/createComma.mjs +28 -0
  82. package/lib/factory/expressions/createComma.mjs.map +1 -0
  83. package/lib/factory/expressions/createCommaListExpression.mjs +23 -0
  84. package/lib/factory/expressions/createCommaListExpression.mjs.map +1 -0
  85. package/lib/factory/expressions/createComputedPropertyName.mjs +23 -0
  86. package/lib/factory/expressions/createComputedPropertyName.mjs.map +1 -0
  87. package/lib/factory/expressions/createConditionalExpression.mjs +28 -0
  88. package/lib/factory/expressions/createConditionalExpression.mjs.map +1 -0
  89. package/lib/factory/expressions/createDeleteExpression.mjs +22 -0
  90. package/lib/factory/expressions/createDeleteExpression.mjs.map +1 -0
  91. package/lib/factory/expressions/createDivide.mjs +25 -0
  92. package/lib/factory/expressions/createDivide.mjs.map +1 -0
  93. package/lib/factory/expressions/createElementAccessChain.mjs +32 -0
  94. package/lib/factory/expressions/createElementAccessChain.mjs.map +1 -0
  95. package/lib/factory/expressions/createElementAccessExpression.mjs +28 -0
  96. package/lib/factory/expressions/createElementAccessExpression.mjs.map +1 -0
  97. package/lib/factory/expressions/createEquality.mjs +27 -0
  98. package/lib/factory/expressions/createEquality.mjs.map +1 -0
  99. package/lib/factory/expressions/createExponent.mjs +26 -0
  100. package/lib/factory/expressions/createExponent.mjs.map +1 -0
  101. package/lib/factory/expressions/createFunctionExpression.mjs +38 -0
  102. package/lib/factory/expressions/createFunctionExpression.mjs.map +1 -0
  103. package/lib/factory/expressions/createGreaterThan.mjs +27 -0
  104. package/lib/factory/expressions/createGreaterThan.mjs.map +1 -0
  105. package/lib/factory/expressions/createGreaterThanEquals.mjs +27 -0
  106. package/lib/factory/expressions/createGreaterThanEquals.mjs.map +1 -0
  107. package/lib/factory/expressions/createImmediatelyInvokedArrowFunction.mjs +29 -0
  108. package/lib/factory/expressions/createImmediatelyInvokedArrowFunction.mjs.map +1 -0
  109. package/lib/factory/expressions/createImmediatelyInvokedFunctionExpression.mjs +29 -0
  110. package/lib/factory/expressions/createImmediatelyInvokedFunctionExpression.mjs.map +1 -0
  111. package/lib/factory/expressions/createInequality.mjs +27 -0
  112. package/lib/factory/expressions/createInequality.mjs.map +1 -0
  113. package/lib/factory/expressions/createLeftShift.mjs +26 -0
  114. package/lib/factory/expressions/createLeftShift.mjs.map +1 -0
  115. package/lib/factory/expressions/createLessThan.mjs +26 -0
  116. package/lib/factory/expressions/createLessThan.mjs.map +1 -0
  117. package/lib/factory/expressions/createLessThanEquals.mjs +27 -0
  118. package/lib/factory/expressions/createLessThanEquals.mjs.map +1 -0
  119. package/lib/factory/expressions/createLogicalAnd.mjs +27 -0
  120. package/lib/factory/expressions/createLogicalAnd.mjs.map +1 -0
  121. package/lib/factory/expressions/createLogicalNot.mjs +25 -0
  122. package/lib/factory/expressions/createLogicalNot.mjs.map +1 -0
  123. package/lib/factory/expressions/createLogicalOr.mjs +26 -0
  124. package/lib/factory/expressions/createLogicalOr.mjs.map +1 -0
  125. package/lib/factory/expressions/createMetaProperty.mjs +29 -0
  126. package/lib/factory/expressions/createMetaProperty.mjs.map +1 -0
  127. package/lib/factory/expressions/createModulo.mjs +24 -0
  128. package/lib/factory/expressions/createModulo.mjs.map +1 -0
  129. package/lib/factory/expressions/createMultiply.mjs +24 -0
  130. package/lib/factory/expressions/createMultiply.mjs.map +1 -0
  131. package/lib/factory/expressions/createNewExpression.mjs +30 -0
  132. package/lib/factory/expressions/createNewExpression.mjs.map +1 -0
  133. package/lib/factory/expressions/createNonNullChain.mjs +24 -0
  134. package/lib/factory/expressions/createNonNullChain.mjs.map +1 -0
  135. package/lib/factory/expressions/createNonNullExpression.mjs +24 -0
  136. package/lib/factory/expressions/createNonNullExpression.mjs.map +1 -0
  137. package/lib/factory/expressions/createObjectBindingPattern.mjs +24 -0
  138. package/lib/factory/expressions/createObjectBindingPattern.mjs.map +1 -0
  139. package/lib/factory/expressions/createObjectLiteralExpression.mjs +27 -0
  140. package/lib/factory/expressions/createObjectLiteralExpression.mjs.map +1 -0
  141. package/lib/factory/expressions/createOmittedExpression.mjs +23 -0
  142. package/lib/factory/expressions/createOmittedExpression.mjs.map +1 -0
  143. package/lib/factory/expressions/createParenthesizedExpression.mjs +24 -0
  144. package/lib/factory/expressions/createParenthesizedExpression.mjs.map +1 -0
  145. package/lib/factory/expressions/createPartiallyEmittedExpression.mjs +26 -0
  146. package/lib/factory/expressions/createPartiallyEmittedExpression.mjs.map +1 -0
  147. package/lib/factory/expressions/createPostfixDecrement.mjs +23 -0
  148. package/lib/factory/expressions/createPostfixDecrement.mjs.map +1 -0
  149. package/lib/factory/expressions/createPostfixIncrement.mjs +23 -0
  150. package/lib/factory/expressions/createPostfixIncrement.mjs.map +1 -0
  151. package/lib/factory/expressions/createPostfixUnaryExpression.mjs +25 -0
  152. package/lib/factory/expressions/createPostfixUnaryExpression.mjs.map +1 -0
  153. package/lib/factory/expressions/createPrefixDecrement.mjs +23 -0
  154. package/lib/factory/expressions/createPrefixDecrement.mjs.map +1 -0
  155. package/lib/factory/expressions/createPrefixIncrement.mjs +23 -0
  156. package/lib/factory/expressions/createPrefixIncrement.mjs.map +1 -0
  157. package/lib/factory/expressions/createPrefixMinus.mjs +23 -0
  158. package/lib/factory/expressions/createPrefixMinus.mjs.map +1 -0
  159. package/lib/factory/expressions/createPrefixPlus.mjs +23 -0
  160. package/lib/factory/expressions/createPrefixPlus.mjs.map +1 -0
  161. package/lib/factory/expressions/createPrefixUnaryExpression.mjs +25 -0
  162. package/lib/factory/expressions/createPrefixUnaryExpression.mjs.map +1 -0
  163. package/lib/factory/expressions/createPropertyAccessChain.mjs +32 -0
  164. package/lib/factory/expressions/createPropertyAccessChain.mjs.map +1 -0
  165. package/lib/factory/expressions/createPropertyAccessExpression.mjs +28 -0
  166. package/lib/factory/expressions/createPropertyAccessExpression.mjs.map +1 -0
  167. package/lib/factory/expressions/createPropertyAssignment.mjs +26 -0
  168. package/lib/factory/expressions/createPropertyAssignment.mjs.map +1 -0
  169. package/lib/factory/expressions/createRegularExpressionLiteral.mjs +23 -0
  170. package/lib/factory/expressions/createRegularExpressionLiteral.mjs.map +1 -0
  171. package/lib/factory/expressions/createRightShift.mjs +24 -0
  172. package/lib/factory/expressions/createRightShift.mjs.map +1 -0
  173. package/lib/factory/expressions/createSatisfiesExpression.mjs +25 -0
  174. package/lib/factory/expressions/createSatisfiesExpression.mjs.map +1 -0
  175. package/lib/factory/expressions/createShorthandPropertyAssignment.mjs +31 -0
  176. package/lib/factory/expressions/createShorthandPropertyAssignment.mjs.map +1 -0
  177. package/lib/factory/expressions/createSpreadAssignment.mjs +23 -0
  178. package/lib/factory/expressions/createSpreadAssignment.mjs.map +1 -0
  179. package/lib/factory/expressions/createSpreadElement.mjs +23 -0
  180. package/lib/factory/expressions/createSpreadElement.mjs.map +1 -0
  181. package/lib/factory/expressions/createStrictEquality.mjs +24 -0
  182. package/lib/factory/expressions/createStrictEquality.mjs.map +1 -0
  183. package/lib/factory/expressions/createStrictInequality.mjs +24 -0
  184. package/lib/factory/expressions/createStrictInequality.mjs.map +1 -0
  185. package/lib/factory/expressions/createSubtract.mjs +24 -0
  186. package/lib/factory/expressions/createSubtract.mjs.map +1 -0
  187. package/lib/factory/expressions/createTaggedTemplateExpression.mjs +27 -0
  188. package/lib/factory/expressions/createTaggedTemplateExpression.mjs.map +1 -0
  189. package/lib/factory/expressions/createTemplateExpression.mjs +27 -0
  190. package/lib/factory/expressions/createTemplateExpression.mjs.map +1 -0
  191. package/lib/factory/expressions/createTemplateSpan.mjs +28 -0
  192. package/lib/factory/expressions/createTemplateSpan.mjs.map +1 -0
  193. package/lib/factory/expressions/createTypeAssertion.mjs +25 -0
  194. package/lib/factory/expressions/createTypeAssertion.mjs.map +1 -0
  195. package/lib/factory/expressions/createTypeOfExpression.mjs +22 -0
  196. package/lib/factory/expressions/createTypeOfExpression.mjs.map +1 -0
  197. package/lib/factory/expressions/createUnsignedRightShift.mjs +24 -0
  198. package/lib/factory/expressions/createUnsignedRightShift.mjs.map +1 -0
  199. package/lib/factory/expressions/createVoidExpression.mjs +23 -0
  200. package/lib/factory/expressions/createVoidExpression.mjs.map +1 -0
  201. package/lib/factory/expressions/createVoidZero.mjs +22 -0
  202. package/lib/factory/expressions/createVoidZero.mjs.map +1 -0
  203. package/lib/factory/expressions/createYieldExpression.mjs +26 -0
  204. package/lib/factory/expressions/createYieldExpression.mjs.map +1 -0
  205. package/lib/factory/file/createBundle.mjs +29 -0
  206. package/lib/factory/file/createBundle.mjs.map +1 -0
  207. package/lib/factory/file/createNodeArray.mjs +24 -0
  208. package/lib/factory/file/createNodeArray.mjs.map +1 -0
  209. package/lib/factory/file/createSourceFile.mjs +24 -0
  210. package/lib/factory/file/createSourceFile.mjs.map +1 -0
  211. package/lib/factory/file/updateSourceFile.mjs +14 -0
  212. package/lib/factory/file/updateSourceFile.mjs.map +1 -0
  213. package/lib/factory/imports/createExportAssignment.mjs +27 -0
  214. package/lib/factory/imports/createExportAssignment.mjs.map +1 -0
  215. package/lib/factory/imports/createExportDeclaration.mjs +38 -0
  216. package/lib/factory/imports/createExportDeclaration.mjs.map +1 -0
  217. package/lib/factory/imports/createExportDefault.mjs +23 -0
  218. package/lib/factory/imports/createExportDefault.mjs.map +1 -0
  219. package/lib/factory/imports/createExportSpecifier.mjs +32 -0
  220. package/lib/factory/imports/createExportSpecifier.mjs.map +1 -0
  221. package/lib/factory/imports/createExternalModuleExport.mjs +26 -0
  222. package/lib/factory/imports/createExternalModuleExport.mjs.map +1 -0
  223. package/lib/factory/imports/createImportAttribute.mjs +25 -0
  224. package/lib/factory/imports/createImportAttribute.mjs.map +1 -0
  225. package/lib/factory/imports/createImportAttributes.mjs +30 -0
  226. package/lib/factory/imports/createImportAttributes.mjs.map +1 -0
  227. package/lib/factory/imports/createImportClause.mjs +27 -0
  228. package/lib/factory/imports/createImportClause.mjs.map +1 -0
  229. package/lib/factory/imports/createImportDeclaration.mjs +34 -0
  230. package/lib/factory/imports/createImportDeclaration.mjs.map +1 -0
  231. package/lib/factory/imports/createImportSpecifier.mjs +28 -0
  232. package/lib/factory/imports/createImportSpecifier.mjs.map +1 -0
  233. package/lib/factory/imports/createNamedExports.mjs +25 -0
  234. package/lib/factory/imports/createNamedExports.mjs.map +1 -0
  235. package/lib/factory/imports/createNamedImports.mjs +25 -0
  236. package/lib/factory/imports/createNamedImports.mjs.map +1 -0
  237. package/lib/factory/imports/createNamespaceExport.mjs +25 -0
  238. package/lib/factory/imports/createNamespaceExport.mjs.map +1 -0
  239. package/lib/factory/imports/createNamespaceImport.mjs +24 -0
  240. package/lib/factory/imports/createNamespaceImport.mjs.map +1 -0
  241. package/lib/factory/index.mjs +268 -0
  242. package/lib/factory/index.mjs.map +1 -0
  243. package/lib/factory/internal/asEntityName.mjs +7 -0
  244. package/lib/factory/internal/asEntityName.mjs.map +1 -0
  245. package/lib/factory/internal/asName.mjs +11 -0
  246. package/lib/factory/internal/asName.mjs.map +1 -0
  247. package/lib/factory/internal/asPropertyName.mjs +7 -0
  248. package/lib/factory/internal/asPropertyName.mjs.map +1 -0
  249. package/lib/factory/internal/make.mjs +14 -0
  250. package/lib/factory/internal/make.mjs.map +1 -0
  251. package/lib/factory/jsdoc/createJSDocAllType.mjs +21 -0
  252. package/lib/factory/jsdoc/createJSDocAllType.mjs.map +1 -0
  253. package/lib/factory/jsdoc/createJSDocAugmentsTag.mjs +30 -0
  254. package/lib/factory/jsdoc/createJSDocAugmentsTag.mjs.map +1 -0
  255. package/lib/factory/jsdoc/createJSDocAuthorTag.mjs +27 -0
  256. package/lib/factory/jsdoc/createJSDocAuthorTag.mjs.map +1 -0
  257. package/lib/factory/jsdoc/createJSDocCallbackTag.mjs +37 -0
  258. package/lib/factory/jsdoc/createJSDocCallbackTag.mjs.map +1 -0
  259. package/lib/factory/jsdoc/createJSDocClassTag.mjs +27 -0
  260. package/lib/factory/jsdoc/createJSDocClassTag.mjs.map +1 -0
  261. package/lib/factory/jsdoc/createJSDocComment.mjs +29 -0
  262. package/lib/factory/jsdoc/createJSDocComment.mjs.map +1 -0
  263. package/lib/factory/jsdoc/createJSDocDeprecatedTag.mjs +27 -0
  264. package/lib/factory/jsdoc/createJSDocDeprecatedTag.mjs.map +1 -0
  265. package/lib/factory/jsdoc/createJSDocEnumTag.mjs +31 -0
  266. package/lib/factory/jsdoc/createJSDocEnumTag.mjs.map +1 -0
  267. package/lib/factory/jsdoc/createJSDocFunctionType.mjs +26 -0
  268. package/lib/factory/jsdoc/createJSDocFunctionType.mjs.map +1 -0
  269. package/lib/factory/jsdoc/createJSDocImplementsTag.mjs +30 -0
  270. package/lib/factory/jsdoc/createJSDocImplementsTag.mjs.map +1 -0
  271. package/lib/factory/jsdoc/createJSDocImportTag.mjs +34 -0
  272. package/lib/factory/jsdoc/createJSDocImportTag.mjs.map +1 -0
  273. package/lib/factory/jsdoc/createJSDocLink.mjs +29 -0
  274. package/lib/factory/jsdoc/createJSDocLink.mjs.map +1 -0
  275. package/lib/factory/jsdoc/createJSDocLinkCode.mjs +29 -0
  276. package/lib/factory/jsdoc/createJSDocLinkCode.mjs.map +1 -0
  277. package/lib/factory/jsdoc/createJSDocLinkPlain.mjs +29 -0
  278. package/lib/factory/jsdoc/createJSDocLinkPlain.mjs.map +1 -0
  279. package/lib/factory/jsdoc/createJSDocMemberName.mjs +26 -0
  280. package/lib/factory/jsdoc/createJSDocMemberName.mjs.map +1 -0
  281. package/lib/factory/jsdoc/createJSDocNameReference.mjs +25 -0
  282. package/lib/factory/jsdoc/createJSDocNameReference.mjs.map +1 -0
  283. package/lib/factory/jsdoc/createJSDocNamepathType.mjs +25 -0
  284. package/lib/factory/jsdoc/createJSDocNamepathType.mjs.map +1 -0
  285. package/lib/factory/jsdoc/createJSDocNonNullableType.mjs +33 -0
  286. package/lib/factory/jsdoc/createJSDocNonNullableType.mjs.map +1 -0
  287. package/lib/factory/jsdoc/createJSDocNullableType.mjs +33 -0
  288. package/lib/factory/jsdoc/createJSDocNullableType.mjs.map +1 -0
  289. package/lib/factory/jsdoc/createJSDocOptionalType.mjs +23 -0
  290. package/lib/factory/jsdoc/createJSDocOptionalType.mjs.map +1 -0
  291. package/lib/factory/jsdoc/createJSDocOverloadTag.mjs +35 -0
  292. package/lib/factory/jsdoc/createJSDocOverloadTag.mjs.map +1 -0
  293. package/lib/factory/jsdoc/createJSDocOverrideTag.mjs +27 -0
  294. package/lib/factory/jsdoc/createJSDocOverrideTag.mjs.map +1 -0
  295. package/lib/factory/jsdoc/createJSDocParameterTag.mjs +46 -0
  296. package/lib/factory/jsdoc/createJSDocParameterTag.mjs.map +1 -0
  297. package/lib/factory/jsdoc/createJSDocPrivateTag.mjs +27 -0
  298. package/lib/factory/jsdoc/createJSDocPrivateTag.mjs.map +1 -0
  299. package/lib/factory/jsdoc/createJSDocPropertyTag.mjs +40 -0
  300. package/lib/factory/jsdoc/createJSDocPropertyTag.mjs.map +1 -0
  301. package/lib/factory/jsdoc/createJSDocProtectedTag.mjs +27 -0
  302. package/lib/factory/jsdoc/createJSDocProtectedTag.mjs.map +1 -0
  303. package/lib/factory/jsdoc/createJSDocPublicTag.mjs +27 -0
  304. package/lib/factory/jsdoc/createJSDocPublicTag.mjs.map +1 -0
  305. package/lib/factory/jsdoc/createJSDocReadonlyTag.mjs +27 -0
  306. package/lib/factory/jsdoc/createJSDocReadonlyTag.mjs.map +1 -0
  307. package/lib/factory/jsdoc/createJSDocReturnTag.mjs +32 -0
  308. package/lib/factory/jsdoc/createJSDocReturnTag.mjs.map +1 -0
  309. package/lib/factory/jsdoc/createJSDocSatisfiesTag.mjs +31 -0
  310. package/lib/factory/jsdoc/createJSDocSatisfiesTag.mjs.map +1 -0
  311. package/lib/factory/jsdoc/createJSDocSeeTag.mjs +31 -0
  312. package/lib/factory/jsdoc/createJSDocSeeTag.mjs.map +1 -0
  313. package/lib/factory/jsdoc/createJSDocSignature.mjs +32 -0
  314. package/lib/factory/jsdoc/createJSDocSignature.mjs.map +1 -0
  315. package/lib/factory/jsdoc/createJSDocTemplateTag.mjs +34 -0
  316. package/lib/factory/jsdoc/createJSDocTemplateTag.mjs.map +1 -0
  317. package/lib/factory/jsdoc/createJSDocText.mjs +25 -0
  318. package/lib/factory/jsdoc/createJSDocText.mjs.map +1 -0
  319. package/lib/factory/jsdoc/createJSDocThisTag.mjs +30 -0
  320. package/lib/factory/jsdoc/createJSDocThisTag.mjs.map +1 -0
  321. package/lib/factory/jsdoc/createJSDocThrowsTag.mjs +30 -0
  322. package/lib/factory/jsdoc/createJSDocThrowsTag.mjs.map +1 -0
  323. package/lib/factory/jsdoc/createJSDocTypeExpression.mjs +24 -0
  324. package/lib/factory/jsdoc/createJSDocTypeExpression.mjs.map +1 -0
  325. package/lib/factory/jsdoc/createJSDocTypeLiteral.mjs +29 -0
  326. package/lib/factory/jsdoc/createJSDocTypeLiteral.mjs.map +1 -0
  327. package/lib/factory/jsdoc/createJSDocTypeTag.mjs +31 -0
  328. package/lib/factory/jsdoc/createJSDocTypeTag.mjs.map +1 -0
  329. package/lib/factory/jsdoc/createJSDocTypedefTag.mjs +34 -0
  330. package/lib/factory/jsdoc/createJSDocTypedefTag.mjs.map +1 -0
  331. package/lib/factory/jsdoc/createJSDocUnknownTag.mjs +27 -0
  332. package/lib/factory/jsdoc/createJSDocUnknownTag.mjs.map +1 -0
  333. package/lib/factory/jsdoc/createJSDocUnknownType.mjs +21 -0
  334. package/lib/factory/jsdoc/createJSDocUnknownType.mjs.map +1 -0
  335. package/lib/factory/jsdoc/createJSDocVariadicType.mjs +24 -0
  336. package/lib/factory/jsdoc/createJSDocVariadicType.mjs.map +1 -0
  337. package/lib/factory/jsx/createJsxAttribute.mjs +29 -0
  338. package/lib/factory/jsx/createJsxAttribute.mjs.map +1 -0
  339. package/lib/factory/jsx/createJsxAttributes.mjs +27 -0
  340. package/lib/factory/jsx/createJsxAttributes.mjs.map +1 -0
  341. package/lib/factory/jsx/createJsxClosingElement.mjs +24 -0
  342. package/lib/factory/jsx/createJsxClosingElement.mjs.map +1 -0
  343. package/lib/factory/jsx/createJsxElement.mjs +32 -0
  344. package/lib/factory/jsx/createJsxElement.mjs.map +1 -0
  345. package/lib/factory/jsx/createJsxExpression.mjs +29 -0
  346. package/lib/factory/jsx/createJsxExpression.mjs.map +1 -0
  347. package/lib/factory/jsx/createJsxFragment.mjs +32 -0
  348. package/lib/factory/jsx/createJsxFragment.mjs.map +1 -0
  349. package/lib/factory/jsx/createJsxJsxClosingFragment.mjs +23 -0
  350. package/lib/factory/jsx/createJsxJsxClosingFragment.mjs.map +1 -0
  351. package/lib/factory/jsx/createJsxNamespacedName.mjs +28 -0
  352. package/lib/factory/jsx/createJsxNamespacedName.mjs.map +1 -0
  353. package/lib/factory/jsx/createJsxOpeningElement.mjs +32 -0
  354. package/lib/factory/jsx/createJsxOpeningElement.mjs.map +1 -0
  355. package/lib/factory/jsx/createJsxOpeningFragment.mjs +22 -0
  356. package/lib/factory/jsx/createJsxOpeningFragment.mjs.map +1 -0
  357. package/lib/factory/jsx/createJsxSelfClosingElement.mjs +31 -0
  358. package/lib/factory/jsx/createJsxSelfClosingElement.mjs.map +1 -0
  359. package/lib/factory/jsx/createJsxSpreadAttribute.mjs +24 -0
  360. package/lib/factory/jsx/createJsxSpreadAttribute.mjs.map +1 -0
  361. package/lib/factory/jsx/createJsxText.mjs +31 -0
  362. package/lib/factory/jsx/createJsxText.mjs.map +1 -0
  363. package/lib/factory/literals/createBigIntLiteral.mjs +23 -0
  364. package/lib/factory/literals/createBigIntLiteral.mjs.map +1 -0
  365. package/lib/factory/literals/createNoSubstitutionTemplateLiteral.mjs +24 -0
  366. package/lib/factory/literals/createNoSubstitutionTemplateLiteral.mjs.map +1 -0
  367. package/lib/factory/literals/createNumericLiteral.mjs +23 -0
  368. package/lib/factory/literals/createNumericLiteral.mjs.map +1 -0
  369. package/lib/factory/literals/createStringLiteral.mjs +29 -0
  370. package/lib/factory/literals/createStringLiteral.mjs.map +1 -0
  371. package/lib/factory/literals/createStringLiteralFromNode.mjs +25 -0
  372. package/lib/factory/literals/createStringLiteralFromNode.mjs.map +1 -0
  373. package/lib/factory/literals/createTemplateHead.mjs +27 -0
  374. package/lib/factory/literals/createTemplateHead.mjs.map +1 -0
  375. package/lib/factory/literals/createTemplateMiddle.mjs +25 -0
  376. package/lib/factory/literals/createTemplateMiddle.mjs.map +1 -0
  377. package/lib/factory/literals/createTemplateTail.mjs +25 -0
  378. package/lib/factory/literals/createTemplateTail.mjs.map +1 -0
  379. package/lib/factory/names/createDecorator.mjs +23 -0
  380. package/lib/factory/names/createDecorator.mjs.map +1 -0
  381. package/lib/factory/names/createFalse.mjs +23 -0
  382. package/lib/factory/names/createFalse.mjs.map +1 -0
  383. package/lib/factory/names/createIdentifier.mjs +23 -0
  384. package/lib/factory/names/createIdentifier.mjs.map +1 -0
  385. package/lib/factory/names/createLoopVariable.mjs +28 -0
  386. package/lib/factory/names/createLoopVariable.mjs.map +1 -0
  387. package/lib/factory/names/createModifier.mjs +25 -0
  388. package/lib/factory/names/createModifier.mjs.map +1 -0
  389. package/lib/factory/names/createModifiersFromModifierFlags.mjs +82 -0
  390. package/lib/factory/names/createModifiersFromModifierFlags.mjs.map +1 -0
  391. package/lib/factory/names/createNull.mjs +23 -0
  392. package/lib/factory/names/createNull.mjs.map +1 -0
  393. package/lib/factory/names/createPrivateIdentifier.mjs +23 -0
  394. package/lib/factory/names/createPrivateIdentifier.mjs.map +1 -0
  395. package/lib/factory/names/createQualifiedName.mjs +28 -0
  396. package/lib/factory/names/createQualifiedName.mjs.map +1 -0
  397. package/lib/factory/names/createSuper.mjs +23 -0
  398. package/lib/factory/names/createSuper.mjs.map +1 -0
  399. package/lib/factory/names/createTempVariable.mjs +33 -0
  400. package/lib/factory/names/createTempVariable.mjs.map +1 -0
  401. package/lib/factory/names/createThis.mjs +23 -0
  402. package/lib/factory/names/createThis.mjs.map +1 -0
  403. package/lib/factory/names/createToken.mjs +24 -0
  404. package/lib/factory/names/createToken.mjs.map +1 -0
  405. package/lib/factory/names/createTrue.mjs +23 -0
  406. package/lib/factory/names/createTrue.mjs.map +1 -0
  407. package/lib/factory/names/createUniqueName.mjs +32 -0
  408. package/lib/factory/names/createUniqueName.mjs.map +1 -0
  409. package/lib/factory/names/createUniquePrivateName.mjs +29 -0
  410. package/lib/factory/names/createUniquePrivateName.mjs.map +1 -0
  411. package/lib/factory/statements/createBlock.mjs +29 -0
  412. package/lib/factory/statements/createBlock.mjs.map +1 -0
  413. package/lib/factory/statements/createBreakStatement.mjs +31 -0
  414. package/lib/factory/statements/createBreakStatement.mjs.map +1 -0
  415. package/lib/factory/statements/createCaseBlock.mjs +30 -0
  416. package/lib/factory/statements/createCaseBlock.mjs.map +1 -0
  417. package/lib/factory/statements/createCaseClause.mjs +28 -0
  418. package/lib/factory/statements/createCaseClause.mjs.map +1 -0
  419. package/lib/factory/statements/createCatchClause.mjs +35 -0
  420. package/lib/factory/statements/createCatchClause.mjs.map +1 -0
  421. package/lib/factory/statements/createContinueStatement.mjs +31 -0
  422. package/lib/factory/statements/createContinueStatement.mjs.map +1 -0
  423. package/lib/factory/statements/createDebuggerStatement.mjs +21 -0
  424. package/lib/factory/statements/createDebuggerStatement.mjs.map +1 -0
  425. package/lib/factory/statements/createDefaultClause.mjs +24 -0
  426. package/lib/factory/statements/createDefaultClause.mjs.map +1 -0
  427. package/lib/factory/statements/createDoStatement.mjs +27 -0
  428. package/lib/factory/statements/createDoStatement.mjs.map +1 -0
  429. package/lib/factory/statements/createEmptyStatement.mjs +21 -0
  430. package/lib/factory/statements/createEmptyStatement.mjs.map +1 -0
  431. package/lib/factory/statements/createExpressionStatement.mjs +23 -0
  432. package/lib/factory/statements/createExpressionStatement.mjs.map +1 -0
  433. package/lib/factory/statements/createForInStatement.mjs +29 -0
  434. package/lib/factory/statements/createForInStatement.mjs.map +1 -0
  435. package/lib/factory/statements/createForOfStatement.mjs +39 -0
  436. package/lib/factory/statements/createForOfStatement.mjs.map +1 -0
  437. package/lib/factory/statements/createForStatement.mjs +32 -0
  438. package/lib/factory/statements/createForStatement.mjs.map +1 -0
  439. package/lib/factory/statements/createIfStatement.mjs +31 -0
  440. package/lib/factory/statements/createIfStatement.mjs.map +1 -0
  441. package/lib/factory/statements/createLabeledStatement.mjs +28 -0
  442. package/lib/factory/statements/createLabeledStatement.mjs.map +1 -0
  443. package/lib/factory/statements/createNotEmittedStatement.mjs +20 -0
  444. package/lib/factory/statements/createNotEmittedStatement.mjs.map +1 -0
  445. package/lib/factory/statements/createReturnStatement.mjs +28 -0
  446. package/lib/factory/statements/createReturnStatement.mjs.map +1 -0
  447. package/lib/factory/statements/createSwitchStatement.mjs +31 -0
  448. package/lib/factory/statements/createSwitchStatement.mjs.map +1 -0
  449. package/lib/factory/statements/createThrowStatement.mjs +22 -0
  450. package/lib/factory/statements/createThrowStatement.mjs.map +1 -0
  451. package/lib/factory/statements/createTryStatement.mjs +34 -0
  452. package/lib/factory/statements/createTryStatement.mjs.map +1 -0
  453. package/lib/factory/statements/createVariableDeclaration.mjs +38 -0
  454. package/lib/factory/statements/createVariableDeclaration.mjs.map +1 -0
  455. package/lib/factory/statements/createVariableDeclarationList.mjs +28 -0
  456. package/lib/factory/statements/createVariableDeclarationList.mjs.map +1 -0
  457. package/lib/factory/statements/createVariableStatement.mjs +33 -0
  458. package/lib/factory/statements/createVariableStatement.mjs.map +1 -0
  459. package/lib/factory/statements/createWhileStatement.mjs +27 -0
  460. package/lib/factory/statements/createWhileStatement.mjs.map +1 -0
  461. package/lib/factory/statements/createWithStatement.mjs +27 -0
  462. package/lib/factory/statements/createWithStatement.mjs.map +1 -0
  463. package/lib/factory/types/createArrayTypeNode.mjs +25 -0
  464. package/lib/factory/types/createArrayTypeNode.mjs.map +1 -0
  465. package/lib/factory/types/createCallSignature.mjs +26 -0
  466. package/lib/factory/types/createCallSignature.mjs.map +1 -0
  467. package/lib/factory/types/createConditionalTypeNode.mjs +28 -0
  468. package/lib/factory/types/createConditionalTypeNode.mjs.map +1 -0
  469. package/lib/factory/types/createConstructSignature.mjs +25 -0
  470. package/lib/factory/types/createConstructSignature.mjs.map +1 -0
  471. package/lib/factory/types/createConstructorTypeNode.mjs +27 -0
  472. package/lib/factory/types/createConstructorTypeNode.mjs.map +1 -0
  473. package/lib/factory/types/createExpressionWithTypeArguments.mjs +25 -0
  474. package/lib/factory/types/createExpressionWithTypeArguments.mjs.map +1 -0
  475. package/lib/factory/types/createFunctionTypeNode.mjs +27 -0
  476. package/lib/factory/types/createFunctionTypeNode.mjs.map +1 -0
  477. package/lib/factory/types/createImportTypeNode.mjs +27 -0
  478. package/lib/factory/types/createImportTypeNode.mjs.map +1 -0
  479. package/lib/factory/types/createIndexSignature.mjs +25 -0
  480. package/lib/factory/types/createIndexSignature.mjs.map +1 -0
  481. package/lib/factory/types/createIndexedAccessTypeNode.mjs +25 -0
  482. package/lib/factory/types/createIndexedAccessTypeNode.mjs.map +1 -0
  483. package/lib/factory/types/createInferTypeNode.mjs +24 -0
  484. package/lib/factory/types/createInferTypeNode.mjs.map +1 -0
  485. package/lib/factory/types/createIntersectionTypeNode.mjs +24 -0
  486. package/lib/factory/types/createIntersectionTypeNode.mjs.map +1 -0
  487. package/lib/factory/types/createKeywordTypeNode.mjs +25 -0
  488. package/lib/factory/types/createKeywordTypeNode.mjs.map +1 -0
  489. package/lib/factory/types/createLiteralTypeNode.mjs +26 -0
  490. package/lib/factory/types/createLiteralTypeNode.mjs.map +1 -0
  491. package/lib/factory/types/createMappedTypeNode.mjs +44 -0
  492. package/lib/factory/types/createMappedTypeNode.mjs.map +1 -0
  493. package/lib/factory/types/createMethodSignature.mjs +39 -0
  494. package/lib/factory/types/createMethodSignature.mjs.map +1 -0
  495. package/lib/factory/types/createNamedTupleMember.mjs +33 -0
  496. package/lib/factory/types/createNamedTupleMember.mjs.map +1 -0
  497. package/lib/factory/types/createNotEmittedTypeElement.mjs +17 -0
  498. package/lib/factory/types/createNotEmittedTypeElement.mjs.map +1 -0
  499. package/lib/factory/types/createOptionalTypeNode.mjs +23 -0
  500. package/lib/factory/types/createOptionalTypeNode.mjs.map +1 -0
  501. package/lib/factory/types/createParenthesizedType.mjs +23 -0
  502. package/lib/factory/types/createParenthesizedType.mjs.map +1 -0
  503. package/lib/factory/types/createPropertySignature.mjs +34 -0
  504. package/lib/factory/types/createPropertySignature.mjs.map +1 -0
  505. package/lib/factory/types/createRestTypeNode.mjs +22 -0
  506. package/lib/factory/types/createRestTypeNode.mjs.map +1 -0
  507. package/lib/factory/types/createTemplateLiteralType.mjs +27 -0
  508. package/lib/factory/types/createTemplateLiteralType.mjs.map +1 -0
  509. package/lib/factory/types/createTemplateLiteralTypeSpan.mjs +27 -0
  510. package/lib/factory/types/createTemplateLiteralTypeSpan.mjs.map +1 -0
  511. package/lib/factory/types/createThisTypeNode.mjs +22 -0
  512. package/lib/factory/types/createThisTypeNode.mjs.map +1 -0
  513. package/lib/factory/types/createTupleTypeNode.mjs +24 -0
  514. package/lib/factory/types/createTupleTypeNode.mjs.map +1 -0
  515. package/lib/factory/types/createTypeLiteralNode.mjs +25 -0
  516. package/lib/factory/types/createTypeLiteralNode.mjs.map +1 -0
  517. package/lib/factory/types/createTypeOperatorNode.mjs +26 -0
  518. package/lib/factory/types/createTypeOperatorNode.mjs.map +1 -0
  519. package/lib/factory/types/createTypeParameterDeclaration.mjs +34 -0
  520. package/lib/factory/types/createTypeParameterDeclaration.mjs.map +1 -0
  521. package/lib/factory/types/createTypePredicateNode.mjs +35 -0
  522. package/lib/factory/types/createTypePredicateNode.mjs.map +1 -0
  523. package/lib/factory/types/createTypeQueryNode.mjs +23 -0
  524. package/lib/factory/types/createTypeQueryNode.mjs.map +1 -0
  525. package/lib/factory/types/createTypeReferenceNode.mjs +30 -0
  526. package/lib/factory/types/createTypeReferenceNode.mjs.map +1 -0
  527. package/lib/factory/types/createUnionTypeNode.mjs +24 -0
  528. package/lib/factory/types/createUnionTypeNode.mjs.map +1 -0
  529. package/lib/index.d.ts +0 -1
  530. package/lib/index.js.map +1 -1
  531. package/lib/index.mjs +10 -0
  532. package/lib/index.mjs.map +1 -0
  533. package/lib/internal/doc.mjs +171 -0
  534. package/lib/internal/doc.mjs.map +1 -0
  535. package/lib/syntax/NodeFlags.mjs +23 -0
  536. package/lib/syntax/NodeFlags.mjs.map +1 -0
  537. package/lib/syntax/SyntaxKind.mjs +110 -0
  538. package/lib/syntax/SyntaxKind.mjs.map +1 -0
  539. package/package.json +6 -9
  540. package/src/TsPrinter.ts +702 -88
  541. package/src/index.ts +0 -1
package/src/TsPrinter.ts CHANGED
@@ -1,4 +1,12 @@
1
- import type { ModifierLike, Node, SourceFile, Statement } from "./ast";
1
+ import type {
2
+ Block,
3
+ Expression,
4
+ ModifierLike,
5
+ Node,
6
+ SourceFile,
7
+ Statement,
8
+ TypeNode,
9
+ } from "./ast";
2
10
  import type { SynthesizedComment } from "./comments";
3
11
  import {
4
12
  getSyntheticLeadingComments,
@@ -18,34 +26,13 @@ import {
18
26
  } from "./internal/doc";
19
27
  import { NodeFlags, SyntaxKind } from "./syntax";
20
28
 
21
- /** Options for {@link TsPrinter}. */
22
- export interface TsPrinterOptions {
23
- /** Maximum line width before groups break. Defaults to `80`. */
24
- printWidth?: number;
25
- /** Indentation unit. Defaults to two spaces. */
26
- indent?: string;
27
- /** New line sequence. Defaults to `"\n"` (LineFeed). */
28
- newLine?: string;
29
- }
30
-
31
- const escapeString = (text: string, singleQuote?: boolean): string => {
32
- const escaped: string = text
33
- .replace(/\\/g, "\\\\")
34
- .replace(/\n/g, "\\n")
35
- .replace(/\r/g, "\\r")
36
- .replace(/\t/g, "\\t");
37
- return singleQuote === true
38
- ? `'${escaped.replace(/'/g, "\\'")}'`
39
- : `"${escaped.replace(/"/g, '\\"')}"`;
40
- };
41
-
42
29
  /**
43
30
  * Printer turning {@link factory} produced AST nodes into TypeScript source
44
31
  * text.
45
32
  *
46
33
  * The printer is a width-aware pretty-printer: it builds a Prettier-style
47
34
  * document for the {@link Node} discriminated union and lays it out against
48
- * {@link TsPrinterOptions.printWidth}. Lists (arguments, parameters, generic
35
+ * {@link TsPrinter.IProps.printWidth}. Lists (arguments, parameters, generic
49
36
  * arguments, array / object members, ...) print on one line when they fit and
50
37
  * break onto indented lines — with trailing commas — when they do not. Every
51
38
  * `node.kind` narrows to its concrete type, so the walk is fully type-checked;
@@ -65,7 +52,7 @@ export class TsPrinter {
65
52
  private readonly indent_: string;
66
53
  private readonly newLine_: string;
67
54
 
68
- public constructor(options: TsPrinterOptions = {}) {
55
+ public constructor(options: TsPrinter.IProps = {}) {
69
56
  this.printWidth_ = options.printWidth ?? 80;
70
57
  this.indent_ = options.indent ?? " ";
71
58
  this.newLine_ = options.newLine ?? "\n";
@@ -221,6 +208,17 @@ export class TsPrinter {
221
208
  );
222
209
  }
223
210
 
211
+ private args(args: readonly Expression[]): Doc {
212
+ return this.delim(
213
+ "(",
214
+ args.map((a) => this.expressionForDisallowedComma(a)),
215
+ ")",
216
+ {
217
+ trailingComma: true,
218
+ },
219
+ );
220
+ }
221
+
224
222
  private modifiers(
225
223
  mods: readonly ModifierLike[] | undefined,
226
224
  decoratorsOnNewLine: boolean,
@@ -334,7 +332,7 @@ export class TsPrinter {
334
332
  case "Token":
335
333
  return node.token;
336
334
  case "Decorator":
337
- return concat(["@", this.emit(node.expression)]);
335
+ return concat(["@", this.leftSideExpression(node.expression)]);
338
336
 
339
337
  /* literals */
340
338
  case "StringLiteral":
@@ -348,7 +346,7 @@ export class TsPrinter {
348
346
  case "ArrayLiteralExpression":
349
347
  return this.delim(
350
348
  "[",
351
- node.elements.map((e) => this.emit(e)),
349
+ node.elements.map((e) => this.expressionForDisallowedComma(e)),
352
350
  "]",
353
351
  { trailingComma: true, forceBreak: node.multiLine === true },
354
352
  );
@@ -367,66 +365,86 @@ export class TsPrinter {
367
365
  return concat([
368
366
  this.emit(node.name),
369
367
  ": ",
370
- this.emit(node.initializer),
368
+ this.expressionForDisallowedComma(node.initializer),
371
369
  ]);
372
370
  case "ShorthandPropertyAssignment":
373
371
  return concat([
374
372
  this.emit(node.name),
375
373
  node.objectAssignmentInitializer
376
- ? concat([" = ", this.emit(node.objectAssignmentInitializer)])
374
+ ? concat([
375
+ " = ",
376
+ this.expressionForDisallowedComma(
377
+ node.objectAssignmentInitializer,
378
+ ),
379
+ ])
377
380
  : "",
378
381
  ]);
379
382
  case "SpreadAssignment":
380
- return concat(["...", this.emit(node.expression)]);
383
+ return concat([
384
+ "...",
385
+ this.expressionForDisallowedComma(node.expression),
386
+ ]);
381
387
  case "PropertyAccessExpression":
382
- return concat([this.emit(node.expression), ".", this.emit(node.name)]);
388
+ return concat([
389
+ this.leftSideExpression(node.expression),
390
+ ".",
391
+ this.emit(node.name),
392
+ ]);
383
393
  case "ElementAccessExpression":
384
394
  return concat([
385
- this.emit(node.expression),
395
+ this.leftSideExpression(node.expression),
386
396
  "[",
387
- this.emit(node.argumentExpression),
397
+ this.expressionForDisallowedComma(node.argumentExpression),
388
398
  "]",
389
399
  ]);
390
400
  case "CallExpression":
391
401
  return concat([
392
- this.emit(node.expression),
402
+ this.leftSideExpression(node.expression),
393
403
  this.typeArguments(node.typeArguments),
394
- this.params(node.arguments),
404
+ this.args(node.arguments),
395
405
  ]);
396
406
  case "NewExpression":
397
407
  return concat([
398
408
  "new ",
399
- this.emit(node.expression),
409
+ this.newExpressionTarget(node.expression),
400
410
  this.typeArguments(node.typeArguments),
401
- this.params(node.arguments ?? []),
411
+ this.args(node.arguments ?? []),
402
412
  ]);
403
413
  case "ParenthesizedExpression":
404
414
  return concat(["(", this.emit(node.expression), ")"]);
405
415
  case "BinaryExpression":
406
416
  return group(
407
417
  concat([
408
- this.emit(node.left),
418
+ this.binaryOperand(node.operator, node.left, true),
409
419
  " ",
410
420
  node.operator,
411
- indent(concat([line, this.emit(node.right)])),
421
+ indent(
422
+ concat([
423
+ line,
424
+ this.binaryOperand(node.operator, node.right, false, node.left),
425
+ ]),
426
+ ),
412
427
  ]),
413
428
  );
414
429
  case "PrefixUnaryExpression":
415
- return concat([node.operator, this.emit(node.operand)]);
430
+ return concat([
431
+ node.operator,
432
+ this.prefixUnaryOperand(node.operand, node.operator),
433
+ ]);
416
434
  case "PostfixUnaryExpression":
417
- return concat([this.emit(node.operand), node.operator]);
435
+ return concat([this.postfixUnaryOperand(node.operand), node.operator]);
418
436
  case "ConditionalExpression":
419
437
  return group(
420
438
  concat([
421
- this.emit(node.condition),
439
+ this.conditionalCondition(node.condition),
422
440
  indent(
423
441
  concat([
424
442
  line,
425
443
  "? ",
426
- this.emit(node.whenTrue),
444
+ this.conditionalBranch(node.whenTrue),
427
445
  line,
428
446
  ": ",
429
- this.emit(node.whenFalse),
447
+ this.conditionalBranch(node.whenFalse),
430
448
  ]),
431
449
  ),
432
450
  ]),
@@ -438,7 +456,7 @@ export class TsPrinter {
438
456
  this.params(node.parameters),
439
457
  this.optType(node.type),
440
458
  " => ",
441
- this.emit(node.body),
459
+ this.arrowFunctionBody(node.body),
442
460
  ]);
443
461
  case "FunctionExpression":
444
462
  return concat([
@@ -454,24 +472,27 @@ export class TsPrinter {
454
472
  ]);
455
473
  case "AsExpression":
456
474
  return concat([
457
- this.emit(node.expression),
475
+ this.assertionExpressionOperand(node.expression),
458
476
  " as ",
459
477
  this.emit(node.type),
460
478
  ]);
461
479
  case "SatisfiesExpression":
462
480
  return concat([
463
- this.emit(node.expression),
481
+ this.assertionExpressionOperand(node.expression),
464
482
  " satisfies ",
465
483
  this.emit(node.type),
466
484
  ]);
467
485
  case "NonNullExpression":
468
- return concat([this.emit(node.expression), "!"]);
486
+ return concat([this.leftSideExpression(node.expression), "!"]);
469
487
  case "SpreadElement":
470
- return concat(["...", this.emit(node.expression)]);
488
+ return concat([
489
+ "...",
490
+ this.expressionForDisallowedComma(node.expression),
491
+ ]);
471
492
  case "AwaitExpression":
472
- return concat(["await ", this.emit(node.expression)]);
493
+ return concat(["await ", this.prefixUnaryOperand(node.expression)]);
473
494
  case "TypeOfExpression":
474
- return concat(["typeof ", this.emit(node.expression)]);
495
+ return concat(["typeof ", this.prefixUnaryOperand(node.expression)]);
475
496
 
476
497
  /* types */
477
498
  case "KeywordTypeNode":
@@ -484,15 +505,9 @@ export class TsPrinter {
484
505
  case "ArrayTypeNode":
485
506
  return concat([this.postfixTypeOperand(node.elementType), "[]"]);
486
507
  case "UnionTypeNode":
487
- return this.binaryType(
488
- "|",
489
- node.types.map((t) => this.emit(t)),
490
- );
508
+ return this.binaryType("|", node.types);
491
509
  case "IntersectionTypeNode":
492
- return this.binaryType(
493
- "&",
494
- node.types.map((t) => this.emit(t)),
495
- );
510
+ return this.binaryType("&", node.types);
496
511
  case "LiteralTypeNode":
497
512
  return this.emit(node.literal);
498
513
  case "TypeLiteralNode":
@@ -516,7 +531,11 @@ export class TsPrinter {
516
531
  case "ParenthesizedTypeNode":
517
532
  return concat(["(", this.emit(node.type), ")"]);
518
533
  case "TypeOperatorNode":
519
- return concat([node.operator, " ", this.emit(node.type)]);
534
+ return concat([
535
+ node.operator,
536
+ " ",
537
+ this.typeOperatorOperand(node.type, node.operator),
538
+ ]);
520
539
  case "IndexedAccessTypeNode":
521
540
  return concat([
522
541
  this.postfixTypeOperand(node.objectType),
@@ -576,7 +595,12 @@ export class TsPrinter {
576
595
  this.emit(node.name),
577
596
  node.questionToken ? "?" : "",
578
597
  this.optType(node.type),
579
- node.initializer ? concat([" = ", this.emit(node.initializer)]) : "",
598
+ node.initializer
599
+ ? concat([
600
+ " = ",
601
+ this.expressionForDisallowedComma(node.initializer),
602
+ ])
603
+ : "",
580
604
  ]);
581
605
  case "HeritageClause":
582
606
  return concat([
@@ -616,10 +640,18 @@ export class TsPrinter {
616
640
  this.emit(node.name),
617
641
  node.exclamationToken ? "!" : "",
618
642
  this.optType(node.type),
619
- node.initializer ? concat([" = ", this.emit(node.initializer)]) : "",
643
+ node.initializer
644
+ ? concat([
645
+ " = ",
646
+ this.expressionForDisallowedComma(node.initializer),
647
+ ])
648
+ : "",
620
649
  ]);
621
650
  case "ExpressionStatement":
622
- return concat([this.emit(node.expression), ";"]);
651
+ return concat([
652
+ this.expressionStatementExpression(node.expression),
653
+ ";",
654
+ ]);
623
655
  case "ReturnStatement":
624
656
  return node.expression
625
657
  ? concat(["return ", this.emit(node.expression), ";"])
@@ -670,7 +702,12 @@ export class TsPrinter {
670
702
  ? this.emit(node.questionOrExclamationToken)
671
703
  : "",
672
704
  this.optType(node.type),
673
- node.initializer ? concat([" = ", this.emit(node.initializer)]) : "",
705
+ node.initializer
706
+ ? concat([
707
+ " = ",
708
+ this.expressionForDisallowedComma(node.initializer),
709
+ ])
710
+ : "",
674
711
  ";",
675
712
  ]);
676
713
  case "MethodDeclaration":
@@ -755,7 +792,12 @@ export class TsPrinter {
755
792
  case "EnumMember":
756
793
  return concat([
757
794
  this.emit(node.name),
758
- node.initializer ? concat([" = ", this.emit(node.initializer)]) : "",
795
+ node.initializer
796
+ ? concat([
797
+ " = ",
798
+ this.expressionForDisallowedComma(node.initializer),
799
+ ])
800
+ : "",
759
801
  ]);
760
802
 
761
803
  /* imports & exports */
@@ -822,7 +864,10 @@ export class TsPrinter {
822
864
  return concat([
823
865
  this.modifiers(node.modifiers, false),
824
866
  node.isExportEquals ? "export = " : "export default ",
825
- this.emit(node.expression),
867
+ this.exportAssignmentExpression(
868
+ node.expression,
869
+ node.isExportEquals === true,
870
+ ),
826
871
  ";",
827
872
  ]);
828
873
 
@@ -1030,9 +1075,9 @@ export class TsPrinter {
1030
1075
  ]);
1031
1076
  case "ConditionalTypeNode":
1032
1077
  return concat([
1033
- this.emit(node.checkType),
1078
+ this.conditionalTypeCheckOperand(node.checkType),
1034
1079
  " extends ",
1035
- this.emit(node.extendsType),
1080
+ this.conditionalTypeExtendsOperand(node.extendsType),
1036
1081
  " ? ",
1037
1082
  this.emit(node.trueType),
1038
1083
  " : ",
@@ -1083,9 +1128,9 @@ export class TsPrinter {
1083
1128
  this.emit(node.type),
1084
1129
  ]);
1085
1130
  case "OptionalTypeNode":
1086
- return concat([this.emit(node.type), "?"]);
1131
+ return concat([this.postfixTypeOperand(node.type), "?"]);
1087
1132
  case "RestTypeNode":
1088
- return concat(["...", this.emit(node.type)]);
1133
+ return concat(["...", this.postfixTypeOperand(node.type)]);
1089
1134
  case "ImportTypeNode":
1090
1135
  return concat([
1091
1136
  node.isTypeOf ? "typeof " : "",
@@ -1126,10 +1171,13 @@ export class TsPrinter {
1126
1171
  concat(node.templateSpans.map((s) => this.emit(s))),
1127
1172
  ]);
1128
1173
  case "TemplateSpan":
1129
- return concat([this.emit(node.expression), this.emit(node.literal)]);
1174
+ return concat([
1175
+ this.expressionForDisallowedComma(node.expression),
1176
+ this.emit(node.literal),
1177
+ ]);
1130
1178
  case "TaggedTemplateExpression":
1131
1179
  return concat([
1132
- this.emit(node.tag),
1180
+ this.leftSideExpression(node.tag),
1133
1181
  this.typeArguments(node.typeArguments),
1134
1182
  this.emit(node.template),
1135
1183
  ]);
@@ -1137,12 +1185,14 @@ export class TsPrinter {
1137
1185
  return concat([
1138
1186
  "yield",
1139
1187
  node.asteriskToken ? "*" : "",
1140
- node.expression ? concat([" ", this.emit(node.expression)]) : "",
1188
+ node.expression
1189
+ ? concat([" ", this.expressionForDisallowedComma(node.expression)])
1190
+ : "",
1141
1191
  ]);
1142
1192
  case "DeleteExpression":
1143
- return concat(["delete ", this.emit(node.expression)]);
1193
+ return concat(["delete ", this.prefixUnaryOperand(node.expression)]);
1144
1194
  case "VoidExpression":
1145
- return concat(["void ", this.emit(node.expression)]);
1195
+ return concat(["void ", this.prefixUnaryOperand(node.expression)]);
1146
1196
  case "RegularExpressionLiteral":
1147
1197
  return node.text;
1148
1198
  case "ClassExpression":
@@ -1163,7 +1213,11 @@ export class TsPrinter {
1163
1213
  node.elements.map((e) => this.emit(e)),
1164
1214
  );
1165
1215
  case "ComputedPropertyName":
1166
- return concat(["[", this.emit(node.expression), "]"]);
1216
+ return concat([
1217
+ "[",
1218
+ this.expressionForDisallowedComma(node.expression),
1219
+ "]",
1220
+ ]);
1167
1221
  case "OmittedExpression":
1168
1222
  return "";
1169
1223
  case "BindingElement":
@@ -1171,7 +1225,12 @@ export class TsPrinter {
1171
1225
  node.dotDotDotToken ? "..." : "",
1172
1226
  node.propertyName ? concat([this.emit(node.propertyName), ": "]) : "",
1173
1227
  this.emit(node.name),
1174
- node.initializer ? concat([" = ", this.emit(node.initializer)]) : "",
1228
+ node.initializer
1229
+ ? concat([
1230
+ " = ",
1231
+ this.expressionForDisallowedComma(node.initializer),
1232
+ ])
1233
+ : "",
1175
1234
  ]);
1176
1235
  case "ObjectBindingPattern":
1177
1236
  return this.delim(
@@ -1192,31 +1251,31 @@ export class TsPrinter {
1192
1251
  "<",
1193
1252
  this.emit(node.type),
1194
1253
  ">",
1195
- this.emit(node.expression),
1254
+ this.prefixUnaryOperand(node.expression),
1196
1255
  ]);
1197
1256
  case "PropertyAccessChain":
1198
1257
  return concat([
1199
- this.emit(node.expression),
1258
+ this.leftSideExpression(node.expression),
1200
1259
  node.questionDotToken ? "?." : ".",
1201
1260
  this.emit(node.name),
1202
1261
  ]);
1203
1262
  case "ElementAccessChain":
1204
1263
  return concat([
1205
- this.emit(node.expression),
1264
+ this.leftSideExpression(node.expression),
1206
1265
  node.questionDotToken ? "?." : "",
1207
1266
  "[",
1208
- this.emit(node.argumentExpression),
1267
+ this.expressionForDisallowedComma(node.argumentExpression),
1209
1268
  "]",
1210
1269
  ]);
1211
1270
  case "CallChain":
1212
1271
  return concat([
1213
- this.emit(node.expression),
1272
+ this.leftSideExpression(node.expression),
1214
1273
  node.questionDotToken ? "?." : "",
1215
1274
  this.typeArguments(node.typeArguments),
1216
- this.params(node.arguments),
1275
+ this.args(node.arguments),
1217
1276
  ]);
1218
1277
  case "NonNullChain":
1219
- return concat([this.emit(node.expression), "!"]);
1278
+ return concat([this.leftSideExpression(node.expression), "!"]);
1220
1279
 
1221
1280
  /* jsx */
1222
1281
  case "JsxElement":
@@ -1540,16 +1599,478 @@ export class TsPrinter {
1540
1599
  * parenthesizing the lower-precedence type forms that would otherwise
1541
1600
  * re-associate — matching the legacy printer's parenthesizer rules.
1542
1601
  */
1543
- private postfixTypeOperand(type: Node): Doc {
1544
- const parenthesize: boolean =
1602
+ private parenthesizedExpression(expression: Expression): Doc {
1603
+ return expression.kind === "ParenthesizedExpression"
1604
+ ? this.emit(expression)
1605
+ : concat(["(", this.emit(expression), ")"]);
1606
+ }
1607
+
1608
+ private expressionForDisallowedComma(expression: Expression): Doc {
1609
+ return this.expressionPrecedence(expression) > ExpressionPrecedence.Comma
1610
+ ? this.emit(expression)
1611
+ : this.parenthesizedExpression(expression);
1612
+ }
1613
+
1614
+ private leftSideExpression(expression: Expression): Doc {
1615
+ return this.isLeftHandSideExpression(expression)
1616
+ ? this.emit(expression)
1617
+ : this.parenthesizedExpression(expression);
1618
+ }
1619
+
1620
+ private newExpressionTarget(expression: Expression): Doc {
1621
+ return expression.kind !== "CallExpression" &&
1622
+ expression.kind !== "CallChain" &&
1623
+ (expression.kind !== "NewExpression" ||
1624
+ expression.arguments !== undefined) &&
1625
+ this.isLeftHandSideExpression(expression)
1626
+ ? this.emit(expression)
1627
+ : this.parenthesizedExpression(expression);
1628
+ }
1629
+
1630
+ private prefixUnaryOperand(operand: Expression, operator?: SyntaxKind): Doc {
1631
+ const body: Doc = this.isUnaryExpression(operand)
1632
+ ? this.emit(operand)
1633
+ : this.parenthesizedExpression(operand);
1634
+ return this.needsPrefixUnaryGap(operator, operand)
1635
+ ? concat([" ", body])
1636
+ : body;
1637
+ }
1638
+
1639
+ private postfixUnaryOperand(operand: Expression): Doc {
1640
+ return this.isLeftHandSideExpression(operand)
1641
+ ? this.emit(operand)
1642
+ : this.parenthesizedExpression(operand);
1643
+ }
1644
+
1645
+ private conditionalCondition(condition: Expression): Doc {
1646
+ return this.expressionPrecedence(condition) >
1647
+ ExpressionPrecedence.Conditional
1648
+ ? this.emit(condition)
1649
+ : this.parenthesizedExpression(condition);
1650
+ }
1651
+
1652
+ private conditionalBranch(branch: Expression): Doc {
1653
+ return this.expressionForDisallowedComma(branch);
1654
+ }
1655
+
1656
+ private arrowFunctionBody(body: Block | Expression): Doc {
1657
+ return body.kind === "Block"
1658
+ ? this.emit(body)
1659
+ : this.expressionNeedsConciseBodyParentheses(body)
1660
+ ? this.parenthesizedExpression(body)
1661
+ : this.emit(body);
1662
+ }
1663
+
1664
+ private expressionStatementExpression(expression: Expression): Doc {
1665
+ return this.expressionNeedsStatementParentheses(expression)
1666
+ ? this.parenthesizedExpression(expression)
1667
+ : this.emit(expression);
1668
+ }
1669
+
1670
+ private exportAssignmentExpression(
1671
+ expression: Expression,
1672
+ isExportEquals: boolean,
1673
+ ): Doc {
1674
+ return isExportEquals
1675
+ ? this.expressionForDisallowedComma(expression)
1676
+ : this.expressionNeedsExportDefaultParentheses(expression)
1677
+ ? this.parenthesizedExpression(expression)
1678
+ : this.emit(expression);
1679
+ }
1680
+
1681
+ private assertionExpressionOperand(expression: Expression): Doc {
1682
+ return this.expressionPrecedence(expression) >=
1683
+ ExpressionPrecedence.Relational
1684
+ ? this.expressionForDisallowedComma(expression)
1685
+ : this.parenthesizedExpression(expression);
1686
+ }
1687
+
1688
+ private binaryOperand(
1689
+ operator: SyntaxKind,
1690
+ operand: Expression,
1691
+ isLeftSide: boolean,
1692
+ leftOperand?: Expression,
1693
+ ): Doc {
1694
+ return this.binaryOperandNeedsParentheses(
1695
+ operator,
1696
+ operand,
1697
+ isLeftSide,
1698
+ leftOperand,
1699
+ )
1700
+ ? this.parenthesizedExpression(operand)
1701
+ : this.emit(operand);
1702
+ }
1703
+
1704
+ private binaryOperandNeedsParentheses(
1705
+ operator: SyntaxKind,
1706
+ operand: Expression,
1707
+ isLeftSide: boolean,
1708
+ leftOperand?: Expression,
1709
+ ): boolean {
1710
+ if (operand.kind === "ParenthesizedExpression") return false;
1711
+ if (
1712
+ operator === SyntaxKind.AsteriskAsteriskToken &&
1713
+ isLeftSide &&
1714
+ this.expressionPrecedence(operand) === ExpressionPrecedence.Unary
1715
+ )
1716
+ return true;
1717
+ if (
1718
+ operand.kind === "BinaryExpression" &&
1719
+ this.mixingBinaryOperatorsRequiresParentheses(operator, operand.operator)
1720
+ )
1721
+ return true;
1722
+
1723
+ const operatorPrecedence: ExpressionPrecedence =
1724
+ this.binaryOperatorPrecedence(operator);
1725
+ const operandPrecedence: ExpressionPrecedence =
1726
+ this.expressionPrecedence(operand);
1727
+ if (
1728
+ !isLeftSide &&
1729
+ operand.kind === "ArrowFunction" &&
1730
+ operatorPrecedence > ExpressionPrecedence.Assignment
1731
+ )
1732
+ return true;
1733
+ if (operandPrecedence < operatorPrecedence) return true;
1734
+ if (operandPrecedence > operatorPrecedence) return false;
1735
+
1736
+ if (isLeftSide)
1737
+ return this.binaryOperatorAssociativity(operator) === Associativity.Right;
1738
+ if (operand.kind === "BinaryExpression" && operand.operator === operator) {
1739
+ if (this.operatorHasAssociativeProperty(operator)) return false;
1740
+ if (
1741
+ operator === SyntaxKind.PlusToken &&
1742
+ leftOperand !== undefined &&
1743
+ this.literalKindOfBinaryPlusOperand(leftOperand) !== undefined &&
1744
+ this.literalKindOfBinaryPlusOperand(leftOperand) ===
1745
+ this.literalKindOfBinaryPlusOperand(operand)
1746
+ )
1747
+ return false;
1748
+ }
1749
+ return this.expressionAssociativity(operand) === Associativity.Left;
1750
+ }
1751
+
1752
+ private expressionPrecedence(expression: Expression): ExpressionPrecedence {
1753
+ switch (expression.kind) {
1754
+ case "CommaListExpression":
1755
+ return ExpressionPrecedence.Comma;
1756
+ case "YieldExpression":
1757
+ return ExpressionPrecedence.Yield;
1758
+ case "ConditionalExpression":
1759
+ return ExpressionPrecedence.Conditional;
1760
+ case "BinaryExpression":
1761
+ return this.binaryOperatorPrecedence(expression.operator);
1762
+ case "AsExpression":
1763
+ case "SatisfiesExpression":
1764
+ return ExpressionPrecedence.Relational;
1765
+ case "TypeAssertion":
1766
+ case "PrefixUnaryExpression":
1767
+ case "TypeOfExpression":
1768
+ case "VoidExpression":
1769
+ case "DeleteExpression":
1770
+ case "AwaitExpression":
1771
+ case "NonNullExpression":
1772
+ case "NonNullChain":
1773
+ return ExpressionPrecedence.Unary;
1774
+ case "PostfixUnaryExpression":
1775
+ return ExpressionPrecedence.Update;
1776
+ case "CallExpression":
1777
+ case "CallChain":
1778
+ return ExpressionPrecedence.LeftHandSide;
1779
+ case "NewExpression":
1780
+ case "TaggedTemplateExpression":
1781
+ case "PropertyAccessExpression":
1782
+ case "PropertyAccessChain":
1783
+ case "ElementAccessExpression":
1784
+ case "ElementAccessChain":
1785
+ case "MetaProperty":
1786
+ return ExpressionPrecedence.Member;
1787
+ default:
1788
+ return ExpressionPrecedence.Primary;
1789
+ }
1790
+ }
1791
+
1792
+ private expressionAssociativity(expression: Expression): Associativity {
1793
+ switch (expression.kind) {
1794
+ case "NewExpression":
1795
+ return expression.arguments === undefined
1796
+ ? Associativity.Right
1797
+ : Associativity.Left;
1798
+ case "PrefixUnaryExpression":
1799
+ case "TypeOfExpression":
1800
+ case "VoidExpression":
1801
+ case "DeleteExpression":
1802
+ case "AwaitExpression":
1803
+ case "ConditionalExpression":
1804
+ case "YieldExpression":
1805
+ return Associativity.Right;
1806
+ case "BinaryExpression":
1807
+ return this.binaryOperatorAssociativity(expression.operator);
1808
+ default:
1809
+ return Associativity.Left;
1810
+ }
1811
+ }
1812
+
1813
+ private binaryOperatorPrecedence(operator: SyntaxKind): ExpressionPrecedence {
1814
+ switch (operator) {
1815
+ case SyntaxKind.CommaToken:
1816
+ return ExpressionPrecedence.Comma;
1817
+ case SyntaxKind.EqualsToken:
1818
+ case SyntaxKind.PlusEqualsToken:
1819
+ case SyntaxKind.MinusEqualsToken:
1820
+ case SyntaxKind.AsteriskEqualsToken:
1821
+ case SyntaxKind.SlashEqualsToken:
1822
+ case SyntaxKind.QuestionQuestionEqualsToken:
1823
+ return ExpressionPrecedence.Assignment;
1824
+ case SyntaxKind.QuestionQuestionToken:
1825
+ case SyntaxKind.BarBarToken:
1826
+ return ExpressionPrecedence.LogicalOR;
1827
+ case SyntaxKind.AmpersandAmpersandToken:
1828
+ return ExpressionPrecedence.LogicalAND;
1829
+ case SyntaxKind.BarToken:
1830
+ return ExpressionPrecedence.BitwiseOR;
1831
+ case SyntaxKind.CaretToken:
1832
+ return ExpressionPrecedence.BitwiseXOR;
1833
+ case SyntaxKind.AmpersandToken:
1834
+ return ExpressionPrecedence.BitwiseAND;
1835
+ case SyntaxKind.EqualsEqualsToken:
1836
+ case SyntaxKind.ExclamationEqualsToken:
1837
+ case SyntaxKind.EqualsEqualsEqualsToken:
1838
+ case SyntaxKind.ExclamationEqualsEqualsToken:
1839
+ return ExpressionPrecedence.Equality;
1840
+ case SyntaxKind.LessThanToken:
1841
+ case SyntaxKind.LessThanEqualsToken:
1842
+ case SyntaxKind.GreaterThanToken:
1843
+ case SyntaxKind.GreaterThanEqualsToken:
1844
+ case SyntaxKind.InstanceOfKeyword:
1845
+ case SyntaxKind.InKeyword:
1846
+ case SyntaxKind.AsKeyword:
1847
+ case SyntaxKind.SatisfiesKeyword:
1848
+ return ExpressionPrecedence.Relational;
1849
+ case SyntaxKind.LessThanLessThanToken:
1850
+ case SyntaxKind.GreaterThanGreaterThanToken:
1851
+ case SyntaxKind.GreaterThanGreaterThanGreaterThanToken:
1852
+ return ExpressionPrecedence.Shift;
1853
+ case SyntaxKind.PlusToken:
1854
+ case SyntaxKind.MinusToken:
1855
+ return ExpressionPrecedence.Additive;
1856
+ case SyntaxKind.AsteriskToken:
1857
+ case SyntaxKind.SlashToken:
1858
+ case SyntaxKind.PercentToken:
1859
+ return ExpressionPrecedence.Multiplicative;
1860
+ case SyntaxKind.AsteriskAsteriskToken:
1861
+ return ExpressionPrecedence.Exponentiation;
1862
+ default:
1863
+ return ExpressionPrecedence.Invalid;
1864
+ }
1865
+ }
1866
+
1867
+ private binaryOperatorAssociativity(operator: SyntaxKind): Associativity {
1868
+ switch (operator) {
1869
+ case SyntaxKind.AsteriskAsteriskToken:
1870
+ case SyntaxKind.EqualsToken:
1871
+ case SyntaxKind.PlusEqualsToken:
1872
+ case SyntaxKind.MinusEqualsToken:
1873
+ case SyntaxKind.AsteriskEqualsToken:
1874
+ case SyntaxKind.SlashEqualsToken:
1875
+ case SyntaxKind.QuestionQuestionEqualsToken:
1876
+ return Associativity.Right;
1877
+ default:
1878
+ return Associativity.Left;
1879
+ }
1880
+ }
1881
+
1882
+ private mixingBinaryOperatorsRequiresParentheses(
1883
+ left: SyntaxKind,
1884
+ right: SyntaxKind,
1885
+ ): boolean {
1886
+ return (
1887
+ (left === SyntaxKind.QuestionQuestionToken &&
1888
+ (right === SyntaxKind.AmpersandAmpersandToken ||
1889
+ right === SyntaxKind.BarBarToken)) ||
1890
+ (right === SyntaxKind.QuestionQuestionToken &&
1891
+ (left === SyntaxKind.AmpersandAmpersandToken ||
1892
+ left === SyntaxKind.BarBarToken))
1893
+ );
1894
+ }
1895
+
1896
+ private operatorHasAssociativeProperty(operator: SyntaxKind): boolean {
1897
+ return (
1898
+ operator === SyntaxKind.AsteriskToken ||
1899
+ operator === SyntaxKind.BarToken ||
1900
+ operator === SyntaxKind.AmpersandToken ||
1901
+ operator === SyntaxKind.CaretToken ||
1902
+ operator === SyntaxKind.CommaToken
1903
+ );
1904
+ }
1905
+
1906
+ private literalKindOfBinaryPlusOperand(
1907
+ expression: Expression,
1908
+ ): string | undefined {
1909
+ switch (expression.kind) {
1910
+ case "StringLiteral":
1911
+ case "NumericLiteral":
1912
+ case "BigIntLiteral":
1913
+ return expression.kind;
1914
+ case "BinaryExpression": {
1915
+ if (expression.operator !== SyntaxKind.PlusToken) return undefined;
1916
+ const left: string | undefined = this.literalKindOfBinaryPlusOperand(
1917
+ expression.left,
1918
+ );
1919
+ return left !== undefined &&
1920
+ left === this.literalKindOfBinaryPlusOperand(expression.right)
1921
+ ? left
1922
+ : undefined;
1923
+ }
1924
+ default:
1925
+ return undefined;
1926
+ }
1927
+ }
1928
+
1929
+ private isUnaryExpression(expression: Expression): boolean {
1930
+ return this.expressionPrecedence(expression) >= ExpressionPrecedence.Unary;
1931
+ }
1932
+
1933
+ private isLeftHandSideExpression(expression: Expression): boolean {
1934
+ switch (expression.kind) {
1935
+ case "ArrowFunction":
1936
+ case "ClassExpression":
1937
+ case "FunctionExpression":
1938
+ case "NumericLiteral":
1939
+ case "ObjectLiteralExpression":
1940
+ return false;
1941
+ default:
1942
+ break;
1943
+ }
1944
+ return (
1945
+ this.expressionPrecedence(expression) >=
1946
+ ExpressionPrecedence.LeftHandSide ||
1947
+ expression.kind === "NonNullExpression" ||
1948
+ expression.kind === "NonNullChain"
1949
+ );
1950
+ }
1951
+
1952
+ private expressionNeedsStatementParentheses(expression: Expression): boolean {
1953
+ const leftmost: Expression = this.leftmostExpression(expression);
1954
+ return (
1955
+ leftmost.kind === "FunctionExpression" ||
1956
+ leftmost.kind === "ObjectLiteralExpression"
1957
+ );
1958
+ }
1959
+
1960
+ private expressionNeedsConciseBodyParentheses(
1961
+ expression: Expression,
1962
+ ): boolean {
1963
+ return (
1964
+ this.expressionPrecedence(expression) <= ExpressionPrecedence.Comma ||
1965
+ this.leftmostExpression(expression).kind === "ObjectLiteralExpression"
1966
+ );
1967
+ }
1968
+
1969
+ private expressionNeedsExportDefaultParentheses(
1970
+ expression: Expression,
1971
+ ): boolean {
1972
+ const leftmost: Expression = this.leftmostExpression(expression);
1973
+ return (
1974
+ this.expressionPrecedence(expression) <= ExpressionPrecedence.Comma ||
1975
+ leftmost.kind === "ClassExpression" ||
1976
+ leftmost.kind === "FunctionExpression"
1977
+ );
1978
+ }
1979
+
1980
+ private leftmostExpression(expression: Expression): Expression {
1981
+ switch (expression.kind) {
1982
+ case "AsExpression":
1983
+ case "CallExpression":
1984
+ case "CallChain":
1985
+ case "ElementAccessExpression":
1986
+ case "ElementAccessChain":
1987
+ case "NonNullExpression":
1988
+ case "NonNullChain":
1989
+ case "PropertyAccessExpression":
1990
+ case "PropertyAccessChain":
1991
+ case "SatisfiesExpression":
1992
+ return this.leftmostExpression(expression.expression);
1993
+ case "BinaryExpression":
1994
+ return this.leftmostExpression(expression.left);
1995
+ case "ConditionalExpression":
1996
+ return this.leftmostExpression(expression.condition);
1997
+ case "TaggedTemplateExpression":
1998
+ return this.leftmostExpression(expression.tag);
1999
+ default:
2000
+ return expression;
2001
+ }
2002
+ }
2003
+
2004
+ private needsPrefixUnaryGap(
2005
+ operator: SyntaxKind | undefined,
2006
+ operand: Expression,
2007
+ ): boolean {
2008
+ if (operator === undefined || operand.kind !== "PrefixUnaryExpression")
2009
+ return false;
2010
+ return (
2011
+ (operator === SyntaxKind.PlusToken &&
2012
+ (operand.operator === SyntaxKind.PlusToken ||
2013
+ operand.operator === SyntaxKind.PlusPlusToken)) ||
2014
+ (operator === SyntaxKind.MinusToken &&
2015
+ (operand.operator === SyntaxKind.MinusToken ||
2016
+ operand.operator === SyntaxKind.MinusMinusToken))
2017
+ );
2018
+ }
2019
+
2020
+ private parenthesizedType(type: TypeNode): Doc {
2021
+ return type.kind === "ParenthesizedTypeNode"
2022
+ ? this.emit(type)
2023
+ : concat(["(", this.emit(type), ")"]);
2024
+ }
2025
+
2026
+ private conditionalTypeCheckOperand(type: TypeNode): Doc {
2027
+ return type.kind === "FunctionTypeNode" ||
2028
+ type.kind === "ConstructorTypeNode" ||
2029
+ type.kind === "ConditionalTypeNode"
2030
+ ? this.parenthesizedType(type)
2031
+ : this.emit(type);
2032
+ }
2033
+
2034
+ private conditionalTypeExtendsOperand(type: TypeNode): Doc {
2035
+ return type.kind === "ConditionalTypeNode"
2036
+ ? this.parenthesizedType(type)
2037
+ : this.emit(type);
2038
+ }
2039
+
2040
+ private typeOperatorOperand(type: TypeNode, operator: SyntaxKind): Doc {
2041
+ return this.typeOperatorOperandNeedsParentheses(type, operator)
2042
+ ? this.parenthesizedType(type)
2043
+ : this.emit(type);
2044
+ }
2045
+
2046
+ private typeOperatorOperandNeedsParentheses(
2047
+ type: TypeNode,
2048
+ operator?: SyntaxKind,
2049
+ ): boolean {
2050
+ return (
1545
2051
  type.kind === "UnionTypeNode" ||
1546
2052
  type.kind === "IntersectionTypeNode" ||
1547
2053
  type.kind === "FunctionTypeNode" ||
1548
2054
  type.kind === "ConstructorTypeNode" ||
1549
2055
  type.kind === "ConditionalTypeNode" ||
2056
+ (operator === SyntaxKind.ReadonlyKeyword &&
2057
+ type.kind === "TypeOperatorNode")
2058
+ );
2059
+ }
2060
+
2061
+ private postfixTypeOperand(type: TypeNode): Doc {
2062
+ return this.postfixTypeOperandNeedsParentheses(type)
2063
+ ? this.parenthesizedType(type)
2064
+ : this.emit(type);
2065
+ }
2066
+
2067
+ private postfixTypeOperandNeedsParentheses(type: TypeNode): boolean {
2068
+ return (
1550
2069
  type.kind === "InferTypeNode" ||
1551
- type.kind === "TypeOperatorNode";
1552
- return parenthesize ? concat(["(", this.emit(type), ")"]) : this.emit(type);
2070
+ type.kind === "TypeOperatorNode" ||
2071
+ type.kind === "TypeQueryNode" ||
2072
+ this.typeOperatorOperandNeedsParentheses(type)
2073
+ );
1553
2074
  }
1554
2075
 
1555
2076
  /** Render a JSDoc tag's trailing comment, prefixed with a space when present. */
@@ -1563,7 +2084,10 @@ export class TsPrinter {
1563
2084
  }
1564
2085
 
1565
2086
  /** Width-aware `|` / `&` type list with leading-operator breaks. */
1566
- private binaryType(operator: string, parts: Doc[]): Doc {
2087
+ private binaryType(operator: "|" | "&", types: readonly TypeNode[]): Doc {
2088
+ const parts: Doc[] = this.flattenBinaryTypes(operator, types).map((type) =>
2089
+ this.binaryTypeOperand(operator, type),
2090
+ );
1567
2091
  if (parts.length === 1) return parts[0]!;
1568
2092
  return group(
1569
2093
  indent(
@@ -1575,6 +2099,39 @@ export class TsPrinter {
1575
2099
  );
1576
2100
  }
1577
2101
 
2102
+ private flattenBinaryTypes(
2103
+ operator: "|" | "&",
2104
+ types: readonly TypeNode[],
2105
+ ): TypeNode[] {
2106
+ const flattened: TypeNode[] = [];
2107
+ for (const type of types)
2108
+ if (operator === "|" && type.kind === "UnionTypeNode")
2109
+ flattened.push(...this.flattenBinaryTypes(operator, type.types));
2110
+ else if (operator === "&" && type.kind === "IntersectionTypeNode")
2111
+ flattened.push(...this.flattenBinaryTypes(operator, type.types));
2112
+ else flattened.push(type);
2113
+ return flattened;
2114
+ }
2115
+
2116
+ private binaryTypeOperand(operator: "|" | "&", type: TypeNode): Doc {
2117
+ return this.binaryTypeOperandNeedsParentheses(operator, type)
2118
+ ? this.parenthesizedType(type)
2119
+ : this.emit(type);
2120
+ }
2121
+
2122
+ private binaryTypeOperandNeedsParentheses(
2123
+ operator: "|" | "&",
2124
+ type: TypeNode,
2125
+ ): boolean {
2126
+ return (
2127
+ type.kind === "FunctionTypeNode" ||
2128
+ type.kind === "ConstructorTypeNode" ||
2129
+ type.kind === "ConditionalTypeNode" ||
2130
+ type.kind === "UnionTypeNode" ||
2131
+ (operator === "|" && type.kind === "IntersectionTypeNode")
2132
+ );
2133
+ }
2134
+
1578
2135
  private unsupported(node: never): never {
1579
2136
  throw new Error(
1580
2137
  `@ttsc/factory: TsPrinter cannot print node of kind "${
@@ -1583,3 +2140,60 @@ export class TsPrinter {
1583
2140
  );
1584
2141
  }
1585
2142
  }
2143
+
2144
+ export namespace TsPrinter {
2145
+ /** Options for {@link TsPrinter}. */
2146
+ export interface IProps {
2147
+ /** Maximum line width before groups break. Defaults to `80`. */
2148
+ printWidth?: number;
2149
+ /** Indentation unit. Defaults to two spaces. */
2150
+ indent?: string;
2151
+ /** New line sequence. Defaults to `"\n"` (LineFeed). */
2152
+ newLine?: string;
2153
+ }
2154
+ }
2155
+
2156
+ const escapeString = (text: string, singleQuote?: boolean): string => {
2157
+ const escaped: string = text
2158
+ .replace(/\\/g, "\\\\")
2159
+ .replace(/\n/g, "\\n")
2160
+ .replace(/\r/g, "\\r")
2161
+ .replace(/\t/g, "\\t");
2162
+ return singleQuote === true
2163
+ ? `'${escaped.replace(/'/g, "\\'")}'`
2164
+ : `"${escaped.replace(/"/g, '\\"')}"`;
2165
+ };
2166
+
2167
+ const ExpressionPrecedence = {
2168
+ Comma: 0,
2169
+ Yield: 2,
2170
+ Assignment: 3,
2171
+ Conditional: 4,
2172
+ LogicalOR: 5,
2173
+ LogicalAND: 6,
2174
+ BitwiseOR: 7,
2175
+ BitwiseXOR: 8,
2176
+ BitwiseAND: 9,
2177
+ Equality: 10,
2178
+ Relational: 11,
2179
+ Shift: 12,
2180
+ Additive: 13,
2181
+ Multiplicative: 14,
2182
+ Exponentiation: 15,
2183
+ Unary: 16,
2184
+ Update: 17,
2185
+ LeftHandSide: 18,
2186
+ Member: 19,
2187
+ Primary: 20,
2188
+ Invalid: -1,
2189
+ } as const;
2190
+
2191
+ type ExpressionPrecedence =
2192
+ (typeof ExpressionPrecedence)[keyof typeof ExpressionPrecedence];
2193
+
2194
+ const Associativity = {
2195
+ Left: "left",
2196
+ Right: "right",
2197
+ } as const;
2198
+
2199
+ type Associativity = (typeof Associativity)[keyof typeof Associativity];