typescript 7.0.2 → 7.1.0-beta

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 (389) hide show
  1. package/NOTICE.txt +5 -36
  2. package/dist/api/async/api.d.ts +597 -122
  3. package/dist/api/async/api.d.ts.map +1 -1
  4. package/dist/api/async/api.js +1775 -333
  5. package/dist/api/async/api.js.map +1 -1
  6. package/dist/api/async/client.d.ts +18 -2
  7. package/dist/api/async/client.d.ts.map +1 -1
  8. package/dist/api/async/client.js +255 -68
  9. package/dist/api/async/client.js.map +1 -1
  10. package/dist/api/async/types.d.ts +99 -34
  11. package/dist/api/async/types.d.ts.map +1 -1
  12. package/dist/api/compilerOptions.generated.d.ts +123 -0
  13. package/dist/api/compilerOptions.generated.d.ts.map +1 -0
  14. package/dist/api/compilerOptions.generated.js +8 -0
  15. package/dist/api/compilerOptions.generated.js.map +1 -0
  16. package/dist/api/diagnosticFormatter.d.ts +9 -0
  17. package/dist/api/diagnosticFormatter.d.ts.map +1 -0
  18. package/dist/api/diagnosticFormatter.js +169 -0
  19. package/dist/api/diagnosticFormatter.js.map +1 -0
  20. package/dist/api/fs.d.ts +68 -13
  21. package/dist/api/fs.d.ts.map +1 -1
  22. package/dist/api/fs.js +62 -101
  23. package/dist/api/fs.js.map +1 -1
  24. package/dist/api/fsCallbacks.d.ts +27 -0
  25. package/dist/api/fsCallbacks.d.ts.map +1 -0
  26. package/dist/api/fsCallbacks.js +111 -0
  27. package/dist/api/fsCallbacks.js.map +1 -0
  28. package/dist/api/node/encoder.d.ts +3 -0
  29. package/dist/api/node/encoder.d.ts.map +1 -1
  30. package/dist/api/node/encoder.generated.js +2 -2
  31. package/dist/api/node/encoder.generated.js.map +1 -1
  32. package/dist/api/node/encoder.js +20 -15
  33. package/dist/api/node/encoder.js.map +1 -1
  34. package/dist/api/node/msgpack.d.ts.map +1 -1
  35. package/dist/api/node/msgpack.js +2 -3
  36. package/dist/api/node/msgpack.js.map +1 -1
  37. package/dist/api/node/node.d.ts +28 -9
  38. package/dist/api/node/node.d.ts.map +1 -1
  39. package/dist/api/node/node.generated.d.ts +9 -2
  40. package/dist/api/node/node.generated.d.ts.map +1 -1
  41. package/dist/api/node/node.generated.js +55 -6
  42. package/dist/api/node/node.generated.js.map +1 -1
  43. package/dist/api/node/node.infrastructure.d.ts +6 -4
  44. package/dist/api/node/node.infrastructure.d.ts.map +1 -1
  45. package/dist/api/node/node.infrastructure.js +20 -40
  46. package/dist/api/node/node.infrastructure.js.map +1 -1
  47. package/dist/api/node/node.js +178 -23
  48. package/dist/api/node/node.js.map +1 -1
  49. package/dist/api/node/protocol.d.ts +5 -2
  50. package/dist/api/node/protocol.d.ts.map +1 -1
  51. package/dist/api/node/protocol.generated.js +2 -2
  52. package/dist/api/node/protocol.generated.js.map +1 -1
  53. package/dist/api/node/protocol.js +5 -2
  54. package/dist/api/node/protocol.js.map +1 -1
  55. package/dist/api/node/wtf8.d.ts +6 -2
  56. package/dist/api/node/wtf8.d.ts.map +1 -1
  57. package/dist/api/node/wtf8.js +71 -2
  58. package/dist/api/node/wtf8.js.map +1 -1
  59. package/dist/api/options.d.ts +19 -7
  60. package/dist/api/options.d.ts.map +1 -1
  61. package/dist/api/options.js +21 -0
  62. package/dist/api/options.js.map +1 -1
  63. package/dist/api/path.d.ts +49 -39
  64. package/dist/api/path.d.ts.map +1 -1
  65. package/dist/api/path.js +409 -33
  66. package/dist/api/path.js.map +1 -1
  67. package/dist/api/prepareCompilerOptions.generated.d.ts +5 -0
  68. package/dist/api/prepareCompilerOptions.generated.d.ts.map +1 -0
  69. package/dist/api/prepareCompilerOptions.generated.js +24 -0
  70. package/dist/api/prepareCompilerOptions.generated.js.map +1 -0
  71. package/dist/api/proto.d.ts +58 -217
  72. package/dist/api/proto.d.ts.map +1 -1
  73. package/dist/api/proto.generated.d.ts +1419 -0
  74. package/dist/api/proto.generated.d.ts.map +1 -0
  75. package/dist/api/proto.generated.js +21 -0
  76. package/dist/api/proto.generated.js.map +1 -0
  77. package/dist/api/proto.js +28 -15
  78. package/dist/api/proto.js.map +1 -1
  79. package/dist/api/sourceFileCache.d.ts +51 -20
  80. package/dist/api/sourceFileCache.d.ts.map +1 -1
  81. package/dist/api/sourceFileCache.js +168 -37
  82. package/dist/api/sourceFileCache.js.map +1 -1
  83. package/dist/api/sync/api.d.ts +1365 -220
  84. package/dist/api/sync/api.d.ts.map +1 -1
  85. package/dist/api/sync/api.js +4673 -930
  86. package/dist/api/sync/api.js.map +1 -1
  87. package/dist/api/sync/client.d.ts +8 -2
  88. package/dist/api/sync/client.d.ts.map +1 -1
  89. package/dist/api/sync/client.js +80 -30
  90. package/dist/api/sync/client.js.map +1 -1
  91. package/dist/api/sync/generatorSupport.d.ts +32 -0
  92. package/dist/api/sync/generatorSupport.d.ts.map +1 -0
  93. package/dist/api/sync/generatorSupport.js +338 -0
  94. package/dist/api/sync/generatorSupport.js.map +1 -0
  95. package/dist/api/sync/types.d.ts +248 -56
  96. package/dist/api/sync/types.d.ts.map +1 -1
  97. package/dist/api/syncChannel.d.ts +3 -0
  98. package/dist/api/syncChannel.d.ts.map +1 -1
  99. package/dist/api/syncChannel.js +20 -2
  100. package/dist/api/syncChannel.js.map +1 -1
  101. package/dist/api/timing.d.ts +2 -2
  102. package/dist/api/timing.d.ts.map +1 -1
  103. package/dist/api/timing.js +1 -1
  104. package/dist/api/timing.js.map +1 -1
  105. package/dist/api/timingDump.d.ts +13 -0
  106. package/dist/api/timingDump.d.ts.map +1 -0
  107. package/dist/api/timingDump.js +38 -0
  108. package/dist/api/timingDump.js.map +1 -0
  109. package/dist/api/typedPaths.d.ts +3 -0
  110. package/dist/api/typedPaths.d.ts.map +1 -0
  111. package/dist/api/typedPaths.js +2 -0
  112. package/dist/api/typedPaths.js.map +1 -0
  113. package/dist/api/userPreferences.generated.d.ts +195 -0
  114. package/dist/api/userPreferences.generated.d.ts.map +1 -0
  115. package/dist/api/userPreferences.generated.js +3 -0
  116. package/dist/api/userPreferences.generated.js.map +1 -0
  117. package/dist/ast/ast.d.ts +90 -7
  118. package/dist/ast/ast.d.ts.map +1 -1
  119. package/dist/ast/ast.generated.d.ts +45 -39
  120. package/dist/ast/ast.generated.d.ts.map +1 -1
  121. package/dist/ast/ast.generated.js +1 -1
  122. package/dist/ast/ast.generated.js.map +1 -1
  123. package/dist/ast/ast.js +1 -0
  124. package/dist/ast/ast.js.map +1 -1
  125. package/dist/ast/astnav.d.ts +3 -2
  126. package/dist/ast/astnav.d.ts.map +1 -1
  127. package/dist/ast/astnav.js +148 -3
  128. package/dist/ast/astnav.js.map +1 -1
  129. package/dist/ast/factory.generated.d.ts +8 -154
  130. package/dist/ast/factory.generated.d.ts.map +1 -1
  131. package/dist/ast/factory.generated.js +2701 -7
  132. package/dist/ast/factory.generated.js.map +1 -1
  133. package/dist/ast/index.d.ts +5 -0
  134. package/dist/ast/index.d.ts.map +1 -1
  135. package/dist/ast/index.js +5 -0
  136. package/dist/ast/index.js.map +1 -1
  137. package/dist/ast/is.d.ts +2 -12
  138. package/dist/ast/is.d.ts.map +1 -1
  139. package/dist/ast/is.generated.d.ts +889 -1
  140. package/dist/ast/is.generated.d.ts.map +1 -1
  141. package/dist/ast/is.generated.js +300 -3
  142. package/dist/ast/is.generated.js.map +1 -1
  143. package/dist/ast/is.js +224 -1
  144. package/dist/ast/is.js.map +1 -1
  145. package/dist/ast/jsdoc.d.ts +2 -1
  146. package/dist/ast/jsdoc.d.ts.map +1 -1
  147. package/dist/ast/jsdoc.js +14 -8
  148. package/dist/ast/jsdoc.js.map +1 -1
  149. package/dist/ast/modifiers.d.ts +4 -0
  150. package/dist/ast/modifiers.d.ts.map +1 -0
  151. package/dist/ast/modifiers.js +41 -0
  152. package/dist/ast/modifiers.js.map +1 -0
  153. package/dist/ast/scanner.d.ts.map +1 -1
  154. package/dist/ast/scanner.js +2 -1
  155. package/dist/ast/scanner.js.map +1 -1
  156. package/dist/ast/spanMap.d.ts +88 -0
  157. package/dist/ast/spanMap.d.ts.map +1 -0
  158. package/dist/ast/spanMap.js +417 -0
  159. package/dist/ast/spanMap.js.map +1 -0
  160. package/dist/ast/utils.d.ts +14 -1
  161. package/dist/ast/utils.d.ts.map +1 -1
  162. package/dist/ast/utils.js +251 -0
  163. package/dist/ast/utils.js.map +1 -1
  164. package/dist/ast/visitor.d.ts +2 -0
  165. package/dist/ast/visitor.d.ts.map +1 -1
  166. package/dist/ast/visitor.generated.d.ts.map +1 -1
  167. package/dist/ast/visitor.generated.js +5 -4
  168. package/dist/ast/visitor.generated.js.map +1 -1
  169. package/dist/ast/visitor.js +40 -0
  170. package/dist/ast/visitor.js.map +1 -1
  171. package/dist/enums/caseSensitivity.d.ts +2 -0
  172. package/dist/enums/caseSensitivity.d.ts.map +1 -0
  173. package/dist/enums/caseSensitivity.enum.d.ts +5 -0
  174. package/dist/enums/caseSensitivity.enum.d.ts.map +1 -0
  175. package/dist/enums/caseSensitivity.enum.js +7 -0
  176. package/dist/enums/caseSensitivity.enum.js.map +1 -0
  177. package/dist/enums/caseSensitivity.js +7 -0
  178. package/dist/enums/caseSensitivity.js.map +1 -0
  179. package/dist/enums/checkFlags.d.ts +2 -0
  180. package/dist/enums/checkFlags.d.ts.map +1 -0
  181. package/dist/enums/checkFlags.enum.d.ts +34 -0
  182. package/dist/enums/checkFlags.enum.d.ts.map +1 -0
  183. package/dist/enums/checkFlags.enum.js +36 -0
  184. package/dist/enums/checkFlags.enum.js.map +1 -0
  185. package/dist/enums/checkFlags.js +36 -0
  186. package/dist/enums/checkFlags.js.map +1 -0
  187. package/dist/enums/completionItemKind.enum.js +1 -1
  188. package/dist/enums/completionItemKind.enum.js.map +1 -1
  189. package/dist/enums/completionItemKind.js +1 -1
  190. package/dist/enums/completionItemKind.js.map +1 -1
  191. package/dist/enums/diagnosticCategory.enum.js +1 -1
  192. package/dist/enums/diagnosticCategory.enum.js.map +1 -1
  193. package/dist/enums/diagnosticCategory.js +1 -1
  194. package/dist/enums/diagnosticCategory.js.map +1 -1
  195. package/dist/enums/diagnosticDirectivePolicy.d.ts +2 -0
  196. package/dist/enums/diagnosticDirectivePolicy.d.ts.map +1 -0
  197. package/dist/enums/diagnosticDirectivePolicy.enum.d.ts +5 -0
  198. package/dist/enums/diagnosticDirectivePolicy.enum.d.ts.map +1 -0
  199. package/dist/enums/diagnosticDirectivePolicy.enum.js +7 -0
  200. package/dist/enums/diagnosticDirectivePolicy.enum.js.map +1 -0
  201. package/dist/enums/diagnosticDirectivePolicy.js +7 -0
  202. package/dist/enums/diagnosticDirectivePolicy.js.map +1 -0
  203. package/dist/enums/elementFlags.enum.js +1 -1
  204. package/dist/enums/elementFlags.enum.js.map +1 -1
  205. package/dist/enums/elementFlags.js +1 -1
  206. package/dist/enums/elementFlags.js.map +1 -1
  207. package/dist/enums/emitOnly.d.ts +2 -0
  208. package/dist/enums/emitOnly.d.ts.map +1 -0
  209. package/dist/enums/emitOnly.enum.d.ts +6 -0
  210. package/dist/enums/emitOnly.enum.d.ts.map +1 -0
  211. package/dist/enums/emitOnly.enum.js +8 -0
  212. package/dist/enums/emitOnly.enum.js.map +1 -0
  213. package/dist/enums/emitOnly.js +8 -0
  214. package/dist/enums/emitOnly.js.map +1 -0
  215. package/dist/enums/indexKind.d.ts +2 -0
  216. package/dist/enums/indexKind.d.ts.map +1 -0
  217. package/dist/enums/indexKind.enum.d.ts +5 -0
  218. package/dist/enums/indexKind.enum.d.ts.map +1 -0
  219. package/dist/enums/indexKind.enum.js +7 -0
  220. package/dist/enums/indexKind.enum.js.map +1 -0
  221. package/dist/enums/indexKind.js +7 -0
  222. package/dist/enums/indexKind.js.map +1 -0
  223. package/dist/enums/internalSymbolName.enum.js +1 -1
  224. package/dist/enums/internalSymbolName.enum.js.map +1 -1
  225. package/dist/enums/internalSymbolName.js +1 -1
  226. package/dist/enums/internalSymbolName.js.map +1 -1
  227. package/dist/enums/jsDeclarationKind.d.ts +2 -0
  228. package/dist/enums/jsDeclarationKind.d.ts.map +1 -0
  229. package/dist/enums/jsDeclarationKind.enum.d.ts +10 -0
  230. package/dist/enums/jsDeclarationKind.enum.d.ts.map +1 -0
  231. package/dist/enums/jsDeclarationKind.enum.js +12 -0
  232. package/dist/enums/jsDeclarationKind.enum.js.map +1 -0
  233. package/dist/enums/jsDeclarationKind.js +12 -0
  234. package/dist/enums/jsDeclarationKind.js.map +1 -0
  235. package/dist/enums/jsxEmit.enum.d.ts +2 -2
  236. package/dist/enums/jsxEmit.enum.d.ts.map +1 -1
  237. package/dist/enums/jsxEmit.enum.js +3 -3
  238. package/dist/enums/jsxEmit.enum.js.map +1 -1
  239. package/dist/enums/jsxEmit.js +3 -3
  240. package/dist/enums/jsxEmit.js.map +1 -1
  241. package/dist/enums/modifierFlags.enum.js +1 -1
  242. package/dist/enums/modifierFlags.enum.js.map +1 -1
  243. package/dist/enums/modifierFlags.js +1 -1
  244. package/dist/enums/modifierFlags.js.map +1 -1
  245. package/dist/enums/moduleDetectionKind.enum.js +1 -1
  246. package/dist/enums/moduleDetectionKind.enum.js.map +1 -1
  247. package/dist/enums/moduleDetectionKind.js +1 -1
  248. package/dist/enums/moduleDetectionKind.js.map +1 -1
  249. package/dist/enums/moduleKind.enum.js +1 -1
  250. package/dist/enums/moduleKind.enum.js.map +1 -1
  251. package/dist/enums/moduleKind.js +1 -1
  252. package/dist/enums/moduleKind.js.map +1 -1
  253. package/dist/enums/moduleResolutionKind.enum.js +1 -1
  254. package/dist/enums/moduleResolutionKind.enum.js.map +1 -1
  255. package/dist/enums/moduleResolutionKind.js +1 -1
  256. package/dist/enums/moduleResolutionKind.js.map +1 -1
  257. package/dist/enums/newLineKind.enum.js +1 -1
  258. package/dist/enums/newLineKind.enum.js.map +1 -1
  259. package/dist/enums/newLineKind.js +1 -1
  260. package/dist/enums/newLineKind.js.map +1 -1
  261. package/dist/enums/nodeBuilderFlags.enum.js +1 -1
  262. package/dist/enums/nodeBuilderFlags.enum.js.map +1 -1
  263. package/dist/enums/nodeBuilderFlags.js +1 -1
  264. package/dist/enums/nodeBuilderFlags.js.map +1 -1
  265. package/dist/enums/nodeFlags.enum.js +1 -1
  266. package/dist/enums/nodeFlags.enum.js.map +1 -1
  267. package/dist/enums/nodeFlags.js +1 -1
  268. package/dist/enums/nodeFlags.js.map +1 -1
  269. package/dist/enums/objectFlags.enum.d.ts +3 -2
  270. package/dist/enums/objectFlags.enum.d.ts.map +1 -1
  271. package/dist/enums/objectFlags.enum.js +4 -3
  272. package/dist/enums/objectFlags.enum.js.map +1 -1
  273. package/dist/enums/objectFlags.js +4 -3
  274. package/dist/enums/objectFlags.js.map +1 -1
  275. package/dist/enums/outerExpressionKinds.enum.js +1 -1
  276. package/dist/enums/outerExpressionKinds.enum.js.map +1 -1
  277. package/dist/enums/outerExpressionKinds.js +1 -1
  278. package/dist/enums/outerExpressionKinds.js.map +1 -1
  279. package/dist/enums/scriptKind.d.ts.map +1 -1
  280. package/dist/enums/scriptKind.enum.d.ts +1 -3
  281. package/dist/enums/scriptKind.enum.d.ts.map +1 -1
  282. package/dist/enums/scriptKind.enum.js +1 -2
  283. package/dist/enums/scriptKind.enum.js.map +1 -1
  284. package/dist/enums/scriptKind.js +1 -2
  285. package/dist/enums/scriptKind.js.map +1 -1
  286. package/dist/enums/scriptTarget.d.ts.map +1 -1
  287. package/dist/enums/scriptTarget.enum.d.ts +1 -0
  288. package/dist/enums/scriptTarget.enum.d.ts.map +1 -1
  289. package/dist/enums/scriptTarget.enum.js +2 -0
  290. package/dist/enums/scriptTarget.enum.js.map +1 -1
  291. package/dist/enums/scriptTarget.js +2 -0
  292. package/dist/enums/scriptTarget.js.map +1 -1
  293. package/dist/enums/signatureFlags.enum.js +1 -1
  294. package/dist/enums/signatureFlags.enum.js.map +1 -1
  295. package/dist/enums/signatureFlags.js +1 -1
  296. package/dist/enums/signatureFlags.js.map +1 -1
  297. package/dist/enums/signatureKind.enum.js +1 -1
  298. package/dist/enums/signatureKind.enum.js.map +1 -1
  299. package/dist/enums/signatureKind.js +1 -1
  300. package/dist/enums/signatureKind.js.map +1 -1
  301. package/dist/enums/spanMapFeature.d.ts +2 -0
  302. package/dist/enums/spanMapFeature.d.ts.map +1 -0
  303. package/dist/enums/spanMapFeature.enum.d.ts +25 -0
  304. package/dist/enums/spanMapFeature.enum.d.ts.map +1 -0
  305. package/dist/enums/spanMapFeature.enum.js +27 -0
  306. package/dist/enums/spanMapFeature.enum.js.map +1 -0
  307. package/dist/enums/spanMapFeature.js +27 -0
  308. package/dist/enums/spanMapFeature.js.map +1 -0
  309. package/dist/enums/spanMapFidelity.d.ts +2 -0
  310. package/dist/enums/spanMapFidelity.d.ts.map +1 -0
  311. package/dist/enums/spanMapFidelity.enum.d.ts +7 -0
  312. package/dist/enums/spanMapFidelity.enum.d.ts.map +1 -0
  313. package/dist/enums/spanMapFidelity.enum.js +9 -0
  314. package/dist/enums/spanMapFidelity.enum.js.map +1 -0
  315. package/dist/enums/spanMapFidelity.js +9 -0
  316. package/dist/enums/spanMapFidelity.js.map +1 -0
  317. package/dist/enums/spanMapKind.d.ts +2 -0
  318. package/dist/enums/spanMapKind.d.ts.map +1 -0
  319. package/dist/enums/spanMapKind.enum.d.ts +6 -0
  320. package/dist/enums/spanMapKind.enum.d.ts.map +1 -0
  321. package/dist/enums/spanMapKind.enum.js +8 -0
  322. package/dist/enums/spanMapKind.enum.js.map +1 -0
  323. package/dist/enums/spanMapKind.js +8 -0
  324. package/dist/enums/spanMapKind.js.map +1 -0
  325. package/dist/enums/symbolFlags.enum.d.ts +1 -2
  326. package/dist/enums/symbolFlags.enum.d.ts.map +1 -1
  327. package/dist/enums/symbolFlags.enum.js +2 -3
  328. package/dist/enums/symbolFlags.enum.js.map +1 -1
  329. package/dist/enums/symbolFlags.js +2 -3
  330. package/dist/enums/symbolFlags.js.map +1 -1
  331. package/dist/enums/symbolOwnerKind.d.ts +2 -0
  332. package/dist/enums/symbolOwnerKind.d.ts.map +1 -0
  333. package/dist/enums/symbolOwnerKind.enum.d.ts +5 -0
  334. package/dist/enums/symbolOwnerKind.enum.d.ts.map +1 -0
  335. package/dist/enums/symbolOwnerKind.enum.js +7 -0
  336. package/dist/enums/symbolOwnerKind.enum.js.map +1 -0
  337. package/dist/enums/symbolOwnerKind.js +7 -0
  338. package/dist/enums/symbolOwnerKind.js.map +1 -0
  339. package/dist/enums/syntaxKind.enum.d.ts +198 -197
  340. package/dist/enums/syntaxKind.enum.d.ts.map +1 -1
  341. package/dist/enums/syntaxKind.enum.js +199 -198
  342. package/dist/enums/syntaxKind.enum.js.map +1 -1
  343. package/dist/enums/syntaxKind.js +199 -198
  344. package/dist/enums/syntaxKind.js.map +1 -1
  345. package/dist/enums/tokenFlags.enum.js +1 -1
  346. package/dist/enums/tokenFlags.enum.js.map +1 -1
  347. package/dist/enums/tokenFlags.js +1 -1
  348. package/dist/enums/tokenFlags.js.map +1 -1
  349. package/dist/enums/typeFlags.enum.js +1 -1
  350. package/dist/enums/typeFlags.enum.js.map +1 -1
  351. package/dist/enums/typeFlags.js +1 -1
  352. package/dist/enums/typeFlags.js.map +1 -1
  353. package/dist/enums/typeFormatFlags.d.ts +2 -0
  354. package/dist/enums/typeFormatFlags.d.ts.map +1 -0
  355. package/dist/enums/typeFormatFlags.enum.d.ts +29 -0
  356. package/dist/enums/typeFormatFlags.enum.d.ts.map +1 -0
  357. package/dist/enums/typeFormatFlags.enum.js +31 -0
  358. package/dist/enums/typeFormatFlags.enum.js.map +1 -0
  359. package/dist/enums/typeFormatFlags.js +31 -0
  360. package/dist/enums/typeFormatFlags.js.map +1 -0
  361. package/dist/enums/typePredicateKind.enum.js +1 -1
  362. package/dist/enums/typePredicateKind.enum.js.map +1 -1
  363. package/dist/enums/typePredicateKind.js +1 -1
  364. package/dist/enums/typePredicateKind.js.map +1 -1
  365. package/dist/internal/utils.js.map +1 -1
  366. package/dist/vscode/extensionApi.d.ts +101 -0
  367. package/dist/vscode/extensionApi.d.ts.map +1 -0
  368. package/dist/vscode/extensionApi.js +2 -0
  369. package/dist/vscode/extensionApi.js.map +1 -0
  370. package/dist/vscode/moduleLoader.d.ts +14 -0
  371. package/dist/vscode/moduleLoader.d.ts.map +1 -0
  372. package/dist/vscode/moduleLoader.js +36 -0
  373. package/dist/vscode/moduleLoader.js.map +1 -0
  374. package/dist/vscode/protocol.generated.d.ts +2886 -0
  375. package/dist/vscode/protocol.generated.d.ts.map +1 -0
  376. package/dist/vscode/protocol.generated.js +4 -0
  377. package/dist/vscode/protocol.generated.js.map +1 -0
  378. package/lib/getExePath.js +2 -2
  379. package/lib/version.cjs +1 -1
  380. package/lib/version.d.cts +1 -1
  381. package/package.json +40 -34
  382. package/schemas/jsconfig.schema.json +2207 -0
  383. package/schemas/tsconfig.schema.json +2206 -0
  384. package/vendor/vscode-jsonrpc/lib/node/main.js +1 -1
  385. package/vendor/vscode-jsonrpc/package.json +1 -1
  386. package/dist/api/compilerOptions.d.ts +0 -109
  387. package/dist/api/compilerOptions.d.ts.map +0 -1
  388. package/dist/api/compilerOptions.js +0 -2
  389. package/dist/api/compilerOptions.js.map +0 -1
@@ -1,37 +1,124 @@
1
- /// <reference path="../node/node.ts" preserve="true" />
1
+ import { CheckFlags } from "#enums/checkFlags";
2
2
  import { CompletionItemKind } from "#enums/completionItemKind";
3
3
  import { DiagnosticCategory } from "#enums/diagnosticCategory";
4
4
  import { ElementFlags } from "#enums/elementFlags";
5
+ import { EmitOnly } from "#enums/emitOnly";
6
+ import { IndexKind } from "#enums/indexKind";
7
+ import { JsxEmit } from "#enums/jsxEmit";
5
8
  import { ModuleKind } from "#enums/moduleKind";
9
+ import { ModuleResolutionKind } from "#enums/moduleResolutionKind";
10
+ import { NewLineKind } from "#enums/newLineKind";
6
11
  import { NodeBuilderFlags } from "#enums/nodeBuilderFlags";
7
12
  import { ObjectFlags } from "#enums/objectFlags";
13
+ import { ScriptKind } from "#enums/scriptKind";
8
14
  import { SignatureFlags } from "#enums/signatureFlags";
9
15
  import { SignatureKind } from "#enums/signatureKind";
10
16
  import { SymbolFlags } from "#enums/symbolFlags";
17
+ import { SymbolOwnerKind } from "#enums/symbolOwnerKind";
11
18
  import { TypeFlags } from "#enums/typeFlags";
19
+ import { TypeFormatFlags } from "#enums/typeFormatFlags";
12
20
  import { TypePredicateKind } from "#enums/typePredicateKind";
13
21
  import { ModifierFlags, unescapeLeadingUnderscores, } from "../../ast/index.js";
22
+ import { assertNever } from "../../internal/utils.js";
14
23
  import { encodeNode, uint8ArrayToBase64, } from "../node/encoder.js";
15
- import { decodeNode, getNodeId, parseNodeHandle, readParseOptionsKey, readSourceFileHash, RemoteSourceFile, } from "../node/node.js";
24
+ import { decodeNode, getNodeId, parseNodeHandleFromCompiler, readParseOptionsKey, readSourceFileHash, readSourceFileLease, RemoteNode, RemoteSourceFile, } from "../node/node.js";
16
25
  import { Wtf8Decoder } from "../node/wtf8.js";
17
- import { createGetCanonicalFileName, toPath, } from "../path.js";
18
- import { resolveFileName, toUpdateSnapshotRequest, } from "../proto.js";
19
- import { SourceFileCache } from "../sourceFileCache.js";
26
+ import { canonicalize, CaseSensitivity, pathKey, toRootedDirectoryPath, toRootedPath, } from "../path.js";
27
+ import { prepareCompilerOptions } from "../prepareCompilerOptions.generated.js";
28
+ import { resolveFileName, validateSymbolResponse, } from "../proto.js";
29
+ import { SourceFileCache, } from "../sourceFileCache.js";
20
30
  import { Client, } from "./client.js";
31
+ export { formatDiagnostics, formatDiagnosticsWithColorAndContext } from "../diagnosticFormatter.js";
21
32
  export { documentURIToFileName, fileNameToDocumentURI } from "../path.js";
22
- export { CompletionItemKind, DiagnosticCategory, ElementFlags, ModifierFlags, ModuleKind, NodeBuilderFlags, ObjectFlags, SignatureFlags, SignatureKind, SymbolFlags, TypeFlags, TypePredicateKind };
33
+ export { CheckFlags, CompletionItemKind, DiagnosticCategory, ElementFlags, EmitOnly, IndexKind, JsxEmit, ModifierFlags, ModuleKind, ModuleResolutionKind, NodeBuilderFlags, ObjectFlags, ScriptKind, SignatureFlags, SignatureKind, SymbolFlags, SymbolOwnerKind, TypeFlags, TypeFormatFlags, TypePredicateKind };
34
+ let nextModuleResolutionCallbackId = 0;
35
+ function registerModuleResolutionCallback(client, callback, getSnapshot) {
36
+ const name = `resolveModuleName/${++nextModuleResolutionCallbackId}`;
37
+ const dispose = client.registerCallback(name, params => {
38
+ const { moduleName, containingDirectory, resolutionMode, snapshot: snapshotId, inProgressSnapshot } = params;
39
+ let snapshot = snapshotId === undefined ? undefined : getSnapshot(snapshotId);
40
+ if (snapshotId !== undefined && snapshot === undefined) {
41
+ throw new Error(`Snapshot ${snapshotId} is inactive`);
42
+ }
43
+ if (inProgressSnapshot !== undefined) {
44
+ snapshot = -inProgressSnapshot;
45
+ }
46
+ return callback(moduleName, containingDirectory, resolutionMode, { snapshot });
47
+ });
48
+ return { name, dispose };
49
+ }
50
+ // @sync-only-start
51
+ // export { all, defer, type APIRequestGenerator, type AnyAPIRequestGenerator, type AllAPIRequestGenerator, type DeferredAPIRequestGenerator, type ExecutedGeneratorsResults } from "./generatorSupport.ts";
52
+ // import {executeRequestGenerators, type ExecutedGeneratorsResults, type AnyAPIRequestGenerator} from "./generatorSupport.ts";
53
+ // import { sourceFileResponseToUint8Array } from "../node/encoder.ts";
54
+ // @sync-only-end
23
55
  export class API {
56
+ /** @internal */
24
57
  client;
58
+ /** @internal */
25
59
  sourceFileCache;
26
60
  toPath;
61
+ decoder = new Wtf8Decoder();
62
+ currentDirectory;
63
+ caseSensitivity;
27
64
  initialized = false;
28
- activeSnapshots = new Set();
29
- latestSnapshot;
30
- internal;
65
+ initializing;
66
+ activeSnapshots = new Map();
67
+ activeBuildOrchestrators = new Set();
68
+ activeSourceFileLeases = new Map();
69
+ printer;
70
+ debug;
31
71
  constructor(options = {}) {
32
72
  this.client = new Client(options);
33
73
  this.sourceFileCache = new SourceFileCache();
34
- this.internal = new InternalAPI(this.client, () => this.ensureInitialized());
74
+ this.printer = new Printer(this.client);
75
+ this.debug = new DebugHandlers(this.client, () => this.ensureInitialized()); // @sync: this.debug = new DebugHandlers(this.client, this.ensureInitialized);
76
+ }
77
+ /**
78
+ * Looks up a remote declaration's binder symbol. Throws for synthesized or configuration ASTs.
79
+ */
80
+ async getSymbol(declaration) {
81
+ const file = getRemoteSourceFile(declaration);
82
+ if (!file)
83
+ throw new Error(`Source file not found for declaration`);
84
+ const record = file.symbolCache;
85
+ if (!record)
86
+ throw new Error(`Cached source file not found for declaration`);
87
+ const index = parseNodeHandleFromCompiler(getNodeId(declaration)).index;
88
+ const cached = record.symbolsByDeclarationNodeIndex.get(index);
89
+ if (cached)
90
+ return cached;
91
+ // @sync-only-start
92
+ // return this.fetchDeclarationSymbol(record, index);
93
+ // @sync-only-end
94
+ // @sync-skip-block-start
95
+ let request = record.declarationSymbolRequests.get(index);
96
+ if (!request) {
97
+ request = this.fetchDeclarationSymbol(record, index);
98
+ record.declarationSymbolRequests.set(index, request);
99
+ }
100
+ try {
101
+ return await request;
102
+ }
103
+ finally {
104
+ record.declarationSymbolRequests.delete(index);
105
+ }
106
+ // @sync-skip-block-end
107
+ }
108
+ async fetchDeclarationSymbol(record, index) {
109
+ const data = await this.client.apiRequest("getSymbolOfDeclaration", {
110
+ file: record.descriptor,
111
+ index,
112
+ });
113
+ validateSymbolResponse(data);
114
+ const reference = data.reference;
115
+ if (reference.kind !== SymbolOwnerKind.File) {
116
+ throw new Error(`Symbol ${reference.id} is not file-owned`);
117
+ }
118
+ const fileOwner = { record, api: this };
119
+ const symbol = this.sourceFileCache.getOrCreateSymbol(record, reference.file, reference.id, () => new Symbol(data, { kind: SymbolOwnerKind.File, owner: fileOwner }));
120
+ record.symbolsByDeclarationNodeIndex.set(index, symbol);
121
+ return symbol;
35
122
  }
36
123
  /**
37
124
  * Create an API instance from an existing LSP connection's API session.
@@ -42,56 +129,323 @@ export class API {
42
129
  await api.ensureInitialized();
43
130
  return api;
44
131
  }
132
+ // @sync-skip-block-start
133
+ batchContext() {
134
+ return this.client.batchContext();
135
+ }
136
+ // @sync-skip-block-end
137
+ // @sync-only-start
138
+ // batch<T extends readonly AnyAPIRequestGenerator[]>(...requestGenerators: T): ExecutedGeneratorsResults<T> {
139
+ // return executeRequestGenerators(requestGenerators, requests => this.client.batchRequests(requests).responses);
140
+ // }
141
+ // @sync-only-end
45
142
  async ensureInitialized() {
46
- if (!this.initialized) {
143
+ if (this.initialized)
144
+ return;
145
+ return this.initializing ??= this.initializeWorker();
146
+ }
147
+ async initializeWorker() {
148
+ try {
47
149
  const response = await this.client.apiRequest("initialize", null);
48
- const getCanonicalFileName = createGetCanonicalFileName(response.useCaseSensitiveFileNames);
49
- const currentDirectory = response.currentDirectory;
50
- this.toPath = (fileName) => toPath(fileName, currentDirectory, getCanonicalFileName);
150
+ this.currentDirectory = response.currentDirectory;
151
+ this.caseSensitivity = response.caseSensitivity;
152
+ this.toPath = (fileName, basePath = response.currentDirectory) => pathKey(toRootedPath(fileName, toRootedDirectoryPath(basePath, response.currentDirectory)), response.caseSensitivity);
51
153
  this.initialized = true;
52
154
  }
155
+ catch (error) {
156
+ this.initializing = undefined;
157
+ throw error;
158
+ }
159
+ }
160
+ getCurrentDirectory() {
161
+ if (this.currentDirectory === undefined) {
162
+ throw new Error("API has not been initialized");
163
+ }
164
+ return this.currentDirectory;
165
+ }
166
+ getCanonicalFileName(fileName) {
167
+ return canonicalize(fileName, this.getCaseSensitivity());
168
+ }
169
+ getCaseSensitivity() {
170
+ if (this.caseSensitivity === undefined) {
171
+ throw new Error("API has not been initialized");
172
+ }
173
+ return this.caseSensitivity;
174
+ }
175
+ getNewLine() {
176
+ return "\n";
177
+ }
178
+ /** @internal */
179
+ async createBuildOrchestrator(rootNames, buildOrchestratorOptions) {
180
+ await this.ensureInitialized();
181
+ const orchestratorResponse = await this.client.apiRequest("createBuildOrchestrator", {
182
+ ...buildOrchestratorOptions,
183
+ ...buildOrchestratorOptions.overrideCompilerOptions,
184
+ cwd: buildOrchestratorOptions.cwd === undefined
185
+ ? undefined
186
+ : toRootedDirectoryPath(buildOrchestratorOptions.cwd, this.getCurrentDirectory()),
187
+ rootNames,
188
+ });
189
+ const orchestrator = new BuildOrchestrator(this.client, orchestratorResponse, () => {
190
+ this.activeBuildOrchestrators.delete(orchestrator);
191
+ });
192
+ this.activeBuildOrchestrators.add(orchestrator);
193
+ return orchestrator;
53
194
  }
54
195
  async parseConfigFile(file) {
55
196
  await this.ensureInitialized();
56
197
  return this.client.apiRequest("parseConfigFile", { file });
57
198
  }
58
- async updateSnapshot(params) {
199
+ async parseCommandLine(commandLine) {
59
200
  await this.ensureInitialized();
60
- const requestParams = toUpdateSnapshotRequest(params);
61
- const data = await this.client.apiRequest("updateSnapshot", requestParams);
62
- // Retain cached source files from previous snapshot for unchanged files
63
- if (this.latestSnapshot) {
64
- this.sourceFileCache.retainForSnapshot(data.snapshot, this.latestSnapshot.id, data.changes);
65
- if (this.latestSnapshot.isDisposed()) {
66
- this.sourceFileCache.releaseSnapshot(this.latestSnapshot.id);
67
- }
201
+ return this.client.apiRequest("parseCommandLine", { commandLine });
202
+ }
203
+ async readConfigFile(file) {
204
+ await this.ensureInitialized();
205
+ return this.client.apiRequest("readConfigFile", { file });
206
+ }
207
+ async parseJsonConfigFileContent(json, options) {
208
+ await this.ensureInitialized();
209
+ return this.client.apiRequest("parseJsonConfigFileContent", { json, ...options });
210
+ }
211
+ /**
212
+ * Create and retain a source file independently of a program.
213
+ * Dispose the returned lease when the source file no longer needs to remain available remotely.
214
+ */
215
+ async createSourceFile(fileName, sourceText, options = {}) {
216
+ await this.ensureInitialized();
217
+ const data = await this.client.apiRequestBinary("createSourceFile", { fileName, sourceText, options });
218
+ if (!data) {
219
+ throw new Error("createSourceFile returned no source file");
68
220
  }
69
- const snapshot = new Snapshot(data, this.client, this.sourceFileCache, this.toPath, () => {
70
- this.activeSnapshots.delete(snapshot);
71
- if (snapshot !== this.latestSnapshot) {
72
- this.sourceFileCache.releaseSnapshot(snapshot.id);
73
- }
221
+ return this.retainSourceFileResponse(data);
222
+ }
223
+ /**
224
+ * Read, create, and retain a source file independently of a program.
225
+ * Dispose the returned lease when the source file no longer needs to remain available remotely.
226
+ */
227
+ async createSourceFileFromFile(file, options = {}) {
228
+ await this.ensureInitialized();
229
+ const data = await this.client.apiRequestBinary("createSourceFileFromFile", { fileName: resolveFileName(file), options });
230
+ if (!data) {
231
+ throw new Error("createSourceFileFromFile returned no source file");
232
+ }
233
+ return this.retainSourceFileResponse(data);
234
+ }
235
+ /**
236
+ * Retain an ordinary remote source file independently of the snapshot or lease that produced it.
237
+ */
238
+ async retainSourceFile(sourceFile) {
239
+ await this.ensureInitialized();
240
+ if (!(sourceFile instanceof RemoteSourceFile)) {
241
+ throw new TypeError("Only remote source files can be retained");
242
+ }
243
+ const cached = this.sourceFileCache.get(sourceFile);
244
+ if (cached && cached !== sourceFile) {
245
+ throw new Error("Source file is no longer the canonical cached instance");
246
+ }
247
+ const result = await this.client.apiRequest("retainSourceFile", { file: sourceFileDescriptor(sourceFile) });
248
+ return this.addSourceFileLease(sourceFile, result.lease);
249
+ }
250
+ retainSourceFileResponse(data) {
251
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
252
+ const lease = readSourceFileLease(view);
253
+ try {
254
+ const decoded = new RemoteSourceFile(data, this.decoder, this.client.getTimingCollector(), this);
255
+ return this.addSourceFileLease(decoded, lease);
256
+ }
257
+ catch (error) {
258
+ // @sync-skip-block-start
259
+ void this.client.apiRequest("releaseSourceFile", { lease }).catch(() => { });
260
+ // @sync-skip-block-end
261
+ // @sync-only-start
262
+ // try {
263
+ // this.client.apiRequest("releaseSourceFile", { lease });
264
+ // }
265
+ // catch {}
266
+ // @sync-only-end
267
+ throw error;
268
+ }
269
+ }
270
+ addSourceFileLease(sourceFile, lease) {
271
+ const cached = this.sourceFileCache.setForLease(sourceFile, lease);
272
+ const retained = new RetainedSourceFile(cached, lease, () => {
273
+ this.activeSourceFileLeases.delete(lease);
274
+ this.sourceFileCache.releaseLease(lease);
275
+ });
276
+ this.activeSourceFileLeases.set(lease, retained);
277
+ return retained;
278
+ }
279
+ async transpileModule(input, options = {}) {
280
+ await this.ensureInitialized();
281
+ return this.client.apiRequest("transpileModule", { input, options });
282
+ }
283
+ async transpileModuleFromFile(file, options = {}) {
284
+ await this.ensureInitialized();
285
+ return this.client.apiRequest("transpileModuleFromFile", { fileName: resolveFileName(file), options });
286
+ }
287
+ async transpileDeclaration(input, options = {}) {
288
+ await this.ensureInitialized();
289
+ return this.client.apiRequest("transpileDeclaration", { input, options });
290
+ }
291
+ async transpileDeclarationFromFile(file, options = {}) {
292
+ await this.ensureInitialized();
293
+ return this.client.apiRequest("transpileDeclarationFromFile", { fileName: resolveFileName(file), options });
294
+ }
295
+ async createSnapshot(params) {
296
+ await this.ensureInitialized();
297
+ const requestParams = this.prepareCreateSnapshotParams(params);
298
+ const data = await this.client.apiRequest("createSnapshot", requestParams);
299
+ const snapshot = new Snapshot(data, this.toPath, this, () => {
300
+ this.activeSnapshots.delete(snapshot.id);
301
+ this.sourceFileCache.releaseSnapshot(snapshot.id);
302
+ }, this.createSnapshotUpdater(() => snapshot), undefined);
303
+ this.activeSnapshots.set(snapshot.id, snapshot);
304
+ return snapshot;
305
+ }
306
+ async updateSnapshot(baseSnapshot, params) {
307
+ await this.ensureInitialized();
308
+ if (this.activeSnapshots.get(baseSnapshot.id) !== baseSnapshot || baseSnapshot.isDisposed()) {
309
+ throw new Error("Cannot update an inactive snapshot");
310
+ }
311
+ const data = await this.client.apiRequest("updateSnapshot", {
312
+ snapshot: baseSnapshot.id,
313
+ changes: this.prepareCreateSnapshotParams(params),
314
+ });
315
+ if (data.snapshot === baseSnapshot.id) {
316
+ await this.client.apiRequest("release", { snapshot: data.snapshot });
317
+ return baseSnapshot;
318
+ }
319
+ this.sourceFileCache.retainForSnapshot(data.snapshot, baseSnapshot.id, data.changes);
320
+ const snapshot = new Snapshot(data, this.toPath, this, () => {
321
+ this.activeSnapshots.delete(snapshot.id);
322
+ this.sourceFileCache.releaseSnapshot(snapshot.id);
323
+ }, this.createSnapshotUpdater(() => snapshot), baseSnapshot);
324
+ this.activeSnapshots.set(snapshot.id, snapshot);
325
+ return snapshot;
326
+ }
327
+ prepareCreateSnapshotParams(params) {
328
+ params ??= {};
329
+ const prepareOptions = (options) => {
330
+ if (!options)
331
+ return undefined;
332
+ const { moduleResolver, projectReferences, ...rest } = options;
333
+ moduleResolver?.ensureNotDisposed();
334
+ return {
335
+ ...rest,
336
+ moduleResolver: moduleResolver?.id,
337
+ projectReferences: projectReferences?.map(reference => ({
338
+ ...reference,
339
+ path: toRootedPath(reference.path, this.getCurrentDirectory()),
340
+ })),
341
+ };
342
+ };
343
+ return {
344
+ ...params,
345
+ createPrograms: params.createPrograms?.map(program => ({ ...program, options: prepareOptions(program.options) })),
346
+ reconfigurePrograms: params.reconfigurePrograms?.map(program => ({ ...program, options: prepareOptions(program.options) })),
347
+ };
348
+ }
349
+ prepareLanguageServerSnapshotChanges(changes) {
350
+ if (!changes)
351
+ return undefined;
352
+ const prepared = this.prepareCreateSnapshotParams(changes);
353
+ return prepared;
354
+ }
355
+ createSnapshotUpdater(getSnapshot) {
356
+ const update = params => this.updateSnapshot(getSnapshot(), params); // @sync: const update = ((params: CreateSnapshotParams) => this.updateSnapshot(getSnapshot(), params)) as SnapshotUpdater;
357
+ // @sync-only-start
358
+ // const owner = this;
359
+ // update.gen = function* (params: CreateSnapshotParams) { return yield* owner.updateSnapshot.gen(getSnapshot(), params); };
360
+ // @sync-only-end
361
+ return update;
362
+ }
363
+ async getCurrentLanguageServerSnapshot(...args) {
364
+ await this.ensureInitialized();
365
+ const changes = args[0];
366
+ const baseSnapshot = args[1];
367
+ if (baseSnapshot && (this.activeSnapshots.get(baseSnapshot.id) !== baseSnapshot || baseSnapshot.isDisposed())) {
368
+ throw new Error("Cannot use an inactive snapshot as a response base");
369
+ }
370
+ const data = await this.client.apiRequest("getCurrentLanguageServerSnapshot", {
371
+ baseSnapshot: baseSnapshot?.id,
372
+ changes: this.prepareLanguageServerSnapshotChanges(changes),
74
373
  });
75
- this.latestSnapshot = snapshot;
76
- this.activeSnapshots.add(snapshot);
374
+ if (baseSnapshot) {
375
+ this.sourceFileCache.retainForSnapshot(data.snapshot, baseSnapshot.id, data.changes);
376
+ }
377
+ const snapshot = new Snapshot(data, this.toPath, this, () => {
378
+ this.activeSnapshots.delete(snapshot.id);
379
+ this.sourceFileCache.releaseSnapshot(snapshot.id);
380
+ }, this.createSnapshotUpdater(() => snapshot), baseSnapshot);
381
+ this.activeSnapshots.set(snapshot.id, snapshot);
77
382
  return snapshot;
78
383
  }
384
+ async [globalThis.Symbol.asyncDispose]() {
385
+ await this.close(); // @sync: this.close();
386
+ }
79
387
  async close() {
80
- // Dispose all active snapshots
81
- for (const snapshot of [...this.activeSnapshots]) {
82
- await snapshot.dispose();
388
+ await this.initializing?.catch(() => { }); // @sync-skip
389
+ try {
390
+ for (const retained of [...this.activeSourceFileLeases.values()]) {
391
+ await retained.dispose();
392
+ }
83
393
  }
84
- // Release the latest snapshot's cache refs if still held
85
- if (this.latestSnapshot) {
86
- this.sourceFileCache.releaseSnapshot(this.latestSnapshot.id);
87
- this.latestSnapshot = undefined;
394
+ finally {
395
+ try {
396
+ for (const orchestrator of [...this.activeBuildOrchestrators]) {
397
+ await orchestrator.dispose();
398
+ }
399
+ for (const snapshot of [...this.activeSnapshots.values()]) {
400
+ await snapshot.dispose();
401
+ }
402
+ this.sourceFileCache.clear();
403
+ }
404
+ finally {
405
+ await this.client.close(); // always close the underlying connection
406
+ }
407
+ }
408
+ }
409
+ async createModuleResolver(compilerOptions, options) {
410
+ await this.ensureInitialized();
411
+ const callback = options?.resolveModuleName
412
+ ? registerModuleResolutionCallback(this.client, options.resolveModuleName, id => this.activeSnapshots.get(id))
413
+ : undefined;
414
+ try {
415
+ const id = await this.client.apiRequest("createModuleResolver", {
416
+ compilerOptions: prepareCompilerOptions(compilerOptions, this.getCurrentDirectory()),
417
+ moduleResolutions: options?.moduleResolutions,
418
+ resolveModuleNameCallback: callback?.name,
419
+ });
420
+ return new ModuleResolver(id, this.client, callback?.dispose);
421
+ }
422
+ catch (error) {
423
+ callback?.dispose();
424
+ throw error;
88
425
  }
89
- await this.client.close();
90
- this.sourceFileCache.clear();
91
426
  }
92
427
  clearSourceFileCache() {
93
428
  this.sourceFileCache.clear();
94
429
  }
430
+ async runWithTemporaryFileUpdate(baseSnapshot, file, newText, cb) {
431
+ await this.ensureInitialized();
432
+ if (this.activeSnapshots.get(baseSnapshot.id) !== baseSnapshot || baseSnapshot.isDisposed()) {
433
+ throw new Error("Cannot run a temporary file update on an inactive snapshot");
434
+ }
435
+ const snapshot = await baseSnapshot.update({
436
+ fileSystem: {
437
+ kind: "layer",
438
+ files: { [resolveFileName(file)]: newText },
439
+ },
440
+ ensurePrograms: true,
441
+ });
442
+ try {
443
+ await cb(snapshot);
444
+ }
445
+ finally {
446
+ await snapshot.dispose();
447
+ }
448
+ }
95
449
  /**
96
450
  * Returns a snapshot of collected timing information for requests made
97
451
  * through this API instance: client-measured round-trip latency and bytes
@@ -100,8 +454,8 @@ export class API {
100
454
  *
101
455
  * Fetching the snapshot issues a lightweight request to the server to
102
456
  * retrieve its timing collection. Collection must be enabled via the
103
- * `collectTiming` option; when it is not, the returned snapshot has
104
- * `enabled: false` and zeroed totals.
457
+ * `collectTiming` option or `TS_API_TIMING_DIR` environment variable; when
458
+ * it is not, the returned snapshot has `enabled: false` and zeroed totals.
105
459
  */
106
460
  getTimingInfo() {
107
461
  return this.client.getTimingInfo();
@@ -110,11 +464,102 @@ export class API {
110
464
  resetTimingInfo() {
111
465
  return this.client.resetTimingInfo();
112
466
  }
467
+ /** Creates a program from current filesystem state. */
468
+ async createProgram(rootFiles, compilerOptions, createProgramOptions) {
469
+ await this.ensureInitialized();
470
+ const snapshot = await this.createSnapshot({
471
+ createPrograms: [{ rootFiles, compilerOptions, options: createProgramOptions }],
472
+ });
473
+ const program = snapshot.operation.createdPrograms[0];
474
+ if (!program) {
475
+ await snapshot.dispose();
476
+ throw new Error("createProgram did not return a project");
477
+ }
478
+ program.setOwnedSnapshot(snapshot);
479
+ return program;
480
+ }
481
+ }
482
+ function sourceFileDescriptor(sourceFile) {
483
+ return {
484
+ fileName: sourceFile.fileName,
485
+ path: sourceFile.path,
486
+ contentHash: sourceFile.contentHash,
487
+ parseOptionsKey: sourceFile.parseOptionsKey,
488
+ scriptKind: sourceFile.scriptKind,
489
+ nodeId: sourceFile.nodeId,
490
+ };
491
+ }
492
+ /** Returns whether a node is backed by a remote compiler response. */
493
+ export function isRemoteNode(node) {
494
+ return node instanceof RemoteNode;
495
+ }
496
+ function getRemoteSourceFile(node) {
497
+ if (!isRemoteNode(node))
498
+ return undefined;
499
+ const file = node.getSourceFile();
500
+ return file instanceof RemoteSourceFile && file.api ? file : undefined;
501
+ }
502
+ function getNodeAPI(node) {
503
+ const api = getRemoteSourceFile(node)?.api;
504
+ if (!api)
505
+ return undefined;
506
+ if (!(api instanceof API))
507
+ throw new Error("Source file does not belong to the async API"); // @sync: if (!(api instanceof API)) throw new Error("Source file does not belong to the sync API");
508
+ return api;
509
+ }
510
+ /** Looks up a remote declaration's binder symbol through its API. Throws for non-remote declarations. */
511
+ export async function getSymbol(declaration) {
512
+ const api = getNodeAPI(declaration);
513
+ if (!api)
514
+ throw new Error("Source file not found for declaration");
515
+ return api.getSymbol(declaration);
516
+ }
517
+ // @sync-only-start
518
+ // export declare namespace getSymbol {
519
+ // function gen(declaration: Declaration): Generator<ProtocolRequest, Symbol, ProtocolResponse["result"]>;
520
+ // }
521
+ // getSymbol.gen = function* (declaration: Declaration): Generator<ProtocolRequest, Symbol, ProtocolResponse["result"]> {
522
+ // const api = getNodeAPI(declaration);
523
+ // if (!api) throw new Error("Source file not found for declaration");
524
+ // return yield* api.getSymbol.gen(declaration);
525
+ // };
526
+ // @sync-only-end
527
+ /** An independently retained source file and its disposable remote-lifetime lease. */
528
+ export class RetainedSourceFile {
529
+ sourceFile;
530
+ lease;
531
+ onDispose;
532
+ disposed = false;
533
+ disposePromise;
534
+ constructor(sourceFile, lease, onDispose) {
535
+ this.sourceFile = sourceFile;
536
+ this.lease = lease;
537
+ this.onDispose = onDispose;
538
+ }
539
+ [globalThis.Symbol.asyncDispose]() {
540
+ return this.dispose(); // @sync: this.dispose();
541
+ }
542
+ dispose() {
543
+ return this.disposePromise ??= this.disposeWorker();
544
+ }
545
+ async disposeWorker() {
546
+ if (this.disposed)
547
+ return;
548
+ const api = getNodeAPI(this.sourceFile);
549
+ if (!api)
550
+ throw new Error("Retained source file has no owning API");
551
+ this.disposed = true;
552
+ try {
553
+ await api.client.apiRequest("releaseSourceFile", { lease: this.lease });
554
+ }
555
+ finally {
556
+ this.onDispose();
557
+ }
558
+ }
113
559
  }
114
- export class InternalAPI {
560
+ export class DebugHandlers {
115
561
  client;
116
562
  ensureInitialized;
117
- /** @internal */
118
563
  constructor(client, ensureInitialized) {
119
564
  this.client = client;
120
565
  this.ensureInitialized = ensureInitialized;
@@ -136,32 +581,70 @@ export class InternalAPI {
136
581
  }
137
582
  export class Snapshot {
138
583
  id;
584
+ operation;
139
585
  projectMap;
140
586
  toPath;
141
- client;
587
+ api;
142
588
  disposed = false;
589
+ disposePromise;
143
590
  onDispose;
144
591
  snapshotRegistry;
145
- constructor(data, client, sourceFileCache, toPath, onDispose) {
592
+ projectDataMap;
593
+ updateSnapshot;
594
+ get client() {
595
+ return this.api.client;
596
+ }
597
+ constructor(data, toPath, api, onDispose, updateSnapshot, baseSnapshot) {
146
598
  this.id = data.snapshot;
147
- this.client = client;
599
+ this.api = api;
148
600
  this.toPath = toPath;
149
601
  this.onDispose = onDispose;
602
+ this.updateSnapshot = updateSnapshot;
150
603
  this.projectMap = new Map();
151
- this.snapshotRegistry = new SnapshotObjectRegistry(client, this.id, projectId => this.projectMap.get(projectId));
152
- for (const projData of data.projects) {
153
- const project = new Project(projData, this.id, client, sourceFileCache, toPath, this.snapshotRegistry);
154
- this.projectMap.set(toPath(projData.configFileName), project);
604
+ const projectDataMap = new Map(baseSnapshot?.projectDataMap);
605
+ for (const projectId of data.changes?.removedProjects ?? []) {
606
+ projectDataMap.delete(projectId);
607
+ }
608
+ for (const projectData of data.projects) {
609
+ projectDataMap.set(projectData.id, projectData);
155
610
  }
611
+ this.projectDataMap = new Map([...projectDataMap].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0));
612
+ this.snapshotRegistry = new SnapshotObjectRegistry(this.id);
613
+ for (const projData of this.projectDataMap.values()) {
614
+ const project = new Project(projData, this.id, toPath, api, this.snapshotRegistry);
615
+ this.projectMap.set(projData.id, project);
616
+ }
617
+ this.operation = {
618
+ createdPrograms: data.operation.createdPrograms?.map(projectId => this.requireProject(projectId).program),
619
+ openedFiles: data.operation.openedFiles?.map(result => ({ project: this.requireProject(result.project) })),
620
+ };
156
621
  }
157
622
  getProjects() {
158
623
  this.ensureNotDisposed();
159
624
  return [...this.projectMap.values()];
160
625
  }
161
- getProject(configFileName) {
626
+ getConfiguredProject(configFileName) {
162
627
  this.ensureNotDisposed();
163
- return this.projectMap.get(this.toPath(configFileName));
628
+ const id = this.toPath(configFileName);
629
+ return this.projectMap.get(id);
164
630
  }
631
+ getProject(projectId) {
632
+ this.ensureNotDisposed();
633
+ return this.projectMap.get(projectId);
634
+ }
635
+ getProgram(projectId) {
636
+ return this.getProject(projectId)?.program;
637
+ }
638
+ update(params) {
639
+ this.ensureNotDisposed();
640
+ return this.updateSnapshot(params);
641
+ }
642
+ /**
643
+ * Gets the default project for a given file from the configured projects and
644
+ * inferred project already loaded in the snapshot. Synthetic projects are not
645
+ * considered. Files that have been opened with `openFiles` are guaranteed to
646
+ * have a result.
647
+ */
165
648
  async getDefaultProjectForFile(file) {
166
649
  this.ensureNotDisposed();
167
650
  const data = await this.client.apiRequest("getDefaultProjectForFile", {
@@ -170,12 +653,15 @@ export class Snapshot {
170
653
  });
171
654
  if (!data)
172
655
  return undefined;
173
- return this.projectMap.get(this.toPath(data.configFileName));
656
+ return this.projectMap.get(data.id);
174
657
  }
175
- [globalThis.Symbol.dispose]() {
176
- this.dispose();
658
+ [globalThis.Symbol.asyncDispose]() {
659
+ return this.dispose(); // @sync: this.dispose();
177
660
  }
178
- async dispose() {
661
+ dispose() {
662
+ return this.disposePromise ??= this.disposeWorker();
663
+ }
664
+ async disposeWorker() {
179
665
  if (this.disposed)
180
666
  return;
181
667
  this.disposed = true;
@@ -184,8 +670,12 @@ export class Snapshot {
184
670
  }
185
671
  this.projectMap.clear();
186
672
  this.snapshotRegistry.clear();
187
- this.onDispose();
188
- await this.client.apiRequest("release", { snapshot: this.id });
673
+ try {
674
+ await this.client.apiRequest("release", { snapshot: this.id });
675
+ }
676
+ finally {
677
+ this.onDispose();
678
+ }
189
679
  }
190
680
  isDisposed() {
191
681
  return this.disposed;
@@ -195,26 +685,78 @@ export class Snapshot {
195
685
  throw new Error("Snapshot is disposed");
196
686
  }
197
687
  }
688
+ requireProject(projectId) {
689
+ const project = this.projectMap.get(projectId);
690
+ if (!project) {
691
+ throw new Error(`Snapshot operation returned unknown project '${projectId}'`);
692
+ }
693
+ return project;
694
+ }
695
+ }
696
+ export class ModuleResolver {
697
+ id;
698
+ client;
699
+ disposeCallback;
700
+ disposed = false;
701
+ constructor(id, client, disposeCallback) {
702
+ this.id = id;
703
+ this.client = client;
704
+ this.disposeCallback = disposeCallback;
705
+ }
706
+ async resolveModuleName(moduleName, containingDirectory, resolutionMode, options) {
707
+ this.ensureNotDisposed();
708
+ if (options?.snapshot instanceof Snapshot && options.snapshot.isDisposed()) {
709
+ throw new Error("Snapshot is disposed");
710
+ }
711
+ return this.client.apiRequest("resolveModuleName", {
712
+ snapshot: options?.snapshot instanceof Snapshot ? options.snapshot.id : undefined,
713
+ inProgressSnapshot: typeof options?.snapshot === "number" ? -options.snapshot : undefined,
714
+ resolver: this.id,
715
+ moduleName,
716
+ containingDirectory,
717
+ resolutionMode,
718
+ });
719
+ }
720
+ [globalThis.Symbol.asyncDispose]() {
721
+ return this.dispose();
722
+ }
723
+ async dispose() {
724
+ if (this.disposed)
725
+ return;
726
+ await this.client.apiRequest("releaseModuleResolver", { resolver: this.id });
727
+ this.disposed = true;
728
+ this.disposeCallback?.();
729
+ }
730
+ /** @internal */
731
+ ensureNotDisposed() {
732
+ if (this.disposed)
733
+ throw new Error("ModuleResolver is disposed");
734
+ }
198
735
  }
199
736
  class SnapshotObjectRegistry {
200
737
  symbols = new Map();
201
- client;
738
+ projectRegistries = new Map();
202
739
  snapshotId;
203
- resolveProject;
204
- constructor(client, snapshotId, resolveProject) {
205
- this.client = client;
740
+ constructor(snapshotId) {
206
741
  this.snapshotId = snapshotId;
207
- this.resolveProject = resolveProject;
208
742
  }
209
- /** Resolve a project id (a config file path) to its Project within this snapshot. */
210
- getProject(projectId) {
211
- return this.resolveProject(projectId);
743
+ addProjectRegistry(registry) {
744
+ this.projectRegistries.set(registry.project.id, registry);
212
745
  }
213
746
  getOrCreateSymbol(data) {
214
- let symbol = this.symbols.get(data.id);
747
+ const reference = data.reference;
748
+ if (reference.kind !== SymbolOwnerKind.Snapshot)
749
+ throw new Error(`Symbol ${reference.id} is not snapshot-owned`);
750
+ let symbol = this.symbols.get(reference.id);
215
751
  if (!symbol) {
216
- symbol = new Symbol(data, this);
217
- this.symbols.set(data.id, symbol);
752
+ if (reference.snapshot !== this.snapshotId) {
753
+ throw new Error(`Symbol ${reference.id} belongs to snapshot ${reference.snapshot}, not ${this.snapshotId}`);
754
+ }
755
+ const registry = this.projectRegistries.get(reference.project);
756
+ if (!registry)
757
+ throw new Error(`Symbol ${reference.id} references unknown project '${reference.project}'`);
758
+ symbol = new Symbol(data, { kind: SymbolOwnerKind.Snapshot, registry });
759
+ this.symbols.set(reference.id, symbol);
218
760
  }
219
761
  return symbol;
220
762
  }
@@ -224,65 +766,51 @@ class SnapshotObjectRegistry {
224
766
  clear() {
225
767
  this.symbols.clear();
226
768
  }
227
- async fetchSymbol(source, method, handle, projectId) {
228
- if (!handle)
229
- return undefined;
230
- const cached = this.getSymbol(handle);
231
- if (cached)
232
- return cached;
233
- const data = await this.client.apiRequest(method, {
234
- snapshot: this.snapshotId,
235
- project: projectId,
236
- objectId: source.id,
237
- });
238
- if (!data)
239
- throw new Error(`${method} returned null symbol for ${source.constructor.name} ${source.id}`);
240
- return this.getOrCreateSymbol(data);
241
- }
242
- async fetchSymbols(source, method, handles, projectId) {
243
- if (handles) {
244
- const result = new Array(handles.length);
245
- let allCached = true;
246
- for (let i = 0; i < handles.length; i++) {
247
- const cached = this.getSymbol(handles[i]);
248
- if (!cached) {
249
- allCached = false;
250
- break;
251
- }
252
- result[i] = cached;
253
- }
254
- if (allCached)
255
- return result;
256
- }
257
- const symbolData = await this.client.apiRequest(method, {
258
- snapshot: this.snapshotId,
259
- project: projectId,
260
- objectId: source.id,
261
- });
262
- if (symbolData == null)
263
- return [];
264
- else
265
- return symbolData.map(data => this.getOrCreateSymbol(data));
266
- }
267
769
  }
268
770
  class ProjectObjectRegistry {
269
- client;
270
771
  snapshotId;
271
772
  project;
272
773
  snapshotRegistry;
273
774
  types = new Map();
274
775
  signatures = new Map();
275
- constructor(client, snapshotId, project, snapshotRegistry) {
276
- this.client = client;
776
+ disposed = false;
777
+ get client() {
778
+ return this.project.api.client;
779
+ }
780
+ get sourceFileCache() {
781
+ return this.project.api.sourceFileCache;
782
+ }
783
+ constructor(snapshotId, project, snapshotRegistry) {
277
784
  this.snapshotId = snapshotId;
278
785
  this.project = project;
279
786
  this.snapshotRegistry = snapshotRegistry;
787
+ snapshotRegistry.addProjectRegistry(this);
280
788
  }
281
789
  getOrCreateSymbol(data) {
282
- return this.snapshotRegistry.getOrCreateSymbol(data);
790
+ this.ensureNotDisposed();
791
+ validateSymbolResponse(data);
792
+ const reference = data.reference;
793
+ if (reference.kind === SymbolOwnerKind.Snapshot) {
794
+ return this.snapshotRegistry.getOrCreateSymbol(data);
795
+ }
796
+ const record = this.sourceFileCache.getOrCreateRecord(reference.file, this.snapshotId, this.project.id);
797
+ return this.sourceFileCache.getOrCreateSymbol(record, reference.file, reference.id, () => new Symbol(data, {
798
+ kind: SymbolOwnerKind.File,
799
+ owner: { record, api: this.project.api },
800
+ }));
283
801
  }
284
- getSymbol(id) {
285
- return this.snapshotRegistry.getSymbol(id);
802
+ /** Find an already-interned symbol and retain its file record for this registry. */
803
+ getCachedSymbol(reference) {
804
+ this.ensureNotDisposed();
805
+ if (reference.file === undefined) {
806
+ return this.snapshotRegistry.getSymbol(reference.id);
807
+ }
808
+ const record = this.sourceFileCache.findRecord(reference.file);
809
+ const symbol = record?.symbolsById.get(reference.id);
810
+ if (record && symbol) {
811
+ this.sourceFileCache.retainRecord(record, this.snapshotId, this.project.id);
812
+ }
813
+ return symbol;
286
814
  }
287
815
  getOrCreateType(data) {
288
816
  let type = this.types.get(data.id);
@@ -295,6 +823,9 @@ class ProjectObjectRegistry {
295
823
  getType(id) {
296
824
  return this.types.get(id);
297
825
  }
826
+ createNodeHandle(handle) {
827
+ return new NodeHandle(handle, this.project);
828
+ }
298
829
  getOrCreateSignature(data) {
299
830
  let sig = this.signatures.get(data.id);
300
831
  if (!sig) {
@@ -307,10 +838,15 @@ class ProjectObjectRegistry {
307
838
  return this.signatures.get(id);
308
839
  }
309
840
  clear() {
841
+ this.disposed = true;
310
842
  this.types.clear();
311
843
  this.signatures.clear();
312
844
  }
313
- async fetchType(source, method, handle) {
845
+ ensureNotDisposed() {
846
+ if (this.disposed)
847
+ throw new Error("Project object registry is disposed");
848
+ }
849
+ async fetchOptionalType(source, method, handle) {
314
850
  if (handle !== false) {
315
851
  if (!handle)
316
852
  return undefined;
@@ -324,11 +860,31 @@ class ProjectObjectRegistry {
324
860
  objectId: source.id,
325
861
  });
326
862
  if (!data)
327
- throw new Error(`${method} returned null type for ${source.constructor.name} ${source.id}`);
863
+ return undefined;
328
864
  return this.getOrCreateType(data);
329
865
  }
330
- async fetchSymbol(source, method, handle) {
331
- return this.snapshotRegistry.fetchSymbol(source, method, handle, this.project.id);
866
+ async fetchType(source, method, handle) {
867
+ const result = await this.fetchOptionalType(source, method, handle);
868
+ if (result === undefined)
869
+ throw new Error(`${method} returned no type for ${source.constructor.name} ${source.id}`);
870
+ return result;
871
+ }
872
+ async fetchSymbol(source, method, reference) {
873
+ if (!reference)
874
+ return undefined;
875
+ const cached = this.getCachedSymbol(reference);
876
+ if (cached)
877
+ return cached;
878
+ const data = source instanceof Symbol
879
+ ? await this.client.apiRequest(method, { symbol: source.reference })
880
+ : await this.client.apiRequest(method, {
881
+ snapshot: this.snapshotId,
882
+ project: this.project.id,
883
+ objectId: source.id,
884
+ });
885
+ if (!data)
886
+ throw new Error(`${method} returned null symbol for ${source.constructor.name} ${source.id}`);
887
+ return this.getOrCreateSymbol(data);
332
888
  }
333
889
  async fetchSignature(source, method, handle) {
334
890
  if (!handle)
@@ -370,8 +926,29 @@ class ProjectObjectRegistry {
370
926
  else
371
927
  return typesData.map(data => this.getOrCreateType(data));
372
928
  }
373
- async fetchSymbols(source, method, handles) {
374
- return this.snapshotRegistry.fetchSymbols(source, method, handles, this.project.id);
929
+ async fetchSymbols(source, method, references) {
930
+ if (references) {
931
+ const result = new Array(references.length);
932
+ for (let i = 0; i < references.length; i++) {
933
+ const cached = this.getCachedSymbol(references[i]);
934
+ if (!cached) {
935
+ return this.fetchSymbolsFromServer(source, method);
936
+ }
937
+ result[i] = cached;
938
+ }
939
+ return result;
940
+ }
941
+ return this.fetchSymbolsFromServer(source, method);
942
+ }
943
+ async fetchSymbolsFromServer(source, method) {
944
+ const data = source instanceof Symbol
945
+ ? await this.client.apiRequest(method, { symbol: source.reference })
946
+ : await this.client.apiRequest(method, {
947
+ snapshot: this.snapshotId,
948
+ project: this.project.id,
949
+ objectId: source.id,
950
+ });
951
+ return data?.map(symbol => this.getOrCreateSymbol(symbol)) ?? [];
375
952
  }
376
953
  // getBaseTypes is a checker-level endpoint keyed by `type` (not `objectId`),
377
954
  // so it cannot go through fetchTypes. This helper reuses that server method.
@@ -385,52 +962,274 @@ class ProjectObjectRegistry {
385
962
  return [];
386
963
  return typesData.map(data => this.getOrCreateType(data));
387
964
  }
388
- }
389
- export class Project {
390
- id;
391
- configFileName;
392
- compilerOptions;
393
- rootFiles;
394
- program;
395
- checker;
396
- emitter;
397
- client;
398
- constructor(data, snapshotId, client, sourceFileCache, toPath, snapshotRegistry) {
399
- this.id = data.id;
965
+ async fetchPropertiesOfType(source) {
966
+ const data = await this.client.apiRequest("getPropertiesOfType", {
967
+ snapshot: this.snapshotId,
968
+ project: this.project.id,
969
+ type: source.id,
970
+ });
971
+ return data ? data.map(symbol => this.getOrCreateSymbol(symbol)) : [];
972
+ }
973
+ async fetchApparentPropertiesOfType(source) {
974
+ const data = await this.client.apiRequest("getApparentPropertiesOfType", {
975
+ snapshot: this.snapshotId,
976
+ project: this.project.id,
977
+ objectId: source.id,
978
+ });
979
+ return data ? data.map(symbol => this.getOrCreateSymbol(symbol)) : [];
980
+ }
981
+ async fetchPropertyOfType(source, name) {
982
+ const data = await this.client.apiRequest("getPropertyOfType", {
983
+ snapshot: this.snapshotId,
984
+ project: this.project.id,
985
+ type: source.id,
986
+ name,
987
+ });
988
+ return data ? this.getOrCreateSymbol(data) : undefined;
989
+ }
990
+ async fetchSignaturesOfType(source, kind) {
991
+ const data = await this.client.apiRequest("getSignaturesOfType", {
992
+ snapshot: this.snapshotId,
993
+ project: this.project.id,
994
+ type: source.id,
995
+ kind,
996
+ });
997
+ return data.map(signature => this.getOrCreateSignature(signature));
998
+ }
999
+ async fetchIndexInfosOfType(source) {
1000
+ const data = await this.client.apiRequest("getIndexInfosOfType", {
1001
+ snapshot: this.snapshotId,
1002
+ project: this.project.id,
1003
+ type: source.id,
1004
+ });
1005
+ if (!data)
1006
+ return [];
1007
+ return data.map(info => ({
1008
+ keyType: this.getOrCreateType(info.keyType),
1009
+ valueType: this.getOrCreateType(info.valueType),
1010
+ isReadonly: info.isReadonly ?? false,
1011
+ declaration: info.declaration ? new NodeHandle(info.declaration, this.project) : undefined,
1012
+ }));
1013
+ }
1014
+ async fetchTypeParameterAtPosition(source, pos) {
1015
+ const data = await this.client.apiRequest("getTypeParameterAtPosition", {
1016
+ snapshot: this.snapshotId,
1017
+ project: this.project.id,
1018
+ signature: source.id,
1019
+ index: pos,
1020
+ });
1021
+ return this.getOrCreateType(data);
1022
+ }
1023
+ }
1024
+ export class Project {
1025
+ /** @internal */
1026
+ api;
1027
+ id;
1028
+ configFileName;
1029
+ currentDirectory;
1030
+ dirty;
1031
+ parsedCommandLine;
1032
+ program;
1033
+ checker;
1034
+ languageService;
1035
+ constructor(data, snapshotId, toPath, api, snapshotRegistry) {
1036
+ this.id = data.id;
1037
+ this.api = api;
400
1038
  this.configFileName = data.configFileName;
401
- this.compilerOptions = data.compilerOptions;
402
- this.rootFiles = data.rootFiles;
403
- this.client = client;
404
- this.program = new Program(snapshotId, this, client, sourceFileCache, toPath);
405
- const objectRegistry = new ProjectObjectRegistry(client, snapshotId, this, snapshotRegistry);
406
- this.checker = new Checker(snapshotId, this, client, objectRegistry);
407
- this.emitter = new Emitter(client);
1039
+ this.currentDirectory = data.currentDirectory;
1040
+ this.dirty = data.dirty;
1041
+ if (!data.parsedCommandLine?.options) {
1042
+ throw new Error(`Project '${data.configFileName}' has no parsed command line`);
1043
+ }
1044
+ this.parsedCommandLine = data.parsedCommandLine;
1045
+ this.program = new Program(snapshotId, this, toPath);
1046
+ const objectRegistry = new ProjectObjectRegistry(snapshotId, this, snapshotRegistry);
1047
+ this.checker = new Checker(snapshotId, this, objectRegistry);
1048
+ this.languageService = new LanguageService(snapshotId, this, objectRegistry);
408
1049
  }
409
1050
  dispose() {
410
1051
  this.checker.dispose();
411
1052
  }
412
1053
  }
1054
+ export class LanguageService {
1055
+ snapshotId;
1056
+ project;
1057
+ objectRegistry;
1058
+ get client() {
1059
+ return this.project.api.client;
1060
+ }
1061
+ constructor(snapshotId, project, objectRegistry) {
1062
+ this.snapshotId = snapshotId;
1063
+ this.project = project;
1064
+ this.objectRegistry = objectRegistry;
1065
+ }
1066
+ async getImportAdderEdits(file, actions) {
1067
+ const requestActions = actions.map(action => {
1068
+ switch (action.kind) {
1069
+ case "importSymbol":
1070
+ const importSymbolAction = {
1071
+ kind: "importSymbol",
1072
+ symbol: action.symbol.reference,
1073
+ };
1074
+ if (action.isValidTypeOnlyUseSite !== undefined) {
1075
+ importSymbolAction.isValidTypeOnlyUseSite = action.isValidTypeOnlyUseSite;
1076
+ }
1077
+ return importSymbolAction;
1078
+ default:
1079
+ return assertNever(action.kind);
1080
+ }
1081
+ });
1082
+ const data = await this.client.apiRequest("getImportAdderEdits", {
1083
+ snapshot: this.snapshotId,
1084
+ project: this.project.id,
1085
+ file,
1086
+ actions: requestActions,
1087
+ });
1088
+ return data ?? [];
1089
+ }
1090
+ async getImportEditsForSymbols(file, symbols, options = {}) {
1091
+ return this.getImportAdderEdits(file, symbols.map((symbol) => {
1092
+ if (options.isValidTypeOnlyUseSite !== undefined) {
1093
+ return {
1094
+ kind: "importSymbol",
1095
+ symbol,
1096
+ isValidTypeOnlyUseSite: options.isValidTypeOnlyUseSite,
1097
+ };
1098
+ }
1099
+ return {
1100
+ kind: "importSymbol",
1101
+ symbol,
1102
+ };
1103
+ }));
1104
+ }
1105
+ async getReferencedSymbolsForNode(node, position) {
1106
+ const data = await this.client.apiRequest("getReferencedSymbolsForNode", {
1107
+ snapshot: this.snapshotId,
1108
+ project: this.project.id,
1109
+ node: getNodeId(node),
1110
+ position,
1111
+ });
1112
+ return (data ?? []).map(entry => ({
1113
+ definition: new NodeHandle(entry.definition, this.project),
1114
+ symbol: entry.symbol ? this.objectRegistry.getOrCreateSymbol(entry.symbol) : undefined,
1115
+ references: (entry.references ?? []).map(h => new NodeHandle(h, this.project)),
1116
+ }));
1117
+ }
1118
+ async getSignatureUsage(signatureDecl) {
1119
+ const data = await this.client.apiRequest("getSignatureUsages", {
1120
+ snapshot: this.snapshotId,
1121
+ project: this.project.id,
1122
+ signatureDecl: getNodeId(signatureDecl),
1123
+ });
1124
+ return (data ?? []).map(entry => ({
1125
+ name: new NodeHandle(entry.name, this.project),
1126
+ call: entry.call ? new NodeHandle(entry.call, this.project) : undefined,
1127
+ }));
1128
+ }
1129
+ async getCompletionsAtPosition(document, position, options) {
1130
+ const data = await this.client.apiRequest("getCompletionsAtPosition", {
1131
+ snapshot: this.snapshotId,
1132
+ project: this.project.id,
1133
+ file: document,
1134
+ position,
1135
+ triggerCharacter: options?.triggerCharacter,
1136
+ includeSymbol: options?.includeSymbol,
1137
+ });
1138
+ if (!data)
1139
+ return undefined;
1140
+ return {
1141
+ isIncomplete: data.isIncomplete,
1142
+ entries: data.entries.map(e => ({
1143
+ ...e,
1144
+ symbol: e.symbol ? this.objectRegistry.getOrCreateSymbol(e.symbol) : undefined,
1145
+ })),
1146
+ };
1147
+ }
1148
+ /**
1149
+ * Format a synthesized node with the correct indentation for insertion at a
1150
+ * specific position in an existing source file.
1151
+ *
1152
+ * @param node The synthesized AST node to format.
1153
+ * @param file The target file where the node will be inserted.
1154
+ * @param position The UTF-16 code-unit offset in the target file for insertion.
1155
+ * @returns The formatted text of the node, indented for the insertion position.
1156
+ */
1157
+ async formatNodeForInsertion(node, file, position) {
1158
+ const encoded = encodeNode(node);
1159
+ const base64 = uint8ArrayToBase64(encoded);
1160
+ return this.client.apiRequest("formatNodeForInsertion", {
1161
+ snapshot: this.snapshotId,
1162
+ project: this.project.id,
1163
+ file,
1164
+ position,
1165
+ data: base64,
1166
+ });
1167
+ }
1168
+ }
413
1169
  export class Program {
1170
+ /** @internal */
414
1171
  snapshotId;
1172
+ id;
415
1173
  project;
416
- client;
417
- sourceFileCache;
418
1174
  toPath;
419
1175
  decoder = new Wtf8Decoder();
420
1176
  sourceFileMetadataCache = new Map();
421
- constructor(snapshotId, project, client, sourceFileCache, toPath) {
1177
+ ownedSnapshot;
1178
+ disposePromise;
1179
+ get client() {
1180
+ return this.project.api.client;
1181
+ }
1182
+ get sourceFileCache() {
1183
+ return this.project.api.sourceFileCache;
1184
+ }
1185
+ constructor(snapshotId, project, toPath) {
422
1186
  this.snapshotId = snapshotId;
1187
+ this.id = project.id;
423
1188
  this.project = project;
424
- this.client = client;
425
- this.sourceFileCache = sourceFileCache;
426
1189
  this.toPath = toPath;
427
1190
  }
1191
+ getCurrentDirectory() {
1192
+ return this.project.currentDirectory;
1193
+ }
1194
+ getCanonicalFileName(fileName) {
1195
+ return this.project.api.getCanonicalFileName(fileName);
1196
+ }
1197
+ getNewLine() {
1198
+ return this.project.parsedCommandLine.options.newLine === NewLineKind.CRLF ? "\r\n" : "\n";
1199
+ }
1200
+ /** @internal */
1201
+ setOwnedSnapshot(snapshot) {
1202
+ this.ownedSnapshot = snapshot;
1203
+ }
1204
+ [globalThis.Symbol.asyncDispose]() {
1205
+ return this.dispose(); // @sync: this.dispose();
1206
+ }
1207
+ dispose() {
1208
+ return this.disposePromise ??= this.disposeWorker();
1209
+ }
1210
+ async disposeWorker() {
1211
+ const snapshot = this.ownedSnapshot;
1212
+ this.ownedSnapshot = undefined;
1213
+ if (snapshot)
1214
+ await snapshot.dispose();
1215
+ }
428
1216
  getCompilerOptions() {
429
- return this.project.compilerOptions;
1217
+ return this.project.parsedCommandLine.options;
430
1218
  }
431
1219
  async getSourceFile(file) {
432
1220
  const fileName = resolveFileName(file);
433
- const path = this.toPath(fileName);
1221
+ const path = this.pathKeyForFileName(fileName);
1222
+ return this.getSourceFileWorker(file, path);
1223
+ }
1224
+ /**
1225
+ * Returns the source file for an already-canonical path.
1226
+ */
1227
+ getSourceFileByPath(path) {
1228
+ // The wire format is a string, but the cache key remains the supplied
1229
+ // PathKey and is never treated as a RootedPath.
1230
+ return this.getSourceFileWorker(path, path);
1231
+ }
1232
+ async getSourceFileWorker(file, path) {
434
1233
  // Check if we already have a retained cache entry for this (snapshot, project) pair
435
1234
  const retained = this.sourceFileCache.getRetained(path, this.snapshotId, this.project.id);
436
1235
  if (retained) {
@@ -445,12 +1244,64 @@ export class Program {
445
1244
  if (!binaryData) {
446
1245
  return undefined;
447
1246
  }
448
- const view = new DataView(binaryData.buffer, binaryData.byteOffset, binaryData.byteLength);
449
- const contentHash = readSourceFileHash(view);
450
- const parseOptionsKey = readParseOptionsKey(view);
451
1247
  // Create a new RemoteSourceFile and cache it (set returns existing if hash matches)
452
- const sourceFile = new RemoteSourceFile(binaryData, this.decoder, this.client.getTimingCollector());
453
- return this.sourceFileCache.set(path, sourceFile, parseOptionsKey, contentHash, this.snapshotId, this.project.id);
1248
+ const decoded = new RemoteSourceFile(binaryData, this.decoder, this.client.getTimingCollector(), this.project.api);
1249
+ return this.sourceFileCache.set(decoded, this.snapshotId, this.project.id);
1250
+ }
1251
+ async getResolvedModule(file, moduleName, mode) {
1252
+ const result = await this.client.apiRequest("getResolvedModule", {
1253
+ snapshot: this.snapshotId,
1254
+ project: this.project.id,
1255
+ file,
1256
+ moduleName,
1257
+ mode,
1258
+ });
1259
+ return result ?? undefined;
1260
+ }
1261
+ async getModeForUsageLocation(file, usage) {
1262
+ return this.client.apiRequest("getModeForUsageLocation", {
1263
+ snapshot: this.snapshotId,
1264
+ project: this.project.id,
1265
+ file,
1266
+ usage: getNodeId(usage),
1267
+ });
1268
+ }
1269
+ async getModeForResolutionAtIndex(file, index) {
1270
+ return this.client.apiRequest("getModeForResolutionAtIndex", {
1271
+ snapshot: this.snapshotId,
1272
+ project: this.project.id,
1273
+ file,
1274
+ index,
1275
+ });
1276
+ }
1277
+ async getResolvedModuleFromModuleSpecifier(moduleSpecifier, sourceFile) {
1278
+ const result = await this.client.apiRequest("getResolvedModuleFromModuleSpecifier", {
1279
+ snapshot: this.snapshotId,
1280
+ project: this.project.id,
1281
+ moduleSpecifier: getNodeId(moduleSpecifier),
1282
+ sourceFile,
1283
+ });
1284
+ return result ?? undefined;
1285
+ }
1286
+ async getResolvedTypeReferenceDirective(file, typeDirectiveName, mode) {
1287
+ const result = await this.client.apiRequest("getResolvedTypeReferenceDirective", {
1288
+ snapshot: this.snapshotId,
1289
+ project: this.project.id,
1290
+ file,
1291
+ typeDirectiveName,
1292
+ mode,
1293
+ });
1294
+ return result ?? undefined;
1295
+ }
1296
+ async getResolvedTypeReferenceDirectiveFromTypeReferenceDirective(typeReferenceDirective, sourceFile) {
1297
+ const result = await this.client.apiRequest("getResolvedTypeReferenceDirectiveFromTypeReferenceDirective", {
1298
+ snapshot: this.snapshotId,
1299
+ project: this.project.id,
1300
+ sourceFile,
1301
+ typeDirectiveName: typeReferenceDirective.fileName,
1302
+ resolutionMode: typeReferenceDirective.resolutionMode,
1303
+ });
1304
+ return result ?? undefined;
454
1305
  }
455
1306
  async getSourceFileNames() {
456
1307
  const data = await this.client.apiRequest("getSourceFileNames", {
@@ -464,8 +1315,8 @@ export class Program {
464
1315
  * is not part of the program. Metadata is fetched lazily per file and cached on this
465
1316
  * `Program` instance.
466
1317
  */
467
- getSourceFileMetadata(fileName) {
468
- return this.getSourceFileMetadataByPath(this.toPath(fileName));
1318
+ getSourceFileMetadata(file) {
1319
+ return this.getSourceFileMetadataByPath(this.pathKeyForFileName(resolveFileName(file)));
469
1320
  }
470
1321
  /**
471
1322
  * Returns program-stored metadata for the source file at the given path, or `undefined`
@@ -482,6 +1333,8 @@ export class Program {
482
1333
  return metadata;
483
1334
  }
484
1335
  async fetchSourceFileMetadata(path) {
1336
+ // PathKey is serialized as a string; the server deliberately treats all
1337
+ // client-provided path text as untrusted input.
485
1338
  const data = await this.client.apiRequest("getSourceFileMetadata", {
486
1339
  snapshot: this.snapshotId,
487
1340
  project: this.project.id,
@@ -489,6 +1342,9 @@ export class Program {
489
1342
  });
490
1343
  return data ?? undefined;
491
1344
  }
1345
+ pathKeyForFileName(fileName) {
1346
+ return this.toPath(fileName, this.project.currentDirectory);
1347
+ }
492
1348
  /**
493
1349
  * Returns whether the given source file was loaded as part of an external library
494
1350
  * (e.g. a dependency resolved from `node_modules`). The underlying program metadata is
@@ -508,62 +1364,103 @@ export class Program {
508
1364
  return metadata?.isDefaultLibrary ?? false;
509
1365
  }
510
1366
  /**
511
- * Get syntactic (parse) diagnostics for a specific file or all files.
512
- * @param file - Optional file to get diagnostics for. If omitted, returns diagnostics for all files.
1367
+ * Get all config source file names associated with this program's project config.
1368
+ * Includes the root config file and any extended config files.
1369
+ */
1370
+ async getConfigFileNames() {
1371
+ const data = await this.client.apiRequest("getConfigFileNames", {
1372
+ snapshot: this.snapshotId,
1373
+ project: this.project.id,
1374
+ });
1375
+ return data ?? [];
1376
+ }
1377
+ /**
1378
+ * Get a config source file by file name/URI.
1379
+ * This can return the project's root tsconfig file or one of its extended config files.
1380
+ */
1381
+ async getConfigSourceFile(file) {
1382
+ const binaryData = await this.client.apiRequestBinary("getConfigSourceFile", {
1383
+ snapshot: this.snapshotId,
1384
+ project: this.project.id,
1385
+ file,
1386
+ });
1387
+ if (!binaryData) {
1388
+ return undefined;
1389
+ }
1390
+ return new RemoteSourceFile(binaryData, this.decoder, undefined, this.project.api);
1391
+ }
1392
+ /**
1393
+ * Get syntactic (parse) diagnostics for specific files or all files.
1394
+ * @param file - Optional file(s) to get diagnostics for. If omitted, returns diagnostics for all files.
513
1395
  */
514
1396
  async getSyntacticDiagnostics(file) {
1397
+ const files = file === undefined ? undefined
1398
+ : Array.isArray(file) ? file
1399
+ : [file];
515
1400
  const data = await this.client.apiRequest("getSyntacticDiagnostics", {
516
1401
  snapshot: this.snapshotId,
517
1402
  project: this.project.id,
518
- ...(file !== undefined ? { file } : {}),
1403
+ files,
519
1404
  });
520
1405
  return data ?? [];
521
1406
  }
522
1407
  /**
523
- * Get binder diagnostics for a specific file or all files.
524
- * @param file - Optional file to get diagnostics for. If omitted, returns diagnostics for all files.
1408
+ * Get binder diagnostics for specific files or all files.
1409
+ * @param file - Optional file(s) to get diagnostics for. If omitted, returns diagnostics for all files.
525
1410
  */
526
1411
  async getBindDiagnostics(file) {
1412
+ const files = file === undefined ? undefined
1413
+ : Array.isArray(file) ? file
1414
+ : [file];
527
1415
  const data = await this.client.apiRequest("getBindDiagnostics", {
528
1416
  snapshot: this.snapshotId,
529
1417
  project: this.project.id,
530
- ...(file !== undefined ? { file } : {}),
1418
+ files,
531
1419
  });
532
1420
  return data ?? [];
533
1421
  }
534
1422
  /**
535
- * Get semantic (type-check) diagnostics for a specific file or all files.
536
- * @param file - Optional file to get diagnostics for. If omitted, returns diagnostics for all files.
1423
+ * Get semantic (type-check) diagnostics for specific files or all files.
1424
+ * @param file - Optional file(s) to get diagnostics for. If omitted, returns diagnostics for all files.
537
1425
  */
538
1426
  async getSemanticDiagnostics(file) {
1427
+ const files = file === undefined ? undefined
1428
+ : Array.isArray(file) ? file
1429
+ : [file];
539
1430
  const data = await this.client.apiRequest("getSemanticDiagnostics", {
540
1431
  snapshot: this.snapshotId,
541
1432
  project: this.project.id,
542
- ...(file !== undefined ? { file } : {}),
1433
+ files,
543
1434
  });
544
1435
  return data ?? [];
545
1436
  }
546
1437
  /**
547
- * Get suggestion diagnostics for a specific file or all files.
548
- * @param file - Optional file to get diagnostics for. If omitted, returns diagnostics for all files.
1438
+ * Get suggestion diagnostics for specific files or all files.
1439
+ * @param file - Optional file(s) to get diagnostics for. If omitted, returns diagnostics for all files.
549
1440
  */
550
1441
  async getSuggestionDiagnostics(file) {
1442
+ const files = file === undefined ? undefined
1443
+ : Array.isArray(file) ? file
1444
+ : [file];
551
1445
  const data = await this.client.apiRequest("getSuggestionDiagnostics", {
552
1446
  snapshot: this.snapshotId,
553
1447
  project: this.project.id,
554
- ...(file !== undefined ? { file } : {}),
1448
+ files,
555
1449
  });
556
1450
  return data ?? [];
557
1451
  }
558
1452
  /**
559
- * Get declaration emit diagnostics for a specific file or all files.
560
- * @param file - Optional file to get diagnostics for. If omitted, returns diagnostics for all files.
1453
+ * Get declaration emit diagnostics for specific files or all files.
1454
+ * @param file - Optional file(s) to get diagnostics for. If omitted, returns diagnostics for all files.
561
1455
  */
562
1456
  async getDeclarationDiagnostics(file) {
1457
+ const files = file === undefined ? undefined
1458
+ : Array.isArray(file) ? file
1459
+ : [file];
563
1460
  const data = await this.client.apiRequest("getDeclarationDiagnostics", {
564
1461
  snapshot: this.snapshotId,
565
1462
  project: this.project.id,
566
- ...(file !== undefined ? { file } : {}),
1463
+ files,
567
1464
  });
568
1465
  return data ?? [];
569
1466
  }
@@ -597,22 +1494,206 @@ export class Program {
597
1494
  });
598
1495
  return data ?? [];
599
1496
  }
1497
+ /**
1498
+ * Emits files to the configured filesystem. Layer and host filesystems are
1499
+ * written through; full filesystems remain immutable and return emitted
1500
+ * files in {@link EmitResult.fileSystem}.
1501
+ */
1502
+ async emit(emitOnly) {
1503
+ const response = await this.client.apiRequest("emit", {
1504
+ snapshot: this.snapshotId,
1505
+ project: this.project.id,
1506
+ emitOnly,
1507
+ });
1508
+ const fileSystem = response.emittedFilesContents.length
1509
+ ? {
1510
+ kind: "layer",
1511
+ files: Object.fromEntries(response.emittedFiles.map((fileName, index) => [fileName, response.emittedFilesContents[index]])),
1512
+ }
1513
+ : undefined;
1514
+ return {
1515
+ emitSkipped: response.emitSkipped,
1516
+ diagnostics: response.diagnostics,
1517
+ emittedFiles: response.emittedFiles,
1518
+ fileSystem,
1519
+ };
1520
+ }
1521
+ /**
1522
+ * Emits files and returns their contents without writing to the filesystem.
1523
+ */
1524
+ async emitToString(emitOnly) {
1525
+ const response = await this.client.apiRequest("emitToString", {
1526
+ snapshot: this.snapshotId,
1527
+ project: this.project.id,
1528
+ emitOnly,
1529
+ });
1530
+ return toEmitOutput(response);
1531
+ }
1532
+ /**
1533
+ * Gets JavaScript output for selected files regardless of project `noEmit`, `emitDeclarationOnly`, and `noEmitOnError` settings.
1534
+ */
1535
+ async getJavaScriptEmit(files) {
1536
+ const response = await this.client.apiRequest("getJavaScriptEmit", {
1537
+ snapshot: this.snapshotId,
1538
+ project: this.project.id,
1539
+ files,
1540
+ });
1541
+ return toEmitOutput(response);
1542
+ }
1543
+ /**
1544
+ * Gets declaration output for selected files regardless of project `noEmit`, `declaration`, `emitDeclarationOnly`, and `noEmitOnError` settings.
1545
+ */
1546
+ async getDeclarationEmit(files) {
1547
+ const response = await this.client.apiRequest("getDeclarationEmit", {
1548
+ snapshot: this.snapshotId,
1549
+ project: this.project.id,
1550
+ files,
1551
+ });
1552
+ return toEmitOutput(response);
1553
+ }
1554
+ getProject() {
1555
+ return this.project;
1556
+ }
1557
+ }
1558
+ export class BuildOrchestrator {
1559
+ client;
1560
+ id;
1561
+ disposed = false;
1562
+ disposePromise;
1563
+ onDispose;
1564
+ constructor(client, orchestratorResponse, onDispose) {
1565
+ this.client = client;
1566
+ this.id = orchestratorResponse.buildOrchestratorID;
1567
+ this.onDispose = onDispose;
1568
+ }
1569
+ [globalThis.Symbol.asyncDispose]() {
1570
+ return this.dispose(); // @sync: this.dispose();
1571
+ }
1572
+ dispose() {
1573
+ return this.disposePromise ??= this.disposeWorker();
1574
+ }
1575
+ async disposeWorker() {
1576
+ if (this.disposed)
1577
+ return;
1578
+ this.disposed = true;
1579
+ try {
1580
+ await this.client.apiRequest("disposeBuildOrchestrator", {
1581
+ buildOrchestratorID: this.id,
1582
+ });
1583
+ }
1584
+ finally {
1585
+ this.onDispose();
1586
+ }
1587
+ }
1588
+ async build(project) {
1589
+ this.ensureNotDisposed();
1590
+ const response = await this.client.apiRequest("build", {
1591
+ buildOrchestratorID: this.id,
1592
+ ...(project !== undefined ? { project } : {}),
1593
+ });
1594
+ return response;
1595
+ }
1596
+ async buildReferences(project) {
1597
+ this.ensureNotDisposed();
1598
+ const response = await this.client.apiRequest("buildReferences", {
1599
+ buildOrchestratorID: this.id,
1600
+ project,
1601
+ });
1602
+ return response;
1603
+ }
1604
+ async clean(project) {
1605
+ this.ensureNotDisposed();
1606
+ const response = await this.client.apiRequest("cleanBuild", {
1607
+ buildOrchestratorID: this.id,
1608
+ ...(project !== undefined ? { project } : {}),
1609
+ });
1610
+ return response;
1611
+ }
1612
+ async cleanReferences(project) {
1613
+ this.ensureNotDisposed();
1614
+ const response = await this.client.apiRequest("cleanReferences", {
1615
+ buildOrchestratorID: this.id,
1616
+ ...(project !== undefined ? { project } : {}),
1617
+ });
1618
+ return response;
1619
+ }
1620
+ isDisposed() {
1621
+ return this.disposed;
1622
+ }
1623
+ ensureNotDisposed() {
1624
+ if (this.disposed) {
1625
+ throw new Error("Build orchestrator is disposed");
1626
+ }
1627
+ }
1628
+ }
1629
+ function toEmitOutput(response) {
1630
+ const outputFiles = new Map();
1631
+ for (const { fileName, ...outputFile } of response.outputFiles) {
1632
+ outputFiles.set(fileName, outputFile);
1633
+ }
1634
+ return {
1635
+ emitSkipped: response.emitSkipped,
1636
+ diagnostics: response.diagnostics,
1637
+ outputFiles,
1638
+ };
600
1639
  }
601
1640
  export class Checker {
602
1641
  snapshotId;
603
1642
  project;
604
- client;
605
1643
  objectRegistry;
606
1644
  wellKnownSymbols;
607
- constructor(snapshotId, project, client, objectRegistry) {
1645
+ wellKnownSignatures;
1646
+ get client() {
1647
+ return this.project.api.client;
1648
+ }
1649
+ constructor(snapshotId, project, objectRegistry) {
608
1650
  this.snapshotId = snapshotId;
609
1651
  this.project = project;
610
- this.client = client;
611
1652
  this.objectRegistry = objectRegistry;
612
1653
  }
613
1654
  dispose() {
614
1655
  this.objectRegistry.clear();
615
1656
  }
1657
+ /** Get the merged symbol, or the original symbol if it has not been merged. */
1658
+ async getMergedSymbol(symbol) {
1659
+ const data = await this.client.apiRequest("getMergedSymbol", {
1660
+ snapshot: this.snapshotId,
1661
+ project: this.project.id,
1662
+ symbol: symbol.reference,
1663
+ });
1664
+ return this.objectRegistry.getOrCreateSymbol(data);
1665
+ }
1666
+ /**
1667
+ * Get a node's merged symbol. For a declaration, prefer
1668
+ * {@link Checker.getSymbolOfDeclaration} for a non-nullable result.
1669
+ */
1670
+ async getSymbolOfNode(node) {
1671
+ const data = await this.client.apiRequest("getSymbolOfNode", {
1672
+ snapshot: this.snapshotId,
1673
+ project: this.project.id,
1674
+ location: getNodeId(node),
1675
+ });
1676
+ return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
1677
+ }
1678
+ /** Get a declaration's merged symbol. */
1679
+ async getSymbolOfDeclaration(node) {
1680
+ const data = await this.client.apiRequest("getSymbolOfDeclarationForChecker", {
1681
+ snapshot: this.snapshotId,
1682
+ project: this.project.id,
1683
+ location: getNodeId(node),
1684
+ });
1685
+ // Declarations normally have symbols, but preserve unexpected null results at runtime.
1686
+ return (data && this.objectRegistry.getOrCreateSymbol(data));
1687
+ }
1688
+ /** Get a symbol's merged parent, if any. */
1689
+ async getParentOfSymbol(symbol) {
1690
+ const data = await this.client.apiRequest("getParentOfSymbolForChecker", {
1691
+ snapshot: this.snapshotId,
1692
+ project: this.project.id,
1693
+ symbol: symbol.reference,
1694
+ });
1695
+ return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
1696
+ }
616
1697
  async getSymbolAtLocation(nodeOrNodes) {
617
1698
  if (Array.isArray(nodeOrNodes)) {
618
1699
  const data = await this.client.apiRequest("getSymbolsAtLocations", {
@@ -647,21 +1728,37 @@ export class Checker {
647
1728
  });
648
1729
  return data.map(d => d ? this.objectRegistry.getOrCreateSymbol(d) : undefined);
649
1730
  }
1731
+ async getSymbolOfSourceFile(fileOrFiles) {
1732
+ if (Array.isArray(fileOrFiles)) {
1733
+ const data = await this.client.apiRequest("getSymbolsOfSourceFiles", {
1734
+ snapshot: this.snapshotId,
1735
+ project: this.project.id,
1736
+ files: fileOrFiles,
1737
+ });
1738
+ return data.map(d => d ? this.objectRegistry.getOrCreateSymbol(d) : undefined);
1739
+ }
1740
+ const data = await this.client.apiRequest("getSymbolOfSourceFile", {
1741
+ snapshot: this.snapshotId,
1742
+ project: this.project.id,
1743
+ file: fileOrFiles,
1744
+ });
1745
+ return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
1746
+ }
650
1747
  async getTypeOfSymbol(symbolOrSymbols) {
651
1748
  if (Array.isArray(symbolOrSymbols)) {
652
1749
  const data = await this.client.apiRequest("getTypesOfSymbols", {
653
1750
  snapshot: this.snapshotId,
654
1751
  project: this.project.id,
655
- symbols: symbolOrSymbols.map(s => s.id),
1752
+ symbols: symbolOrSymbols.map(symbol => symbol.reference),
656
1753
  });
657
- return data.map(d => d ? this.objectRegistry.getOrCreateType(d) : undefined);
1754
+ return data.map(d => this.objectRegistry.getOrCreateType(d));
658
1755
  }
659
1756
  const data = await this.client.apiRequest("getTypeOfSymbol", {
660
1757
  snapshot: this.snapshotId,
661
1758
  project: this.project.id,
662
- symbol: symbolOrSymbols.id,
1759
+ symbol: symbolOrSymbols.reference,
663
1760
  });
664
- return data ? this.objectRegistry.getOrCreateType(data) : undefined;
1761
+ return this.objectRegistry.getOrCreateType(data);
665
1762
  }
666
1763
  /**
667
1764
  * Get the declared type of a symbol. Always returns a type; for symbols whose
@@ -672,63 +1769,32 @@ export class Checker {
672
1769
  const data = await this.client.apiRequest("getDeclaredTypeOfSymbol", {
673
1770
  snapshot: this.snapshotId,
674
1771
  project: this.project.id,
675
- symbol: symbol.id,
1772
+ symbol: symbol.reference,
676
1773
  });
677
- if (!data)
678
- throw new Error(`getDeclaredTypeOfSymbol returned no type for symbol ${symbol.id}`);
679
1774
  return this.objectRegistry.getOrCreateType(data);
680
1775
  }
681
- async getReferencesToSymbolInFile(file, symbol) {
682
- const data = await this.client.apiRequest("getReferencesToSymbolInFile", {
683
- snapshot: this.snapshotId,
684
- project: this.project.id,
685
- file,
686
- symbol: symbol.id,
687
- });
688
- return (data ?? []).map(h => new NodeHandle(h, this.project));
689
- }
690
- async getReferencedSymbolsForNode(node, position) {
691
- const data = await this.client.apiRequest("getReferencedSymbolsForNode", {
692
- snapshot: this.snapshotId,
693
- project: this.project.id,
694
- node: getNodeId(node),
695
- position,
696
- });
697
- return (data ?? []).map(entry => ({
698
- definition: new NodeHandle(entry.definition, this.project),
699
- symbol: entry.symbol ? this.objectRegistry.getOrCreateSymbol(entry.symbol) : undefined,
700
- references: (entry.references ?? []).map(h => new NodeHandle(h, this.project)),
701
- }));
702
- }
703
- async getSignatureUsage(signatureDecl) {
704
- const data = await this.client.apiRequest("getSignatureUsages", {
1776
+ /**
1777
+ * Get the type of a symbol, excluding the missing type when
1778
+ * `exactOptionalPropertyTypes: true` is set; for symbols whose
1779
+ * type cannot be determined the checker yields the error type
1780
+ * (use {@link Type.isErrorType} to detect it).
1781
+ */
1782
+ async getNonMissingTypeOfSymbol(symbol) {
1783
+ const data = await this.client.apiRequest("getNonMissingTypeOfSymbol", {
705
1784
  snapshot: this.snapshotId,
706
1785
  project: this.project.id,
707
- signatureDecl: getNodeId(signatureDecl),
1786
+ symbol: symbol.reference,
708
1787
  });
709
- return (data ?? []).map(entry => ({
710
- name: new NodeHandle(entry.name, this.project),
711
- call: entry.call ? new NodeHandle(entry.call, this.project) : undefined,
712
- }));
1788
+ return this.objectRegistry.getOrCreateType(data);
713
1789
  }
714
- async getCompletionsAtPosition(document, position, options) {
715
- const data = await this.client.apiRequest("getCompletionsAtPosition", {
1790
+ async getReferencesToSymbolInFile(file, symbol) {
1791
+ const data = await this.client.apiRequest("getReferencesToSymbolInFile", {
716
1792
  snapshot: this.snapshotId,
717
1793
  project: this.project.id,
718
- file: document,
719
- position,
720
- triggerCharacter: options?.triggerCharacter,
721
- includeSymbol: options?.includeSymbol,
1794
+ file,
1795
+ symbol: symbol.reference,
722
1796
  });
723
- if (!data)
724
- return undefined;
725
- return {
726
- isIncomplete: data.isIncomplete,
727
- entries: data.entries.map(e => ({
728
- ...e,
729
- symbol: e.symbol ? this.objectRegistry.getOrCreateSymbol(e.symbol) : undefined,
730
- })),
731
- };
1797
+ return (data ?? []).map(h => new NodeHandle(h, this.project));
732
1798
  }
733
1799
  async getTypeAtLocation(nodeOrNodes) {
734
1800
  if (Array.isArray(nodeOrNodes)) {
@@ -737,31 +1803,30 @@ export class Checker {
737
1803
  project: this.project.id,
738
1804
  locations: nodeOrNodes.map(node => getNodeId(node)),
739
1805
  });
740
- return data.map(d => d ? this.objectRegistry.getOrCreateType(d) : undefined);
1806
+ return data.map(d => this.objectRegistry.getOrCreateType(d));
741
1807
  }
742
1808
  const data = await this.client.apiRequest("getTypeAtLocation", {
743
1809
  snapshot: this.snapshotId,
744
1810
  project: this.project.id,
745
1811
  location: getNodeId(nodeOrNodes),
746
1812
  });
747
- return data ? this.objectRegistry.getOrCreateType(data) : undefined;
1813
+ return this.objectRegistry.getOrCreateType(data);
748
1814
  }
749
1815
  async getSignaturesOfType(type, kind) {
750
- const data = await this.client.apiRequest("getSignaturesOfType", {
751
- snapshot: this.snapshotId,
752
- project: this.project.id,
753
- type: type.id,
754
- kind,
755
- });
756
- return data.map(d => this.objectRegistry.getOrCreateSignature(d));
1816
+ return kind === SignatureKind.Call ? type.getCallSignatures() : type.getConstructSignatures();
757
1817
  }
1818
+ /**
1819
+ * Get the resolved signature of a call-like expression. Always returns a
1820
+ * signature; when a call cannot be resolved the checker yields the unknown
1821
+ * signature (use {@link Checker.isUnknownSignature} to detect it).
1822
+ */
758
1823
  async getResolvedSignature(node) {
759
1824
  const data = await this.client.apiRequest("getResolvedSignature", {
760
1825
  snapshot: this.snapshotId,
761
1826
  project: this.project.id,
762
1827
  location: getNodeId(node),
763
1828
  });
764
- return data ? this.objectRegistry.getOrCreateSignature(data) : undefined;
1829
+ return this.objectRegistry.getOrCreateSignature(data);
765
1830
  }
766
1831
  async getTypeAtPosition(file, positionOrPositions) {
767
1832
  if (typeof positionOrPositions === "number") {
@@ -796,6 +1861,22 @@ export class Checker {
796
1861
  });
797
1862
  return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
798
1863
  }
1864
+ /**
1865
+ * Returns all symbols with the given meaning that are visible at `location`.
1866
+ */
1867
+ async getSymbolsInScope(location, meaning) {
1868
+ // Distinguish Node (has `kind`) from DocumentPosition (has `document` and `position`)
1869
+ const isNode = "kind" in location;
1870
+ const data = await this.client.apiRequest("getSymbolsInScope", {
1871
+ snapshot: this.snapshotId,
1872
+ project: this.project.id,
1873
+ meaning,
1874
+ location: isNode ? getNodeId(location) : undefined,
1875
+ file: isNode ? undefined : location.document,
1876
+ position: isNode ? undefined : location.position,
1877
+ });
1878
+ return data ? data.map(d => this.objectRegistry.getOrCreateSymbol(d)) : [];
1879
+ }
799
1880
  async getResolvedSymbol(node) {
800
1881
  const text = node.text;
801
1882
  if (!text)
@@ -810,38 +1891,62 @@ export class Checker {
810
1891
  });
811
1892
  return data ? this.objectRegistry.getOrCreateType(data) : undefined;
812
1893
  }
813
- async getBaseTypeOfLiteralType(type) {
814
- const data = await this.client.apiRequest("getBaseTypeOfLiteralType", {
1894
+ async getContextualTypeForArgumentAtIndex(node, argIndex) {
1895
+ const data = await this.client.apiRequest("getContextualTypeForArgument", {
815
1896
  snapshot: this.snapshotId,
816
1897
  project: this.project.id,
817
- type: type.id,
1898
+ location: getNodeId(node),
1899
+ index: argIndex,
818
1900
  });
819
1901
  return data ? this.objectRegistry.getOrCreateType(data) : undefined;
820
1902
  }
821
- async getNonNullableType(type) {
822
- const data = await this.client.apiRequest("getNonNullableType", {
1903
+ async getAwaitedType(type) {
1904
+ const data = await this.client.apiRequest("getAwaitedType", {
823
1905
  snapshot: this.snapshotId,
824
1906
  project: this.project.id,
825
1907
  type: type.id,
826
1908
  });
827
1909
  return data ? this.objectRegistry.getOrCreateType(data) : undefined;
828
1910
  }
1911
+ /** Get the base type of a literal type (e.g. `number` for `42`). Always returns a type. */
1912
+ async getBaseTypeOfLiteralType(type) {
1913
+ const data = await this.client.apiRequest("getBaseTypeOfLiteralType", {
1914
+ snapshot: this.snapshotId,
1915
+ project: this.project.id,
1916
+ type: type.id,
1917
+ });
1918
+ return this.objectRegistry.getOrCreateType(data);
1919
+ }
1920
+ /** Get the type with `null` and `undefined` removed. Always returns a type. */
1921
+ async getNonNullableType(type) {
1922
+ return type.getNonNullableType();
1923
+ }
1924
+ /**
1925
+ * Get the type for a type node. Always returns a type; for type nodes whose
1926
+ * type cannot be determined the checker yields the error type (use
1927
+ * {@link Type.isErrorType} to detect it).
1928
+ */
829
1929
  async getTypeFromTypeNode(node) {
830
1930
  const data = await this.client.apiRequest("getTypeFromTypeNode", {
831
1931
  snapshot: this.snapshotId,
832
1932
  project: this.project.id,
833
1933
  location: getNodeId(node),
834
1934
  });
835
- return data ? this.objectRegistry.getOrCreateType(data) : undefined;
1935
+ return this.objectRegistry.getOrCreateType(data);
836
1936
  }
1937
+ /** Get the widened type. Always returns a type. */
837
1938
  async getWidenedType(type) {
838
1939
  const data = await this.client.apiRequest("getWidenedType", {
839
1940
  snapshot: this.snapshotId,
840
1941
  project: this.project.id,
841
1942
  type: type.id,
842
1943
  });
843
- return data ? this.objectRegistry.getOrCreateType(data) : undefined;
1944
+ return this.objectRegistry.getOrCreateType(data);
844
1945
  }
1946
+ /**
1947
+ * Get the type of the parameter at the given index in a signature. Always
1948
+ * returns a type; an out-of-range index yields the `any` type.
1949
+ */
845
1950
  async getParameterType(signature, index) {
846
1951
  const data = await this.client.apiRequest("getParameterType", {
847
1952
  snapshot: this.snapshotId,
@@ -849,7 +1954,7 @@ export class Checker {
849
1954
  signature: signature.id,
850
1955
  index,
851
1956
  });
852
- return data ? this.objectRegistry.getOrCreateType(data) : undefined;
1957
+ return this.objectRegistry.getOrCreateType(data);
853
1958
  }
854
1959
  async isArrayLikeType(type) {
855
1960
  return this.client.apiRequest("isArrayLikeType", {
@@ -883,11 +1988,9 @@ export class Checker {
883
1988
  const data = await this.client.apiRequest("getTypeOfSymbolAtLocation", {
884
1989
  snapshot: this.snapshotId,
885
1990
  project: this.project.id,
886
- symbol: symbol.id,
1991
+ symbol: symbol.reference,
887
1992
  location: getNodeId(location),
888
1993
  });
889
- if (!data)
890
- throw new Error(`getTypeOfSymbolAtLocation returned no type for symbol ${symbol.id}`);
891
1994
  return this.objectRegistry.getOrCreateType(data);
892
1995
  }
893
1996
  async getIntrinsicType(method) {
@@ -930,6 +2033,9 @@ export class Checker {
930
2033
  async getESSymbolType() {
931
2034
  return this.getIntrinsicType("getESSymbolType");
932
2035
  }
2036
+ async getNonPrimitiveType() {
2037
+ return this.getIntrinsicType("getNonPrimitiveType");
2038
+ }
933
2039
  async typeToTypeNode(type, enclosingDeclaration, flags) {
934
2040
  const binaryData = await this.client.apiRequestBinary("typeToTypeNode", {
935
2041
  snapshot: this.snapshotId,
@@ -956,13 +2062,16 @@ export class Checker {
956
2062
  return decodeNode(binaryData);
957
2063
  }
958
2064
  async typeToString(type, enclosingDeclaration, flags) {
959
- return this.client.apiRequest("typeToString", {
2065
+ const result = await this.client.apiRequest("typeToString", {
960
2066
  snapshot: this.snapshotId,
961
2067
  project: this.project.id,
962
2068
  type: type.id,
963
2069
  location: enclosingDeclaration ? getNodeId(enclosingDeclaration) : undefined,
964
2070
  flags,
965
2071
  });
2072
+ if (typeof result !== "string")
2073
+ throw new TypeError("typeToString returned a non-string result");
2074
+ return result;
966
2075
  }
967
2076
  async isContextSensitive(node) {
968
2077
  return this.client.apiRequest("isContextSensitive", {
@@ -979,27 +2088,42 @@ export class Checker {
979
2088
  });
980
2089
  }
981
2090
  async isTupleType(type) {
982
- return this.client.apiRequest("isTupleType", {
2091
+ return type.isTupleType();
2092
+ }
2093
+ async isTupleTypeTarget(type) {
2094
+ return type.isTupleTypeTarget();
2095
+ }
2096
+ /**
2097
+ * The following symbols are considered read-only:
2098
+ * - Properties with a `readonly` modifier
2099
+ * - Variables declared with `const`
2100
+ * - Get accessors without matching set accessors
2101
+ * - Enum members
2102
+ * - `Object.defineProperty` assignments with `writable: false` or no setter
2103
+ * - Unions and intersections of the above
2104
+ */
2105
+ async isReadonlySymbol(symbol) {
2106
+ return this.client.apiRequest("isReadonlySymbol", {
983
2107
  snapshot: this.snapshotId,
984
2108
  project: this.project.id,
985
- type: type.id,
2109
+ symbol: symbol.reference,
986
2110
  });
987
2111
  }
2112
+ /** Get the return type of a signature. Always returns a type. */
988
2113
  async getReturnTypeOfSignature(signature) {
989
- const data = await this.client.apiRequest("getReturnTypeOfSignature", {
990
- snapshot: this.snapshotId,
991
- project: this.project.id,
992
- signature: signature.id,
993
- });
994
- return data ? this.objectRegistry.getOrCreateType(data) : undefined;
2114
+ return signature.getReturnType();
995
2115
  }
2116
+ /**
2117
+ * Get the rest type of a signature. Always returns a type; a signature with
2118
+ * no rest parameter yields the `any` type.
2119
+ */
996
2120
  async getRestTypeOfSignature(signature) {
997
2121
  const data = await this.client.apiRequest("getRestTypeOfSignature", {
998
2122
  snapshot: this.snapshotId,
999
2123
  project: this.project.id,
1000
2124
  signature: signature.id,
1001
2125
  });
1002
- return data ? this.objectRegistry.getOrCreateType(data) : undefined;
2126
+ return this.objectRegistry.getOrCreateType(data);
1003
2127
  }
1004
2128
  async getTypePredicateOfSignature(signature) {
1005
2129
  const data = await this.client.apiRequest("getTypePredicateOfSignature", {
@@ -1021,55 +2145,57 @@ export class Checker {
1021
2145
  * yields an empty array.
1022
2146
  */
1023
2147
  async getBaseTypes(type) {
1024
- const data = await this.client.apiRequest("getBaseTypes", {
1025
- snapshot: this.snapshotId,
1026
- project: this.project.id,
1027
- type: type.id,
1028
- });
1029
- return data ? data.map(d => this.objectRegistry.getOrCreateType(d)) : [];
2148
+ return await type.getBaseTypes() ?? [];
1030
2149
  }
2150
+ /** Get the apparent type of a type. Always returns a type. */
1031
2151
  async getApparentType(type) {
1032
- const data = await this.client.apiRequest("getApparentType", {
1033
- snapshot: this.snapshotId,
1034
- project: this.project.id,
1035
- type: type.id,
1036
- });
1037
- return data ? this.objectRegistry.getOrCreateType(data) : undefined;
2152
+ return type.getApparentType();
2153
+ }
2154
+ /** Get the reduced type of a type. Always returns a type. */
2155
+ async getReducedType(type) {
2156
+ return type.getReducedType();
1038
2157
  }
1039
2158
  async getPropertiesOfType(type) {
1040
- const data = await this.client.apiRequest("getPropertiesOfType", {
2159
+ return type.getProperties();
2160
+ }
2161
+ async getIndexInfosOfType(type) {
2162
+ return type.getIndexInfos();
2163
+ }
2164
+ async getIndexInfoOfType(type, kind) {
2165
+ const data = await this.client.apiRequest("getIndexInfoOfType", {
1041
2166
  snapshot: this.snapshotId,
1042
2167
  project: this.project.id,
1043
2168
  type: type.id,
2169
+ kind,
1044
2170
  });
1045
- return data ? data.map(d => this.objectRegistry.getOrCreateSymbol(d)) : [];
2171
+ return data ? {
2172
+ keyType: this.objectRegistry.getOrCreateType(data.keyType),
2173
+ valueType: this.objectRegistry.getOrCreateType(data.valueType),
2174
+ isReadonly: data.isReadonly ?? false,
2175
+ declaration: data.declaration ? new NodeHandle(data.declaration, this.project) : undefined,
2176
+ } : undefined;
1046
2177
  }
1047
- async getIndexInfosOfType(type) {
1048
- const data = await this.client.apiRequest("getIndexInfosOfType", {
2178
+ async getIndexTypeOfType(type, kind) {
2179
+ return kind === IndexKind.String ? type.getStringIndexType() : type.getNumberIndexType();
2180
+ }
2181
+ async getTypeOfPropertyOfType(type, propertyName) {
2182
+ const data = await this.client.apiRequest("getTypeOfPropertyOfType", {
1049
2183
  snapshot: this.snapshotId,
1050
2184
  project: this.project.id,
1051
2185
  type: type.id,
2186
+ name: propertyName,
1052
2187
  });
1053
- if (!data)
1054
- return [];
1055
- return data.map(d => ({
1056
- keyType: this.objectRegistry.getOrCreateType(d.keyType),
1057
- valueType: this.objectRegistry.getOrCreateType(d.valueType),
1058
- isReadonly: d.isReadonly ?? false,
1059
- declaration: d.declaration ? new NodeHandle(d.declaration, this.project) : undefined,
1060
- }));
2188
+ return data ? this.objectRegistry.getOrCreateType(data) : undefined;
1061
2189
  }
1062
2190
  /**
1063
2191
  * Get the constraint of a type parameter (the `T` in `<U extends T>`), or
1064
2192
  * undefined if it has none.
1065
2193
  */
1066
2194
  async getConstraintOfTypeParameter(type) {
1067
- const data = await this.client.apiRequest("getConstraintOfTypeParameter", {
1068
- snapshot: this.snapshotId,
1069
- project: this.project.id,
1070
- type: type.id,
1071
- });
1072
- return data ? this.objectRegistry.getOrCreateType(data) : undefined;
2195
+ return type.getConstraint();
2196
+ }
2197
+ async getDefaultFromTypeParameter(type) {
2198
+ return type.getDefault();
1073
2199
  }
1074
2200
  async getBaseConstraintOfType(type) {
1075
2201
  const data = await this.client.apiRequest("getBaseConstraintOfType", {
@@ -1094,15 +2220,28 @@ export class Checker {
1094
2220
  project: this.project.id,
1095
2221
  location: getNodeId(node),
1096
2222
  });
1097
- return data ?? undefined;
2223
+ if (!data || (typeof data.value !== "string" && typeof data.value !== "number")) {
2224
+ return undefined;
2225
+ }
2226
+ if (data.isNumber && typeof data.value === "string") {
2227
+ if (data.value === "+Infinity") {
2228
+ return Infinity;
2229
+ }
2230
+ else if (data.value === "-Infinity") {
2231
+ return -Infinity;
2232
+ }
2233
+ return NaN;
2234
+ }
2235
+ return data.value;
1098
2236
  }
2237
+ /** Get the signature of a function-like declaration. Always returns a signature. */
1099
2238
  async getSignatureFromDeclaration(node) {
1100
2239
  const data = await this.client.apiRequest("getSignatureFromDeclaration", {
1101
2240
  snapshot: this.snapshotId,
1102
2241
  project: this.project.id,
1103
2242
  location: getNodeId(node),
1104
2243
  });
1105
- return data ? this.objectRegistry.getOrCreateSignature(data) : undefined;
2244
+ return this.objectRegistry.getOrCreateSignature(data);
1106
2245
  }
1107
2246
  async getExportSpecifierLocalTargetSymbol(node) {
1108
2247
  const data = await this.client.apiRequest("getExportSpecifierLocalTargetSymbol", {
@@ -1121,20 +2260,51 @@ export class Checker {
1121
2260
  const data = await this.client.apiRequest("getAliasedSymbol", {
1122
2261
  snapshot: this.snapshotId,
1123
2262
  project: this.project.id,
1124
- symbol: symbol.id,
2263
+ symbol: symbol.reference,
1125
2264
  });
1126
- if (!data)
1127
- throw new Error(`getAliasedSymbol returned no symbol for symbol ${symbol.id}`);
1128
2265
  return this.objectRegistry.getOrCreateSymbol(data);
1129
2266
  }
2267
+ /**
2268
+ * Get the fully qualified name of a symbol, walking up its parent chain
2269
+ * (e.g. `"/path/to/module".Namespace.Name`).
2270
+ */
2271
+ async getFullyQualifiedName(symbol) {
2272
+ return this.client.apiRequest("getFullyQualifiedName", {
2273
+ snapshot: this.snapshotId,
2274
+ project: this.project.id,
2275
+ symbol: symbol.reference,
2276
+ });
2277
+ }
1130
2278
  async getImmediateAliasedSymbol(symbol) {
1131
2279
  const data = await this.client.apiRequest("getImmediateAliasedSymbol", {
1132
2280
  snapshot: this.snapshotId,
1133
2281
  project: this.project.id,
1134
- symbol: symbol.id,
2282
+ symbol: symbol.reference,
1135
2283
  });
1136
2284
  return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
1137
2285
  }
2286
+ /**
2287
+ * Get the target symbol if instantiated, or the provided symbol otherwise.
2288
+ */
2289
+ async getTargetSymbol(symbol) {
2290
+ if (symbol.checkFlags & CheckFlags.Instantiated) {
2291
+ const data = await this.client.apiRequest("getTargetSymbol", {
2292
+ snapshot: this.snapshotId,
2293
+ project: this.project.id,
2294
+ symbol: symbol.reference,
2295
+ });
2296
+ return this.objectRegistry.getOrCreateSymbol(data);
2297
+ }
2298
+ return symbol;
2299
+ }
2300
+ async getExportSymbolOfSymbol(symbol) {
2301
+ const data = await this.client.apiRequest("getExportSymbolOfSymbolForChecker", {
2302
+ snapshot: this.snapshotId,
2303
+ project: this.project.id,
2304
+ symbol: symbol.reference,
2305
+ });
2306
+ return this.objectRegistry.getOrCreateSymbol(data);
2307
+ }
1138
2308
  /**
1139
2309
  * Fetch (once, then cache) the handle ids of the per-checker singleton
1140
2310
  * symbols (unknown, undefined, arguments). These ids are stable for the life
@@ -1166,11 +2336,30 @@ export class Checker {
1166
2336
  async isArgumentsSymbol(symbol) {
1167
2337
  return symbol.id === (await this.getWellKnownSymbols()).arguments;
1168
2338
  }
2339
+ /**
2340
+ * Fetch (once, then cache) the handle id of the per-checker unknown
2341
+ * signature. This id is stable for the life of the project's checker, so
2342
+ * identity checks against it are local after the first call.
2343
+ */
2344
+ getWellKnownSignatures() {
2345
+ return this.wellKnownSignatures ??= this.client.apiRequest("getWellKnownSignatures", {
2346
+ snapshot: this.snapshotId,
2347
+ project: this.project.id,
2348
+ });
2349
+ }
2350
+ /**
2351
+ * Returns `true` if the signature is the checker's "unknown" signature (e.g.
2352
+ * the result of {@link Checker.getResolvedSignature} on a call that cannot be
2353
+ * resolved).
2354
+ */
2355
+ async isUnknownSignature(signature) {
2356
+ return signature.id === (await this.getWellKnownSignatures()).unknown;
2357
+ }
1169
2358
  async getExportsOfModule(symbol) {
1170
2359
  const data = await this.client.apiRequest("getExportsOfModule", {
1171
2360
  snapshot: this.snapshotId,
1172
2361
  project: this.project.id,
1173
- symbol: symbol.id,
2362
+ symbol: symbol.reference,
1174
2363
  });
1175
2364
  return data ? data.map(d => this.objectRegistry.getOrCreateSymbol(d)) : [];
1176
2365
  }
@@ -1178,7 +2367,7 @@ export class Checker {
1178
2367
  const data = await this.client.apiRequest("getMemberInModuleExports", {
1179
2368
  snapshot: this.snapshotId,
1180
2369
  project: this.project.id,
1181
- symbol: symbol.id,
2370
+ symbol: symbol.reference,
1182
2371
  name,
1183
2372
  });
1184
2373
  return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
@@ -1187,7 +2376,7 @@ export class Checker {
1187
2376
  const data = await this.client.apiRequest("getJsDocTags", {
1188
2377
  snapshot: this.snapshotId,
1189
2378
  project: this.project.id,
1190
- symbol: symbol.id,
2379
+ symbol: symbol.reference,
1191
2380
  });
1192
2381
  return data ?? [];
1193
2382
  }
@@ -1195,7 +2384,7 @@ export class Checker {
1195
2384
  return this.client.apiRequest("getDocumentationComment", {
1196
2385
  snapshot: this.snapshotId,
1197
2386
  project: this.project.id,
1198
- symbol: symbol.id,
2387
+ symbol: symbol.reference,
1199
2388
  });
1200
2389
  }
1201
2390
  /**
@@ -1210,7 +2399,7 @@ export class Checker {
1210
2399
  return data ? data.map(d => this.objectRegistry.getOrCreateType(d)) : [];
1211
2400
  }
1212
2401
  }
1213
- export class Emitter {
2402
+ export class Printer {
1214
2403
  client;
1215
2404
  constructor(client) {
1216
2405
  this.client = client;
@@ -1220,7 +2409,19 @@ export class Emitter {
1220
2409
  const base64 = uint8ArrayToBase64(encoded);
1221
2410
  return this.client.apiRequest("printNode", {
1222
2411
  data: base64,
1223
- ...options,
2412
+ preserveSourceNewlines: options.preserveSourceNewlines,
2413
+ neverAsciiEscape: options.neverAsciiEscape,
2414
+ terminateUnterminatedLiterals: options.terminateUnterminatedLiterals,
2415
+ });
2416
+ }
2417
+ async printFile(sourceFile, options = {}) {
2418
+ const encoded = encodeNode(sourceFile);
2419
+ const base64 = uint8ArrayToBase64(encoded);
2420
+ return this.client.apiRequest("printNode", {
2421
+ data: base64,
2422
+ preserveSourceNewlines: options.preserveSourceNewlines,
2423
+ neverAsciiEscape: options.neverAsciiEscape,
2424
+ terminateUnterminatedLiterals: options.terminateUnterminatedLiterals,
1224
2425
  });
1225
2426
  }
1226
2427
  }
@@ -1231,71 +2432,89 @@ export class NodeHandle {
1231
2432
  * is remembered so callers don't have to pass it explicitly.
1232
2433
  */
1233
2434
  canonicalProject;
2435
+ /** The owning source file of a file-owned symbol's declaration. */
2436
+ fileOwner;
1234
2437
  index;
1235
2438
  kind;
1236
2439
  path;
1237
- constructor(handle, canonicalProject) {
1238
- const parsed = parseNodeHandle(handle);
2440
+ constructor(handle, canonicalProject, fileOwner) {
2441
+ const parsed = parseNodeHandleFromCompiler(handle);
1239
2442
  this.index = parsed.index;
1240
2443
  this.kind = parsed.kind;
1241
2444
  this.path = parsed.path;
1242
2445
  this.canonicalProject = canonicalProject;
2446
+ this.fileOwner = fileOwner;
1243
2447
  }
1244
2448
  /**
1245
2449
  * Resolve this handle to the actual AST node by fetching the source file from a project
1246
2450
  * and looking up the node by index. If no project is passed, the project that produced
1247
- * the handle is used.
2451
+ * the handle is used. Declarations of file-owned symbols identify an exact source file and
2452
+ * resolve through it, independently of any project.
1248
2453
  */
1249
2454
  async resolve(project = this.canonicalProject) {
1250
- const sourceFile = await project.program.getSourceFile(this.path);
2455
+ if (this.fileOwner) {
2456
+ const sourceFile = this.fileOwner.record.file ?? await this.fetchOwnerFile(this.fileOwner);
2457
+ return sourceFile.getOrCreateNodeAtIndex(this.index);
2458
+ }
2459
+ if (!project)
2460
+ throw new Error(`Node handle for '${this.path}' has no project context`);
2461
+ const sourceFile = await project.program.getSourceFileByPath(this.path);
1251
2462
  if (!sourceFile) {
1252
2463
  return undefined;
1253
2464
  }
1254
2465
  return sourceFile.getOrCreateNodeAtIndex(this.index);
1255
2466
  }
2467
+ async fetchOwnerFile(fileOwner) {
2468
+ const data = await fileOwner.api.client.apiRequestBinary("getCachedSourceFile", { file: fileOwner.record.descriptor });
2469
+ if (!data)
2470
+ throw new Error(`Source file '${fileOwner.record.descriptor.fileName}' is not available`);
2471
+ return fileOwner.api.sourceFileCache.attachFile(fileOwner.record, new RemoteSourceFile(data, new Wtf8Decoder(), fileOwner.api.client.getTimingCollector(), fileOwner.api));
2472
+ }
1256
2473
  }
1257
2474
  export class Symbol {
1258
- objectRegistry;
1259
- /**
1260
- * The project this symbol was first observed in, used as the default project for
1261
- * lookups that need a project context (members/exports/parent). Symbols are shared
1262
- * snapshot-wide, so these lookups can otherwise be ambiguous about which project to use.
1263
- */
1264
- canonicalProject;
1265
- id;
2475
+ storage;
2476
+ get id() {
2477
+ return this.reference.id;
2478
+ }
1266
2479
  /** The escaped (`__String`) name, used as the key in member/export tables. */
1267
2480
  escapedName;
1268
2481
  /** The display name (escaped underscores removed). */
1269
2482
  name;
1270
2483
  flags;
1271
2484
  checkFlags;
2485
+ /** @internal */
2486
+ reference;
1272
2487
  declarations;
1273
2488
  valueDeclaration;
1274
2489
  parent;
1275
2490
  exportSymbol;
1276
2491
  membersCache;
1277
2492
  exportsCache;
1278
- constructor(data, objectRegistry) {
1279
- this.objectRegistry = objectRegistry;
1280
- this.id = data.id;
2493
+ constructor(data, storage) {
2494
+ if (data.reference.kind !== storage.kind)
2495
+ throw new Error(`Symbol ${data.reference.id} has mismatched ownership and storage`);
2496
+ this.storage = storage;
2497
+ this.reference = data.reference;
1281
2498
  this.escapedName = data.name;
1282
2499
  this.name = unescapeLeadingUnderscores(data.name);
1283
2500
  this.flags = data.flags;
1284
2501
  this.checkFlags = data.checkFlags;
1285
- const canonicalProject = objectRegistry.getProject(data.project);
1286
- if (!canonicalProject) {
1287
- throw new Error(`Symbol ${data.id} references unknown canonical project '${data.project}'`);
1288
- }
1289
- this.canonicalProject = canonicalProject;
1290
- this.declarations = (data.declarations ?? []).map(d => new NodeHandle(d, canonicalProject));
1291
- this.valueDeclaration = data.valueDeclaration ? new NodeHandle(data.valueDeclaration, canonicalProject) : undefined;
2502
+ // A file-owned symbol has no canonical project; its declarations resolve through its file.
2503
+ const project = storage.kind === SymbolOwnerKind.Snapshot ? storage.registry.project : undefined;
2504
+ const fileOwner = storage.kind === SymbolOwnerKind.File ? storage.owner : undefined;
2505
+ this.declarations = (data.declarations ?? []).map(handle => new NodeHandle(handle, project, fileOwner));
2506
+ this.valueDeclaration = data.valueDeclaration
2507
+ ? new NodeHandle(data.valueDeclaration, project, fileOwner)
2508
+ : undefined;
1292
2509
  if (data.parent !== undefined)
1293
2510
  this.parent = data.parent;
1294
2511
  if (data.exportSymbol !== undefined)
1295
2512
  this.exportSymbol = data.exportSymbol;
1296
2513
  }
1297
2514
  async getParent() {
1298
- return this.objectRegistry.fetchSymbol(this, "getParentOfSymbol", this.parent, this.canonicalProject.id);
2515
+ if (!this.parent)
2516
+ return undefined;
2517
+ return this.fetchSymbol("getParentOfSymbol", this.parent);
1299
2518
  }
1300
2519
  /**
1301
2520
  * Get this symbol's members keyed by escaped name. The result is cached on
@@ -1312,7 +2531,7 @@ export class Symbol {
1312
2531
  return this.exportsCache ??= this.fetchSymbolTable("getExportsOfSymbol");
1313
2532
  }
1314
2533
  async fetchSymbolTable(method) {
1315
- const symbols = await this.objectRegistry.fetchSymbols(this, method, undefined, this.canonicalProject.id);
2534
+ const symbols = await this.fetchSymbols(method);
1316
2535
  const table = new Map();
1317
2536
  for (const symbol of symbols) {
1318
2537
  table.set(symbol.escapedName, symbol);
@@ -1322,7 +2541,7 @@ export class Symbol {
1322
2541
  async getExportSymbol() {
1323
2542
  if (!this.exportSymbol)
1324
2543
  return this;
1325
- return this.objectRegistry.fetchSymbol(this, "getExportSymbolOfSymbol", this.exportSymbol, this.canonicalProject.id);
2544
+ return this.fetchSymbol("getExportSymbolOfSymbol", this.exportSymbol);
1326
2545
  }
1327
2546
  async getJsDocTags(checker) {
1328
2547
  return checker.getJsDocTagsOfSymbol(this);
@@ -1330,9 +2549,40 @@ export class Symbol {
1330
2549
  async getDocumentationComment(checker) {
1331
2550
  return checker.getDocumentationCommentOfSymbol(this);
1332
2551
  }
2552
+ async fetchSymbol(method, reference) {
2553
+ if (this.storage.kind === SymbolOwnerKind.Snapshot) {
2554
+ return this.storage.registry.fetchSymbol(this, method, reference);
2555
+ }
2556
+ const fileOwner = this.storage.owner;
2557
+ // A file-owned symbol's relationships are always owned by the same file.
2558
+ const cached = reference.file === fileOwner.record.descriptor.nodeId ? fileOwner.record.symbolsById.get(reference.id) : undefined;
2559
+ if (cached)
2560
+ return cached;
2561
+ const data = await fileOwner.api.client.apiRequest(method, { symbol: this.reference });
2562
+ if (!data)
2563
+ throw new Error(`${method} returned null symbol for Symbol ${this.id}`);
2564
+ return this.internFileSymbol(fileOwner, data);
2565
+ }
2566
+ async fetchSymbols(method) {
2567
+ if (this.storage.kind === SymbolOwnerKind.Snapshot) {
2568
+ return this.storage.registry.fetchSymbols(this, method);
2569
+ }
2570
+ const fileOwner = this.storage.owner;
2571
+ const data = await fileOwner.api.client.apiRequest(method, { symbol: this.reference });
2572
+ return data?.map(symbol => this.internFileSymbol(fileOwner, symbol)) ?? [];
2573
+ }
2574
+ internFileSymbol(fileOwner, data) {
2575
+ validateSymbolResponse(data);
2576
+ const reference = data.reference;
2577
+ if (reference.kind !== SymbolOwnerKind.File)
2578
+ throw new Error(`Symbol ${reference.id} is not file-owned`);
2579
+ return fileOwner.api.sourceFileCache.getOrCreateSymbol(fileOwner.record, reference.file, reference.id, () => new Symbol(data, { kind: SymbolOwnerKind.File, owner: fileOwner }));
2580
+ }
1333
2581
  }
1334
2582
  class TypeObject {
1335
2583
  objectRegistry;
2584
+ // Fields included in TypeResponse. References to other objects are stored as IDs
2585
+ // and resolved lazily via the object registry.
1336
2586
  id;
1337
2587
  flags;
1338
2588
  objectFlags;
@@ -1343,14 +2593,17 @@ class TypeObject {
1343
2593
  freshType;
1344
2594
  regularType;
1345
2595
  target;
2596
+ tupleType;
1346
2597
  typeParameters;
1347
2598
  outerTypeParameters;
1348
2599
  localTypeParameters;
2600
+ thisType;
1349
2601
  aliasTypeArguments;
1350
2602
  aliasSymbol;
1351
2603
  elementFlags;
1352
2604
  fixedLength;
1353
2605
  readonly;
2606
+ labeledElementDeclarations;
1354
2607
  texts;
1355
2608
  objectType;
1356
2609
  indexType;
@@ -1358,8 +2611,31 @@ class TypeObject {
1358
2611
  extendsType;
1359
2612
  baseType;
1360
2613
  substConstraint;
1361
- trueType; // false if not yet loaded
1362
- falseType; // false if not yet loaded
2614
+ typeParameter;
2615
+ constraintType;
2616
+ nameType;
2617
+ templateType;
2618
+ // Cached results of lazy fetches, not included in TypeResponse
2619
+ // (typically because they require some amount of computation or
2620
+ // could cause an arbitrarily large number of types to be cached
2621
+ // on the server for ID-based lookup). `false` is a sentinel value
2622
+ // indicating a fetch has not yet occurred.
2623
+ trueType;
2624
+ falseType;
2625
+ constraint;
2626
+ default;
2627
+ nonNullableType;
2628
+ apparentType;
2629
+ reducedType;
2630
+ properties;
2631
+ apparentProperties;
2632
+ callSignatures;
2633
+ constructSignatures;
2634
+ indexInfos;
2635
+ baseTypes;
2636
+ types;
2637
+ stringIndexType;
2638
+ numberIndexType;
1363
2639
  constructor(data, objectRegistry) {
1364
2640
  this.objectRegistry = objectRegistry;
1365
2641
  this.id = data.id;
@@ -1371,7 +2647,25 @@ class TypeObject {
1371
2647
  if (data.value != null) {
1372
2648
  // BigInt literal values are serialized as decimal strings (e.g. "-123") because
1373
2649
  // JSON cannot represent bigint. Decode them back into a real bigint here.
1374
- this.value = (data.flags & TypeFlags.BigIntLiteral) ? BigInt(data.value) : data.value;
2650
+ const value = data.value;
2651
+ if (data.flags & TypeFlags.BigIntLiteral) {
2652
+ this.value = BigInt(value);
2653
+ }
2654
+ // JSON cannot represent infinities, so the API serializes them as strings.
2655
+ else if (data.flags & TypeFlags.NumberLiteral && typeof value === "string") {
2656
+ if (value === "+Infinity") {
2657
+ this.value = Infinity;
2658
+ }
2659
+ else if (value === "-Infinity") {
2660
+ this.value = -Infinity;
2661
+ }
2662
+ else {
2663
+ this.value = NaN;
2664
+ }
2665
+ }
2666
+ else {
2667
+ this.value = value;
2668
+ }
1375
2669
  }
1376
2670
  if (data.intrinsicName !== undefined)
1377
2671
  this.intrinsicName = data.intrinsicName;
@@ -1383,18 +2677,24 @@ class TypeObject {
1383
2677
  this.regularType = data.regularType;
1384
2678
  if (data.target !== undefined)
1385
2679
  this.target = data.target;
2680
+ this.tupleType = data.isTupleType ?? false;
1386
2681
  this.typeParameters = data.typeParameters ?? [];
1387
2682
  this.outerTypeParameters = data.outerTypeParameters ?? [];
1388
2683
  this.localTypeParameters = data.localTypeParameters ?? [];
2684
+ if (data.thisType !== undefined)
2685
+ this.thisType = data.thisType;
1389
2686
  this.aliasTypeArguments = data.aliasTypeArguments ?? [];
1390
2687
  if (data.aliasSymbol !== undefined)
1391
2688
  this.aliasSymbol = data.aliasSymbol;
1392
- if (data.elementFlags !== undefined)
1393
- this.elementFlags = data.elementFlags;
1394
- if (data.fixedLength !== undefined)
2689
+ if (data.fixedLength !== undefined) {
2690
+ this.elementFlags = data.elementFlags ?? [];
1395
2691
  this.fixedLength = data.fixedLength;
2692
+ }
1396
2693
  if (data.readonly !== undefined)
1397
2694
  this.readonly = data.readonly;
2695
+ if (data.labeledElementDeclarations !== undefined) {
2696
+ this.labeledElementDeclarations = data.labeledElementDeclarations.map(handle => handle ? objectRegistry.createNodeHandle(handle) : undefined);
2697
+ }
1398
2698
  if (data.texts !== undefined)
1399
2699
  this.texts = data.texts;
1400
2700
  if (data.objectType !== undefined)
@@ -1409,12 +2709,102 @@ class TypeObject {
1409
2709
  this.baseType = data.baseType;
1410
2710
  if (data.substConstraint !== undefined)
1411
2711
  this.substConstraint = data.substConstraint;
2712
+ if (data.typeParameter !== undefined)
2713
+ this.typeParameter = data.typeParameter;
2714
+ if (data.constraintType !== undefined)
2715
+ this.constraintType = data.constraintType;
2716
+ if (data.nameType !== undefined)
2717
+ this.nameType = data.nameType;
2718
+ if (data.templateType !== undefined)
2719
+ this.templateType = data.templateType;
1412
2720
  this.trueType = false;
1413
2721
  this.falseType = false;
2722
+ this.constraint = false;
2723
+ this.default = false;
2724
+ this.nonNullableType = false;
2725
+ this.apparentType = false;
2726
+ this.reducedType = false;
2727
+ this.properties = false;
2728
+ this.apparentProperties = false;
2729
+ this.callSignatures = false;
2730
+ this.constructSignatures = false;
2731
+ this.indexInfos = false;
2732
+ this.baseTypes = false;
2733
+ this.types = false;
2734
+ this.stringIndexType = false;
2735
+ this.numberIndexType = false;
1414
2736
  }
1415
2737
  async getSymbol() {
1416
2738
  return this.objectRegistry.fetchSymbol(this, "getSymbolOfType", this.symbol);
1417
2739
  }
2740
+ async getProperties() {
2741
+ if (this.properties === false) {
2742
+ this.properties = await this.objectRegistry.fetchPropertiesOfType(this);
2743
+ }
2744
+ return this.properties;
2745
+ }
2746
+ getProperty(propertyName) {
2747
+ return this.objectRegistry.fetchPropertyOfType(this, propertyName);
2748
+ }
2749
+ async getApparentProperties() {
2750
+ if (this.apparentProperties === false) {
2751
+ this.apparentProperties = await this.objectRegistry.fetchApparentPropertiesOfType(this);
2752
+ }
2753
+ return this.apparentProperties;
2754
+ }
2755
+ async getCallSignatures() {
2756
+ if (this.callSignatures === false) {
2757
+ this.callSignatures = await this.objectRegistry.fetchSignaturesOfType(this, SignatureKind.Call);
2758
+ }
2759
+ return this.callSignatures;
2760
+ }
2761
+ async getConstructSignatures() {
2762
+ if (this.constructSignatures === false) {
2763
+ this.constructSignatures = await this.objectRegistry.fetchSignaturesOfType(this, SignatureKind.Construct);
2764
+ }
2765
+ return this.constructSignatures;
2766
+ }
2767
+ async getNonNullableType() {
2768
+ const result = await this.objectRegistry.fetchType(this, "getNonNullableType", this.nonNullableType);
2769
+ this.nonNullableType = result.id;
2770
+ return result;
2771
+ }
2772
+ async getStringIndexType() {
2773
+ if (this.stringIndexType === false) {
2774
+ this.stringIndexType = await this.getStringIndexTypeWorker();
2775
+ }
2776
+ return this.stringIndexType;
2777
+ }
2778
+ async getStringIndexTypeWorker() {
2779
+ const infos = await this.getIndexInfos();
2780
+ return infos.find(info => (info.keyType.flags & TypeFlags.String) !== 0)?.valueType;
2781
+ }
2782
+ async getNumberIndexType() {
2783
+ if (this.numberIndexType === false) {
2784
+ this.numberIndexType = await this.getNumberIndexTypeWorker();
2785
+ }
2786
+ return this.numberIndexType;
2787
+ }
2788
+ async getNumberIndexTypeWorker() {
2789
+ const infos = await this.getIndexInfos();
2790
+ return infos.find(info => (info.keyType.flags & TypeFlags.Number) !== 0)?.valueType;
2791
+ }
2792
+ async getApparentType() {
2793
+ const result = await this.objectRegistry.fetchType(this, "getApparentType", this.apparentType);
2794
+ this.apparentType = result.id;
2795
+ return result;
2796
+ }
2797
+ async getReducedType() {
2798
+ const result = await this.objectRegistry.fetchType(this, "getReducedType", this.reducedType);
2799
+ this.reducedType = result.id;
2800
+ return result;
2801
+ }
2802
+ async getIndexInfos() {
2803
+ if (this.indexInfos === false) {
2804
+ this.indexInfos = await this.objectRegistry.fetchIndexInfosOfType(this);
2805
+ }
2806
+ return this.indexInfos;
2807
+ }
1418
2808
  async getAliasSymbol() {
1419
2809
  return this.objectRegistry.fetchSymbol(this, "getAliasSymbolOfType", this.aliasSymbol);
1420
2810
  }
@@ -1422,10 +2812,10 @@ class TypeObject {
1422
2812
  return this.objectRegistry.fetchType(this, "getTargetOfType", this.target);
1423
2813
  }
1424
2814
  async getFreshType() {
1425
- return this.objectRegistry.fetchType(this, "getFreshTypeOfType", this.freshType);
2815
+ return this.objectRegistry.fetchOptionalType(this, "getFreshTypeOfType", this.freshType);
1426
2816
  }
1427
2817
  async getRegularType() {
1428
- return this.objectRegistry.fetchType(this, "getRegularTypeOfType", this.regularType);
2818
+ return this.objectRegistry.fetchOptionalType(this, "getRegularTypeOfType", this.regularType);
1429
2819
  }
1430
2820
  async getTypes() {
1431
2821
  // Only union, intersection, and template literal types have constituent
@@ -1434,7 +2824,10 @@ class TypeObject {
1434
2824
  if (!(this.flags & (TypeFlags.UnionOrIntersection | TypeFlags.TemplateLiteral))) {
1435
2825
  return undefined;
1436
2826
  }
1437
- return this.objectRegistry.fetchTypes(this, "getTypesOfType");
2827
+ if (this.types === false) {
2828
+ this.types = await this.objectRegistry.fetchTypes(this, "getTypesOfType");
2829
+ }
2830
+ return this.types;
1438
2831
  }
1439
2832
  async getTypeParameters() {
1440
2833
  return this.objectRegistry.fetchTypes(this, "getTypeParametersOfType", this.typeParameters);
@@ -1445,9 +2838,24 @@ class TypeObject {
1445
2838
  async getLocalTypeParameters() {
1446
2839
  return this.objectRegistry.fetchTypes(this, "getLocalTypeParametersOfType", this.localTypeParameters);
1447
2840
  }
2841
+ async getThisType() {
2842
+ return this.objectRegistry.fetchOptionalType(this, "getThisTypeOfType", this.thisType);
2843
+ }
1448
2844
  async getAliasTypeArguments() {
1449
2845
  return this.objectRegistry.fetchTypes(this, "getAliasTypeArgumentsOfType", this.aliasTypeArguments);
1450
2846
  }
2847
+ async getTypeParameter() {
2848
+ return this.objectRegistry.fetchType(this, "getTypeParameterOfMappedType", this.typeParameter);
2849
+ }
2850
+ async getConstraintType() {
2851
+ return this.objectRegistry.fetchType(this, "getConstraintTypeOfMappedType", this.constraintType);
2852
+ }
2853
+ async getNameType() {
2854
+ return this.objectRegistry.fetchOptionalType(this, "getNameTypeOfMappedType", this.nameType);
2855
+ }
2856
+ async getTemplateType() {
2857
+ return this.objectRegistry.fetchType(this, "getTemplateTypeOfMappedType", this.templateType);
2858
+ }
1451
2859
  async getObjectType() {
1452
2860
  return this.objectRegistry.fetchType(this, "getObjectTypeOfType", this.objectType);
1453
2861
  }
@@ -1464,8 +2872,20 @@ class TypeObject {
1464
2872
  return this.objectRegistry.fetchType(this, "getBaseTypeOfType", this.baseType);
1465
2873
  }
1466
2874
  async getConstraint() {
2875
+ // Type parameters resolve their constraint lazily through the checker,
2876
+ // whereas substitution types carry a preloaded constraint handle.
2877
+ if (this.flags & TypeFlags.TypeParameter) {
2878
+ const result = await this.objectRegistry.fetchOptionalType(this, "getConstraintOfTypeParameter", this.constraint);
2879
+ this.constraint = result ? result.id : 0;
2880
+ return result;
2881
+ }
1467
2882
  return this.objectRegistry.fetchType(this, "getConstraintOfType", this.substConstraint);
1468
2883
  }
2884
+ async getDefault() {
2885
+ const result = await this.objectRegistry.fetchOptionalType(this, "getDefaultFromTypeParameter", this.default);
2886
+ this.default = result ? result.id : 0;
2887
+ return result;
2888
+ }
1469
2889
  async getTrueType() {
1470
2890
  const result = await this.objectRegistry.fetchType(this, "getTrueTypeOfConditionalType", this.trueType);
1471
2891
  this.trueType = result.id;
@@ -1484,7 +2904,10 @@ class TypeObject {
1484
2904
  if (!this.isClassOrInterface()) {
1485
2905
  return undefined;
1486
2906
  }
1487
- return this.objectRegistry.fetchBaseTypes(this);
2907
+ if (this.baseTypes === false) {
2908
+ this.baseTypes = await this.objectRegistry.fetchBaseTypes(this);
2909
+ }
2910
+ return this.baseTypes;
1488
2911
  }
1489
2912
  isClassOrInterface() {
1490
2913
  return isClassOrInterfaceType(this);
@@ -1523,7 +2946,10 @@ class TypeObject {
1523
2946
  return isTypeReference(this);
1524
2947
  }
1525
2948
  isTupleType() {
1526
- return isTupleType(this);
2949
+ return this.tupleType;
2950
+ }
2951
+ isTupleTypeTarget() {
2952
+ return this.fixedLength !== undefined;
1527
2953
  }
1528
2954
  isIndexType() {
1529
2955
  return isIndexType(this);
@@ -1546,6 +2972,9 @@ class TypeObject {
1546
2972
  isTypeParameter() {
1547
2973
  return isTypeParameter(this);
1548
2974
  }
2975
+ isMappedType() {
2976
+ return !!(this.flags & TypeFlags.Object) && !!(this.objectFlags & ObjectFlags.Mapped);
2977
+ }
1549
2978
  }
1550
2979
  export function isUnionType(type) {
1551
2980
  return (type.flags & TypeFlags.Union) !== 0;
@@ -1590,7 +3019,10 @@ export function isTypeReference(type) {
1590
3019
  return isObjectType(type) && (type.objectFlags & ObjectFlags.Reference) !== 0;
1591
3020
  }
1592
3021
  export function isTupleType(type) {
1593
- return isObjectType(type) && (type.objectFlags & ObjectFlags.Tuple) !== 0;
3022
+ return type.isTupleType();
3023
+ }
3024
+ export function isTupleTypeTarget(type) {
3025
+ return type.isTupleTypeTarget();
1594
3026
  }
1595
3027
  export function isIndexType(type) {
1596
3028
  return (type.flags & TypeFlags.Index) !== 0;
@@ -1622,6 +3054,7 @@ export class Signature {
1622
3054
  parameters;
1623
3055
  thisParameter;
1624
3056
  target;
3057
+ returnType;
1625
3058
  constructor(data, project, objectRegistry) {
1626
3059
  this.id = data.id;
1627
3060
  this.flags = data.flags;
@@ -1631,6 +3064,7 @@ export class Signature {
1631
3064
  this.parameters = data.parameters ?? [];
1632
3065
  this.thisParameter = data.thisParameter;
1633
3066
  this.target = data.target;
3067
+ this.returnType = false;
1634
3068
  }
1635
3069
  async getTypeParameters() {
1636
3070
  return this.objectRegistry.fetchTypes(this, "getTypeParametersOfSignature", this.typeParameters);
@@ -1644,6 +3078,14 @@ export class Signature {
1644
3078
  async getTarget() {
1645
3079
  return this.objectRegistry.fetchSignature(this, "getTargetOfSignature", this.target);
1646
3080
  }
3081
+ async getReturnType() {
3082
+ const result = await this.objectRegistry.fetchType(this, "getReturnTypeOfSignature", this.returnType);
3083
+ this.returnType = result.id;
3084
+ return result;
3085
+ }
3086
+ getTypeParameterAtPosition(pos) {
3087
+ return this.objectRegistry.fetchTypeParameterAtPosition(this, pos);
3088
+ }
1647
3089
  get hasRestParameter() {
1648
3090
  return (this.flags & SignatureFlags.HasRestParameter) !== 0;
1649
3091
  }