rooklang 0.0.0-stage → 0.3.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 (314) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +177 -2
  3. package/README.ru.md +178 -0
  4. package/dist/ast/declarations.d.ts +185 -0
  5. package/dist/ast/declarations.js +1 -0
  6. package/dist/ast/expressions.d.ts +201 -0
  7. package/dist/ast/expressions.js +1 -0
  8. package/dist/ast/markup.d.ts +141 -0
  9. package/dist/ast/markup.js +1 -0
  10. package/dist/ast/statements.d.ts +173 -0
  11. package/dist/ast/statements.js +1 -0
  12. package/dist/ast.d.ts +18 -0
  13. package/dist/ast.js +18 -0
  14. package/dist/attrs.d.ts +8 -0
  15. package/dist/attrs.js +23 -0
  16. package/dist/browser.d.ts +30 -0
  17. package/dist/browser.js +36 -0
  18. package/dist/build.d.ts +48 -0
  19. package/dist/build.js +112 -0
  20. package/dist/checker/assignments.d.ts +14 -0
  21. package/dist/checker/assignments.js +197 -0
  22. package/dist/checker/base.d.ts +124 -0
  23. package/dist/checker/base.js +180 -0
  24. package/dist/checker/bigint.d.ts +15 -0
  25. package/dist/checker/bigint.js +85 -0
  26. package/dist/checker/builtins.d.ts +9 -0
  27. package/dist/checker/builtins.js +307 -0
  28. package/dist/checker/bytes.d.ts +11 -0
  29. package/dist/checker/bytes.js +72 -0
  30. package/dist/checker/calls.d.ts +23 -0
  31. package/dist/checker/calls.js +210 -0
  32. package/dist/checker/channel.d.ts +14 -0
  33. package/dist/checker/channel.js +44 -0
  34. package/dist/checker/channels.d.ts +9 -0
  35. package/dist/checker/channels.js +95 -0
  36. package/dist/checker/checker.d.ts +4 -0
  37. package/dist/checker/checker.js +22 -0
  38. package/dist/checker/classes.d.ts +24 -0
  39. package/dist/checker/classes.js +223 -0
  40. package/dist/checker/completion-names.d.ts +11 -0
  41. package/dist/checker/completion-names.js +100 -0
  42. package/dist/checker/completion.d.ts +25 -0
  43. package/dist/checker/completion.js +222 -0
  44. package/dist/checker/component-values.d.ts +11 -0
  45. package/dist/checker/component-values.js +88 -0
  46. package/dist/checker/components.d.ts +37 -0
  47. package/dist/checker/components.js +287 -0
  48. package/dist/checker/context.d.ts +196 -0
  49. package/dist/checker/context.js +35 -0
  50. package/dist/checker/control-flow.d.ts +24 -0
  51. package/dist/checker/control-flow.js +237 -0
  52. package/dist/checker/declarations.d.ts +26 -0
  53. package/dist/checker/declarations.js +259 -0
  54. package/dist/checker/decorator-exports.d.ts +5 -0
  55. package/dist/checker/decorator-exports.js +40 -0
  56. package/dist/checker/decorator-members.d.ts +28 -0
  57. package/dist/checker/decorator-members.js +140 -0
  58. package/dist/checker/decorator-wrappers.d.ts +20 -0
  59. package/dist/checker/decorator-wrappers.js +132 -0
  60. package/dist/checker/decorators.d.ts +28 -0
  61. package/dist/checker/decorators.js +265 -0
  62. package/dist/checker/dom-svg.d.ts +7 -0
  63. package/dist/checker/dom-svg.js +19 -0
  64. package/dist/checker/dom.d.ts +22 -0
  65. package/dist/checker/dom.js +361 -0
  66. package/dist/checker/expressions.d.ts +32 -0
  67. package/dist/checker/expressions.js +244 -0
  68. package/dist/checker/flow.d.ts +18 -0
  69. package/dist/checker/flow.js +134 -0
  70. package/dist/checker/forwarding.d.ts +15 -0
  71. package/dist/checker/forwarding.js +78 -0
  72. package/dist/checker/functions.d.ts +24 -0
  73. package/dist/checker/functions.js +154 -0
  74. package/dist/checker/go-for.d.ts +12 -0
  75. package/dist/checker/go-for.js +93 -0
  76. package/dist/checker/goroutines.d.ts +19 -0
  77. package/dist/checker/goroutines.js +110 -0
  78. package/dist/checker/helpers.d.ts +35 -0
  79. package/dist/checker/helpers.js +162 -0
  80. package/dist/checker/imports.d.ts +7 -0
  81. package/dist/checker/imports.js +83 -0
  82. package/dist/checker/initializers.d.ts +22 -0
  83. package/dist/checker/initializers.js +104 -0
  84. package/dist/checker/iterables.d.ts +5 -0
  85. package/dist/checker/iterables.js +17 -0
  86. package/dist/checker/iterators.d.ts +13 -0
  87. package/dist/checker/iterators.js +95 -0
  88. package/dist/checker/loops.d.ts +10 -0
  89. package/dist/checker/loops.js +82 -0
  90. package/dist/checker/markup.d.ts +28 -0
  91. package/dist/checker/markup.js +220 -0
  92. package/dist/checker/members.d.ts +29 -0
  93. package/dist/checker/members.js +233 -0
  94. package/dist/checker/operators.d.ts +13 -0
  95. package/dist/checker/operators.js +177 -0
  96. package/dist/checker/promise.d.ts +17 -0
  97. package/dist/checker/promise.js +49 -0
  98. package/dist/checker/refs.d.ts +26 -0
  99. package/dist/checker/refs.js +136 -0
  100. package/dist/checker/resolution.d.ts +23 -0
  101. package/dist/checker/resolution.js +173 -0
  102. package/dist/checker/statements.d.ts +28 -0
  103. package/dist/checker/statements.js +212 -0
  104. package/dist/checker/styles.d.ts +14 -0
  105. package/dist/checker/styles.js +49 -0
  106. package/dist/checker/transfer.d.ts +5 -0
  107. package/dist/checker/transfer.js +83 -0
  108. package/dist/checker/types/bytes.d.ts +4 -0
  109. package/dist/checker/types/bytes.js +51 -0
  110. package/dist/checker/types/classes.d.ts +22 -0
  111. package/dist/checker/types/classes.js +93 -0
  112. package/dist/checker/types/constructors.d.ts +27 -0
  113. package/dist/checker/types/constructors.js +129 -0
  114. package/dist/checker/types/generics.d.ts +20 -0
  115. package/dist/checker/types/generics.js +75 -0
  116. package/dist/checker/types/lazy.d.ts +30 -0
  117. package/dist/checker/types/lazy.js +92 -0
  118. package/dist/checker/types/model.d.ts +149 -0
  119. package/dist/checker/types/model.js +15 -0
  120. package/dist/checker/types/params.d.ts +7 -0
  121. package/dist/checker/types/params.js +220 -0
  122. package/dist/checker/types/printing.d.ts +6 -0
  123. package/dist/checker/types/printing.js +109 -0
  124. package/dist/checker/types/relations.d.ts +16 -0
  125. package/dist/checker/types/relations.js +294 -0
  126. package/dist/checker/types.d.ts +9 -0
  127. package/dist/checker/types.js +10 -0
  128. package/dist/cli.d.ts +2 -0
  129. package/dist/cli.js +193 -0
  130. package/dist/codegen/analysis.d.ts +18 -0
  131. package/dist/codegen/analysis.js +144 -0
  132. package/dist/codegen/attributes.d.ts +40 -0
  133. package/dist/codegen/attributes.js +227 -0
  134. package/dist/codegen/calls.d.ts +22 -0
  135. package/dist/codegen/calls.js +106 -0
  136. package/dist/codegen/chan-helpers.d.ts +2 -0
  137. package/dist/codegen/chan-helpers.js +253 -0
  138. package/dist/codegen/component-helpers.d.ts +33 -0
  139. package/dist/codegen/component-helpers.js +18 -0
  140. package/dist/codegen/component-props.d.ts +42 -0
  141. package/dist/codegen/component-props.js +173 -0
  142. package/dist/codegen/component-values.d.ts +27 -0
  143. package/dist/codegen/component-values.js +146 -0
  144. package/dist/codegen/components.d.ts +53 -0
  145. package/dist/codegen/components.js +268 -0
  146. package/dist/codegen/control-flow.d.ts +25 -0
  147. package/dist/codegen/control-flow.js +152 -0
  148. package/dist/codegen/control-statements.d.ts +28 -0
  149. package/dist/codegen/control-statements.js +226 -0
  150. package/dist/codegen/creation.d.ts +31 -0
  151. package/dist/codegen/creation.js +113 -0
  152. package/dist/codegen/early-returns.d.ts +59 -0
  153. package/dist/codegen/early-returns.js +244 -0
  154. package/dist/codegen/element-helpers.d.ts +12 -0
  155. package/dist/codegen/element-helpers.js +54 -0
  156. package/dist/codegen/elements.d.ts +71 -0
  157. package/dist/codegen/elements.js +293 -0
  158. package/dist/codegen/emitter.d.ts +135 -0
  159. package/dist/codegen/emitter.js +296 -0
  160. package/dist/codegen/expressions.d.ts +49 -0
  161. package/dist/codegen/expressions.js +262 -0
  162. package/dist/codegen/functions.d.ts +28 -0
  163. package/dist/codegen/functions.js +170 -0
  164. package/dist/codegen/go-helpers.d.ts +9 -0
  165. package/dist/codegen/go-helpers.js +307 -0
  166. package/dist/codegen/helpers.d.ts +10 -0
  167. package/dist/codegen/helpers.js +356 -0
  168. package/dist/codegen/imported.d.ts +38 -0
  169. package/dist/codegen/imported.js +71 -0
  170. package/dist/codegen/js.d.ts +20 -0
  171. package/dist/codegen/js.js +113 -0
  172. package/dist/codegen/mutations.d.ts +10 -0
  173. package/dist/codegen/mutations.js +102 -0
  174. package/dist/codegen/parallel.d.ts +7 -0
  175. package/dist/codegen/parallel.js +63 -0
  176. package/dist/codegen/reactive.d.ts +95 -0
  177. package/dist/codegen/reactive.js +280 -0
  178. package/dist/codegen/refs.d.ts +62 -0
  179. package/dist/codegen/refs.js +160 -0
  180. package/dist/codegen/select-helpers.d.ts +2 -0
  181. package/dist/codegen/select-helpers.js +135 -0
  182. package/dist/codegen/simple-statements.d.ts +42 -0
  183. package/dist/codegen/simple-statements.js +253 -0
  184. package/dist/codegen/statements.d.ts +22 -0
  185. package/dist/codegen/statements.js +142 -0
  186. package/dist/codegen/styles.d.ts +54 -0
  187. package/dist/codegen/styles.js +157 -0
  188. package/dist/codegen/syntax.d.ts +18 -0
  189. package/dist/codegen/syntax.js +70 -0
  190. package/dist/codegen/thread-helpers.d.ts +2 -0
  191. package/dist/codegen/thread-helpers.js +198 -0
  192. package/dist/codegen/updates.d.ts +51 -0
  193. package/dist/codegen/updates.js +201 -0
  194. package/dist/codegen/web-components.d.ts +20 -0
  195. package/dist/codegen/web-components.js +149 -0
  196. package/dist/compile-file.d.ts +11 -0
  197. package/dist/compile-file.js +24 -0
  198. package/dist/compile.d.ts +53 -0
  199. package/dist/compile.js +187 -0
  200. package/dist/completion.d.ts +10 -0
  201. package/dist/completion.js +134 -0
  202. package/dist/config.d.ts +2 -0
  203. package/dist/config.js +44 -0
  204. package/dist/css/hash.d.ts +1 -0
  205. package/dist/css/hash.js +10 -0
  206. package/dist/css/parse.d.ts +42 -0
  207. package/dist/css/parse.js +138 -0
  208. package/dist/css/print.d.ts +9 -0
  209. package/dist/css/print.js +35 -0
  210. package/dist/css/selectors.d.ts +29 -0
  211. package/dist/css/selectors.js +168 -0
  212. package/dist/declarations.d.ts +3 -0
  213. package/dist/declarations.js +207 -0
  214. package/dist/decorator-copy.d.ts +18 -0
  215. package/dist/decorator-copy.js +158 -0
  216. package/dist/decorators.d.ts +61 -0
  217. package/dist/decorators.js +241 -0
  218. package/dist/diagnostics.d.ts +17 -0
  219. package/dist/diagnostics.js +22 -0
  220. package/dist/go-for.d.ts +26 -0
  221. package/dist/go-for.js +155 -0
  222. package/dist/goroutines.d.ts +37 -0
  223. package/dist/goroutines.js +253 -0
  224. package/dist/html-tag.d.ts +21 -0
  225. package/dist/html-tag.js +103 -0
  226. package/dist/index.d.ts +33 -0
  227. package/dist/index.js +55 -0
  228. package/dist/inline-packages.d.ts +32 -0
  229. package/dist/inline-packages.js +129 -0
  230. package/dist/iterators.d.ts +10 -0
  231. package/dist/iterators.js +33 -0
  232. package/dist/lexer/base.d.ts +24 -0
  233. package/dist/lexer/base.js +87 -0
  234. package/dist/lexer/lexer.d.ts +8 -0
  235. package/dist/lexer/lexer.js +134 -0
  236. package/dist/lexer/literals.d.ts +18 -0
  237. package/dist/lexer/literals.js +203 -0
  238. package/dist/lexer/markup.d.ts +10 -0
  239. package/dist/lexer/markup.js +93 -0
  240. package/dist/lexer/style.d.ts +17 -0
  241. package/dist/lexer/style.js +97 -0
  242. package/dist/lexer/tables.d.ts +53 -0
  243. package/dist/lexer/tables.js +101 -0
  244. package/dist/lexer/token.d.ts +42 -0
  245. package/dist/lexer/token.js +108 -0
  246. package/dist/loader.d.ts +1 -0
  247. package/dist/loader.js +50 -0
  248. package/dist/methods.d.ts +5 -0
  249. package/dist/methods.js +81 -0
  250. package/dist/modules.d.ts +3 -0
  251. package/dist/modules.js +49 -0
  252. package/dist/names.d.ts +23 -0
  253. package/dist/names.js +267 -0
  254. package/dist/parser/base.d.ts +96 -0
  255. package/dist/parser/base.js +202 -0
  256. package/dist/parser/classes.d.ts +8 -0
  257. package/dist/parser/classes.js +164 -0
  258. package/dist/parser/control-flow.d.ts +29 -0
  259. package/dist/parser/control-flow.js +232 -0
  260. package/dist/parser/declarations.d.ts +27 -0
  261. package/dist/parser/declarations.js +238 -0
  262. package/dist/parser/decorators.d.ts +30 -0
  263. package/dist/parser/decorators.js +176 -0
  264. package/dist/parser/expressions.d.ts +15 -0
  265. package/dist/parser/expressions.js +255 -0
  266. package/dist/parser/literals.d.ts +27 -0
  267. package/dist/parser/literals.js +206 -0
  268. package/dist/parser/markup.d.ts +22 -0
  269. package/dist/parser/markup.js +193 -0
  270. package/dist/parser/parser.d.ts +14 -0
  271. package/dist/parser/parser.js +22 -0
  272. package/dist/parser/simple-statements.d.ts +22 -0
  273. package/dist/parser/simple-statements.js +156 -0
  274. package/dist/parser/statements.d.ts +37 -0
  275. package/dist/parser/statements.js +267 -0
  276. package/dist/parser/syntax.d.ts +51 -0
  277. package/dist/parser/syntax.js +173 -0
  278. package/dist/parser/types.d.ts +23 -0
  279. package/dist/parser/types.js +218 -0
  280. package/dist/recursion.d.ts +25 -0
  281. package/dist/recursion.js +170 -0
  282. package/dist/refs.d.ts +49 -0
  283. package/dist/refs.js +210 -0
  284. package/dist/run.d.ts +1 -0
  285. package/dist/run.js +21 -0
  286. package/dist/source.d.ts +15 -0
  287. package/dist/source.js +34 -0
  288. package/dist/style-modules.d.ts +17 -0
  289. package/dist/style-modules.js +49 -0
  290. package/dist/styles.d.ts +36 -0
  291. package/dist/styles.js +160 -0
  292. package/dist/svg.d.ts +8 -0
  293. package/dist/svg.js +77 -0
  294. package/dist/ts-types.d.ts +11 -0
  295. package/dist/ts-types.js +133 -0
  296. package/dist/typed-arrays.d.ts +8 -0
  297. package/dist/typed-arrays.js +43 -0
  298. package/dist/typescript/convert-base.d.ts +42 -0
  299. package/dist/typescript/convert-base.js +135 -0
  300. package/dist/typescript/convert-objects.d.ts +28 -0
  301. package/dist/typescript/convert-objects.js +245 -0
  302. package/dist/typescript/convert.d.ts +14 -0
  303. package/dist/typescript/convert.js +67 -0
  304. package/dist/typescript/importer.d.ts +37 -0
  305. package/dist/typescript/importer.js +152 -0
  306. package/dist/typescript/library.d.ts +23 -0
  307. package/dist/typescript/library.js +81 -0
  308. package/dist/vite.d.ts +11 -0
  309. package/dist/vite.js +86 -0
  310. package/dist/walk-types.d.ts +4 -0
  311. package/dist/walk-types.js +56 -0
  312. package/dist/walk.d.ts +5 -0
  313. package/dist/walk.js +315 -0
  314. package/package.json +104 -4
@@ -0,0 +1,15 @@
1
+ import type * as ast from '../ast.ts';
2
+ import { type Member, type ObjectType, type Type } from './types.ts';
3
+ /** What an operator gives for a bigint, and the error to report if it cannot take one. */
4
+ export interface BigintResult {
5
+ type: Type;
6
+ error?: string;
7
+ }
8
+ /** `left <operator> right` when either side is a bigint, or `null` to check it as usual. */
9
+ export declare function bigintBinary(operator: ast.BinaryOperator, left: Type, right: Type): BigintResult | null;
10
+ /** `-b`, `~b` and `+b` of a bigint, or `null` when the value is not one. */
11
+ export declare function bigintUnary(operator: '-' | '+' | '~', type: Type): BigintResult | null;
12
+ /** The members of a bigint that the built-in types list; the lib files add the rest. */
13
+ export declare function bigintMember(name: string): Member | undefined;
14
+ /** `BigInt(x)` makes a bigint of a number, a string or a bool; `BigInt.asIntN(64, b)` wraps one. */
15
+ export declare const BIGINT_OBJECT: ObjectType;
@@ -0,0 +1,85 @@
1
+ import { isUntyped } from "./helpers.js";
2
+ import { ANY, BIGINT, BOOL, func, method, NUMBER, STRING, typeToString, union, UNKNOWN, widenLiterals, } from "./types.js";
3
+ const MIX_HINT = 'convert one of them, e.g. BigInt(n) or Number(b)';
4
+ const isBigint = (type) => widenLiterals(type).kind === 'bigint';
5
+ const isNumber = (type) => widenLiterals(type).kind === 'number';
6
+ /** `left <operator> right` when either side is a bigint, or `null` to check it as usual. */
7
+ export function bigintBinary(operator, left, right) {
8
+ if (!isBigint(left) && !isBigint(right))
9
+ return null;
10
+ const mixed = (isBigint(left) && isNumber(right)) || (isNumber(left) && isBigint(right));
11
+ const untyped = isUntyped(left) || isUntyped(right);
12
+ const both = isBigint(left) && isBigint(right);
13
+ switch (operator) {
14
+ case '>>>':
15
+ return { type: UNKNOWN, error: '">>>" does not work with bigint: use ">>"' };
16
+ case '+':
17
+ case '-':
18
+ case '*':
19
+ case '/':
20
+ case '%':
21
+ case '**':
22
+ case '<<':
23
+ case '>>':
24
+ case '&':
25
+ case '|':
26
+ case '^':
27
+ if (both)
28
+ return { type: BIGINT };
29
+ if (untyped)
30
+ return { type: operator === '+' ? ANY : BIGINT };
31
+ if (mixed) {
32
+ return {
33
+ type: UNKNOWN,
34
+ error: `cannot mix bigint and number in "${operator}": ${MIX_HINT}`,
35
+ };
36
+ }
37
+ return null;
38
+ case '<':
39
+ case '>':
40
+ case '<=':
41
+ case '>=':
42
+ return both || mixed || untyped ? { type: BOOL } : null;
43
+ case '==':
44
+ case '!=':
45
+ return mixed
46
+ ? {
47
+ type: BOOL,
48
+ error: `cannot compare ${typeToString(left)} and ${typeToString(right)} with "${operator}", it is always ${operator === '!='}: ${MIX_HINT}`,
49
+ }
50
+ : null;
51
+ default:
52
+ return null;
53
+ }
54
+ }
55
+ /** `-b`, `~b` and `+b` of a bigint, or `null` when the value is not one. */
56
+ export function bigintUnary(operator, type) {
57
+ if (!isBigint(type))
58
+ return null;
59
+ return operator === '+'
60
+ ? { type: UNKNOWN, error: '"+" does not work with bigint: use Number(b)' }
61
+ : { type: BIGINT };
62
+ }
63
+ /** The members of a bigint that the built-in types list; the lib files add the rest. */
64
+ export function bigintMember(name) {
65
+ switch (name) {
66
+ case 'toString':
67
+ return method(func([NUMBER], [STRING], { required: 0 }));
68
+ case 'toLocaleString':
69
+ return method(func([ANY, ANY], [STRING], { required: 0 }));
70
+ case 'valueOf':
71
+ return method(func([], [BIGINT]));
72
+ default:
73
+ return undefined;
74
+ }
75
+ }
76
+ /** `BigInt(x)` makes a bigint of a number, a string or a bool; `BigInt.asIntN(64, b)` wraps one. */
77
+ export const BIGINT_OBJECT = {
78
+ kind: 'object',
79
+ name: 'BigInt',
80
+ members: new Map([
81
+ ['asIntN', method(func([NUMBER, BIGINT], [BIGINT]))],
82
+ ['asUintN', method(func([NUMBER, BIGINT], [BIGINT]))],
83
+ ]),
84
+ call: func([union([NUMBER, STRING, BOOL, BIGINT])], [BIGINT]),
85
+ };
@@ -0,0 +1,9 @@
1
+ import { type Member, type Type } from './types.ts';
2
+ export declare function stringMember(name: string): Member | undefined;
3
+ export declare function numberMember(name: string): Member | undefined;
4
+ export declare function boolMember(name: string): Member | undefined;
5
+ export declare function arrayMember(element: Type, name: string): Member | undefined;
6
+ export declare const GLOBAL_VALUES: ReadonlyMap<string, Type>;
7
+ /** Built-in types that a library from TypeScript's lib files replaces: untyped ones and the DOM. */
8
+ export declare const LIBRARY_TYPES: ReadonlySet<string>;
9
+ export declare const GLOBAL_TYPES: ReadonlyMap<string, Type>;
@@ -0,0 +1,307 @@
1
+ import { holdsBigInts, TYPED_ELEMENTS } from "../typed-arrays.js";
2
+ import { BIGINT_OBJECT } from "./bigint.js";
3
+ import { DOM_TYPES, EVENT } from "./dom.js";
4
+ import { SVG_TYPES } from "./dom-svg.js";
5
+ import { chanOf } from "./channel.js";
6
+ import { PROMISE } from "./promise.js";
7
+ import { BUFFERS } from "./transfer.js";
8
+ import { ANY, arrayOf, BIGINT, BOOL, ERROR, ERROR_CLASS, func, method, NUMBER, nullable, property, STRING, } from "./types.js";
9
+ // Types of the JS standard library that Rook programs use most. Anything not listed here
10
+ // can still be reached through the untyped globals below.
11
+ function object(name, members, call) {
12
+ return { kind: 'object', name, members: new Map(Object.entries(members)), call: call ?? null };
13
+ }
14
+ const numberToNumber = method(func([NUMBER], [NUMBER]));
15
+ export function stringMember(name) {
16
+ switch (name) {
17
+ case 'length':
18
+ return property(NUMBER);
19
+ case 'at':
20
+ return method(func([NUMBER], [nullable(STRING)]));
21
+ case 'charAt':
22
+ return method(func([NUMBER], [STRING]));
23
+ case 'charCodeAt':
24
+ return method(func([NUMBER], [NUMBER]));
25
+ case 'codePointAt':
26
+ return method(func([NUMBER], [nullable(NUMBER)]));
27
+ case 'indexOf':
28
+ case 'lastIndexOf':
29
+ return method(func([STRING, NUMBER], [NUMBER], { required: 1 }));
30
+ case 'includes':
31
+ case 'startsWith':
32
+ case 'endsWith':
33
+ return method(func([STRING, NUMBER], [BOOL], { required: 1 }));
34
+ case 'slice':
35
+ case 'substring':
36
+ return method(func([NUMBER, NUMBER], [STRING], { required: 0 }));
37
+ case 'toUpperCase':
38
+ case 'toLowerCase':
39
+ case 'trim':
40
+ case 'trimStart':
41
+ case 'trimEnd':
42
+ case 'normalize':
43
+ case 'toString':
44
+ return method(func([], [STRING]));
45
+ case 'split':
46
+ return method(func([ANY, NUMBER], [arrayOf(STRING)], { required: 0 }));
47
+ case 'replace':
48
+ case 'replaceAll':
49
+ return method(func([ANY, ANY], [STRING]));
50
+ case 'repeat':
51
+ return method(func([NUMBER], [STRING]));
52
+ case 'padStart':
53
+ case 'padEnd':
54
+ return method(func([NUMBER, STRING], [STRING], { required: 1 }));
55
+ case 'concat':
56
+ return method(func([], [STRING], { rest: STRING }));
57
+ case 'localeCompare':
58
+ return method(func([STRING], [NUMBER]));
59
+ case 'match':
60
+ return method(func([ANY], [ANY]));
61
+ default:
62
+ return undefined;
63
+ }
64
+ }
65
+ export function numberMember(name) {
66
+ switch (name) {
67
+ case 'toFixed':
68
+ case 'toPrecision':
69
+ case 'toString':
70
+ return method(func([NUMBER], [STRING], { required: 0 }));
71
+ case 'toLocaleString':
72
+ return method(func([], [STRING]));
73
+ default:
74
+ return undefined;
75
+ }
76
+ }
77
+ export function boolMember(name) {
78
+ return name === 'toString' ? method(func([], [STRING])) : undefined;
79
+ }
80
+ export function arrayMember(element, name) {
81
+ const array = arrayOf(element);
82
+ const U = { kind: 'param', name: 'U' };
83
+ /** `func(value T, index number) R`; callbacks may declare fewer parameters. */
84
+ const callback = (result) => func([element, NUMBER], [result]);
85
+ switch (name) {
86
+ case 'length':
87
+ return property(NUMBER);
88
+ case 'push':
89
+ case 'unshift':
90
+ return method(func([], [NUMBER], { rest: element }));
91
+ case 'pop':
92
+ case 'shift':
93
+ return method(func([], [nullable(element)]));
94
+ case 'at':
95
+ return method(func([NUMBER], [nullable(element)]));
96
+ case 'indexOf':
97
+ case 'lastIndexOf':
98
+ return method(func([element], [NUMBER]));
99
+ case 'includes':
100
+ return method(func([element], [BOOL]));
101
+ case 'join':
102
+ return method(func([STRING], [STRING], { required: 0 }));
103
+ case 'slice':
104
+ return method(func([NUMBER, NUMBER], [array], { required: 0 }));
105
+ case 'splice':
106
+ return method(func([NUMBER, NUMBER], [array], { required: 1, rest: element }));
107
+ case 'concat':
108
+ return method(func([], [array], { rest: array }));
109
+ case 'reverse':
110
+ return method(func([], [array]));
111
+ case 'fill':
112
+ return method(func([element], [array]));
113
+ case 'sort':
114
+ return method(func([func([element, element], [NUMBER])], [array], { required: 0 }));
115
+ case 'map':
116
+ return method(func([callback(U)], [arrayOf(U)], { typeParams: [U] }));
117
+ case 'flatMap':
118
+ return method(func([callback(arrayOf(U))], [arrayOf(U)], { typeParams: [U] }));
119
+ case 'filter':
120
+ return method(func([callback(BOOL)], [array]));
121
+ case 'find':
122
+ case 'findLast':
123
+ return method(func([callback(BOOL)], [nullable(element)]));
124
+ case 'findIndex':
125
+ case 'findLastIndex':
126
+ return method(func([callback(BOOL)], [NUMBER]));
127
+ case 'some':
128
+ case 'every':
129
+ return method(func([callback(BOOL)], [BOOL]));
130
+ case 'forEach':
131
+ return method(func([func([element, NUMBER], [])], []));
132
+ case 'reduce':
133
+ return method(func([func([U, element, NUMBER], [U]), U], [U], { typeParams: [U] }));
134
+ case 'entries':
135
+ case 'keys':
136
+ case 'values':
137
+ return method(func([], [ANY]));
138
+ case 'toString':
139
+ return method(func([], [STRING]));
140
+ default:
141
+ return undefined;
142
+ }
143
+ }
144
+ const log = method(func([], [], { rest: ANY }));
145
+ const console = object('console', {
146
+ log,
147
+ error: log,
148
+ warn: log,
149
+ info: log,
150
+ debug: log,
151
+ });
152
+ const math = object('Math', {
153
+ PI: property(NUMBER),
154
+ E: property(NUMBER),
155
+ LN2: property(NUMBER),
156
+ LN10: property(NUMBER),
157
+ SQRT2: property(NUMBER),
158
+ abs: numberToNumber,
159
+ floor: numberToNumber,
160
+ ceil: numberToNumber,
161
+ round: numberToNumber,
162
+ trunc: numberToNumber,
163
+ sign: numberToNumber,
164
+ sqrt: numberToNumber,
165
+ cbrt: numberToNumber,
166
+ exp: numberToNumber,
167
+ log: numberToNumber,
168
+ log2: numberToNumber,
169
+ log10: numberToNumber,
170
+ sin: numberToNumber,
171
+ cos: numberToNumber,
172
+ tan: numberToNumber,
173
+ asin: numberToNumber,
174
+ acos: numberToNumber,
175
+ atan: numberToNumber,
176
+ pow: method(func([NUMBER, NUMBER], [NUMBER])),
177
+ atan2: method(func([NUMBER, NUMBER], [NUMBER])),
178
+ min: method(func([], [NUMBER], { rest: NUMBER })),
179
+ max: method(func([], [NUMBER], { rest: NUMBER })),
180
+ hypot: method(func([], [NUMBER], { rest: NUMBER })),
181
+ random: method(func([], [NUMBER])),
182
+ });
183
+ const json = object('JSON', {
184
+ parse: method(func([STRING], [ANY])),
185
+ stringify: method(func([ANY], [STRING], { rest: ANY })),
186
+ });
187
+ const numberObject = object('Number', {
188
+ isNaN: method(func([ANY], [BOOL])),
189
+ isInteger: method(func([ANY], [BOOL])),
190
+ isFinite: method(func([ANY], [BOOL])),
191
+ isSafeInteger: method(func([ANY], [BOOL])),
192
+ parseFloat: method(func([STRING], [NUMBER])),
193
+ parseInt: method(func([STRING, NUMBER], [NUMBER], { required: 1 })),
194
+ MAX_SAFE_INTEGER: property(NUMBER),
195
+ MIN_SAFE_INTEGER: property(NUMBER),
196
+ MAX_VALUE: property(NUMBER),
197
+ MIN_VALUE: property(NUMBER),
198
+ EPSILON: property(NUMBER),
199
+ POSITIVE_INFINITY: property(NUMBER),
200
+ NEGATIVE_INFINITY: property(NUMBER),
201
+ NaN: property(NUMBER),
202
+ }, func([ANY], [NUMBER]));
203
+ const stringObject = object('String', { fromCharCode: method(func([], [STRING], { rest: NUMBER })) }, func([ANY], [STRING]));
204
+ const booleanObject = object('Boolean', {}, func([ANY], [BOOL]));
205
+ const timer = func([func([], []), NUMBER], [ANY], { required: 1, rest: ANY });
206
+ /** JS globals that are available without types: everything about them is `any`. */
207
+ const MOVED = { kind: 'param', name: 'T' };
208
+ const UNTYPED_GLOBALS = [
209
+ 'Object',
210
+ 'Array',
211
+ 'Date',
212
+ 'RegExp',
213
+ 'Map',
214
+ 'Set',
215
+ 'WeakMap',
216
+ 'WeakSet',
217
+ 'Promise',
218
+ 'Symbol',
219
+ 'Reflect',
220
+ 'Proxy',
221
+ 'Intl',
222
+ 'globalThis',
223
+ 'process',
224
+ 'Buffer',
225
+ 'URL',
226
+ 'URLSearchParams',
227
+ 'TextEncoder',
228
+ 'TextDecoder',
229
+ 'AbortController',
230
+ 'fetch',
231
+ 'structuredClone',
232
+ 'queueMicrotask',
233
+ 'window',
234
+ 'document',
235
+ 'navigator',
236
+ 'location',
237
+ 'localStorage',
238
+ 'sessionStorage',
239
+ 'crypto',
240
+ 'performance',
241
+ ];
242
+ export const GLOBAL_VALUES = new Map([
243
+ ['console', console],
244
+ ['Math', math],
245
+ ['JSON', json],
246
+ ['Number', numberObject],
247
+ ['BigInt', BIGINT_OBJECT],
248
+ ['String', stringObject],
249
+ ['Boolean', booleanObject],
250
+ ['parseInt', func([STRING, NUMBER], [NUMBER], { required: 1 })],
251
+ ['parseFloat', func([STRING], [NUMBER])],
252
+ ['isNaN', func([NUMBER], [BOOL])],
253
+ ['isFinite', func([NUMBER], [BOOL])],
254
+ ...['encodeURIComponent', 'decodeURIComponent', 'encodeURI', 'decodeURI'].map((name) => [name, func([STRING], [STRING])]),
255
+ ['setTimeout', timer],
256
+ ['setInterval', timer],
257
+ ['clearTimeout', func([ANY], [])],
258
+ ['clearInterval', func([ANY], [])],
259
+ ['NaN', NUMBER],
260
+ ['Infinity', NUMBER],
261
+ ['Error', ERROR_CLASS.value],
262
+ // `error("message")` creates an Error, so the result is never null.
263
+ ['error', func([STRING], [ERROR_CLASS.instance])],
264
+ // `close(ch)`: the channel takes no more values (a `<-chan T` cannot be closed: channels.ts).
265
+ ['close', func([chanOf(ANY)], [])],
266
+ // `transfer(buffer)`: the buffer moves to the thread it goes to (what it takes: channels.ts).
267
+ ['transfer', func([MOVED], [MOVED], { typeParams: [MOVED] })],
268
+ // Channels of time, as in Go: the time once after `ms`, or every `ms` until `close(ticks)`.
269
+ ['after', func([NUMBER], [chanOf(NUMBER, 'receive')])],
270
+ ['tick', func([NUMBER], [chanOf(NUMBER)])],
271
+ // `cancel(task)` stops a goroutine: it takes the Promise of `go` (channels.ts).
272
+ ['cancel', func([ANY], [])],
273
+ ...[...UNTYPED_GLOBALS, ...BUFFERS].map((name) => [name, ANY]),
274
+ ]);
275
+ /** Built-in types that a library from TypeScript's lib files replaces: untyped ones and the DOM. */
276
+ export const LIBRARY_TYPES = new Set([
277
+ 'Date',
278
+ 'RegExp',
279
+ 'Map',
280
+ 'Set',
281
+ 'Promise',
282
+ 'URL',
283
+ 'Event',
284
+ ...BUFFERS,
285
+ ...[...DOM_TYPES.keys()].filter((name) => name !== 'Content'),
286
+ ...SVG_TYPES.keys(),
287
+ ]);
288
+ export const GLOBAL_TYPES = new Map([
289
+ ['number', NUMBER],
290
+ // A number from 0 to 255; `[]byte` is a Uint8Array, and `[]float64` a Float64Array
291
+ // (typed-arrays.ts). The ranges of the elements are not checked.
292
+ ...[...TYPED_ELEMENTS].map(([name, array]) => [
293
+ name,
294
+ holdsBigInts(array) ? BIGINT : NUMBER,
295
+ ]),
296
+ ['bigint', BIGINT],
297
+ ['string', STRING],
298
+ ['bool', BOOL],
299
+ ['any', ANY],
300
+ ['error', ERROR],
301
+ ['Error', ERROR_CLASS.instance],
302
+ ...['Date', 'RegExp', 'Map', 'Set', 'URL', ...BUFFERS].map((name) => [name, ANY]),
303
+ ['Promise', PROMISE],
304
+ ...DOM_TYPES,
305
+ ...SVG_TYPES,
306
+ ['Event', EVENT],
307
+ ]);
@@ -0,0 +1,11 @@
1
+ import type * as ast from '../ast.ts';
2
+ import { ChannelChecker } from './channels.ts';
3
+ import { type Type } from './types.ts';
4
+ export declare abstract class BytesChecker extends ChannelChecker {
5
+ protected checkArrayLiteral(node: ast.ArrayLiteral, expected: Type | null): Type;
6
+ private isElements;
7
+ /** `make([]float64, n)`: a typed array of `n` zeros. */
8
+ protected checkMake(node: ast.MakeExpression): Type;
9
+ protected checkConversion(node: ast.ConversionExpression): Type;
10
+ protected checkChain(node: ast.MemberExpression | ast.IndexExpression | ast.CallExpression, expected?: Type | null): [Type, boolean];
11
+ }
@@ -0,0 +1,72 @@
1
+ import { ChannelChecker } from "./channels.js";
2
+ import { isUntyped } from "./helpers.js";
3
+ import { holdsBigInts } from "../typed-arrays.js";
4
+ import { BIGINT, isBytes, nonNull, NUMBER, STRING, typedArrayOf, typeToString, UNKNOWN, } from "./types.js";
5
+ // `[]byte`, a Uint8Array, and the other typed arrays, `[]float64`: an array literal where one is
6
+ // expected, `let data []byte = [1, 2]`; and the conversions of Go between text and its UTF-8
7
+ // bytes, `[]byte("rook")` and `string(data)`.
8
+ export class BytesChecker extends ChannelChecker {
9
+ checkArrayLiteral(node, expected) {
10
+ const typed = expected && nonNull(expected);
11
+ const name = typed && typedArrayOf(typed);
12
+ if (!typed || name === null)
13
+ return super.checkArrayLiteral(node, expected);
14
+ const element = holdsBigInts(name) ? BIGINT : NUMBER;
15
+ for (const item of node.elements) {
16
+ if (item.kind === 'SpreadElement') {
17
+ const spread = this.checkValue(item.argument, typed);
18
+ if (typedArrayOf(spread) !== name && !this.isElements(spread, element)) {
19
+ this.error(`cannot spread ${typeToString(spread)} into ${typeToString(typed)}`, item.argument);
20
+ }
21
+ }
22
+ else {
23
+ this.expectAssignable(this.checkValue(item, element), element, item);
24
+ }
25
+ }
26
+ return typed;
27
+ }
28
+ isElements(type, element) {
29
+ return isUntyped(type) || (type.kind === 'array' && type.element.kind === element.kind);
30
+ }
31
+ /** `make([]float64, n)`: a typed array of `n` zeros. */
32
+ checkMake(node) {
33
+ const type = this.resolveType(node.type);
34
+ this.expectAssignable(this.checkValue(node.length, NUMBER), NUMBER, node.length);
35
+ if (typedArrayOf(type) === null) {
36
+ this.error(`make makes a typed array, e.g. make([]float64, n), not ${typeToString(type)}; a list starts empty and grows, e.g. let names []string = []`, node.type);
37
+ }
38
+ return type;
39
+ }
40
+ checkConversion(node) {
41
+ const type = this.resolveType(node.type);
42
+ const argument = this.checkValue(node.argument, STRING);
43
+ if (!isBytes(type)) {
44
+ this.error(`cannot convert to ${typeToString(type)}: only []byte("text") and string(bytes) convert between types; for other values call a function, e.g. Number(s)`, node.type);
45
+ return UNKNOWN;
46
+ }
47
+ if (!isUntyped(argument) && argument.kind !== 'string' && argument.kind !== 'literal') {
48
+ this.error(`[]byte(...) gives the UTF-8 bytes of a string, not of ${typeToString(argument)}; bytes are written as a list, e.g. let data []byte = [1, 2]`, node.argument);
49
+ }
50
+ return type;
51
+ }
52
+ // `string(data)`: `string` is a type, so a call of it is the conversion, unless the program has
53
+ // a value of that name.
54
+ checkChain(node, expected = null) {
55
+ if (node.kind !== 'CallExpression' ||
56
+ node.callee.kind !== 'Identifier' ||
57
+ node.callee.name !== 'string' ||
58
+ this.lookupValue('string') !== undefined) {
59
+ return super.checkChain(node, expected);
60
+ }
61
+ const [argument, ...rest] = node.arguments;
62
+ if (!argument || argument.kind === 'SpreadElement' || rest.length > 0) {
63
+ this.error('string(...) takes one []byte, e.g. string(data)', node);
64
+ return [STRING, false];
65
+ }
66
+ const type = this.checkValue(argument, this.bytes());
67
+ if (!isBytes(type) && !isUntyped(type)) {
68
+ this.error(`string(...) turns []byte into text, not ${typeToString(type)}; for other values use String(x) or a template string, e.g. \`\${x}\``, argument);
69
+ }
70
+ return [STRING, false];
71
+ }
72
+ }
@@ -0,0 +1,23 @@
1
+ import type * as ast from '../ast.ts';
2
+ import { MemberChecker } from './members.ts';
3
+ import { type FunctionType, type Type, type TypeParam } from './types.ts';
4
+ export declare abstract class CallChecker extends MemberChecker {
5
+ protected checkCall(node: ast.CallExpression, callee: Type, expected?: Type | null): Type;
6
+ protected checkSuperCall(node: ast.CallExpression): Type;
7
+ protected checkNew(node: ast.NewExpression, expected?: Type | null): Type;
8
+ /**
9
+ * Checks a call of an overloaded function (from a `.d.ts`): the first signature that fits the
10
+ * arguments is used. Signatures that take this many arguments are tried first.
11
+ */
12
+ protected checkOverloads(signatures: readonly FunctionType[], args: readonly (ast.Expression | ast.SpreadElement)[], node: ast.NodeBase, expected: Type | null): {
13
+ results: Type[];
14
+ inferred: Map<TypeParam, Type>;
15
+ };
16
+ protected checkArgumentsLoosely(args: readonly (ast.Expression | ast.SpreadElement)[]): void;
17
+ /**
18
+ * Checks call arguments against a signature and returns the result types. Type parameters are
19
+ * inferred into `inferred` from the arguments and then from the expected result.
20
+ */
21
+ protected checkArguments(signature: FunctionType, args: readonly (ast.Expression | ast.SpreadElement)[], node: ast.NodeBase, inferred?: Map<TypeParam, Type>, expected?: Type | null): Type[];
22
+ protected checkArgumentList(signature: FunctionType, args: readonly (ast.Expression | ast.SpreadElement)[], inferred: Map<TypeParam, Type>, needsContext: (arg: ast.Expression | ast.SpreadElement) => boolean, beforeContext?: () => void): void;
23
+ }