typescript 7.0.1-rc → 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 (418) hide show
  1. package/NOTICE.txt +5 -36
  2. package/README.md +39 -14
  3. package/dist/api/async/api.d.ts +827 -123
  4. package/dist/api/async/api.d.ts.map +1 -1
  5. package/dist/api/async/api.js +2367 -340
  6. package/dist/api/async/api.js.map +1 -1
  7. package/dist/api/async/client.d.ts +35 -2
  8. package/dist/api/async/client.d.ts.map +1 -1
  9. package/dist/api/async/client.js +317 -59
  10. package/dist/api/async/client.js.map +1 -1
  11. package/dist/api/async/types.d.ts +199 -53
  12. package/dist/api/async/types.d.ts.map +1 -1
  13. package/dist/api/compilerOptions.generated.d.ts +123 -0
  14. package/dist/api/compilerOptions.generated.d.ts.map +1 -0
  15. package/dist/api/compilerOptions.generated.js +8 -0
  16. package/dist/api/compilerOptions.generated.js.map +1 -0
  17. package/dist/api/diagnosticFormatter.d.ts +9 -0
  18. package/dist/api/diagnosticFormatter.d.ts.map +1 -0
  19. package/dist/api/diagnosticFormatter.js +169 -0
  20. package/dist/api/diagnosticFormatter.js.map +1 -0
  21. package/dist/api/fs.d.ts +68 -13
  22. package/dist/api/fs.d.ts.map +1 -1
  23. package/dist/api/fs.js +62 -101
  24. package/dist/api/fs.js.map +1 -1
  25. package/dist/api/fsCallbacks.d.ts +27 -0
  26. package/dist/api/fsCallbacks.d.ts.map +1 -0
  27. package/dist/api/fsCallbacks.js +111 -0
  28. package/dist/api/fsCallbacks.js.map +1 -0
  29. package/dist/api/node/encoder.d.ts +3 -0
  30. package/dist/api/node/encoder.d.ts.map +1 -1
  31. package/dist/api/node/encoder.generated.js +2 -2
  32. package/dist/api/node/encoder.generated.js.map +1 -1
  33. package/dist/api/node/encoder.js +21 -33
  34. package/dist/api/node/encoder.js.map +1 -1
  35. package/dist/api/node/msgpack.d.ts.map +1 -1
  36. package/dist/api/node/msgpack.js +3 -3
  37. package/dist/api/node/msgpack.js.map +1 -1
  38. package/dist/api/node/node.d.ts +43 -10
  39. package/dist/api/node/node.d.ts.map +1 -1
  40. package/dist/api/node/node.generated.d.ts +20 -2
  41. package/dist/api/node/node.generated.d.ts.map +1 -1
  42. package/dist/api/node/node.generated.js +122 -52
  43. package/dist/api/node/node.generated.js.map +1 -1
  44. package/dist/api/node/node.infrastructure.d.ts +16 -3
  45. package/dist/api/node/node.infrastructure.d.ts.map +1 -1
  46. package/dist/api/node/node.infrastructure.js +20 -40
  47. package/dist/api/node/node.infrastructure.js.map +1 -1
  48. package/dist/api/node/node.js +269 -30
  49. package/dist/api/node/node.js.map +1 -1
  50. package/dist/api/node/protocol.d.ts +5 -2
  51. package/dist/api/node/protocol.d.ts.map +1 -1
  52. package/dist/api/node/protocol.generated.js +2 -2
  53. package/dist/api/node/protocol.generated.js.map +1 -1
  54. package/dist/api/node/protocol.js +5 -2
  55. package/dist/api/node/protocol.js.map +1 -1
  56. package/dist/api/node/wtf8.d.ts +10 -0
  57. package/dist/api/node/wtf8.d.ts.map +1 -0
  58. package/dist/api/node/wtf8.js +130 -0
  59. package/dist/api/node/wtf8.js.map +1 -0
  60. package/dist/api/options.d.ts +26 -6
  61. package/dist/api/options.d.ts.map +1 -1
  62. package/dist/api/options.js +21 -0
  63. package/dist/api/options.js.map +1 -1
  64. package/dist/api/path.d.ts +49 -39
  65. package/dist/api/path.d.ts.map +1 -1
  66. package/dist/api/path.js +409 -33
  67. package/dist/api/path.js.map +1 -1
  68. package/dist/api/prepareCompilerOptions.generated.d.ts +5 -0
  69. package/dist/api/prepareCompilerOptions.generated.d.ts.map +1 -0
  70. package/dist/api/prepareCompilerOptions.generated.js +24 -0
  71. package/dist/api/prepareCompilerOptions.generated.js.map +1 -0
  72. package/dist/api/proto.d.ts +58 -164
  73. package/dist/api/proto.d.ts.map +1 -1
  74. package/dist/api/proto.generated.d.ts +1419 -0
  75. package/dist/api/proto.generated.d.ts.map +1 -0
  76. package/dist/api/proto.generated.js +21 -0
  77. package/dist/api/proto.generated.js.map +1 -0
  78. package/dist/api/proto.js +28 -0
  79. package/dist/api/proto.js.map +1 -1
  80. package/dist/api/sourceFileCache.d.ts +51 -20
  81. package/dist/api/sourceFileCache.d.ts.map +1 -1
  82. package/dist/api/sourceFileCache.js +168 -37
  83. package/dist/api/sourceFileCache.js.map +1 -1
  84. package/dist/api/sync/api.d.ts +1553 -179
  85. package/dist/api/sync/api.d.ts.map +1 -1
  86. package/dist/api/sync/api.js +5086 -758
  87. package/dist/api/sync/api.js.map +1 -1
  88. package/dist/api/sync/client.d.ts +25 -2
  89. package/dist/api/sync/client.d.ts.map +1 -1
  90. package/dist/api/sync/client.js +132 -30
  91. package/dist/api/sync/client.js.map +1 -1
  92. package/dist/api/sync/generatorSupport.d.ts +32 -0
  93. package/dist/api/sync/generatorSupport.d.ts.map +1 -0
  94. package/dist/api/sync/generatorSupport.js +338 -0
  95. package/dist/api/sync/generatorSupport.js.map +1 -0
  96. package/dist/api/sync/types.d.ts +341 -68
  97. package/dist/api/sync/types.d.ts.map +1 -1
  98. package/dist/api/syncChannel.d.ts +7 -1
  99. package/dist/api/syncChannel.d.ts.map +1 -1
  100. package/dist/api/syncChannel.js +41 -3
  101. package/dist/api/syncChannel.js.map +1 -1
  102. package/dist/api/timing.d.ts +175 -0
  103. package/dist/api/timing.d.ts.map +1 -0
  104. package/dist/api/timing.js +149 -0
  105. package/dist/api/timing.js.map +1 -0
  106. package/dist/api/timingDump.d.ts +13 -0
  107. package/dist/api/timingDump.d.ts.map +1 -0
  108. package/dist/api/timingDump.js +38 -0
  109. package/dist/api/timingDump.js.map +1 -0
  110. package/dist/api/typedPaths.d.ts +3 -0
  111. package/dist/api/typedPaths.d.ts.map +1 -0
  112. package/dist/api/typedPaths.js +2 -0
  113. package/dist/api/typedPaths.js.map +1 -0
  114. package/dist/api/userPreferences.generated.d.ts +195 -0
  115. package/dist/api/userPreferences.generated.d.ts.map +1 -0
  116. package/dist/api/userPreferences.generated.js +3 -0
  117. package/dist/api/userPreferences.generated.js.map +1 -0
  118. package/dist/ast/ast.d.ts +125 -8
  119. package/dist/ast/ast.d.ts.map +1 -1
  120. package/dist/ast/ast.generated.d.ts +48 -42
  121. package/dist/ast/ast.generated.d.ts.map +1 -1
  122. package/dist/ast/ast.generated.js +1 -1
  123. package/dist/ast/ast.generated.js.map +1 -1
  124. package/dist/ast/ast.js +1 -0
  125. package/dist/ast/ast.js.map +1 -1
  126. package/dist/ast/astnav.d.ts +3 -2
  127. package/dist/ast/astnav.d.ts.map +1 -1
  128. package/dist/ast/astnav.js +148 -3
  129. package/dist/ast/astnav.js.map +1 -1
  130. package/dist/ast/factory.generated.d.ts +12 -150
  131. package/dist/ast/factory.generated.d.ts.map +1 -1
  132. package/dist/ast/factory.generated.js +2736 -8
  133. package/dist/ast/factory.generated.js.map +1 -1
  134. package/dist/ast/index.d.ts +7 -0
  135. package/dist/ast/index.d.ts.map +1 -1
  136. package/dist/ast/index.js +7 -0
  137. package/dist/ast/index.js.map +1 -1
  138. package/dist/ast/is.d.ts +3 -12
  139. package/dist/ast/is.d.ts.map +1 -1
  140. package/dist/ast/is.generated.d.ts +890 -2
  141. package/dist/ast/is.generated.d.ts.map +1 -1
  142. package/dist/ast/is.generated.js +303 -7
  143. package/dist/ast/is.generated.js.map +1 -1
  144. package/dist/ast/is.js +231 -1
  145. package/dist/ast/is.js.map +1 -1
  146. package/dist/ast/jsdoc.d.ts +12 -0
  147. package/dist/ast/jsdoc.d.ts.map +1 -0
  148. package/dist/ast/jsdoc.js +208 -0
  149. package/dist/ast/jsdoc.js.map +1 -0
  150. package/dist/ast/modifiers.d.ts +4 -0
  151. package/dist/ast/modifiers.d.ts.map +1 -0
  152. package/dist/ast/modifiers.js +41 -0
  153. package/dist/ast/modifiers.js.map +1 -0
  154. package/dist/ast/scanner.d.ts.map +1 -1
  155. package/dist/ast/scanner.js +2 -1
  156. package/dist/ast/scanner.js.map +1 -1
  157. package/dist/ast/spanMap.d.ts +88 -0
  158. package/dist/ast/spanMap.d.ts.map +1 -0
  159. package/dist/ast/spanMap.js +417 -0
  160. package/dist/ast/spanMap.js.map +1 -0
  161. package/dist/ast/utils.d.ts +25 -0
  162. package/dist/ast/utils.d.ts.map +1 -1
  163. package/dist/ast/utils.js +291 -0
  164. package/dist/ast/utils.js.map +1 -1
  165. package/dist/ast/visitor.d.ts +2 -0
  166. package/dist/ast/visitor.d.ts.map +1 -1
  167. package/dist/ast/visitor.generated.d.ts.map +1 -1
  168. package/dist/ast/visitor.generated.js +5 -4
  169. package/dist/ast/visitor.generated.js.map +1 -1
  170. package/dist/ast/visitor.js +40 -0
  171. package/dist/ast/visitor.js.map +1 -1
  172. package/dist/enums/caseSensitivity.d.ts +2 -0
  173. package/dist/enums/caseSensitivity.d.ts.map +1 -0
  174. package/dist/enums/caseSensitivity.enum.d.ts +5 -0
  175. package/dist/enums/caseSensitivity.enum.d.ts.map +1 -0
  176. package/dist/enums/caseSensitivity.enum.js +7 -0
  177. package/dist/enums/caseSensitivity.enum.js.map +1 -0
  178. package/dist/enums/caseSensitivity.js +7 -0
  179. package/dist/enums/caseSensitivity.js.map +1 -0
  180. package/dist/enums/checkFlags.d.ts +2 -0
  181. package/dist/enums/checkFlags.d.ts.map +1 -0
  182. package/dist/enums/checkFlags.enum.d.ts +34 -0
  183. package/dist/enums/checkFlags.enum.d.ts.map +1 -0
  184. package/dist/enums/checkFlags.enum.js +36 -0
  185. package/dist/enums/checkFlags.enum.js.map +1 -0
  186. package/dist/enums/checkFlags.js +36 -0
  187. package/dist/enums/checkFlags.js.map +1 -0
  188. package/dist/enums/completionItemKind.enum.js +1 -1
  189. package/dist/enums/completionItemKind.enum.js.map +1 -1
  190. package/dist/enums/completionItemKind.js +1 -1
  191. package/dist/enums/completionItemKind.js.map +1 -1
  192. package/dist/enums/diagnosticCategory.enum.js +1 -1
  193. package/dist/enums/diagnosticCategory.enum.js.map +1 -1
  194. package/dist/enums/diagnosticCategory.js +1 -1
  195. package/dist/enums/diagnosticCategory.js.map +1 -1
  196. package/dist/enums/diagnosticDirectivePolicy.d.ts +2 -0
  197. package/dist/enums/diagnosticDirectivePolicy.d.ts.map +1 -0
  198. package/dist/enums/diagnosticDirectivePolicy.enum.d.ts +5 -0
  199. package/dist/enums/diagnosticDirectivePolicy.enum.d.ts.map +1 -0
  200. package/dist/enums/diagnosticDirectivePolicy.enum.js +7 -0
  201. package/dist/enums/diagnosticDirectivePolicy.enum.js.map +1 -0
  202. package/dist/enums/diagnosticDirectivePolicy.js +7 -0
  203. package/dist/enums/diagnosticDirectivePolicy.js.map +1 -0
  204. package/dist/enums/elementFlags.enum.js +1 -1
  205. package/dist/enums/elementFlags.enum.js.map +1 -1
  206. package/dist/enums/elementFlags.js +1 -1
  207. package/dist/enums/elementFlags.js.map +1 -1
  208. package/dist/enums/emitOnly.d.ts +2 -0
  209. package/dist/enums/emitOnly.d.ts.map +1 -0
  210. package/dist/enums/emitOnly.enum.d.ts +6 -0
  211. package/dist/enums/emitOnly.enum.d.ts.map +1 -0
  212. package/dist/enums/emitOnly.enum.js +8 -0
  213. package/dist/enums/emitOnly.enum.js.map +1 -0
  214. package/dist/enums/emitOnly.js +8 -0
  215. package/dist/enums/emitOnly.js.map +1 -0
  216. package/dist/enums/indexKind.d.ts +2 -0
  217. package/dist/enums/indexKind.d.ts.map +1 -0
  218. package/dist/enums/indexKind.enum.d.ts +5 -0
  219. package/dist/enums/indexKind.enum.d.ts.map +1 -0
  220. package/dist/enums/indexKind.enum.js +7 -0
  221. package/dist/enums/indexKind.enum.js.map +1 -0
  222. package/dist/enums/indexKind.js +7 -0
  223. package/dist/enums/indexKind.js.map +1 -0
  224. package/dist/enums/internalSymbolName.d.ts +2 -0
  225. package/dist/enums/internalSymbolName.d.ts.map +1 -0
  226. package/dist/enums/internalSymbolName.enum.d.ts +23 -0
  227. package/dist/enums/internalSymbolName.enum.d.ts.map +1 -0
  228. package/dist/enums/internalSymbolName.enum.js +25 -0
  229. package/dist/enums/internalSymbolName.enum.js.map +1 -0
  230. package/dist/enums/internalSymbolName.js +25 -0
  231. package/dist/enums/internalSymbolName.js.map +1 -0
  232. package/dist/enums/jsDeclarationKind.d.ts +2 -0
  233. package/dist/enums/jsDeclarationKind.d.ts.map +1 -0
  234. package/dist/enums/jsDeclarationKind.enum.d.ts +10 -0
  235. package/dist/enums/jsDeclarationKind.enum.d.ts.map +1 -0
  236. package/dist/enums/jsDeclarationKind.enum.js +12 -0
  237. package/dist/enums/jsDeclarationKind.enum.js.map +1 -0
  238. package/dist/enums/jsDeclarationKind.js +12 -0
  239. package/dist/enums/jsDeclarationKind.js.map +1 -0
  240. package/dist/enums/jsxEmit.d.ts +2 -0
  241. package/dist/enums/jsxEmit.d.ts.map +1 -0
  242. package/dist/enums/jsxEmit.enum.d.ts +9 -0
  243. package/dist/enums/jsxEmit.enum.d.ts.map +1 -0
  244. package/dist/enums/jsxEmit.enum.js +11 -0
  245. package/dist/enums/jsxEmit.enum.js.map +1 -0
  246. package/dist/enums/jsxEmit.js +11 -0
  247. package/dist/enums/jsxEmit.js.map +1 -0
  248. package/dist/enums/modifierFlags.enum.js +1 -1
  249. package/dist/enums/modifierFlags.enum.js.map +1 -1
  250. package/dist/enums/modifierFlags.js +1 -1
  251. package/dist/enums/modifierFlags.js.map +1 -1
  252. package/dist/enums/moduleDetectionKind.d.ts +2 -0
  253. package/dist/enums/moduleDetectionKind.d.ts.map +1 -0
  254. package/dist/enums/moduleDetectionKind.enum.d.ts +7 -0
  255. package/dist/enums/moduleDetectionKind.enum.d.ts.map +1 -0
  256. package/dist/enums/moduleDetectionKind.enum.js +9 -0
  257. package/dist/enums/moduleDetectionKind.enum.js.map +1 -0
  258. package/dist/enums/moduleDetectionKind.js +9 -0
  259. package/dist/enums/moduleDetectionKind.js.map +1 -0
  260. package/dist/enums/moduleKind.d.ts +2 -0
  261. package/dist/enums/moduleKind.d.ts.map +1 -0
  262. package/dist/enums/moduleKind.enum.d.ts +17 -0
  263. package/dist/enums/moduleKind.enum.d.ts.map +1 -0
  264. package/dist/enums/moduleKind.enum.js +19 -0
  265. package/dist/enums/moduleKind.enum.js.map +1 -0
  266. package/dist/enums/moduleKind.js +19 -0
  267. package/dist/enums/moduleKind.js.map +1 -0
  268. package/dist/enums/moduleResolutionKind.d.ts +2 -0
  269. package/dist/enums/moduleResolutionKind.d.ts.map +1 -0
  270. package/dist/enums/moduleResolutionKind.enum.d.ts +9 -0
  271. package/dist/enums/moduleResolutionKind.enum.d.ts.map +1 -0
  272. package/dist/enums/moduleResolutionKind.enum.js +11 -0
  273. package/dist/enums/moduleResolutionKind.enum.js.map +1 -0
  274. package/dist/enums/moduleResolutionKind.js +11 -0
  275. package/dist/enums/moduleResolutionKind.js.map +1 -0
  276. package/dist/enums/newLineKind.d.ts +2 -0
  277. package/dist/enums/newLineKind.d.ts.map +1 -0
  278. package/dist/enums/newLineKind.enum.d.ts +6 -0
  279. package/dist/enums/newLineKind.enum.d.ts.map +1 -0
  280. package/dist/enums/newLineKind.enum.js +8 -0
  281. package/dist/enums/newLineKind.enum.js.map +1 -0
  282. package/dist/enums/newLineKind.js +8 -0
  283. package/dist/enums/newLineKind.js.map +1 -0
  284. package/dist/enums/nodeBuilderFlags.enum.js +1 -1
  285. package/dist/enums/nodeBuilderFlags.enum.js.map +1 -1
  286. package/dist/enums/nodeBuilderFlags.js +1 -1
  287. package/dist/enums/nodeBuilderFlags.js.map +1 -1
  288. package/dist/enums/nodeFlags.enum.js +1 -1
  289. package/dist/enums/nodeFlags.enum.js.map +1 -1
  290. package/dist/enums/nodeFlags.js +1 -1
  291. package/dist/enums/nodeFlags.js.map +1 -1
  292. package/dist/enums/objectFlags.enum.d.ts +3 -2
  293. package/dist/enums/objectFlags.enum.d.ts.map +1 -1
  294. package/dist/enums/objectFlags.enum.js +4 -3
  295. package/dist/enums/objectFlags.enum.js.map +1 -1
  296. package/dist/enums/objectFlags.js +4 -3
  297. package/dist/enums/objectFlags.js.map +1 -1
  298. package/dist/enums/outerExpressionKinds.enum.d.ts +5 -1
  299. package/dist/enums/outerExpressionKinds.enum.d.ts.map +1 -1
  300. package/dist/enums/outerExpressionKinds.enum.js +5 -1
  301. package/dist/enums/outerExpressionKinds.enum.js.map +1 -1
  302. package/dist/enums/outerExpressionKinds.js +5 -1
  303. package/dist/enums/outerExpressionKinds.js.map +1 -1
  304. package/dist/enums/scriptKind.d.ts.map +1 -1
  305. package/dist/enums/scriptKind.enum.d.ts +1 -3
  306. package/dist/enums/scriptKind.enum.d.ts.map +1 -1
  307. package/dist/enums/scriptKind.enum.js +1 -2
  308. package/dist/enums/scriptKind.enum.js.map +1 -1
  309. package/dist/enums/scriptKind.js +1 -2
  310. package/dist/enums/scriptKind.js.map +1 -1
  311. package/dist/enums/scriptTarget.d.ts.map +1 -1
  312. package/dist/enums/scriptTarget.enum.d.ts +1 -0
  313. package/dist/enums/scriptTarget.enum.d.ts.map +1 -1
  314. package/dist/enums/scriptTarget.enum.js +2 -0
  315. package/dist/enums/scriptTarget.enum.js.map +1 -1
  316. package/dist/enums/scriptTarget.js +2 -0
  317. package/dist/enums/scriptTarget.js.map +1 -1
  318. package/dist/enums/signatureFlags.enum.js +1 -1
  319. package/dist/enums/signatureFlags.enum.js.map +1 -1
  320. package/dist/enums/signatureFlags.js +1 -1
  321. package/dist/enums/signatureFlags.js.map +1 -1
  322. package/dist/enums/signatureKind.enum.js +1 -1
  323. package/dist/enums/signatureKind.enum.js.map +1 -1
  324. package/dist/enums/signatureKind.js +1 -1
  325. package/dist/enums/signatureKind.js.map +1 -1
  326. package/dist/enums/spanMapFeature.d.ts +2 -0
  327. package/dist/enums/spanMapFeature.d.ts.map +1 -0
  328. package/dist/enums/spanMapFeature.enum.d.ts +25 -0
  329. package/dist/enums/spanMapFeature.enum.d.ts.map +1 -0
  330. package/dist/enums/spanMapFeature.enum.js +27 -0
  331. package/dist/enums/spanMapFeature.enum.js.map +1 -0
  332. package/dist/enums/spanMapFeature.js +27 -0
  333. package/dist/enums/spanMapFeature.js.map +1 -0
  334. package/dist/enums/spanMapFidelity.d.ts +2 -0
  335. package/dist/enums/spanMapFidelity.d.ts.map +1 -0
  336. package/dist/enums/spanMapFidelity.enum.d.ts +7 -0
  337. package/dist/enums/spanMapFidelity.enum.d.ts.map +1 -0
  338. package/dist/enums/spanMapFidelity.enum.js +9 -0
  339. package/dist/enums/spanMapFidelity.enum.js.map +1 -0
  340. package/dist/enums/spanMapFidelity.js +9 -0
  341. package/dist/enums/spanMapFidelity.js.map +1 -0
  342. package/dist/enums/spanMapKind.d.ts +2 -0
  343. package/dist/enums/spanMapKind.d.ts.map +1 -0
  344. package/dist/enums/spanMapKind.enum.d.ts +6 -0
  345. package/dist/enums/spanMapKind.enum.d.ts.map +1 -0
  346. package/dist/enums/spanMapKind.enum.js +8 -0
  347. package/dist/enums/spanMapKind.enum.js.map +1 -0
  348. package/dist/enums/spanMapKind.js +8 -0
  349. package/dist/enums/spanMapKind.js.map +1 -0
  350. package/dist/enums/symbolFlags.enum.d.ts +1 -2
  351. package/dist/enums/symbolFlags.enum.d.ts.map +1 -1
  352. package/dist/enums/symbolFlags.enum.js +2 -3
  353. package/dist/enums/symbolFlags.enum.js.map +1 -1
  354. package/dist/enums/symbolFlags.js +2 -3
  355. package/dist/enums/symbolFlags.js.map +1 -1
  356. package/dist/enums/symbolOwnerKind.d.ts +2 -0
  357. package/dist/enums/symbolOwnerKind.d.ts.map +1 -0
  358. package/dist/enums/symbolOwnerKind.enum.d.ts +5 -0
  359. package/dist/enums/symbolOwnerKind.enum.d.ts.map +1 -0
  360. package/dist/enums/symbolOwnerKind.enum.js +7 -0
  361. package/dist/enums/symbolOwnerKind.enum.js.map +1 -0
  362. package/dist/enums/symbolOwnerKind.js +7 -0
  363. package/dist/enums/symbolOwnerKind.js.map +1 -0
  364. package/dist/enums/syntaxKind.enum.d.ts +198 -197
  365. package/dist/enums/syntaxKind.enum.d.ts.map +1 -1
  366. package/dist/enums/syntaxKind.enum.js +199 -198
  367. package/dist/enums/syntaxKind.enum.js.map +1 -1
  368. package/dist/enums/syntaxKind.js +199 -198
  369. package/dist/enums/syntaxKind.js.map +1 -1
  370. package/dist/enums/tokenFlags.enum.js +1 -1
  371. package/dist/enums/tokenFlags.enum.js.map +1 -1
  372. package/dist/enums/tokenFlags.js +1 -1
  373. package/dist/enums/tokenFlags.js.map +1 -1
  374. package/dist/enums/typeFlags.enum.js +1 -1
  375. package/dist/enums/typeFlags.enum.js.map +1 -1
  376. package/dist/enums/typeFlags.js +1 -1
  377. package/dist/enums/typeFlags.js.map +1 -1
  378. package/dist/enums/typeFormatFlags.d.ts +2 -0
  379. package/dist/enums/typeFormatFlags.d.ts.map +1 -0
  380. package/dist/enums/typeFormatFlags.enum.d.ts +29 -0
  381. package/dist/enums/typeFormatFlags.enum.d.ts.map +1 -0
  382. package/dist/enums/typeFormatFlags.enum.js +31 -0
  383. package/dist/enums/typeFormatFlags.enum.js.map +1 -0
  384. package/dist/enums/typeFormatFlags.js +31 -0
  385. package/dist/enums/typeFormatFlags.js.map +1 -0
  386. package/dist/enums/typePredicateKind.enum.js +1 -1
  387. package/dist/enums/typePredicateKind.enum.js.map +1 -1
  388. package/dist/enums/typePredicateKind.js +1 -1
  389. package/dist/enums/typePredicateKind.js.map +1 -1
  390. package/dist/internal/utils.d.ts +23 -0
  391. package/dist/internal/utils.d.ts.map +1 -0
  392. package/dist/internal/utils.js +25 -0
  393. package/dist/internal/utils.js.map +1 -0
  394. package/dist/vscode/extensionApi.d.ts +101 -0
  395. package/dist/vscode/extensionApi.d.ts.map +1 -0
  396. package/dist/vscode/extensionApi.js +2 -0
  397. package/dist/vscode/extensionApi.js.map +1 -0
  398. package/dist/vscode/moduleLoader.d.ts +14 -0
  399. package/dist/vscode/moduleLoader.d.ts.map +1 -0
  400. package/dist/vscode/moduleLoader.js +36 -0
  401. package/dist/vscode/moduleLoader.js.map +1 -0
  402. package/dist/vscode/protocol.generated.d.ts +2886 -0
  403. package/dist/vscode/protocol.generated.d.ts.map +1 -0
  404. package/dist/vscode/protocol.generated.js +4 -0
  405. package/dist/vscode/protocol.generated.js.map +1 -0
  406. package/lib/getExePath.js +8 -5
  407. package/lib/tsc.js +1 -1
  408. package/lib/version.cjs +3 -0
  409. package/lib/version.d.cts +2 -0
  410. package/package.json +48 -41
  411. package/schemas/jsconfig.schema.json +2207 -0
  412. package/schemas/tsconfig.schema.json +2206 -0
  413. package/vendor/vscode-jsonrpc/lib/node/main.js +1 -1
  414. package/vendor/vscode-jsonrpc/package.json +1 -1
  415. package/dist/api/objectRegistry.d.ts +0 -40
  416. package/dist/api/objectRegistry.d.ts.map +0 -1
  417. package/dist/api/objectRegistry.js +0 -61
  418. package/dist/api/objectRegistry.js.map +0 -1
@@ -1,36 +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";
8
+ import { ModuleKind } from "#enums/moduleKind";
9
+ import { ModuleResolutionKind } from "#enums/moduleResolutionKind";
10
+ import { NewLineKind } from "#enums/newLineKind";
5
11
  import { NodeBuilderFlags } from "#enums/nodeBuilderFlags";
6
12
  import { ObjectFlags } from "#enums/objectFlags";
13
+ import { ScriptKind } from "#enums/scriptKind";
7
14
  import { SignatureFlags } from "#enums/signatureFlags";
8
15
  import { SignatureKind } from "#enums/signatureKind";
9
16
  import { SymbolFlags } from "#enums/symbolFlags";
17
+ import { SymbolOwnerKind } from "#enums/symbolOwnerKind";
10
18
  import { TypeFlags } from "#enums/typeFlags";
19
+ import { TypeFormatFlags } from "#enums/typeFormatFlags";
11
20
  import { TypePredicateKind } from "#enums/typePredicateKind";
12
- import { ModifierFlags, } from "../../ast/index.js";
21
+ import { ModifierFlags, unescapeLeadingUnderscores, } from "../../ast/index.js";
22
+ import { assertNever } from "../../internal/utils.js";
13
23
  import { encodeNode, uint8ArrayToBase64, } from "../node/encoder.js";
14
- import { decodeNode, getNodeId, parseNodeHandle, readParseOptionsKey, readSourceFileHash, RemoteSourceFile, } from "../node/node.js";
15
- import { ObjectRegistry, } from "../objectRegistry.js";
16
- import { createGetCanonicalFileName, toPath, } from "../path.js";
17
- import { resolveFileName } from "../proto.js";
18
- import { SourceFileCache } from "../sourceFileCache.js";
24
+ import { decodeNode, getNodeId, parseNodeHandleFromCompiler, readParseOptionsKey, readSourceFileHash, readSourceFileLease, RemoteNode, RemoteSourceFile, } from "../node/node.js";
25
+ import { Wtf8Decoder } from "../node/wtf8.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";
19
30
  import { Client, } from "./client.js";
20
- export { CompletionItemKind, DiagnosticCategory, ElementFlags, ModifierFlags, NodeBuilderFlags, ObjectFlags, SignatureFlags, SignatureKind, SymbolFlags, TypeFlags, TypePredicateKind };
31
+ export { formatDiagnostics, formatDiagnosticsWithColorAndContext } from "../diagnosticFormatter.js";
21
32
  export { documentURIToFileName, fileNameToDocumentURI } from "../path.js";
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
22
55
  export class API {
56
+ /** @internal */
23
57
  client;
58
+ /** @internal */
24
59
  sourceFileCache;
25
60
  toPath;
61
+ decoder = new Wtf8Decoder();
62
+ currentDirectory;
63
+ caseSensitivity;
26
64
  initialized = false;
27
- activeSnapshots = new Set();
28
- latestSnapshot;
29
- internal;
30
- constructor(options) {
65
+ initializing;
66
+ activeSnapshots = new Map();
67
+ activeBuildOrchestrators = new Set();
68
+ activeSourceFileLeases = new Map();
69
+ printer;
70
+ debug;
71
+ constructor(options = {}) {
31
72
  this.client = new Client(options);
32
73
  this.sourceFileCache = new SourceFileCache();
33
- 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;
34
122
  }
35
123
  /**
36
124
  * Create an API instance from an existing LSP connection's API session.
@@ -41,64 +129,437 @@ export class API {
41
129
  await api.ensureInitialized();
42
130
  return api;
43
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
44
142
  async ensureInitialized() {
45
- if (!this.initialized) {
143
+ if (this.initialized)
144
+ return;
145
+ return this.initializing ??= this.initializeWorker();
146
+ }
147
+ async initializeWorker() {
148
+ try {
46
149
  const response = await this.client.apiRequest("initialize", null);
47
- const getCanonicalFileName = createGetCanonicalFileName(response.useCaseSensitiveFileNames);
48
- const currentDirectory = response.currentDirectory;
49
- 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);
50
153
  this.initialized = true;
51
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;
52
194
  }
53
195
  async parseConfigFile(file) {
54
196
  await this.ensureInitialized();
55
197
  return this.client.apiRequest("parseConfigFile", { file });
56
198
  }
57
- async updateSnapshot(params) {
199
+ async parseCommandLine(commandLine) {
58
200
  await this.ensureInitialized();
59
- const requestParams = params ?? {};
60
- if (requestParams.openProject) {
61
- requestParams.openProject = resolveFileName(requestParams.openProject);
62
- }
63
- const data = await this.client.apiRequest("updateSnapshot", requestParams);
64
- // Retain cached source files from previous snapshot for unchanged files
65
- if (this.latestSnapshot) {
66
- this.sourceFileCache.retainForSnapshot(data.snapshot, this.latestSnapshot.id, data.changes);
67
- if (this.latestSnapshot.isDisposed()) {
68
- this.sourceFileCache.releaseSnapshot(this.latestSnapshot.id);
69
- }
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");
70
220
  }
71
- const snapshot = new Snapshot(data, this.client, this.sourceFileCache, this.toPath, () => {
72
- this.activeSnapshots.delete(snapshot);
73
- if (snapshot !== this.latestSnapshot) {
74
- this.sourceFileCache.releaseSnapshot(snapshot.id);
75
- }
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),
76
314
  });
77
- this.latestSnapshot = snapshot;
78
- this.activeSnapshots.add(snapshot);
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);
79
325
  return snapshot;
80
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),
373
+ });
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);
382
+ return snapshot;
383
+ }
384
+ async [globalThis.Symbol.asyncDispose]() {
385
+ await this.close(); // @sync: this.close();
386
+ }
81
387
  async close() {
82
- // Dispose all active snapshots
83
- for (const snapshot of [...this.activeSnapshots]) {
84
- 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
+ }
85
393
  }
86
- // Release the latest snapshot's cache refs if still held
87
- if (this.latestSnapshot) {
88
- this.sourceFileCache.releaseSnapshot(this.latestSnapshot.id);
89
- 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;
90
425
  }
91
- await this.client.close();
92
- this.sourceFileCache.clear();
93
426
  }
94
427
  clearSourceFileCache() {
95
428
  this.sourceFileCache.clear();
96
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
+ }
449
+ /**
450
+ * Returns a snapshot of collected timing information for requests made
451
+ * through this API instance: client-measured round-trip latency and bytes
452
+ * transferred, folded together with the server's own per-request processing
453
+ * time and an estimated transport overhead (round-trip minus server time).
454
+ *
455
+ * Fetching the snapshot issues a lightweight request to the server to
456
+ * retrieve its timing collection. Collection must be enabled via the
457
+ * `collectTiming` option or `TS_API_TIMING_DIR` environment variable; when
458
+ * it is not, the returned snapshot has `enabled: false` and zeroed totals.
459
+ */
460
+ getTimingInfo() {
461
+ return this.client.getTimingInfo();
462
+ }
463
+ /** Clears all accumulated timing totals and recent-request history, on both the client and the server. */
464
+ resetTimingInfo() {
465
+ return this.client.resetTimingInfo();
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;
97
501
  }
98
- export class InternalAPI {
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
+ }
559
+ }
560
+ export class DebugHandlers {
99
561
  client;
100
562
  ensureInitialized;
101
- /** @internal */
102
563
  constructor(client, ensureInitialized) {
103
564
  this.client = client;
104
565
  this.ensureInitialized = ensureInitialized;
@@ -120,37 +581,70 @@ export class InternalAPI {
120
581
  }
121
582
  export class Snapshot {
122
583
  id;
584
+ operation;
123
585
  projectMap;
124
586
  toPath;
125
- client;
126
- objectRegistry;
587
+ api;
127
588
  disposed = false;
589
+ disposePromise;
128
590
  onDispose;
129
- constructor(data, client, sourceFileCache, toPath, onDispose) {
591
+ snapshotRegistry;
592
+ projectDataMap;
593
+ updateSnapshot;
594
+ get client() {
595
+ return this.api.client;
596
+ }
597
+ constructor(data, toPath, api, onDispose, updateSnapshot, baseSnapshot) {
130
598
  this.id = data.snapshot;
131
- this.client = client;
599
+ this.api = api;
132
600
  this.toPath = toPath;
133
601
  this.onDispose = onDispose;
134
- this.objectRegistry = new SnapshotObjectRegistry({
135
- createSymbol: symbolData => new Symbol(symbolData, this.objectRegistry),
136
- createType: typeData => new TypeObject(typeData, this.objectRegistry),
137
- createSignature: sigData => new Signature(sigData, this.objectRegistry),
138
- }, client, this.id);
139
- // Create projects
602
+ this.updateSnapshot = updateSnapshot;
140
603
  this.projectMap = new Map();
141
- for (const projData of data.projects) {
142
- const project = new Project(projData, this.id, client, this.objectRegistry, sourceFileCache, toPath);
143
- 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);
144
607
  }
608
+ for (const projectData of data.projects) {
609
+ projectDataMap.set(projectData.id, projectData);
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
+ };
145
621
  }
146
622
  getProjects() {
147
623
  this.ensureNotDisposed();
148
624
  return [...this.projectMap.values()];
149
625
  }
150
- getProject(configFileName) {
626
+ getConfiguredProject(configFileName) {
151
627
  this.ensureNotDisposed();
152
- return this.projectMap.get(this.toPath(configFileName));
628
+ const id = this.toPath(configFileName);
629
+ return this.projectMap.get(id);
630
+ }
631
+ getProject(projectId) {
632
+ this.ensureNotDisposed();
633
+ return this.projectMap.get(projectId);
634
+ }
635
+ getProgram(projectId) {
636
+ return this.getProject(projectId)?.program;
153
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
+ */
154
648
  async getDefaultProjectForFile(file) {
155
649
  this.ensureNotDisposed();
156
650
  const data = await this.client.apiRequest("getDefaultProjectForFile", {
@@ -159,18 +653,29 @@ export class Snapshot {
159
653
  });
160
654
  if (!data)
161
655
  return undefined;
162
- return this.projectMap.get(this.toPath(data.configFileName));
656
+ return this.projectMap.get(data.id);
163
657
  }
164
- [globalThis.Symbol.dispose]() {
165
- this.dispose();
658
+ [globalThis.Symbol.asyncDispose]() {
659
+ return this.dispose(); // @sync: this.dispose();
166
660
  }
167
- async dispose() {
661
+ dispose() {
662
+ return this.disposePromise ??= this.disposeWorker();
663
+ }
664
+ async disposeWorker() {
168
665
  if (this.disposed)
169
666
  return;
170
667
  this.disposed = true;
171
- this.objectRegistry.clear();
172
- this.onDispose();
173
- await this.client.apiRequest("release", { snapshot: this.id });
668
+ for (const project of this.projectMap.values()) {
669
+ project.dispose();
670
+ }
671
+ this.projectMap.clear();
672
+ this.snapshotRegistry.clear();
673
+ try {
674
+ await this.client.apiRequest("release", { snapshot: this.id });
675
+ }
676
+ finally {
677
+ this.onDispose();
678
+ }
174
679
  }
175
680
  isDisposed() {
176
681
  return this.disposed;
@@ -180,39 +685,203 @@ export class Snapshot {
180
685
  throw new Error("Snapshot is disposed");
181
686
  }
182
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
+ }
183
695
  }
184
- class SnapshotObjectRegistry extends ObjectRegistry {
696
+ export class ModuleResolver {
697
+ id;
185
698
  client;
186
- snapshotId;
187
- constructor(factories, client, snapshotId) {
188
- super(factories);
699
+ disposeCallback;
700
+ disposed = false;
701
+ constructor(id, client, disposeCallback) {
702
+ this.id = id;
189
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
+ }
735
+ }
736
+ class SnapshotObjectRegistry {
737
+ symbols = new Map();
738
+ projectRegistries = new Map();
739
+ snapshotId;
740
+ constructor(snapshotId) {
190
741
  this.snapshotId = snapshotId;
191
742
  }
192
- async fetchType(source, method, handle) {
193
- if (!handle)
194
- return undefined;
195
- const cached = this.getType(handle);
196
- if (cached)
197
- return cached;
743
+ addProjectRegistry(registry) {
744
+ this.projectRegistries.set(registry.project.id, registry);
745
+ }
746
+ getOrCreateSymbol(data) {
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);
751
+ if (!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);
760
+ }
761
+ return symbol;
762
+ }
763
+ getSymbol(id) {
764
+ return this.symbols.get(id);
765
+ }
766
+ clear() {
767
+ this.symbols.clear();
768
+ }
769
+ }
770
+ class ProjectObjectRegistry {
771
+ snapshotId;
772
+ project;
773
+ snapshotRegistry;
774
+ types = new Map();
775
+ signatures = new Map();
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) {
784
+ this.snapshotId = snapshotId;
785
+ this.project = project;
786
+ this.snapshotRegistry = snapshotRegistry;
787
+ snapshotRegistry.addProjectRegistry(this);
788
+ }
789
+ 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
+ }));
801
+ }
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;
814
+ }
815
+ getOrCreateType(data) {
816
+ let type = this.types.get(data.id);
817
+ if (!type) {
818
+ type = new TypeObject(data, this);
819
+ this.types.set(data.id, type);
820
+ }
821
+ return type;
822
+ }
823
+ getType(id) {
824
+ return this.types.get(id);
825
+ }
826
+ createNodeHandle(handle) {
827
+ return new NodeHandle(handle, this.project);
828
+ }
829
+ getOrCreateSignature(data) {
830
+ let sig = this.signatures.get(data.id);
831
+ if (!sig) {
832
+ sig = new Signature(data, this.project, this);
833
+ this.signatures.set(data.id, sig);
834
+ }
835
+ return sig;
836
+ }
837
+ getSignature(id) {
838
+ return this.signatures.get(id);
839
+ }
840
+ clear() {
841
+ this.disposed = true;
842
+ this.types.clear();
843
+ this.signatures.clear();
844
+ }
845
+ ensureNotDisposed() {
846
+ if (this.disposed)
847
+ throw new Error("Project object registry is disposed");
848
+ }
849
+ async fetchOptionalType(source, method, handle) {
850
+ if (handle !== false) {
851
+ if (!handle)
852
+ return undefined;
853
+ const cached = this.getType(handle);
854
+ if (cached)
855
+ return cached;
856
+ }
198
857
  const data = await this.client.apiRequest(method, {
199
858
  snapshot: this.snapshotId,
859
+ project: this.project.id,
200
860
  objectId: source.id,
201
861
  });
202
862
  if (!data)
203
- throw new Error(`${method} returned null type for ${source.constructor.name} ${source.id}`);
863
+ return undefined;
204
864
  return this.getOrCreateType(data);
205
865
  }
206
- async fetchSymbol(source, method, handle) {
207
- if (!handle)
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)
208
874
  return undefined;
209
- const cached = this.getSymbol(handle);
875
+ const cached = this.getCachedSymbol(reference);
210
876
  if (cached)
211
877
  return cached;
212
- const data = await this.client.apiRequest(method, {
213
- snapshot: this.snapshotId,
214
- objectId: source.id,
215
- });
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
+ });
216
885
  if (!data)
217
886
  throw new Error(`${method} returned null symbol for ${source.constructor.name} ${source.id}`);
218
887
  return this.getOrCreateSymbol(data);
@@ -225,6 +894,7 @@ class SnapshotObjectRegistry extends ObjectRegistry {
225
894
  return cached;
226
895
  const data = await this.client.apiRequest(method, {
227
896
  snapshot: this.snapshotId,
897
+ project: this.project.id,
228
898
  objectId: source.id,
229
899
  });
230
900
  if (!data)
@@ -248,6 +918,7 @@ class SnapshotObjectRegistry extends ObjectRegistry {
248
918
  }
249
919
  const typesData = await this.client.apiRequest(method, {
250
920
  snapshot: this.snapshotId,
921
+ project: this.project.id,
251
922
  objectId: source.id,
252
923
  });
253
924
  if (typesData == null)
@@ -255,134 +926,561 @@ class SnapshotObjectRegistry extends ObjectRegistry {
255
926
  else
256
927
  return typesData.map(data => this.getOrCreateType(data));
257
928
  }
258
- async fetchSymbols(source, method, handles) {
259
- if (handles) {
260
- const result = new Array(handles.length);
261
- let allCached = true;
262
- for (let i = 0; i < handles.length; i++) {
263
- const cached = this.getSymbol(handles[i]);
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]);
264
934
  if (!cached) {
265
- allCached = false;
266
- break;
935
+ return this.fetchSymbolsFromServer(source, method);
267
936
  }
268
937
  result[i] = cached;
269
938
  }
270
- if (allCached)
271
- return result;
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)) ?? [];
952
+ }
953
+ // getBaseTypes is a checker-level endpoint keyed by `type` (not `objectId`),
954
+ // so it cannot go through fetchTypes. This helper reuses that server method.
955
+ async fetchBaseTypes(source) {
956
+ const typesData = await this.client.apiRequest("getBaseTypes", {
957
+ snapshot: this.snapshotId,
958
+ project: this.project.id,
959
+ type: source.id,
960
+ });
961
+ if (typesData == null)
962
+ return [];
963
+ return typesData.map(data => this.getOrCreateType(data));
964
+ }
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;
1038
+ this.configFileName = data.configFileName;
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);
1049
+ }
1050
+ dispose() {
1051
+ this.checker.dispose();
1052
+ }
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
+ }
1169
+ export class Program {
1170
+ /** @internal */
1171
+ snapshotId;
1172
+ id;
1173
+ project;
1174
+ toPath;
1175
+ decoder = new Wtf8Decoder();
1176
+ sourceFileMetadataCache = new Map();
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) {
1186
+ this.snapshotId = snapshotId;
1187
+ this.id = project.id;
1188
+ this.project = project;
1189
+ this.toPath = toPath;
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
+ }
1216
+ getCompilerOptions() {
1217
+ return this.project.parsedCommandLine.options;
1218
+ }
1219
+ async getSourceFile(file) {
1220
+ const fileName = resolveFileName(file);
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) {
1233
+ // Check if we already have a retained cache entry for this (snapshot, project) pair
1234
+ const retained = this.sourceFileCache.getRetained(path, this.snapshotId, this.project.id);
1235
+ if (retained) {
1236
+ return retained;
1237
+ }
1238
+ // Fetch from server
1239
+ const binaryData = await this.client.apiRequestBinary("getSourceFile", {
1240
+ snapshot: this.snapshotId,
1241
+ project: this.project.id,
1242
+ file,
1243
+ });
1244
+ if (!binaryData) {
1245
+ return undefined;
1246
+ }
1247
+ // Create a new RemoteSourceFile and cache it (set returns existing if hash matches)
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;
1305
+ }
1306
+ async getSourceFileNames() {
1307
+ const data = await this.client.apiRequest("getSourceFileNames", {
1308
+ snapshot: this.snapshotId,
1309
+ project: this.project.id,
1310
+ });
1311
+ return data ?? [];
1312
+ }
1313
+ /**
1314
+ * Returns program-stored metadata for the given source file, or `undefined` if the file
1315
+ * is not part of the program. Metadata is fetched lazily per file and cached on this
1316
+ * `Program` instance.
1317
+ */
1318
+ getSourceFileMetadata(file) {
1319
+ return this.getSourceFileMetadataByPath(this.pathKeyForFileName(resolveFileName(file)));
1320
+ }
1321
+ /**
1322
+ * Returns program-stored metadata for the source file at the given path, or `undefined`
1323
+ * if the file is not part of the program. Like {@link getSourceFileMetadata}, but skips
1324
+ * the file name to path conversion. Metadata is fetched lazily per file and cached on
1325
+ * this `Program` instance.
1326
+ */
1327
+ getSourceFileMetadataByPath(path) {
1328
+ let metadata = this.sourceFileMetadataCache.get(path);
1329
+ if (metadata === undefined) {
1330
+ metadata = this.fetchSourceFileMetadata(path);
1331
+ this.sourceFileMetadataCache.set(path, metadata);
272
1332
  }
273
- const symbolData = await this.client.apiRequest(method, {
1333
+ return metadata;
1334
+ }
1335
+ async fetchSourceFileMetadata(path) {
1336
+ // PathKey is serialized as a string; the server deliberately treats all
1337
+ // client-provided path text as untrusted input.
1338
+ const data = await this.client.apiRequest("getSourceFileMetadata", {
274
1339
  snapshot: this.snapshotId,
275
- objectId: source.id,
1340
+ project: this.project.id,
1341
+ file: path,
276
1342
  });
277
- if (symbolData == null)
278
- return [];
279
- else
280
- return symbolData.map(data => this.getOrCreateSymbol(data));
1343
+ return data ?? undefined;
281
1344
  }
282
- }
283
- export class Project {
284
- id;
285
- configFileName;
286
- compilerOptions;
287
- rootFiles;
288
- program;
289
- checker;
290
- emitter;
291
- client;
292
- constructor(data, snapshotId, client, objectRegistry, sourceFileCache, toPath) {
293
- this.id = data.id;
294
- this.configFileName = data.configFileName;
295
- this.compilerOptions = data.compilerOptions;
296
- this.rootFiles = data.rootFiles;
297
- this.client = client;
298
- this.program = new Program(snapshotId, this.id, client, sourceFileCache, toPath);
299
- this.checker = new Checker(snapshotId, this.id, client, objectRegistry);
300
- this.emitter = new Emitter(client);
1345
+ pathKeyForFileName(fileName) {
1346
+ return this.toPath(fileName, this.project.currentDirectory);
301
1347
  }
302
- }
303
- export class Program {
304
- snapshotId;
305
- projectId;
306
- client;
307
- sourceFileCache;
308
- toPath;
309
- decoder = new TextDecoder();
310
- constructor(snapshotId, projectId, client, sourceFileCache, toPath) {
311
- this.snapshotId = snapshotId;
312
- this.projectId = projectId;
313
- this.client = client;
314
- this.sourceFileCache = sourceFileCache;
315
- this.toPath = toPath;
1348
+ /**
1349
+ * Returns whether the given source file was loaded as part of an external library
1350
+ * (e.g. a dependency resolved from `node_modules`). The underlying program metadata is
1351
+ * fetched lazily per file and cached on this `Program` instance.
1352
+ */
1353
+ async isSourceFileFromExternalLibrary(file) {
1354
+ const metadata = await this.getSourceFileMetadataByPath(file.path);
1355
+ return metadata?.isFromExternalLibrary ?? false;
316
1356
  }
317
- async getSourceFile(file) {
318
- const fileName = resolveFileName(file);
319
- const path = this.toPath(fileName);
320
- // Check if we already have a retained cache entry for this (snapshot, project) pair
321
- const retained = this.sourceFileCache.getRetained(path, this.snapshotId, this.projectId);
322
- if (retained) {
323
- return retained;
324
- }
325
- // Fetch from server
326
- const binaryData = await this.client.apiRequestBinary("getSourceFile", {
1357
+ /**
1358
+ * Returns whether the given source file is a default library file (e.g. `lib.d.ts`).
1359
+ * The underlying program metadata is fetched lazily per file and cached on this
1360
+ * `Program` instance.
1361
+ */
1362
+ async isSourceFileDefaultLibrary(file) {
1363
+ const metadata = await this.getSourceFileMetadataByPath(file.path);
1364
+ return metadata?.isDefaultLibrary ?? false;
1365
+ }
1366
+ /**
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", {
327
1383
  snapshot: this.snapshotId,
328
- project: this.projectId,
1384
+ project: this.project.id,
329
1385
  file,
330
1386
  });
331
1387
  if (!binaryData) {
332
1388
  return undefined;
333
1389
  }
334
- const view = new DataView(binaryData.buffer, binaryData.byteOffset, binaryData.byteLength);
335
- const contentHash = readSourceFileHash(view);
336
- const parseOptionsKey = readParseOptionsKey(view);
337
- // Create a new RemoteSourceFile and cache it (set returns existing if hash matches)
338
- const sourceFile = new RemoteSourceFile(binaryData, this.decoder);
339
- return this.sourceFileCache.set(path, sourceFile, parseOptionsKey, contentHash, this.snapshotId, this.projectId);
1390
+ return new RemoteSourceFile(binaryData, this.decoder, undefined, this.project.api);
340
1391
  }
341
1392
  /**
342
- * Get syntactic (parse) diagnostics for a specific file or all files.
343
- * @param file - Optional file to get diagnostics for. If omitted, returns diagnostics for all files.
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.
344
1395
  */
345
1396
  async getSyntacticDiagnostics(file) {
1397
+ const files = file === undefined ? undefined
1398
+ : Array.isArray(file) ? file
1399
+ : [file];
346
1400
  const data = await this.client.apiRequest("getSyntacticDiagnostics", {
347
1401
  snapshot: this.snapshotId,
348
- project: this.projectId,
349
- ...(file !== undefined ? { file } : {}),
1402
+ project: this.project.id,
1403
+ files,
1404
+ });
1405
+ return data ?? [];
1406
+ }
1407
+ /**
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.
1410
+ */
1411
+ async getBindDiagnostics(file) {
1412
+ const files = file === undefined ? undefined
1413
+ : Array.isArray(file) ? file
1414
+ : [file];
1415
+ const data = await this.client.apiRequest("getBindDiagnostics", {
1416
+ snapshot: this.snapshotId,
1417
+ project: this.project.id,
1418
+ files,
350
1419
  });
351
1420
  return data ?? [];
352
1421
  }
353
1422
  /**
354
- * Get semantic (type-check) diagnostics for a specific file or all files.
355
- * @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.
356
1425
  */
357
1426
  async getSemanticDiagnostics(file) {
1427
+ const files = file === undefined ? undefined
1428
+ : Array.isArray(file) ? file
1429
+ : [file];
358
1430
  const data = await this.client.apiRequest("getSemanticDiagnostics", {
359
1431
  snapshot: this.snapshotId,
360
- project: this.projectId,
361
- ...(file !== undefined ? { file } : {}),
1432
+ project: this.project.id,
1433
+ files,
362
1434
  });
363
1435
  return data ?? [];
364
1436
  }
365
1437
  /**
366
- * Get suggestion diagnostics for a specific file or all files.
367
- * @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.
368
1440
  */
369
1441
  async getSuggestionDiagnostics(file) {
1442
+ const files = file === undefined ? undefined
1443
+ : Array.isArray(file) ? file
1444
+ : [file];
370
1445
  const data = await this.client.apiRequest("getSuggestionDiagnostics", {
371
1446
  snapshot: this.snapshotId,
372
- project: this.projectId,
373
- ...(file !== undefined ? { file } : {}),
1447
+ project: this.project.id,
1448
+ files,
374
1449
  });
375
1450
  return data ?? [];
376
1451
  }
377
1452
  /**
378
- * Get declaration emit diagnostics for a specific file or all files.
379
- * @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.
380
1455
  */
381
1456
  async getDeclarationDiagnostics(file) {
1457
+ const files = file === undefined ? undefined
1458
+ : Array.isArray(file) ? file
1459
+ : [file];
382
1460
  const data = await this.client.apiRequest("getDeclarationDiagnostics", {
383
1461
  snapshot: this.snapshotId,
384
- project: this.projectId,
385
- ...(file !== undefined ? { file } : {}),
1462
+ project: this.project.id,
1463
+ files,
1464
+ });
1465
+ return data ?? [];
1466
+ }
1467
+ /**
1468
+ * Get program-wide diagnostics for the project, including compiler options diagnostics.
1469
+ */
1470
+ async getProgramDiagnostics() {
1471
+ const data = await this.client.apiRequest("getProgramDiagnostics", {
1472
+ snapshot: this.snapshotId,
1473
+ project: this.project.id,
1474
+ });
1475
+ return data ?? [];
1476
+ }
1477
+ /**
1478
+ * Get global (non-file-specific) semantic diagnostics for the project.
1479
+ */
1480
+ async getGlobalDiagnostics() {
1481
+ const data = await this.client.apiRequest("getGlobalDiagnostics", {
1482
+ snapshot: this.snapshotId,
1483
+ project: this.project.id,
386
1484
  });
387
1485
  return data ?? [];
388
1486
  }
@@ -392,34 +1490,222 @@ export class Program {
392
1490
  async getConfigFileParsingDiagnostics() {
393
1491
  const data = await this.client.apiRequest("getConfigFileParsingDiagnostics", {
394
1492
  snapshot: this.snapshotId,
395
- project: this.projectId,
1493
+ project: this.project.id,
396
1494
  });
397
1495
  return data ?? [];
398
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
+ };
399
1639
  }
400
1640
  export class Checker {
401
1641
  snapshotId;
402
- projectId;
403
- client;
1642
+ project;
404
1643
  objectRegistry;
405
- constructor(snapshotId, projectId, client, objectRegistry) {
1644
+ wellKnownSymbols;
1645
+ wellKnownSignatures;
1646
+ get client() {
1647
+ return this.project.api.client;
1648
+ }
1649
+ constructor(snapshotId, project, objectRegistry) {
406
1650
  this.snapshotId = snapshotId;
407
- this.projectId = projectId;
408
- this.client = client;
1651
+ this.project = project;
409
1652
  this.objectRegistry = objectRegistry;
410
1653
  }
1654
+ dispose() {
1655
+ this.objectRegistry.clear();
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
+ }
411
1697
  async getSymbolAtLocation(nodeOrNodes) {
412
1698
  if (Array.isArray(nodeOrNodes)) {
413
1699
  const data = await this.client.apiRequest("getSymbolsAtLocations", {
414
1700
  snapshot: this.snapshotId,
415
- project: this.projectId,
1701
+ project: this.project.id,
416
1702
  locations: nodeOrNodes.map(node => getNodeId(node)),
417
1703
  });
418
1704
  return data.map(d => d ? this.objectRegistry.getOrCreateSymbol(d) : undefined);
419
1705
  }
420
1706
  const data = await this.client.apiRequest("getSymbolAtLocation", {
421
1707
  snapshot: this.snapshotId,
422
- project: this.projectId,
1708
+ project: this.project.id,
423
1709
  location: getNodeId(nodeOrNodes),
424
1710
  });
425
1711
  return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
@@ -428,7 +1714,7 @@ export class Checker {
428
1714
  if (typeof positionOrPositions === "number") {
429
1715
  const data = await this.client.apiRequest("getSymbolAtPosition", {
430
1716
  snapshot: this.snapshotId,
431
- project: this.projectId,
1717
+ project: this.project.id,
432
1718
  file,
433
1719
  position: positionOrPositions,
434
1720
  });
@@ -436,126 +1722,117 @@ export class Checker {
436
1722
  }
437
1723
  const data = await this.client.apiRequest("getSymbolsAtPositions", {
438
1724
  snapshot: this.snapshotId,
439
- project: this.projectId,
1725
+ project: this.project.id,
440
1726
  file,
441
1727
  positions: positionOrPositions,
442
1728
  });
443
1729
  return data.map(d => d ? this.objectRegistry.getOrCreateSymbol(d) : undefined);
444
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
+ }
445
1747
  async getTypeOfSymbol(symbolOrSymbols) {
446
1748
  if (Array.isArray(symbolOrSymbols)) {
447
1749
  const data = await this.client.apiRequest("getTypesOfSymbols", {
448
1750
  snapshot: this.snapshotId,
449
- project: this.projectId,
450
- symbols: symbolOrSymbols.map(s => s.id),
1751
+ project: this.project.id,
1752
+ symbols: symbolOrSymbols.map(symbol => symbol.reference),
451
1753
  });
452
- return data.map(d => d ? this.objectRegistry.getOrCreateType(d) : undefined);
1754
+ return data.map(d => this.objectRegistry.getOrCreateType(d));
453
1755
  }
454
1756
  const data = await this.client.apiRequest("getTypeOfSymbol", {
455
1757
  snapshot: this.snapshotId,
456
- project: this.projectId,
457
- symbol: symbolOrSymbols.id,
1758
+ project: this.project.id,
1759
+ symbol: symbolOrSymbols.reference,
458
1760
  });
459
- return data ? this.objectRegistry.getOrCreateType(data) : undefined;
1761
+ return this.objectRegistry.getOrCreateType(data);
460
1762
  }
1763
+ /**
1764
+ * Get the declared type of a symbol. Always returns a type; for symbols whose
1765
+ * declared type cannot be determined the checker yields the error type (use
1766
+ * {@link Type.isErrorType} to detect it).
1767
+ */
461
1768
  async getDeclaredTypeOfSymbol(symbol) {
462
1769
  const data = await this.client.apiRequest("getDeclaredTypeOfSymbol", {
463
1770
  snapshot: this.snapshotId,
464
- project: this.projectId,
465
- symbol: symbol.id,
466
- });
467
- return data ? this.objectRegistry.getOrCreateType(data) : undefined;
468
- }
469
- async getReferencesToSymbolInFile(file, symbol) {
470
- const data = await this.client.apiRequest("getReferencesToSymbolInFile", {
471
- snapshot: this.snapshotId,
472
- project: this.projectId,
473
- file,
474
- symbol: symbol.id,
475
- });
476
- return (data ?? []).map(h => new NodeHandle(h));
477
- }
478
- async getReferencedSymbolsForNode(node, position) {
479
- const data = await this.client.apiRequest("getReferencedSymbolsForNode", {
480
- snapshot: this.snapshotId,
481
- project: this.projectId,
482
- node: getNodeId(node),
483
- position,
1771
+ project: this.project.id,
1772
+ symbol: symbol.reference,
484
1773
  });
485
- return (data ?? []).map(entry => ({
486
- definition: new NodeHandle(entry.definition),
487
- symbol: entry.symbol ? this.objectRegistry.getOrCreateSymbol(entry.symbol) : undefined,
488
- references: (entry.references ?? []).map(h => new NodeHandle(h)),
489
- }));
1774
+ return this.objectRegistry.getOrCreateType(data);
490
1775
  }
491
- async getSignatureUsage(signatureDecl) {
492
- 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", {
493
1784
  snapshot: this.snapshotId,
494
- project: this.projectId,
495
- signatureDecl: getNodeId(signatureDecl),
1785
+ project: this.project.id,
1786
+ symbol: symbol.reference,
496
1787
  });
497
- return (data ?? []).map(entry => ({
498
- name: new NodeHandle(entry.name),
499
- call: entry.call ? new NodeHandle(entry.call) : undefined,
500
- }));
1788
+ return this.objectRegistry.getOrCreateType(data);
501
1789
  }
502
- async getCompletionsAtPosition(document, position, options) {
503
- const data = await this.client.apiRequest("getCompletionsAtPosition", {
1790
+ async getReferencesToSymbolInFile(file, symbol) {
1791
+ const data = await this.client.apiRequest("getReferencesToSymbolInFile", {
504
1792
  snapshot: this.snapshotId,
505
- project: this.projectId,
506
- file: document,
507
- position,
508
- triggerCharacter: options?.triggerCharacter,
509
- includeSymbol: options?.includeSymbol,
1793
+ project: this.project.id,
1794
+ file,
1795
+ symbol: symbol.reference,
510
1796
  });
511
- if (!data)
512
- return undefined;
513
- return {
514
- isIncomplete: data.isIncomplete,
515
- entries: data.entries.map(e => ({
516
- ...e,
517
- symbol: e.symbol ? this.objectRegistry.getOrCreateSymbol(e.symbol) : undefined,
518
- })),
519
- };
1797
+ return (data ?? []).map(h => new NodeHandle(h, this.project));
520
1798
  }
521
1799
  async getTypeAtLocation(nodeOrNodes) {
522
1800
  if (Array.isArray(nodeOrNodes)) {
523
1801
  const data = await this.client.apiRequest("getTypeAtLocations", {
524
1802
  snapshot: this.snapshotId,
525
- project: this.projectId,
1803
+ project: this.project.id,
526
1804
  locations: nodeOrNodes.map(node => getNodeId(node)),
527
1805
  });
528
- return data.map(d => d ? this.objectRegistry.getOrCreateType(d) : undefined);
1806
+ return data.map(d => this.objectRegistry.getOrCreateType(d));
529
1807
  }
530
1808
  const data = await this.client.apiRequest("getTypeAtLocation", {
531
1809
  snapshot: this.snapshotId,
532
- project: this.projectId,
1810
+ project: this.project.id,
533
1811
  location: getNodeId(nodeOrNodes),
534
1812
  });
535
- return data ? this.objectRegistry.getOrCreateType(data) : undefined;
1813
+ return this.objectRegistry.getOrCreateType(data);
536
1814
  }
537
1815
  async getSignaturesOfType(type, kind) {
538
- const data = await this.client.apiRequest("getSignaturesOfType", {
539
- snapshot: this.snapshotId,
540
- project: this.projectId,
541
- type: type.id,
542
- kind,
543
- });
544
- return data.map(d => this.objectRegistry.getOrCreateSignature(d));
1816
+ return kind === SignatureKind.Call ? type.getCallSignatures() : type.getConstructSignatures();
545
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
+ */
546
1823
  async getResolvedSignature(node) {
547
1824
  const data = await this.client.apiRequest("getResolvedSignature", {
548
1825
  snapshot: this.snapshotId,
549
- project: this.projectId,
1826
+ project: this.project.id,
550
1827
  location: getNodeId(node),
551
1828
  });
552
- return data ? this.objectRegistry.getOrCreateSignature(data) : undefined;
1829
+ return this.objectRegistry.getOrCreateSignature(data);
553
1830
  }
554
1831
  async getTypeAtPosition(file, positionOrPositions) {
555
1832
  if (typeof positionOrPositions === "number") {
556
1833
  const data = await this.client.apiRequest("getTypeAtPosition", {
557
1834
  snapshot: this.snapshotId,
558
- project: this.projectId,
1835
+ project: this.project.id,
559
1836
  file,
560
1837
  position: positionOrPositions,
561
1838
  });
@@ -563,7 +1840,7 @@ export class Checker {
563
1840
  }
564
1841
  const data = await this.client.apiRequest("getTypesAtPositions", {
565
1842
  snapshot: this.snapshotId,
566
- project: this.projectId,
1843
+ project: this.project.id,
567
1844
  file,
568
1845
  positions: positionOrPositions,
569
1846
  });
@@ -574,7 +1851,7 @@ export class Checker {
574
1851
  const isNode = location && "kind" in location;
575
1852
  const data = await this.client.apiRequest("resolveName", {
576
1853
  snapshot: this.snapshotId,
577
- project: this.projectId,
1854
+ project: this.project.id,
578
1855
  name,
579
1856
  meaning,
580
1857
  location: isNode ? getNodeId(location) : undefined,
@@ -584,6 +1861,22 @@ export class Checker {
584
1861
  });
585
1862
  return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
586
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
+ }
587
1880
  async getResolvedSymbol(node) {
588
1881
  const text = node.text;
589
1882
  if (!text)
@@ -593,63 +1886,87 @@ export class Checker {
593
1886
  async getContextualType(node) {
594
1887
  const data = await this.client.apiRequest("getContextualType", {
595
1888
  snapshot: this.snapshotId,
596
- project: this.projectId,
1889
+ project: this.project.id,
597
1890
  location: getNodeId(node),
598
1891
  });
599
1892
  return data ? this.objectRegistry.getOrCreateType(data) : undefined;
600
1893
  }
601
- async getBaseTypeOfLiteralType(type) {
602
- const data = await this.client.apiRequest("getBaseTypeOfLiteralType", {
1894
+ async getContextualTypeForArgumentAtIndex(node, argIndex) {
1895
+ const data = await this.client.apiRequest("getContextualTypeForArgument", {
603
1896
  snapshot: this.snapshotId,
604
- project: this.projectId,
605
- type: type.id,
1897
+ project: this.project.id,
1898
+ location: getNodeId(node),
1899
+ index: argIndex,
606
1900
  });
607
1901
  return data ? this.objectRegistry.getOrCreateType(data) : undefined;
608
1902
  }
609
- async getNonNullableType(type) {
610
- const data = await this.client.apiRequest("getNonNullableType", {
1903
+ async getAwaitedType(type) {
1904
+ const data = await this.client.apiRequest("getAwaitedType", {
611
1905
  snapshot: this.snapshotId,
612
- project: this.projectId,
1906
+ project: this.project.id,
613
1907
  type: type.id,
614
1908
  });
615
1909
  return data ? this.objectRegistry.getOrCreateType(data) : undefined;
616
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
+ */
617
1929
  async getTypeFromTypeNode(node) {
618
1930
  const data = await this.client.apiRequest("getTypeFromTypeNode", {
619
1931
  snapshot: this.snapshotId,
620
- project: this.projectId,
1932
+ project: this.project.id,
621
1933
  location: getNodeId(node),
622
1934
  });
623
- return data ? this.objectRegistry.getOrCreateType(data) : undefined;
1935
+ return this.objectRegistry.getOrCreateType(data);
624
1936
  }
1937
+ /** Get the widened type. Always returns a type. */
625
1938
  async getWidenedType(type) {
626
1939
  const data = await this.client.apiRequest("getWidenedType", {
627
1940
  snapshot: this.snapshotId,
628
- project: this.projectId,
1941
+ project: this.project.id,
629
1942
  type: type.id,
630
1943
  });
631
- return data ? this.objectRegistry.getOrCreateType(data) : undefined;
1944
+ return this.objectRegistry.getOrCreateType(data);
632
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
+ */
633
1950
  async getParameterType(signature, index) {
634
1951
  const data = await this.client.apiRequest("getParameterType", {
635
1952
  snapshot: this.snapshotId,
636
- project: this.projectId,
1953
+ project: this.project.id,
637
1954
  signature: signature.id,
638
1955
  index,
639
1956
  });
640
- return data ? this.objectRegistry.getOrCreateType(data) : undefined;
1957
+ return this.objectRegistry.getOrCreateType(data);
641
1958
  }
642
1959
  async isArrayLikeType(type) {
643
1960
  return this.client.apiRequest("isArrayLikeType", {
644
1961
  snapshot: this.snapshotId,
645
- project: this.projectId,
1962
+ project: this.project.id,
646
1963
  type: type.id,
647
1964
  });
648
1965
  }
649
1966
  async isTypeAssignableTo(source, target) {
650
1967
  return this.client.apiRequest("isTypeAssignableTo", {
651
1968
  snapshot: this.snapshotId,
652
- project: this.projectId,
1969
+ project: this.project.id,
653
1970
  source: source.id,
654
1971
  target: target.id,
655
1972
  });
@@ -657,24 +1974,29 @@ export class Checker {
657
1974
  async getShorthandAssignmentValueSymbol(node) {
658
1975
  const data = await this.client.apiRequest("getShorthandAssignmentValueSymbol", {
659
1976
  snapshot: this.snapshotId,
660
- project: this.projectId,
1977
+ project: this.project.id,
661
1978
  location: getNodeId(node),
662
1979
  });
663
1980
  return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
664
1981
  }
1982
+ /**
1983
+ * Get the type of a symbol as narrowed at a specific location. Always returns
1984
+ * a type; for symbols whose type cannot be determined the checker yields the
1985
+ * error type (use {@link Type.isErrorType} to detect it).
1986
+ */
665
1987
  async getTypeOfSymbolAtLocation(symbol, location) {
666
1988
  const data = await this.client.apiRequest("getTypeOfSymbolAtLocation", {
667
1989
  snapshot: this.snapshotId,
668
- project: this.projectId,
669
- symbol: symbol.id,
1990
+ project: this.project.id,
1991
+ symbol: symbol.reference,
670
1992
  location: getNodeId(location),
671
1993
  });
672
- return data ? this.objectRegistry.getOrCreateType(data) : undefined;
1994
+ return this.objectRegistry.getOrCreateType(data);
673
1995
  }
674
1996
  async getIntrinsicType(method) {
675
1997
  const data = await this.client.apiRequest(method, {
676
1998
  snapshot: this.snapshotId,
677
- project: this.projectId,
1999
+ project: this.project.id,
678
2000
  });
679
2001
  return this.objectRegistry.getOrCreateType(data);
680
2002
  }
@@ -711,10 +2033,13 @@ export class Checker {
711
2033
  async getESSymbolType() {
712
2034
  return this.getIntrinsicType("getESSymbolType");
713
2035
  }
2036
+ async getNonPrimitiveType() {
2037
+ return this.getIntrinsicType("getNonPrimitiveType");
2038
+ }
714
2039
  async typeToTypeNode(type, enclosingDeclaration, flags) {
715
2040
  const binaryData = await this.client.apiRequestBinary("typeToTypeNode", {
716
2041
  snapshot: this.snapshotId,
717
- project: this.projectId,
2042
+ project: this.project.id,
718
2043
  type: type.id,
719
2044
  location: enclosingDeclaration ? getNodeId(enclosingDeclaration) : undefined,
720
2045
  flags,
@@ -726,7 +2051,7 @@ export class Checker {
726
2051
  async signatureToSignatureDeclaration(signature, kind, enclosingDeclaration, flags) {
727
2052
  const binaryData = await this.client.apiRequestBinary("signatureToSignatureDeclaration", {
728
2053
  snapshot: this.snapshotId,
729
- project: this.projectId,
2054
+ project: this.project.id,
730
2055
  signature: signature.id,
731
2056
  kind,
732
2057
  location: enclosingDeclaration ? getNodeId(enclosingDeclaration) : undefined,
@@ -737,41 +2062,73 @@ export class Checker {
737
2062
  return decodeNode(binaryData);
738
2063
  }
739
2064
  async typeToString(type, enclosingDeclaration, flags) {
740
- return this.client.apiRequest("typeToString", {
2065
+ const result = await this.client.apiRequest("typeToString", {
741
2066
  snapshot: this.snapshotId,
742
- project: this.projectId,
2067
+ project: this.project.id,
743
2068
  type: type.id,
744
2069
  location: enclosingDeclaration ? getNodeId(enclosingDeclaration) : undefined,
745
2070
  flags,
746
2071
  });
2072
+ if (typeof result !== "string")
2073
+ throw new TypeError("typeToString returned a non-string result");
2074
+ return result;
747
2075
  }
748
2076
  async isContextSensitive(node) {
749
2077
  return this.client.apiRequest("isContextSensitive", {
750
2078
  snapshot: this.snapshotId,
751
- project: this.projectId,
2079
+ project: this.project.id,
752
2080
  location: getNodeId(node),
753
2081
  });
754
2082
  }
755
- async getReturnTypeOfSignature(signature) {
756
- const data = await this.client.apiRequest("getReturnTypeOfSignature", {
2083
+ async isArrayType(type) {
2084
+ return this.client.apiRequest("isArrayType", {
757
2085
  snapshot: this.snapshotId,
758
- project: this.projectId,
759
- signature: signature.id,
2086
+ project: this.project.id,
2087
+ type: type.id,
2088
+ });
2089
+ }
2090
+ async isTupleType(type) {
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", {
2107
+ snapshot: this.snapshotId,
2108
+ project: this.project.id,
2109
+ symbol: symbol.reference,
760
2110
  });
761
- return data ? this.objectRegistry.getOrCreateType(data) : undefined;
762
2111
  }
2112
+ /** Get the return type of a signature. Always returns a type. */
2113
+ async getReturnTypeOfSignature(signature) {
2114
+ return signature.getReturnType();
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
+ */
763
2120
  async getRestTypeOfSignature(signature) {
764
2121
  const data = await this.client.apiRequest("getRestTypeOfSignature", {
765
2122
  snapshot: this.snapshotId,
766
- project: this.projectId,
2123
+ project: this.project.id,
767
2124
  signature: signature.id,
768
2125
  });
769
- return data ? this.objectRegistry.getOrCreateType(data) : undefined;
2126
+ return this.objectRegistry.getOrCreateType(data);
770
2127
  }
771
2128
  async getTypePredicateOfSignature(signature) {
772
2129
  const data = await this.client.apiRequest("getTypePredicateOfSignature", {
773
2130
  snapshot: this.snapshotId,
774
- project: this.projectId,
2131
+ project: this.project.id,
775
2132
  signature: signature.id,
776
2133
  });
777
2134
  if (!data)
@@ -783,55 +2140,266 @@ export class Checker {
783
2140
  type: data.type ? this.objectRegistry.getOrCreateType(data.type) : undefined,
784
2141
  };
785
2142
  }
2143
+ /**
2144
+ * Get the base types of a class or interface type. A type with no base types
2145
+ * yields an empty array.
2146
+ */
786
2147
  async getBaseTypes(type) {
787
- const data = await this.client.apiRequest("getBaseTypes", {
788
- snapshot: this.snapshotId,
789
- project: this.projectId,
790
- type: type.id,
791
- });
792
- return data ? data.map(d => this.objectRegistry.getOrCreateType(d)) : [];
2148
+ return await type.getBaseTypes() ?? [];
2149
+ }
2150
+ /** Get the apparent type of a type. Always returns a type. */
2151
+ async getApparentType(type) {
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();
793
2157
  }
794
2158
  async getPropertiesOfType(type) {
795
- 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", {
796
2166
  snapshot: this.snapshotId,
797
- project: this.projectId,
2167
+ project: this.project.id,
798
2168
  type: type.id,
2169
+ kind,
799
2170
  });
800
- return data ? data.map(d => this.objectRegistry.getOrCreateSymbol(d)) : [];
801
- }
802
- async getIndexInfosOfType(type) {
803
- const data = await this.client.apiRequest("getIndexInfosOfType", {
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;
2177
+ }
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", {
804
2183
  snapshot: this.snapshotId,
805
- project: this.projectId,
2184
+ project: this.project.id,
806
2185
  type: type.id,
2186
+ name: propertyName,
807
2187
  });
808
- if (!data)
809
- return [];
810
- return data.map(d => ({
811
- keyType: this.objectRegistry.getOrCreateType(d.keyType),
812
- valueType: this.objectRegistry.getOrCreateType(d.valueType),
813
- isReadonly: d.isReadonly ?? false,
814
- declaration: d.declaration ? new NodeHandle(d.declaration) : undefined,
815
- }));
2188
+ return data ? this.objectRegistry.getOrCreateType(data) : undefined;
816
2189
  }
2190
+ /**
2191
+ * Get the constraint of a type parameter (the `T` in `<U extends T>`), or
2192
+ * undefined if it has none.
2193
+ */
817
2194
  async getConstraintOfTypeParameter(type) {
818
- const data = await this.client.apiRequest("getConstraintOfTypeParameter", {
2195
+ return type.getConstraint();
2196
+ }
2197
+ async getDefaultFromTypeParameter(type) {
2198
+ return type.getDefault();
2199
+ }
2200
+ async getBaseConstraintOfType(type) {
2201
+ const data = await this.client.apiRequest("getBaseConstraintOfType", {
819
2202
  snapshot: this.snapshotId,
820
- project: this.projectId,
2203
+ project: this.project.id,
821
2204
  type: type.id,
822
2205
  });
823
2206
  return data ? this.objectRegistry.getOrCreateType(data) : undefined;
824
2207
  }
2208
+ async getPropertyOfType(type, name) {
2209
+ const data = await this.client.apiRequest("getPropertyOfType", {
2210
+ snapshot: this.snapshotId,
2211
+ project: this.project.id,
2212
+ type: type.id,
2213
+ name,
2214
+ });
2215
+ return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
2216
+ }
2217
+ async getConstantValue(node) {
2218
+ const data = await this.client.apiRequest("getConstantValue", {
2219
+ snapshot: this.snapshotId,
2220
+ project: this.project.id,
2221
+ location: getNodeId(node),
2222
+ });
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;
2236
+ }
2237
+ /** Get the signature of a function-like declaration. Always returns a signature. */
2238
+ async getSignatureFromDeclaration(node) {
2239
+ const data = await this.client.apiRequest("getSignatureFromDeclaration", {
2240
+ snapshot: this.snapshotId,
2241
+ project: this.project.id,
2242
+ location: getNodeId(node),
2243
+ });
2244
+ return this.objectRegistry.getOrCreateSignature(data);
2245
+ }
2246
+ async getExportSpecifierLocalTargetSymbol(node) {
2247
+ const data = await this.client.apiRequest("getExportSpecifierLocalTargetSymbol", {
2248
+ snapshot: this.snapshotId,
2249
+ project: this.project.id,
2250
+ location: getNodeId(node),
2251
+ });
2252
+ return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
2253
+ }
2254
+ /**
2255
+ * Follow all aliases to get the original symbol. Always returns a symbol; for
2256
+ * an unresolved alias the checker yields the unknown symbol (use
2257
+ * {@link Checker.isUnknownSymbol} to detect it).
2258
+ */
2259
+ async getAliasedSymbol(symbol) {
2260
+ const data = await this.client.apiRequest("getAliasedSymbol", {
2261
+ snapshot: this.snapshotId,
2262
+ project: this.project.id,
2263
+ symbol: symbol.reference,
2264
+ });
2265
+ return this.objectRegistry.getOrCreateSymbol(data);
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
+ }
2278
+ async getImmediateAliasedSymbol(symbol) {
2279
+ const data = await this.client.apiRequest("getImmediateAliasedSymbol", {
2280
+ snapshot: this.snapshotId,
2281
+ project: this.project.id,
2282
+ symbol: symbol.reference,
2283
+ });
2284
+ return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
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
+ }
2308
+ /**
2309
+ * Fetch (once, then cache) the handle ids of the per-checker singleton
2310
+ * symbols (unknown, undefined, arguments). These ids are stable for the life
2311
+ * of the project's checker, so identity checks against them are local after
2312
+ * the first call.
2313
+ */
2314
+ getWellKnownSymbols() {
2315
+ return this.wellKnownSymbols ??= this.client.apiRequest("getWellKnownSymbols", {
2316
+ snapshot: this.snapshotId,
2317
+ project: this.project.id,
2318
+ });
2319
+ }
2320
+ /**
2321
+ * Returns `true` if the symbol is the checker's "unknown" symbol (e.g. the
2322
+ * result of {@link Checker.getAliasedSymbol} on an unresolved alias).
2323
+ */
2324
+ async isUnknownSymbol(symbol) {
2325
+ return symbol.id === (await this.getWellKnownSymbols()).unknown;
2326
+ }
2327
+ /**
2328
+ * Returns `true` if the symbol is the checker's "undefined" symbol.
2329
+ */
2330
+ async isUndefinedSymbol(symbol) {
2331
+ return symbol.id === (await this.getWellKnownSymbols()).undefined;
2332
+ }
2333
+ /**
2334
+ * Returns `true` if the symbol is the checker's "arguments" symbol.
2335
+ */
2336
+ async isArgumentsSymbol(symbol) {
2337
+ return symbol.id === (await this.getWellKnownSymbols()).arguments;
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
+ }
2358
+ async getExportsOfModule(symbol) {
2359
+ const data = await this.client.apiRequest("getExportsOfModule", {
2360
+ snapshot: this.snapshotId,
2361
+ project: this.project.id,
2362
+ symbol: symbol.reference,
2363
+ });
2364
+ return data ? data.map(d => this.objectRegistry.getOrCreateSymbol(d)) : [];
2365
+ }
2366
+ async getMemberInModuleExports(symbol, name) {
2367
+ const data = await this.client.apiRequest("getMemberInModuleExports", {
2368
+ snapshot: this.snapshotId,
2369
+ project: this.project.id,
2370
+ symbol: symbol.reference,
2371
+ name,
2372
+ });
2373
+ return data ? this.objectRegistry.getOrCreateSymbol(data) : undefined;
2374
+ }
2375
+ async getJsDocTagsOfSymbol(symbol) {
2376
+ const data = await this.client.apiRequest("getJsDocTags", {
2377
+ snapshot: this.snapshotId,
2378
+ project: this.project.id,
2379
+ symbol: symbol.reference,
2380
+ });
2381
+ return data ?? [];
2382
+ }
2383
+ async getDocumentationCommentOfSymbol(symbol) {
2384
+ return this.client.apiRequest("getDocumentationComment", {
2385
+ snapshot: this.snapshotId,
2386
+ project: this.project.id,
2387
+ symbol: symbol.reference,
2388
+ });
2389
+ }
2390
+ /**
2391
+ * Get the type arguments of a type reference (e.g. the `string` in `Array<string>`).
2392
+ */
825
2393
  async getTypeArguments(type) {
826
2394
  const data = await this.client.apiRequest("getTypeArguments", {
827
2395
  snapshot: this.snapshotId,
828
- project: this.projectId,
2396
+ project: this.project.id,
829
2397
  type: type.id,
830
2398
  });
831
2399
  return data ? data.map(d => this.objectRegistry.getOrCreateType(d)) : [];
832
2400
  }
833
2401
  }
834
- export class Emitter {
2402
+ export class Printer {
835
2403
  client;
836
2404
  constructor(client) {
837
2405
  this.client = client;
@@ -841,72 +2409,180 @@ export class Emitter {
841
2409
  const base64 = uint8ArrayToBase64(encoded);
842
2410
  return this.client.apiRequest("printNode", {
843
2411
  data: base64,
844
- ...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,
845
2425
  });
846
2426
  }
847
2427
  }
848
2428
  export class NodeHandle {
2429
+ /**
2430
+ * The project this handle was produced in, used as the default for {@link resolve}.
2431
+ * Node handles are only meaningful within a project's program, so the producing project
2432
+ * is remembered so callers don't have to pass it explicitly.
2433
+ */
2434
+ canonicalProject;
2435
+ /** The owning source file of a file-owned symbol's declaration. */
2436
+ fileOwner;
849
2437
  index;
850
2438
  kind;
851
2439
  path;
852
- constructor(handle) {
853
- const parsed = parseNodeHandle(handle);
2440
+ constructor(handle, canonicalProject, fileOwner) {
2441
+ const parsed = parseNodeHandleFromCompiler(handle);
854
2442
  this.index = parsed.index;
855
2443
  this.kind = parsed.kind;
856
2444
  this.path = parsed.path;
2445
+ this.canonicalProject = canonicalProject;
2446
+ this.fileOwner = fileOwner;
857
2447
  }
858
2448
  /**
859
- * Resolve this handle to the actual AST node by fetching the source file
860
- * from the given project and looking up the node by index.
2449
+ * Resolve this handle to the actual AST node by fetching the source file from a project
2450
+ * and looking up the node by index. If no project is passed, the project that produced
2451
+ * the handle is used. Declarations of file-owned symbols identify an exact source file and
2452
+ * resolve through it, independently of any project.
861
2453
  */
862
- async resolve(project) {
863
- const sourceFile = await project.program.getSourceFile(this.path);
2454
+ async resolve(project = this.canonicalProject) {
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);
864
2462
  if (!sourceFile) {
865
2463
  return undefined;
866
2464
  }
867
2465
  return sourceFile.getOrCreateNodeAtIndex(this.index);
868
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
+ }
869
2473
  }
870
2474
  export class Symbol {
871
- objectRegistry;
872
- id;
2475
+ storage;
2476
+ get id() {
2477
+ return this.reference.id;
2478
+ }
2479
+ /** The escaped (`__String`) name, used as the key in member/export tables. */
2480
+ escapedName;
2481
+ /** The display name (escaped underscores removed). */
873
2482
  name;
874
2483
  flags;
875
2484
  checkFlags;
2485
+ /** @internal */
2486
+ reference;
876
2487
  declarations;
877
2488
  valueDeclaration;
878
2489
  parent;
879
2490
  exportSymbol;
880
- constructor(data, objectRegistry) {
881
- this.objectRegistry = objectRegistry;
882
- this.id = data.id;
883
- this.name = data.name;
2491
+ membersCache;
2492
+ exportsCache;
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;
2498
+ this.escapedName = data.name;
2499
+ this.name = unescapeLeadingUnderscores(data.name);
884
2500
  this.flags = data.flags;
885
2501
  this.checkFlags = data.checkFlags;
886
- this.declarations = (data.declarations ?? []).map(d => new NodeHandle(d));
887
- this.valueDeclaration = data.valueDeclaration ? new NodeHandle(data.valueDeclaration) : 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;
888
2509
  if (data.parent !== undefined)
889
2510
  this.parent = data.parent;
890
2511
  if (data.exportSymbol !== undefined)
891
2512
  this.exportSymbol = data.exportSymbol;
892
2513
  }
893
2514
  async getParent() {
894
- return this.objectRegistry.fetchSymbol(this, "getParentOfSymbol", this.parent);
2515
+ if (!this.parent)
2516
+ return undefined;
2517
+ return this.fetchSymbol("getParentOfSymbol", this.parent);
895
2518
  }
896
- async getMembers() {
897
- return this.objectRegistry.fetchSymbols(this, "getMembersOfSymbol");
2519
+ /**
2520
+ * Get this symbol's members keyed by escaped name. The result is cached on
2521
+ * the symbol, so repeated calls do not round-trip to the server.
2522
+ */
2523
+ getMembers() {
2524
+ return this.membersCache ??= this.fetchSymbolTable("getMembersOfSymbol");
898
2525
  }
899
- async getExports() {
900
- return this.objectRegistry.fetchSymbols(this, "getExportsOfSymbol");
2526
+ /**
2527
+ * Get this symbol's exports keyed by escaped name. The result is cached on
2528
+ * the symbol, so repeated calls do not round-trip to the server.
2529
+ */
2530
+ getExports() {
2531
+ return this.exportsCache ??= this.fetchSymbolTable("getExportsOfSymbol");
2532
+ }
2533
+ async fetchSymbolTable(method) {
2534
+ const symbols = await this.fetchSymbols(method);
2535
+ const table = new Map();
2536
+ for (const symbol of symbols) {
2537
+ table.set(symbol.escapedName, symbol);
2538
+ }
2539
+ return table;
901
2540
  }
902
2541
  async getExportSymbol() {
903
2542
  if (!this.exportSymbol)
904
2543
  return this;
905
- return this.objectRegistry.fetchSymbol(this, "getExportSymbolOfSymbol", this.exportSymbol);
2544
+ return this.fetchSymbol("getExportSymbolOfSymbol", this.exportSymbol);
2545
+ }
2546
+ async getJsDocTags(checker) {
2547
+ return checker.getJsDocTagsOfSymbol(this);
2548
+ }
2549
+ async getDocumentationComment(checker) {
2550
+ return checker.getDocumentationCommentOfSymbol(this);
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 }));
906
2580
  }
907
2581
  }
908
2582
  class TypeObject {
909
2583
  objectRegistry;
2584
+ // Fields included in TypeResponse. References to other objects are stored as IDs
2585
+ // and resolved lazily via the object registry.
910
2586
  id;
911
2587
  flags;
912
2588
  objectFlags;
@@ -917,14 +2593,17 @@ class TypeObject {
917
2593
  freshType;
918
2594
  regularType;
919
2595
  target;
2596
+ tupleType;
920
2597
  typeParameters;
921
2598
  outerTypeParameters;
922
2599
  localTypeParameters;
2600
+ thisType;
923
2601
  aliasTypeArguments;
924
2602
  aliasSymbol;
925
2603
  elementFlags;
926
2604
  fixedLength;
927
2605
  readonly;
2606
+ labeledElementDeclarations;
928
2607
  texts;
929
2608
  objectType;
930
2609
  indexType;
@@ -932,6 +2611,31 @@ class TypeObject {
932
2611
  extendsType;
933
2612
  baseType;
934
2613
  substConstraint;
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;
935
2639
  constructor(data, objectRegistry) {
936
2640
  this.objectRegistry = objectRegistry;
937
2641
  this.id = data.id;
@@ -940,8 +2644,29 @@ class TypeObject {
940
2644
  this.objectFlags = data.objectFlags;
941
2645
  if (data.symbol !== undefined)
942
2646
  this.symbol = data.symbol;
943
- if (data.value !== undefined)
944
- this.value = data.value;
2647
+ if (data.value != null) {
2648
+ // BigInt literal values are serialized as decimal strings (e.g. "-123") because
2649
+ // JSON cannot represent bigint. Decode them back into a real bigint here.
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
+ }
2669
+ }
945
2670
  if (data.intrinsicName !== undefined)
946
2671
  this.intrinsicName = data.intrinsicName;
947
2672
  if (data.isThisType !== undefined)
@@ -952,18 +2677,24 @@ class TypeObject {
952
2677
  this.regularType = data.regularType;
953
2678
  if (data.target !== undefined)
954
2679
  this.target = data.target;
2680
+ this.tupleType = data.isTupleType ?? false;
955
2681
  this.typeParameters = data.typeParameters ?? [];
956
2682
  this.outerTypeParameters = data.outerTypeParameters ?? [];
957
2683
  this.localTypeParameters = data.localTypeParameters ?? [];
2684
+ if (data.thisType !== undefined)
2685
+ this.thisType = data.thisType;
958
2686
  this.aliasTypeArguments = data.aliasTypeArguments ?? [];
959
2687
  if (data.aliasSymbol !== undefined)
960
2688
  this.aliasSymbol = data.aliasSymbol;
961
- if (data.elementFlags !== undefined)
962
- this.elementFlags = data.elementFlags;
963
- if (data.fixedLength !== undefined)
2689
+ if (data.fixedLength !== undefined) {
2690
+ this.elementFlags = data.elementFlags ?? [];
964
2691
  this.fixedLength = data.fixedLength;
2692
+ }
965
2693
  if (data.readonly !== undefined)
966
2694
  this.readonly = data.readonly;
2695
+ if (data.labeledElementDeclarations !== undefined) {
2696
+ this.labeledElementDeclarations = data.labeledElementDeclarations.map(handle => handle ? objectRegistry.createNodeHandle(handle) : undefined);
2697
+ }
967
2698
  if (data.texts !== undefined)
968
2699
  this.texts = data.texts;
969
2700
  if (data.objectType !== undefined)
@@ -978,10 +2709,102 @@ class TypeObject {
978
2709
  this.baseType = data.baseType;
979
2710
  if (data.substConstraint !== undefined)
980
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;
2720
+ this.trueType = false;
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;
981
2736
  }
982
2737
  async getSymbol() {
983
2738
  return this.objectRegistry.fetchSymbol(this, "getSymbolOfType", this.symbol);
984
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
+ }
985
2808
  async getAliasSymbol() {
986
2809
  return this.objectRegistry.fetchSymbol(this, "getAliasSymbolOfType", this.aliasSymbol);
987
2810
  }
@@ -989,13 +2812,22 @@ class TypeObject {
989
2812
  return this.objectRegistry.fetchType(this, "getTargetOfType", this.target);
990
2813
  }
991
2814
  async getFreshType() {
992
- return this.objectRegistry.fetchType(this, "getFreshTypeOfType", this.freshType);
2815
+ return this.objectRegistry.fetchOptionalType(this, "getFreshTypeOfType", this.freshType);
993
2816
  }
994
2817
  async getRegularType() {
995
- return this.objectRegistry.fetchType(this, "getRegularTypeOfType", this.regularType);
2818
+ return this.objectRegistry.fetchOptionalType(this, "getRegularTypeOfType", this.regularType);
996
2819
  }
997
2820
  async getTypes() {
998
- return this.objectRegistry.fetchTypes(this, "getTypesOfType");
2821
+ // Only union, intersection, and template literal types have constituent
2822
+ // types; any other kind has none, so return undefined rather than sending
2823
+ // a request the server cannot satisfy.
2824
+ if (!(this.flags & (TypeFlags.UnionOrIntersection | TypeFlags.TemplateLiteral))) {
2825
+ return undefined;
2826
+ }
2827
+ if (this.types === false) {
2828
+ this.types = await this.objectRegistry.fetchTypes(this, "getTypesOfType");
2829
+ }
2830
+ return this.types;
999
2831
  }
1000
2832
  async getTypeParameters() {
1001
2833
  return this.objectRegistry.fetchTypes(this, "getTypeParametersOfType", this.typeParameters);
@@ -1006,9 +2838,24 @@ class TypeObject {
1006
2838
  async getLocalTypeParameters() {
1007
2839
  return this.objectRegistry.fetchTypes(this, "getLocalTypeParametersOfType", this.localTypeParameters);
1008
2840
  }
2841
+ async getThisType() {
2842
+ return this.objectRegistry.fetchOptionalType(this, "getThisTypeOfType", this.thisType);
2843
+ }
1009
2844
  async getAliasTypeArguments() {
1010
2845
  return this.objectRegistry.fetchTypes(this, "getAliasTypeArgumentsOfType", this.aliasTypeArguments);
1011
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
+ }
1012
2859
  async getObjectType() {
1013
2860
  return this.objectRegistry.fetchType(this, "getObjectTypeOfType", this.objectType);
1014
2861
  }
@@ -1025,8 +2872,178 @@ class TypeObject {
1025
2872
  return this.objectRegistry.fetchType(this, "getBaseTypeOfType", this.baseType);
1026
2873
  }
1027
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
+ }
1028
2882
  return this.objectRegistry.fetchType(this, "getConstraintOfType", this.substConstraint);
1029
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
+ }
2889
+ async getTrueType() {
2890
+ const result = await this.objectRegistry.fetchType(this, "getTrueTypeOfConditionalType", this.trueType);
2891
+ this.trueType = result.id;
2892
+ return result;
2893
+ }
2894
+ async getFalseType() {
2895
+ const result = await this.objectRegistry.fetchType(this, "getFalseTypeOfConditionalType", this.falseType);
2896
+ this.falseType = result.id;
2897
+ return result;
2898
+ }
2899
+ /**
2900
+ * Get the base types of this type. Returns `undefined` for any type that is
2901
+ * not a class or interface.
2902
+ */
2903
+ async getBaseTypes() {
2904
+ if (!this.isClassOrInterface()) {
2905
+ return undefined;
2906
+ }
2907
+ if (this.baseTypes === false) {
2908
+ this.baseTypes = await this.objectRegistry.fetchBaseTypes(this);
2909
+ }
2910
+ return this.baseTypes;
2911
+ }
2912
+ isClassOrInterface() {
2913
+ return isClassOrInterfaceType(this);
2914
+ }
2915
+ isUnionType() {
2916
+ return isUnionType(this);
2917
+ }
2918
+ isIntersectionType() {
2919
+ return isIntersectionType(this);
2920
+ }
2921
+ isObjectType() {
2922
+ return isObjectType(this);
2923
+ }
2924
+ isIntrinsicType() {
2925
+ return isIntrinsicType(this);
2926
+ }
2927
+ isErrorType() {
2928
+ return isErrorType(this);
2929
+ }
2930
+ isLiteralType() {
2931
+ return isLiteralType(this);
2932
+ }
2933
+ isStringLiteralType() {
2934
+ return isStringLiteralType(this);
2935
+ }
2936
+ isNumberLiteralType() {
2937
+ return isNumberLiteralType(this);
2938
+ }
2939
+ isBigIntLiteralType() {
2940
+ return isBigIntLiteralType(this);
2941
+ }
2942
+ isBooleanLiteralType() {
2943
+ return isBooleanLiteralType(this);
2944
+ }
2945
+ isTypeReference() {
2946
+ return isTypeReference(this);
2947
+ }
2948
+ isTupleType() {
2949
+ return this.tupleType;
2950
+ }
2951
+ isTupleTypeTarget() {
2952
+ return this.fixedLength !== undefined;
2953
+ }
2954
+ isIndexType() {
2955
+ return isIndexType(this);
2956
+ }
2957
+ isIndexedAccessType() {
2958
+ return isIndexedAccessType(this);
2959
+ }
2960
+ isConditionalType() {
2961
+ return isConditionalType(this);
2962
+ }
2963
+ isSubstitutionType() {
2964
+ return isSubstitutionType(this);
2965
+ }
2966
+ isTemplateLiteralType() {
2967
+ return isTemplateLiteralType(this);
2968
+ }
2969
+ isStringMappingType() {
2970
+ return isStringMappingType(this);
2971
+ }
2972
+ isTypeParameter() {
2973
+ return isTypeParameter(this);
2974
+ }
2975
+ isMappedType() {
2976
+ return !!(this.flags & TypeFlags.Object) && !!(this.objectFlags & ObjectFlags.Mapped);
2977
+ }
2978
+ }
2979
+ export function isUnionType(type) {
2980
+ return (type.flags & TypeFlags.Union) !== 0;
2981
+ }
2982
+ export function isIntersectionType(type) {
2983
+ return (type.flags & TypeFlags.Intersection) !== 0;
2984
+ }
2985
+ export function isObjectType(type) {
2986
+ return (type.flags & TypeFlags.Object) !== 0;
2987
+ }
2988
+ export function isClassOrInterfaceType(type) {
2989
+ return isObjectType(type) && (type.objectFlags & ObjectFlags.ClassOrInterface) !== 0;
2990
+ }
2991
+ export function isIntrinsicType(type) {
2992
+ return (type.flags & TypeFlags.Intrinsic) !== 0;
2993
+ }
2994
+ /**
2995
+ * Whether this is the error type — the placeholder the checker produces when a
2996
+ * type cannot be determined (e.g. an unresolved reference). It is an intrinsic
2997
+ * type named `"error"` (this covers both the singleton error type and the
2998
+ * per-alias error types manufactured for unresolved type alias references).
2999
+ */
3000
+ export function isErrorType(type) {
3001
+ return isIntrinsicType(type) && type.intrinsicName === "error";
3002
+ }
3003
+ export function isLiteralType(type) {
3004
+ return (type.flags & TypeFlags.Literal) !== 0;
3005
+ }
3006
+ export function isStringLiteralType(type) {
3007
+ return (type.flags & TypeFlags.StringLiteral) !== 0;
3008
+ }
3009
+ export function isNumberLiteralType(type) {
3010
+ return (type.flags & TypeFlags.NumberLiteral) !== 0;
3011
+ }
3012
+ export function isBigIntLiteralType(type) {
3013
+ return (type.flags & TypeFlags.BigIntLiteral) !== 0;
3014
+ }
3015
+ export function isBooleanLiteralType(type) {
3016
+ return (type.flags & TypeFlags.BooleanLiteral) !== 0;
3017
+ }
3018
+ export function isTypeReference(type) {
3019
+ return isObjectType(type) && (type.objectFlags & ObjectFlags.Reference) !== 0;
3020
+ }
3021
+ export function isTupleType(type) {
3022
+ return type.isTupleType();
3023
+ }
3024
+ export function isTupleTypeTarget(type) {
3025
+ return type.isTupleTypeTarget();
3026
+ }
3027
+ export function isIndexType(type) {
3028
+ return (type.flags & TypeFlags.Index) !== 0;
3029
+ }
3030
+ export function isIndexedAccessType(type) {
3031
+ return (type.flags & TypeFlags.IndexedAccess) !== 0;
3032
+ }
3033
+ export function isConditionalType(type) {
3034
+ return (type.flags & TypeFlags.Conditional) !== 0;
3035
+ }
3036
+ export function isSubstitutionType(type) {
3037
+ return (type.flags & TypeFlags.Substitution) !== 0;
3038
+ }
3039
+ export function isTemplateLiteralType(type) {
3040
+ return (type.flags & TypeFlags.TemplateLiteral) !== 0;
3041
+ }
3042
+ export function isStringMappingType(type) {
3043
+ return (type.flags & TypeFlags.StringMapping) !== 0;
3044
+ }
3045
+ export function isTypeParameter(type) {
3046
+ return (type.flags & TypeFlags.TypeParameter) !== 0;
1030
3047
  }
1031
3048
  export class Signature {
1032
3049
  flags;
@@ -1037,15 +3054,17 @@ export class Signature {
1037
3054
  parameters;
1038
3055
  thisParameter;
1039
3056
  target;
1040
- constructor(data, objectRegistry) {
3057
+ returnType;
3058
+ constructor(data, project, objectRegistry) {
1041
3059
  this.id = data.id;
1042
3060
  this.flags = data.flags;
1043
3061
  this.objectRegistry = objectRegistry;
1044
- this.declaration = data.declaration ? new NodeHandle(data.declaration) : undefined;
3062
+ this.declaration = data.declaration ? new NodeHandle(data.declaration, project) : undefined;
1045
3063
  this.typeParameters = data.typeParameters ?? [];
1046
3064
  this.parameters = data.parameters ?? [];
1047
3065
  this.thisParameter = data.thisParameter;
1048
3066
  this.target = data.target;
3067
+ this.returnType = false;
1049
3068
  }
1050
3069
  async getTypeParameters() {
1051
3070
  return this.objectRegistry.fetchTypes(this, "getTypeParametersOfSignature", this.typeParameters);
@@ -1059,6 +3078,14 @@ export class Signature {
1059
3078
  async getTarget() {
1060
3079
  return this.objectRegistry.fetchSignature(this, "getTargetOfSignature", this.target);
1061
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
+ }
1062
3089
  get hasRestParameter() {
1063
3090
  return (this.flags & SignatureFlags.HasRestParameter) !== 0;
1064
3091
  }