openalgo-script 0.2.0 → 0.5.0

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 (357) hide show
  1. package/CHANGELOG.md +1198 -0
  2. package/README.md +127 -40
  3. package/dist/adapters/charts/driving.d.ts +50 -0
  4. package/dist/adapters/charts/driving.d.ts.map +1 -0
  5. package/dist/adapters/charts/driving.js +57 -0
  6. package/dist/adapters/charts/driving.js.map +1 -0
  7. package/dist/adapters/charts/run.d.ts +20 -0
  8. package/dist/adapters/charts/run.d.ts.map +1 -1
  9. package/dist/adapters/charts/run.js +83 -16
  10. package/dist/adapters/charts/run.js.map +1 -1
  11. package/dist/adapters/charts/surfaces.d.ts +17 -0
  12. package/dist/adapters/charts/surfaces.d.ts.map +1 -1
  13. package/dist/adapters/charts/tables.js +82 -0
  14. package/dist/adapters/charts/tables.js.map +1 -1
  15. package/dist/adapters/charts/venue.d.ts +73 -0
  16. package/dist/adapters/charts/venue.d.ts.map +1 -0
  17. package/dist/adapters/charts/venue.js +104 -0
  18. package/dist/adapters/charts/venue.js.map +1 -0
  19. package/dist/adapters/codemirror/commands.d.ts +14 -0
  20. package/dist/adapters/codemirror/commands.d.ts.map +1 -0
  21. package/dist/adapters/codemirror/commands.js +52 -0
  22. package/dist/adapters/codemirror/commands.js.map +1 -0
  23. package/dist/adapters/codemirror/completion.d.ts +15 -0
  24. package/dist/adapters/codemirror/completion.d.ts.map +1 -0
  25. package/dist/adapters/codemirror/completion.js +64 -0
  26. package/dist/adapters/codemirror/completion.js.map +1 -0
  27. package/dist/adapters/codemirror/contract.d.ts +156 -0
  28. package/dist/adapters/codemirror/contract.d.ts.map +1 -0
  29. package/dist/adapters/codemirror/contract.js +42 -0
  30. package/dist/adapters/codemirror/contract.js.map +1 -0
  31. package/dist/adapters/codemirror/index.d.ts +43 -0
  32. package/dist/adapters/codemirror/index.d.ts.map +1 -0
  33. package/dist/adapters/codemirror/index.js +8 -0
  34. package/dist/adapters/codemirror/index.js.map +1 -0
  35. package/dist/adapters/codemirror/lint.d.ts +17 -0
  36. package/dist/adapters/codemirror/lint.d.ts.map +1 -0
  37. package/dist/adapters/codemirror/lint.js +62 -0
  38. package/dist/adapters/codemirror/lint.js.map +1 -0
  39. package/dist/adapters/codemirror/positions.d.ts +16 -0
  40. package/dist/adapters/codemirror/positions.d.ts.map +1 -0
  41. package/dist/adapters/codemirror/positions.js +65 -0
  42. package/dist/adapters/codemirror/positions.js.map +1 -0
  43. package/dist/adapters/codemirror/stream.d.ts +23 -0
  44. package/dist/adapters/codemirror/stream.d.ts.map +1 -0
  45. package/dist/adapters/codemirror/stream.js +70 -0
  46. package/dist/adapters/codemirror/stream.js.map +1 -0
  47. package/dist/adapters/codemirror/tokens.d.ts +44 -0
  48. package/dist/adapters/codemirror/tokens.d.ts.map +1 -0
  49. package/dist/adapters/codemirror/tokens.js +34 -0
  50. package/dist/adapters/codemirror/tokens.js.map +1 -0
  51. package/dist/adapters/codemirror/tooltips.d.ts +35 -0
  52. package/dist/adapters/codemirror/tooltips.d.ts.map +1 -0
  53. package/dist/adapters/codemirror/tooltips.js +108 -0
  54. package/dist/adapters/codemirror/tooltips.js.map +1 -0
  55. package/dist/core/accounting/analysis.d.ts +111 -0
  56. package/dist/core/accounting/analysis.d.ts.map +1 -0
  57. package/dist/core/accounting/analysis.js +123 -0
  58. package/dist/core/accounting/analysis.js.map +1 -0
  59. package/dist/core/accounting/charges.d.ts +136 -0
  60. package/dist/core/accounting/charges.d.ts.map +1 -0
  61. package/dist/core/accounting/charges.js +362 -0
  62. package/dist/core/accounting/charges.js.map +1 -0
  63. package/dist/core/accounting/equity.d.ts +191 -0
  64. package/dist/core/accounting/equity.d.ts.map +1 -0
  65. package/dist/core/accounting/equity.js +167 -0
  66. package/dist/core/accounting/equity.js.map +1 -0
  67. package/dist/core/accounting/index.d.ts +46 -0
  68. package/dist/core/accounting/index.d.ts.map +1 -0
  69. package/dist/core/accounting/index.js +37 -0
  70. package/dist/core/accounting/index.js.map +1 -0
  71. package/dist/core/accounting/markers.d.ts +43 -0
  72. package/dist/core/accounting/markers.d.ts.map +1 -0
  73. package/dist/core/accounting/markers.js +64 -0
  74. package/dist/core/accounting/markers.js.map +1 -0
  75. package/dist/core/accounting/monthly.d.ts +52 -0
  76. package/dist/core/accounting/monthly.d.ts.map +1 -0
  77. package/dist/core/accounting/monthly.js +99 -0
  78. package/dist/core/accounting/monthly.js.map +1 -0
  79. package/dist/core/accounting/report.d.ts +41 -0
  80. package/dist/core/accounting/report.d.ts.map +1 -0
  81. package/dist/core/accounting/report.js +65 -0
  82. package/dist/core/accounting/report.js.map +1 -0
  83. package/dist/core/accounting/shapes.d.ts +70 -0
  84. package/dist/core/accounting/shapes.d.ts.map +1 -0
  85. package/dist/core/accounting/shapes.js +21 -0
  86. package/dist/core/accounting/shapes.js.map +1 -0
  87. package/dist/core/accounting/statistics.d.ts +87 -0
  88. package/dist/core/accounting/statistics.d.ts.map +1 -0
  89. package/dist/core/accounting/statistics.js +268 -0
  90. package/dist/core/accounting/statistics.js.map +1 -0
  91. package/dist/core/accounting/trades.d.ts +118 -0
  92. package/dist/core/accounting/trades.d.ts.map +1 -0
  93. package/dist/core/accounting/trades.js +186 -0
  94. package/dist/core/accounting/trades.js.map +1 -0
  95. package/dist/core/backtest/case.d.ts +60 -0
  96. package/dist/core/backtest/case.d.ts.map +1 -0
  97. package/dist/core/backtest/case.js +319 -0
  98. package/dist/core/backtest/case.js.map +1 -0
  99. package/dist/core/backtest/compare.d.ts +38 -0
  100. package/dist/core/backtest/compare.d.ts.map +1 -0
  101. package/dist/core/backtest/compare.js +191 -0
  102. package/dist/core/backtest/compare.js.map +1 -0
  103. package/dist/core/backtest/declaration.d.ts +52 -0
  104. package/dist/core/backtest/declaration.d.ts.map +1 -0
  105. package/dist/core/backtest/declaration.js +48 -0
  106. package/dist/core/backtest/declaration.js.map +1 -0
  107. package/dist/core/backtest/deliver.d.ts +93 -0
  108. package/dist/core/backtest/deliver.d.ts.map +1 -0
  109. package/dist/core/backtest/deliver.js +94 -0
  110. package/dist/core/backtest/deliver.js.map +1 -0
  111. package/dist/core/backtest/drive.d.ts +87 -0
  112. package/dist/core/backtest/drive.d.ts.map +1 -0
  113. package/dist/core/backtest/drive.js +312 -0
  114. package/dist/core/backtest/drive.js.map +1 -0
  115. package/dist/core/backtest/index.d.ts +58 -0
  116. package/dist/core/backtest/index.d.ts.map +1 -0
  117. package/dist/core/backtest/index.js +47 -0
  118. package/dist/core/backtest/index.js.map +1 -0
  119. package/dist/core/backtest/range.d.ts +84 -0
  120. package/dist/core/backtest/range.d.ts.map +1 -0
  121. package/dist/core/backtest/range.js +90 -0
  122. package/dist/core/backtest/range.js.map +1 -0
  123. package/dist/core/backtest/record.d.ts +299 -0
  124. package/dist/core/backtest/record.d.ts.map +1 -0
  125. package/dist/core/backtest/record.js +243 -0
  126. package/dist/core/backtest/record.js.map +1 -0
  127. package/dist/core/backtest/replay.d.ts +48 -0
  128. package/dist/core/backtest/replay.d.ts.map +1 -0
  129. package/dist/core/backtest/replay.js +137 -0
  130. package/dist/core/backtest/replay.js.map +1 -0
  131. package/dist/core/backtest/resting.d.ts +62 -0
  132. package/dist/core/backtest/resting.d.ts.map +1 -0
  133. package/dist/core/backtest/resting.js +59 -0
  134. package/dist/core/backtest/resting.js.map +1 -0
  135. package/dist/core/backtest/settings.d.ts +117 -0
  136. package/dist/core/backtest/settings.d.ts.map +1 -0
  137. package/dist/core/backtest/settings.js +207 -0
  138. package/dist/core/backtest/settings.js.map +1 -0
  139. package/dist/core/backtest/simulate.d.ts +258 -0
  140. package/dist/core/backtest/simulate.d.ts.map +1 -0
  141. package/dist/core/backtest/simulate.js +335 -0
  142. package/dist/core/backtest/simulate.js.map +1 -0
  143. package/dist/core/catalogue/catalogue.generated.d.ts +66 -0
  144. package/dist/core/catalogue/catalogue.generated.d.ts.map +1 -1
  145. package/dist/core/catalogue/catalogue.generated.js +6 -0
  146. package/dist/core/catalogue/catalogue.generated.js.map +1 -1
  147. package/dist/core/catalogue/values.generated.d.ts +24 -0
  148. package/dist/core/catalogue/values.generated.d.ts.map +1 -1
  149. package/dist/core/check/index.d.ts +2 -1
  150. package/dist/core/check/index.d.ts.map +1 -1
  151. package/dist/core/check/index.js +1 -1
  152. package/dist/core/check/index.js.map +1 -1
  153. package/dist/core/check/library-orders.js +2 -2
  154. package/dist/core/check/library-orders.js.map +1 -1
  155. package/dist/core/check/library-prose.generated.d.ts +16 -0
  156. package/dist/core/check/library-prose.generated.d.ts.map +1 -0
  157. package/dist/core/check/library-prose.generated.js +353 -0
  158. package/dist/core/check/library-prose.generated.js.map +1 -0
  159. package/dist/core/check/surface.d.ts +24 -0
  160. package/dist/core/check/surface.d.ts.map +1 -1
  161. package/dist/core/check/surface.js +29 -0
  162. package/dist/core/check/surface.js.map +1 -1
  163. package/dist/core/emit/canonical.d.ts +22 -8
  164. package/dist/core/emit/canonical.d.ts.map +1 -1
  165. package/dist/core/emit/canonical.js +67 -6
  166. package/dist/core/emit/canonical.js.map +1 -1
  167. package/dist/core/emit/defaults.d.ts +35 -16
  168. package/dist/core/emit/defaults.d.ts.map +1 -1
  169. package/dist/core/emit/defaults.js +66 -0
  170. package/dist/core/emit/defaults.js.map +1 -1
  171. package/dist/core/emit/index.d.ts +2 -0
  172. package/dist/core/emit/index.d.ts.map +1 -1
  173. package/dist/core/emit/index.js +2 -0
  174. package/dist/core/emit/index.js.map +1 -1
  175. package/dist/core/engine/arithmetic.d.ts +6 -25
  176. package/dist/core/engine/arithmetic.d.ts.map +1 -1
  177. package/dist/core/engine/arithmetic.js +48 -3
  178. package/dist/core/engine/arithmetic.js.map +1 -1
  179. package/dist/core/engine/index.d.ts +2 -2
  180. package/dist/core/engine/index.d.ts.map +1 -1
  181. package/dist/core/engine/index.js +2 -2
  182. package/dist/core/engine/index.js.map +1 -1
  183. package/dist/core/engine/library/arrays.d.ts.map +1 -1
  184. package/dist/core/engine/library/arrays.js +8 -2
  185. package/dist/core/engine/library/arrays.js.map +1 -1
  186. package/dist/core/engine/library/code-points.d.ts +40 -0
  187. package/dist/core/engine/library/code-points.d.ts.map +1 -0
  188. package/dist/core/engine/library/code-points.js +74 -0
  189. package/dist/core/engine/library/code-points.js.map +1 -0
  190. package/dist/core/engine/library/index.d.ts +5 -0
  191. package/dist/core/engine/library/index.d.ts.map +1 -1
  192. package/dist/core/engine/library/index.js +5 -0
  193. package/dist/core/engine/library/index.js.map +1 -1
  194. package/dist/core/engine/library/text.d.ts.map +1 -1
  195. package/dist/core/engine/library/text.js +51 -34
  196. package/dist/core/engine/library/text.js.map +1 -1
  197. package/dist/core/engine/load.d.ts +35 -1
  198. package/dist/core/engine/load.d.ts.map +1 -1
  199. package/dist/core/engine/load.js +63 -0
  200. package/dist/core/engine/load.js.map +1 -1
  201. package/dist/core/engine/verify-tables.d.ts.map +1 -1
  202. package/dist/core/engine/verify-tables.js +41 -0
  203. package/dist/core/engine/verify-tables.js.map +1 -1
  204. package/dist/core/index.d.ts +43 -4
  205. package/dist/core/index.d.ts.map +1 -1
  206. package/dist/core/index.js +23 -2
  207. package/dist/core/index.js.map +1 -1
  208. package/dist/core/stdlib/index.d.ts +1 -1
  209. package/dist/core/stdlib/index.d.ts.map +1 -1
  210. package/dist/core/stdlib/index.js +1 -1
  211. package/dist/core/stdlib/index.js.map +1 -1
  212. package/dist/core/stdlib/maths/index.d.ts +1 -1
  213. package/dist/core/stdlib/maths/index.d.ts.map +1 -1
  214. package/dist/core/stdlib/maths/index.js +1 -1
  215. package/dist/core/stdlib/maths/index.js.map +1 -1
  216. package/dist/core/stdlib/maths/rounding.d.ts +5 -0
  217. package/dist/core/stdlib/maths/rounding.d.ts.map +1 -1
  218. package/dist/core/stdlib/maths/rounding.js +19 -1
  219. package/dist/core/stdlib/maths/rounding.js.map +1 -1
  220. package/dist/core/version/version.generated.d.ts +1 -1
  221. package/dist/core/version/version.generated.js +1 -1
  222. package/dist/editor/complete.d.ts +40 -0
  223. package/dist/editor/complete.d.ts.map +1 -0
  224. package/dist/editor/complete.js +206 -0
  225. package/dist/editor/complete.js.map +1 -0
  226. package/dist/editor/diagnose.d.ts +18 -0
  227. package/dist/editor/diagnose.d.ts.map +1 -0
  228. package/dist/editor/diagnose.js +70 -0
  229. package/dist/editor/diagnose.js.map +1 -0
  230. package/dist/editor/format.d.ts +11 -0
  231. package/dist/editor/format.d.ts.map +1 -0
  232. package/dist/editor/format.js +50 -0
  233. package/dist/editor/format.js.map +1 -0
  234. package/dist/editor/highlight.d.ts +28 -0
  235. package/dist/editor/highlight.d.ts.map +1 -0
  236. package/dist/editor/highlight.js +65 -0
  237. package/dist/editor/highlight.js.map +1 -0
  238. package/dist/editor/hover.d.ts +40 -0
  239. package/dist/editor/hover.d.ts.map +1 -0
  240. package/dist/editor/hover.js +147 -0
  241. package/dist/editor/hover.js.map +1 -0
  242. package/dist/editor/index.d.ts +60 -0
  243. package/dist/editor/index.d.ts.map +1 -0
  244. package/dist/editor/index.js +7 -0
  245. package/dist/editor/index.js.map +1 -0
  246. package/dist/editor/kinds.d.ts +27 -0
  247. package/dist/editor/kinds.d.ts.map +1 -0
  248. package/dist/editor/kinds.js +118 -0
  249. package/dist/editor/kinds.js.map +1 -0
  250. package/dist/editor/layout.d.ts +47 -0
  251. package/dist/editor/layout.d.ts.map +1 -0
  252. package/dist/editor/layout.js +135 -0
  253. package/dist/editor/layout.js.map +1 -0
  254. package/dist/editor/manifest.d.ts +47 -0
  255. package/dist/editor/manifest.d.ts.map +1 -0
  256. package/dist/editor/manifest.js +93 -0
  257. package/dist/editor/manifest.js.map +1 -0
  258. package/dist/editor/reading.d.ts +41 -0
  259. package/dist/editor/reading.d.ts.map +1 -0
  260. package/dist/editor/reading.js +51 -0
  261. package/dist/editor/reading.js.map +1 -0
  262. package/dist/editor/scan.d.ts +26 -0
  263. package/dist/editor/scan.d.ts.map +1 -0
  264. package/dist/editor/scan.js +139 -0
  265. package/dist/editor/scan.js.map +1 -0
  266. package/dist/editor/scope.d.ts +19 -0
  267. package/dist/editor/scope.d.ts.map +1 -0
  268. package/dist/editor/scope.js +99 -0
  269. package/dist/editor/scope.js.map +1 -0
  270. package/dist/editor/signature.d.ts +38 -0
  271. package/dist/editor/signature.d.ts.map +1 -0
  272. package/dist/editor/signature.js +112 -0
  273. package/dist/editor/signature.js.map +1 -0
  274. package/dist/editor/site.d.ts +46 -0
  275. package/dist/editor/site.d.ts.map +1 -0
  276. package/dist/editor/site.js +184 -0
  277. package/dist/editor/site.js.map +1 -0
  278. package/dist/editor/spacing.d.ts +29 -0
  279. package/dist/editor/spacing.d.ts.map +1 -0
  280. package/dist/editor/spacing.js +116 -0
  281. package/dist/editor/spacing.js.map +1 -0
  282. package/package.json +42 -3
  283. package/spec/README.md +2 -1
  284. package/spec/errors.json +141 -1
  285. package/src/adapters/charts/driving.ts +109 -0
  286. package/src/adapters/charts/run.ts +120 -28
  287. package/src/adapters/charts/surfaces.ts +17 -0
  288. package/src/adapters/charts/tables.ts +88 -0
  289. package/src/adapters/charts/venue.ts +132 -0
  290. package/src/adapters/codemirror/commands.ts +53 -0
  291. package/src/adapters/codemirror/completion.ts +74 -0
  292. package/src/adapters/codemirror/contract.ts +156 -0
  293. package/src/adapters/codemirror/index.ts +66 -0
  294. package/src/adapters/codemirror/lint.ts +66 -0
  295. package/src/adapters/codemirror/positions.ts +79 -0
  296. package/src/adapters/codemirror/stream.ts +87 -0
  297. package/src/adapters/codemirror/tokens.ts +64 -0
  298. package/src/adapters/codemirror/tooltips.ts +113 -0
  299. package/src/core/accounting/analysis.ts +188 -0
  300. package/src/core/accounting/charges.ts +452 -0
  301. package/src/core/accounting/equity.ts +314 -0
  302. package/src/core/accounting/index.ts +51 -0
  303. package/src/core/accounting/markers.ts +95 -0
  304. package/src/core/accounting/monthly.ts +137 -0
  305. package/src/core/accounting/report.ts +94 -0
  306. package/src/core/accounting/shapes.ts +73 -0
  307. package/src/core/accounting/statistics.ts +387 -0
  308. package/src/core/accounting/trades.ts +313 -0
  309. package/src/core/backtest/case.ts +395 -0
  310. package/src/core/backtest/compare.ts +246 -0
  311. package/src/core/backtest/declaration.ts +97 -0
  312. package/src/core/backtest/deliver.ts +161 -0
  313. package/src/core/backtest/drive.ts +468 -0
  314. package/src/core/backtest/index.ts +64 -0
  315. package/src/core/backtest/range.ts +137 -0
  316. package/src/core/backtest/record.ts +470 -0
  317. package/src/core/backtest/replay.ts +168 -0
  318. package/src/core/backtest/resting.ts +125 -0
  319. package/src/core/backtest/settings.ts +280 -0
  320. package/src/core/backtest/simulate.ts +499 -0
  321. package/src/core/catalogue/catalogue.generated.ts +6 -0
  322. package/src/core/catalogue/values.generated.ts +6 -0
  323. package/src/core/check/index.ts +3 -0
  324. package/src/core/check/library-orders.ts +2 -2
  325. package/src/core/check/library-prose.generated.ts +367 -0
  326. package/src/core/check/surface.ts +34 -0
  327. package/src/core/emit/canonical.ts +67 -9
  328. package/src/core/emit/defaults.ts +70 -0
  329. package/src/core/emit/index.ts +2 -0
  330. package/src/core/engine/arithmetic.ts +23 -3
  331. package/src/core/engine/index.ts +2 -2
  332. package/src/core/engine/library/arrays.ts +8 -2
  333. package/src/core/engine/library/code-points.ts +73 -0
  334. package/src/core/engine/library/index.ts +6 -0
  335. package/src/core/engine/library/text.ts +53 -35
  336. package/src/core/engine/load.ts +84 -2
  337. package/src/core/engine/verify-tables.ts +43 -0
  338. package/src/core/index.ts +100 -2
  339. package/src/core/stdlib/index.ts +1 -0
  340. package/src/core/stdlib/maths/index.ts +1 -0
  341. package/src/core/stdlib/maths/rounding.ts +23 -1
  342. package/src/core/version/version.generated.ts +1 -1
  343. package/src/editor/complete.ts +266 -0
  344. package/src/editor/diagnose.ts +71 -0
  345. package/src/editor/format.ts +85 -0
  346. package/src/editor/highlight.ts +110 -0
  347. package/src/editor/hover.ts +199 -0
  348. package/src/editor/index.ts +65 -0
  349. package/src/editor/kinds.ts +157 -0
  350. package/src/editor/layout.ts +189 -0
  351. package/src/editor/manifest.ts +119 -0
  352. package/src/editor/reading.ts +69 -0
  353. package/src/editor/scan.ts +162 -0
  354. package/src/editor/scope.ts +122 -0
  355. package/src/editor/signature.ts +150 -0
  356. package/src/editor/site.ts +233 -0
  357. package/src/editor/spacing.ts +132 -0
@@ -0,0 +1,119 @@
1
+ /**
2
+ * The standard library manifest, as the three functions that read it need it.
3
+ *
4
+ * `complete`, `hover` and `signature` all want the same things about a name:
5
+ * which signature the writer means, how to spell that signature, what each
6
+ * parameter defaults to, and the line the specification gives it. Every one of
7
+ * those is a question the compiler already answers, and the whole value of this
8
+ * file is that it asks rather than knows.
9
+ *
10
+ * which entries a name has the manifest index, `libraryEntries`
11
+ * what a parameter defaults the manifest, or the emitter for the eight
12
+ * declaration calls
13
+ * what the call is for `proseFor`, read out of `stdlib.md`'s own
14
+ * tables at build time, with the warmup its row
15
+ * states beside it
16
+ * what a type is called `typeText`, the checker's own spelling
17
+ *
18
+ * A list of function names typed into this repository would be right on the day
19
+ * it was typed and wrong at the next release, and a missing completion looks
20
+ * exactly like a completion that has not loaded yet, so nobody would report it.
21
+ *
22
+ * ## The default is the compiler's, including for the eight that hide it
23
+ *
24
+ * Most calls carry their default in the manifest, spelled as `stdlib.md` prints
25
+ * it. A `plot`, a `level`, a `table` and the five like them do not: their
26
+ * optional arguments become fields of a declaration rather than arguments an
27
+ * engine is passed, so their values live in the emitter
28
+ * (`compiled-program.md` 2.3). A tooltip built on the manifest alone would show
29
+ * a writer nothing beside `width?` while the compiler writes 1.5.
30
+ *
31
+ * So both are read, through `declarationDefaultText`, which is the same answer
32
+ * `scripts/check-defaults.mjs` holds to what the specification prints. A default
33
+ * shown here cannot differ from the one the compiler applies without failing the
34
+ * build, which is the only way a tooltip's number is worth anything.
35
+ */
36
+ import {
37
+ DECLARATION_CALLS,
38
+ declarationDefaultText,
39
+ libraryEntries,
40
+ typeText,
41
+ } from '../core/index.js';
42
+ import type { LibraryEntry } from '../core/index.js';
43
+
44
+ /** One parameter of a call, with everything a writer is shown about it. */
45
+ export interface Parameter {
46
+ readonly name: string;
47
+ /** The type as the checker spells it: `series number`, `array<line>`. */
48
+ readonly type: string;
49
+ /** Whether the call is refused without it, which is OS3012. */
50
+ readonly required: boolean;
51
+ /**
52
+ * What an omitted argument resolves to, as the specification prints it.
53
+ *
54
+ * Nothing where the specification states no value: `spec/default-exceptions.json`
55
+ * records those and why each one has none, and a number invented to fill the
56
+ * gap would be the defect that file exists to keep out.
57
+ */
58
+ readonly defaultText: string | undefined;
59
+ /** The closed set of strings it accepts, where the library fixes one: OS3008. */
60
+ readonly values: readonly string[];
61
+ }
62
+
63
+ /** Every parameter of one signature, with the defaults from both homes. */
64
+ export function parametersOf(entry: LibraryEntry): readonly Parameter[] {
65
+ const declared = DECLARATION_CALLS.has(entry.name);
66
+ return entry.parameters.map((one) => ({
67
+ name: one.name,
68
+ type: typeText(one.type),
69
+ required: !one.optional,
70
+ defaultText: declared
71
+ ? declarationDefaultText(entry.name, one.name)
72
+ : one.defaultText,
73
+ values: entry.values[one.name] ?? [],
74
+ }));
75
+ }
76
+
77
+ /**
78
+ * One signature, written out the way the specification's tables write one.
79
+ *
80
+ * `ema(src: series number, len: number) -> series number`. The parameter names,
81
+ * the types and the defaults are the manifest's; nothing about the spelling is
82
+ * decided here except the punctuation between them.
83
+ */
84
+ export function signatureTextOf(entry: LibraryEntry): string {
85
+ if (!entry.callable) return `${entry.name}: ${typeText(entry.returns)}`;
86
+ const written = parametersOf(entry).map((one) => {
87
+ const head = `${one.name}${one.required ? '' : '?'}: ${one.type}`;
88
+ return one.defaultText === undefined ? head : `${head} = ${one.defaultText}`;
89
+ });
90
+ return `${entry.name}(${written.join(', ')}) -> ${typeText(entry.returns)}`;
91
+ }
92
+
93
+ /**
94
+ * The signature a half written call means, chosen by the rule that can be
95
+ * applied to a half written call.
96
+ *
97
+ * `stdlib.md` 2.2 resolves an overload by arity first and by argument type
98
+ * second, and the checker does exactly that. The second rule needs a type for
99
+ * every argument, which needs a tree, which a call that is still being typed has
100
+ * not got: `clear(` is two signatures until the argument arrives. So only the
101
+ * first rule is applied here, and where it leaves more than one candidate the
102
+ * first is taken, which is the order `stdlib.md` states them in.
103
+ *
104
+ * That is a narrowing of the checker's answer rather than a second opinion about
105
+ * it: the tooltip may show the array signature of `clear` while the writer meant
106
+ * the grid one, and the moment the argument is written the checker settles it
107
+ * and `diagnose` is what says so. It is recorded in `spec/editor-narrowings.json`.
108
+ */
109
+ export function entryAt(name: string, given: number): LibraryEntry | undefined {
110
+ const entries = libraryEntries(name).filter((one) => one.callable);
111
+ const first = entries[0];
112
+ if (first === undefined || entries.length === 1) return first;
113
+
114
+ const byArity = entries.filter((one) => {
115
+ const required = one.parameters.filter((parameter) => !parameter.optional).length;
116
+ return given >= required && given <= one.parameters.length;
117
+ });
118
+ return byArity[0] ?? first;
119
+ }
@@ -0,0 +1,69 @@
1
+ /**
2
+ * The first step of every function in this tier: text becomes a file, and the
3
+ * file becomes tokens.
4
+ *
5
+ * It is one place rather than four because all four begin identically and
6
+ * because one of them beginning differently is a bug nobody would look for.
7
+ *
8
+ * The bag is created and, for `highlight`, thrown away. That is not waste: the
9
+ * lexer reports rather than throws, so handing it somewhere to report is how it
10
+ * is told to carry on, and a highlighter has nothing to say about a character
11
+ * the language does not have. `diagnose` is what says it.
12
+ */
13
+ import { DiagnosticBag, check, lex, parseTokens, sourceFile } from '../core/index.js';
14
+ import type { CheckedScript, Script, SourceFile, Token } from '../core/index.js';
15
+
16
+ /**
17
+ * The name the file is read under, and why none of these functions takes one.
18
+ *
19
+ * A `SourceFile` carries a name, and the renderer in the core puts it on the
20
+ * first line of a rendered diagnostic. Nothing this tier returns carries it: a
21
+ * diagnostic holds a span, and a highlighted piece holds a span, and neither
22
+ * holds a file. So a name parameter here would be a parameter a caller can only
23
+ * get wrong, with nothing anywhere able to notice that they had. A host that
24
+ * renders a diagnostic with its own file name on it builds the `SourceFile`
25
+ * itself, from the core, which is where the renderer lives.
26
+ */
27
+ const UNNAMED = 'script.oscript';
28
+
29
+ export interface Read {
30
+ readonly file: SourceFile;
31
+ readonly bag: DiagnosticBag;
32
+ readonly tokens: readonly Token[];
33
+ }
34
+
35
+ export interface ReadTree extends Read {
36
+ readonly script: Script;
37
+ }
38
+
39
+ export interface ReadChecked extends ReadTree {
40
+ readonly checked: CheckedScript;
41
+ }
42
+
43
+ /** Text to a file and its tokens. */
44
+ export function read(source: string): Read {
45
+ const file = sourceFile(UNNAMED, source);
46
+ const bag = new DiagnosticBag();
47
+ return { file, bag, tokens: lex(file, bag) };
48
+ }
49
+
50
+ /** The same, with the tree, for the functions that need one. */
51
+ export function readTree(source: string): ReadTree {
52
+ const held = read(source);
53
+ return { ...held, script: parseTokens(held.file, held.tokens, held.bag) };
54
+ }
55
+
56
+ /**
57
+ * The same again, checked, for the two that ask what a name means.
58
+ *
59
+ * `complete` and `hover` both need the checker's answers: which names the file
60
+ * has declared, where each was declared, and what type each one holds. Nothing
61
+ * here is a lighter version of the checker. It is the checker, run on a file
62
+ * that is halfway through being typed, which it is built to survive: a name
63
+ * that does not resolve becomes `unknown` and the lines around it are still
64
+ * checked, so the names above the cursor are still names.
65
+ */
66
+ export function readChecked(source: string): ReadChecked {
67
+ const held = readTree(source);
68
+ return { ...held, checked: check(held.file, held.script, held.bag) };
69
+ }
@@ -0,0 +1,162 @@
1
+ /**
2
+ * The covering scan: every character of a file, exactly once, with what it is.
3
+ *
4
+ * ## The property that decides the shape
5
+ *
6
+ * A host draws highlighting behind or over a text component, and it draws it by
7
+ * walking a list. Drop one character anywhere on a line and everything after it
8
+ * on that line is drawn one column to the left, so the caret stops sitting where
9
+ * the text is. That is not a cosmetic bug: it is the editor feeling broken, and
10
+ * it is reported as "the cursor is in the wrong place" rather than as a
11
+ * highlighting fault, which is why it survives.
12
+ *
13
+ * So the guarantee here is not "here are the tokens". It is **the spans tile the
14
+ * source**: they are in order, they do not overlap, none is empty, and their
15
+ * texts concatenate to the file exactly. A host that renders the spans and
16
+ * nothing else cannot lose a character, because there is nowhere for one to go.
17
+ * `tests/editor/highlight.test.ts` holds that over every script in the
18
+ * repository and over a corpus of malformed ones.
19
+ *
20
+ * ## Where the comments come from
21
+ *
22
+ * The lexer emits no token for a comment, because the parser has no use for one
23
+ * (`language.md` 3.10, and it is the rule that lets a commented-out statement
24
+ * sit at column zero inside a block without closing it). A highlighter does have
25
+ * a use for one, so they have to be recovered, and this is the one place in the
26
+ * project that does it. Leaving it to each host is what produced the two
27
+ * problems this file exists to remove: a platform recovering comments from the
28
+ * gaps between token spans, and doing it with its own scan for `//`.
29
+ *
30
+ * A scan of its own is the wrong answer, because a `//` inside a string literal
31
+ * is ordinary text (3.2) and finding that out means lexing strings a second
32
+ * time. This does not scan the file. It walks the tokens the real lexer
33
+ * produced, and only looks at what is left between them, which by construction
34
+ * holds no string literal: a `//` in a gap is always a comment, with no second
35
+ * opinion about the language anywhere in it.
36
+ *
37
+ * What else can be in a gap is small and worth naming, because a reader of this
38
+ * file will want to know whether it can be surprised: blanks, a line continuation
39
+ * backslash, a region somebody meant as a block comment, and the characters the
40
+ * lexer refused and reported. All of those are `unknown`, which means "the lexer
41
+ * took no token from this", and `diagnose` is what says whether any of it is a
42
+ * mistake.
43
+ */
44
+ import { endOffset } from '../core/index.js';
45
+ import type { SourceFile, Span, Token } from '../core/index.js';
46
+ import { kindOf } from './kinds.js';
47
+ import type { HighlightKind } from './kinds.js';
48
+
49
+ /** One piece of the file, with what it is and the text it covers. */
50
+ export interface Highlight {
51
+ readonly kind: HighlightKind;
52
+ readonly span: Span;
53
+ /**
54
+ * The source the span covers, carried rather than left to the caller to slice.
55
+ *
56
+ * A host that concatenates these gets the file back, so a renderer never
57
+ * indexes the buffer and never has to agree with this module about what an
58
+ * offset means. It is also what makes the covering property a one-line test.
59
+ */
60
+ readonly text: string;
61
+ }
62
+
63
+ const SLASH = 47;
64
+ const LINE_FEED = 10;
65
+
66
+ /** Whether a comment opens at `at`: two slashes, which run to the end of the line. */
67
+ function opensComment(text: string, at: number): boolean {
68
+ return text.charCodeAt(at) === SLASH && text.charCodeAt(at + 1) === SLASH;
69
+ }
70
+
71
+ function isBlank(code: number): boolean {
72
+ // The three the lexer passes over between tokens. A tab is OS1002 in leading
73
+ // whitespace and is still whitespace to look at, so it is painted as such and
74
+ // the compiler is left to be the one that objects to it. A lone carriage
75
+ // return is not one of these: `language.md` 3.1 does not accept it, the lexer
76
+ // reports it, and painting it as a space would hide the one thing about it
77
+ // worth knowing.
78
+ return code === 32 || code === 9 || code === LINE_FEED;
79
+ }
80
+
81
+ /** The end of the line `at` sits on, or the end of the file. */
82
+ function endOfLine(text: string, at: number): number {
83
+ const found = text.indexOf('\n', at);
84
+ return found === -1 ? text.length : found;
85
+ }
86
+
87
+ /**
88
+ * A run of one kind inside a gap, from `from` up to but not including its end.
89
+ *
90
+ * The three cases are tried in the order they can be told apart: a blank is a
91
+ * blank, two slashes open a comment to the end of the line, and anything else
92
+ * runs until one of those two begins.
93
+ */
94
+ function runIn(text: string, from: number, to: number): { end: number; kind: HighlightKind } {
95
+ if (isBlank(text.charCodeAt(from))) {
96
+ let i = from;
97
+ while (i < to && isBlank(text.charCodeAt(i))) i += 1;
98
+ return { end: i, kind: 'whitespace' };
99
+ }
100
+
101
+ if (opensComment(text, from)) {
102
+ return { end: Math.min(endOfLine(text, from), to), kind: 'comment' };
103
+ }
104
+
105
+ let i = from;
106
+ while (i < to && !isBlank(text.charCodeAt(i)) && !opensComment(text, i)) i += 1;
107
+ return { end: i, kind: 'unknown' };
108
+ }
109
+
110
+ /**
111
+ * Every piece of a file, in order, covering it exactly.
112
+ *
113
+ * The token list is walked rather than sorted, and a token that would overlap
114
+ * the piece before it is skipped rather than believed. Both of those are
115
+ * defences rather than expectations: the property this returns is what a host
116
+ * draws with, and it has to hold for a stream from a file somebody is halfway
117
+ * through typing as firmly as for one from a script that compiles.
118
+ */
119
+ export function scan(file: SourceFile, tokens: readonly Token[]): readonly Highlight[] {
120
+ const text = file.text;
121
+ const out: Highlight[] = [];
122
+ let at = 0;
123
+
124
+ const fill = (to: number): void => {
125
+ let from = at;
126
+ while (from < to) {
127
+ const run = runIn(text, from, to);
128
+ out.push({
129
+ kind: run.kind,
130
+ span: file.spanAt(from, run.end - from),
131
+ text: text.slice(from, run.end),
132
+ });
133
+ from = run.end;
134
+ }
135
+ };
136
+
137
+ const read: Token[] = [];
138
+ for (const token of tokens) {
139
+ if (token.span.length === 0) {
140
+ // A dedent and the end of the file are positions rather than text, and a
141
+ // newline at the end of a file is one too. Nothing to paint, but the
142
+ // token still counts as read for the dotted name question next door.
143
+ read.push(token);
144
+ continue;
145
+ }
146
+ if (token.span.offset < at) continue;
147
+ if (token.span.offset > at) {
148
+ fill(token.span.offset);
149
+ at = token.span.offset;
150
+ }
151
+ out.push({
152
+ kind: kindOf(token, read),
153
+ span: token.span,
154
+ text: text.slice(token.span.offset, endOffset(token.span)),
155
+ });
156
+ at = endOffset(token.span);
157
+ read.push(token);
158
+ }
159
+
160
+ fill(text.length);
161
+ return out;
162
+ }
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Which of the file's own names may be written at a position.
3
+ *
4
+ * A completion list that offered every name in the file would offer a loop
5
+ * variable three blocks away and a function parameter from another function,
6
+ * and a writer accepting one of those gets OS2001 from the compiler a moment
7
+ * later. So the two rules the language states are applied, and both are asked of
8
+ * the compiler's own answers rather than worked out again here.
9
+ *
10
+ * declared above OS2001 is "not defined at this point in the file", so a
11
+ * name is offered from the end of the statement that
12
+ * declares it. Not from the end of the name: `x` is not
13
+ * yet a name inside `x = ema(x, 9)`, and `f` is not one
14
+ * inside `f`'s own body, because recursion is OS2005
15
+ * and still inside a name belongs to the block that declared it
16
+ * (`language.md` 12), so it is offered inside that block
17
+ * and nowhere else
18
+ *
19
+ * The bindings are the checker's, not a second walk of the tree: `declaredAt` is
20
+ * the span the checker points OS2002 and OS8010 at, and the kind, the type and
21
+ * the persistence are what it worked out. What is derived here is one thing, the
22
+ * region a binding belongs to, and it is derived from the tree the parser
23
+ * produced by asking which nodes enclose the declaration.
24
+ */
25
+ import { containsOffset, endOffset, isStatement, pathAtOffset } from '../core/index.js';
26
+ import type { AstNode, Binding, CheckedScript, NodeKind } from '../core/index.js';
27
+
28
+ /**
29
+ * The node kinds that hold a scope of their own.
30
+ *
31
+ * A block is the obvious one. A function declaration is here because its
32
+ * parameters are declared in its header rather than in its body, and a loop
33
+ * because its variable is declared in the header too. Anything else a name is
34
+ * declared inside belongs to whichever of these encloses it, and a file level
35
+ * name belongs to the file.
36
+ */
37
+ const SCOPES: ReadonlySet<NodeKind> = new Set<NodeKind>([
38
+ 'block',
39
+ 'functionDeclaration',
40
+ 'forRangeStatement',
41
+ 'forInStatement',
42
+ ]);
43
+
44
+ /**
45
+ * The region a declaration belongs to, and the offset it starts being a name at.
46
+ *
47
+ * Both come from one walk of the path to the declaration. The region is the
48
+ * innermost enclosing scope, or the file. The offset is the end of the statement
49
+ * that declares it, except for a parameter and a loop variable, whose statement
50
+ * is the function or the loop they are read inside: those two are names from the
51
+ * end of the header that declares them.
52
+ */
53
+ interface Region {
54
+ readonly node: AstNode | undefined;
55
+ readonly from: number;
56
+ }
57
+
58
+ const HEADERS: ReadonlySet<Binding['kind']> = new Set<Binding['kind']>(['parameter', 'loop']);
59
+
60
+ function regionOf(script: CheckedScript, binding: Binding): Region {
61
+ const path = pathAtOffset(script.script, binding.declaredAt.offset);
62
+ let node: AstNode | undefined;
63
+ let statement: AstNode | undefined;
64
+
65
+ for (let i = path.length - 1; i >= 0; i -= 1) {
66
+ const held = path[i];
67
+ if (held === undefined) continue;
68
+ if (statement === undefined && isStatement(held)) statement = held;
69
+ if (SCOPES.has(held.kind)) {
70
+ node = held;
71
+ break;
72
+ }
73
+ }
74
+
75
+ const from = HEADERS.has(binding.kind)
76
+ ? endOffset(binding.declaredAt)
77
+ : endOffset(statement?.span ?? binding.declaredAt);
78
+ return { node, from };
79
+ }
80
+
81
+ /**
82
+ * Every name the file itself declares that may be written at an offset.
83
+ *
84
+ * A library name is not here: the manifest answers for those, and a binding of
85
+ * kind `library` is the checker's record of the global scope rather than
86
+ * something the file declared.
87
+ */
88
+ export function inScopeAt(script: CheckedScript, offset: number): readonly Binding[] {
89
+ return script.bindings.filter((binding) => {
90
+ if (binding.kind === 'library') return false;
91
+ const region = regionOf(script, binding);
92
+ if (region.from > offset) return false;
93
+ // No enclosing scope node means the file, and the file holds every offset,
94
+ // including the one past its last character where somebody is typing.
95
+ return region.node === undefined || containsOffset(region.node.span, offset);
96
+ });
97
+ }
98
+
99
+ /**
100
+ * The binding a name means at an offset, or nothing where the file declares none.
101
+ *
102
+ * The declaration itself counts, which the scope rule above deliberately does
103
+ * not: a name is not in scope inside its own right hand side, and pointing at it
104
+ * on the line that declares it is still pointing at it. Without this, a hover
105
+ * over the `x` in `x = ema(close, 9)` would say nothing at all.
106
+ */
107
+ export function bindingNamed(
108
+ script: CheckedScript,
109
+ name: string,
110
+ offset: number,
111
+ ): Binding | undefined {
112
+ const declaring = script.bindings.find(
113
+ (binding) => binding.name === name && containsOffset(binding.declaredAt, offset),
114
+ );
115
+ if (declaring !== undefined) return declaring;
116
+
117
+ const held = inScopeAt(script, offset).filter((binding) => binding.name === name);
118
+ // The innermost declaration wins, which is the one declared last among those
119
+ // still in scope: a block level name shadows a file level one of the same
120
+ // spelling for as long as its block lasts.
121
+ return held[held.length - 1];
122
+ }
@@ -0,0 +1,150 @@
1
+ /**
2
+ * `signature`: the call being written, and which parameter the cursor is in.
3
+ *
4
+ * The call is found from the brackets rather than from the tree, because a call
5
+ * being written has no finished tree node: `ema(close, ` is the state every call
6
+ * is in while somebody types one, and that is exactly when this is asked.
7
+ * `site.ts` does that part.
8
+ *
9
+ * ## The default shown is the default the compiler applies
10
+ *
11
+ * This is the trap worth naming, because getting it wrong produces a tooltip
12
+ * that is confidently wrong rather than absent. `stdlib.md` states a default for
13
+ * every optional argument, and `scripts/check-defaults.mjs` already holds the
14
+ * compiler to those: a value the surface carries that the specification does not
15
+ * state fails the build, and so does one the specification states that the
16
+ * compiler does not apply.
17
+ *
18
+ * So this reads the same two places that check reads, through `parametersOf`:
19
+ * the library manifest for an ordinary call, and the emitter for the eight
20
+ * declaration calls whose optional arguments become fields of a declaration
21
+ * rather than arguments. A number shown here therefore cannot differ from the
22
+ * number the compiler fills in; if it ever does, the defaults check fails before
23
+ * anybody sees the tooltip.
24
+ *
25
+ * A writer's own function is answered too, from the checker's record of it. Its
26
+ * parameter types are the ones the checker worked out, and a default it declares
27
+ * is quoted from the source text rather than printed from the tree, because the
28
+ * text is what the writer wrote.
29
+ */
30
+ import { endOffset, entryFor, fillTemplate, proseFor, typeText } from '../core/index.js';
31
+ import type { CheckedScript, Span } from '../core/index.js';
32
+ import { entryAt, parametersOf, signatureTextOf } from './manifest.js';
33
+ import type { Parameter } from './manifest.js';
34
+ import { readChecked } from './reading.js';
35
+ import { siteAt } from './site.js';
36
+ import type { CallSite } from './site.js';
37
+
38
+ export interface SignatureHelp {
39
+ /** The callee as written: `ema`, `draw.box`, or a name the file declared. */
40
+ readonly name: string;
41
+ /** Whether the library holds it or the file declares it. */
42
+ readonly of: 'library' | 'declared';
43
+ /** The signature written out, the way the specification's tables write one. */
44
+ readonly signature: string;
45
+ readonly parameters: readonly Parameter[];
46
+ /**
47
+ * Which parameter the cursor is in, or -1 where it is in none.
48
+ *
49
+ * A label decides it where one is written, because `plot(close, color = ` is
50
+ * in `color` whatever position it sits in; otherwise the count of commas
51
+ * decides. It is -1 past the last parameter, which is a call with more
52
+ * arguments than the signature takes and is OS3001 the moment it is compiled.
53
+ */
54
+ readonly active: number;
55
+ /** The line the specification gives the call, where it gives one. */
56
+ readonly summary: string | undefined;
57
+ /** Named in the library and not implemented in this version: OS2020. */
58
+ readonly planned: boolean;
59
+ readonly refusal: string | undefined;
60
+ /** The callee's own name, for a host anchoring a tooltip to the call. */
61
+ readonly span: Span;
62
+ }
63
+
64
+ /** Which parameter a position in the argument list means. */
65
+ function activeIn(parameters: readonly Parameter[], call: CallSite): number {
66
+ if (call.label !== undefined) {
67
+ return parameters.findIndex((one) => one.name === call.label);
68
+ }
69
+ return call.argument < parameters.length ? call.argument : -1;
70
+ }
71
+
72
+ /**
73
+ * A function the file declares, as the checker recorded it.
74
+ *
75
+ * `language.md` 11.1 lets a parameter carry a default, and the text of that
76
+ * default is quoted from the source rather than printed back from the tree: the
77
+ * tree holds an expression and printing one would be a second formatter, while
78
+ * the source holds what the writer typed.
79
+ */
80
+ function declaredSignature(
81
+ checked: CheckedScript,
82
+ text: string,
83
+ call: CallSite,
84
+ ): SignatureHelp | undefined {
85
+ const held = checked.functions.find((one) => one.declaration.name.text === call.name);
86
+ if (held === undefined) return undefined;
87
+
88
+ const parameters: Parameter[] = held.declaration.parameters.map((one, index) => {
89
+ const value = one.defaultValue;
90
+ const binding = held.parameters[index];
91
+ return {
92
+ name: one.name.text,
93
+ type: binding === undefined ? 'unknown' : typeText(binding.type),
94
+ required: value === undefined,
95
+ defaultText:
96
+ value === undefined ? undefined : text.slice(value.span.offset, endOffset(value.span)),
97
+ values: [],
98
+ };
99
+ });
100
+
101
+ const written = parameters.map((one) => {
102
+ const head = `${one.name}${one.required ? '' : '?'}: ${one.type}`;
103
+ return one.defaultText === undefined ? head : `${head} = ${one.defaultText}`;
104
+ });
105
+
106
+ return {
107
+ name: call.name,
108
+ of: 'declared',
109
+ signature: `fn ${call.name}(${written.join(', ')})`,
110
+ parameters,
111
+ active: activeIn(parameters, call),
112
+ summary: undefined,
113
+ planned: false,
114
+ refusal: undefined,
115
+ span: call.nameSpan,
116
+ };
117
+ }
118
+
119
+ /**
120
+ * The call the cursor is inside, or nothing where it is inside none.
121
+ *
122
+ * Nothing is the answer for a cursor outside every bracket, and for one inside a
123
+ * bracket whose callee the language does not have: a name that resolves to
124
+ * neither the library nor the file is OS2001, and `diagnose` is what says so.
125
+ * A tooltip that invented a signature for it would be a second opinion about
126
+ * what the file declares.
127
+ */
128
+ export function signature(source: string, offset: number): SignatureHelp | undefined {
129
+ const { file, tokens, checked } = readChecked(source);
130
+ const call = siteAt(file, tokens, offset).call;
131
+ if (call === undefined) return undefined;
132
+
133
+ const entry = entryAt(call.name, call.argument + 1);
134
+ if (entry === undefined) return declaredSignature(checked, file.text, call);
135
+
136
+ const parameters = parametersOf(entry);
137
+ return {
138
+ name: call.name,
139
+ of: 'library',
140
+ signature: signatureTextOf(entry),
141
+ parameters,
142
+ active: activeIn(parameters, call),
143
+ summary: proseFor(call.name)?.summary,
144
+ planned: entry.planned,
145
+ refusal: entry.planned
146
+ ? fillTemplate(entryFor('OS2020').message, { name: call.name })
147
+ : undefined,
148
+ span: call.nameSpan,
149
+ };
150
+ }