@typespec/compiler 0.41.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 (352) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +9 -0
  3. package/cmd/tsp-server.js +3 -0
  4. package/cmd/tsp.js +3 -0
  5. package/dist/cmd/runner.d.ts +9 -0
  6. package/dist/cmd/runner.d.ts.map +1 -0
  7. package/dist/cmd/runner.js +62 -0
  8. package/dist/cmd/runner.js.map +1 -0
  9. package/dist/config/config-interpolation.d.ts +11 -0
  10. package/dist/config/config-interpolation.d.ts.map +1 -0
  11. package/dist/config/config-interpolation.js +109 -0
  12. package/dist/config/config-interpolation.js.map +1 -0
  13. package/dist/config/config-loader.d.ts +25 -0
  14. package/dist/config/config-loader.d.ts.map +1 -0
  15. package/dist/config/config-loader.js +182 -0
  16. package/dist/config/config-loader.js.map +1 -0
  17. package/dist/config/config-schema.d.ts +4 -0
  18. package/dist/config/config-schema.d.ts.map +1 -0
  19. package/dist/config/config-schema.js +84 -0
  20. package/dist/config/config-schema.js.map +1 -0
  21. package/dist/config/index.d.ts +3 -0
  22. package/dist/config/index.d.ts.map +1 -0
  23. package/dist/config/index.js +3 -0
  24. package/dist/config/index.js.map +1 -0
  25. package/dist/config/types.d.ts +79 -0
  26. package/dist/config/types.d.ts.map +1 -0
  27. package/dist/config/types.js +2 -0
  28. package/dist/config/types.js.map +1 -0
  29. package/dist/core/binder.d.ts +29 -0
  30. package/dist/core/binder.d.ts.map +1 -0
  31. package/dist/core/binder.js +455 -0
  32. package/dist/core/binder.js.map +1 -0
  33. package/dist/core/charcode.d.ts +130 -0
  34. package/dist/core/charcode.d.ts.map +1 -0
  35. package/dist/core/charcode.js +115 -0
  36. package/dist/core/charcode.js.map +1 -0
  37. package/dist/core/checker.d.ts +138 -0
  38. package/dist/core/checker.d.ts.map +1 -0
  39. package/dist/core/checker.js +4070 -0
  40. package/dist/core/checker.js.map +1 -0
  41. package/dist/core/cli/args.d.ts +18 -0
  42. package/dist/core/cli/args.d.ts.map +1 -0
  43. package/dist/core/cli/args.js +108 -0
  44. package/dist/core/cli/args.js.map +1 -0
  45. package/dist/core/cli/cli.d.ts +2 -0
  46. package/dist/core/cli/cli.d.ts.map +1 -0
  47. package/dist/core/cli/cli.js +477 -0
  48. package/dist/core/cli/cli.js.map +1 -0
  49. package/dist/core/cli/index.d.ts +2 -0
  50. package/dist/core/cli/index.d.ts.map +1 -0
  51. package/dist/core/cli/index.js +2 -0
  52. package/dist/core/cli/index.js.map +1 -0
  53. package/dist/core/decorator-utils.d.ts +108 -0
  54. package/dist/core/decorator-utils.d.ts.map +1 -0
  55. package/dist/core/decorator-utils.js +326 -0
  56. package/dist/core/decorator-utils.js.map +1 -0
  57. package/dist/core/diagnostics.d.ts +93 -0
  58. package/dist/core/diagnostics.d.ts.map +1 -0
  59. package/dist/core/diagnostics.js +315 -0
  60. package/dist/core/diagnostics.js.map +1 -0
  61. package/dist/core/emitter-utils.d.ts +14 -0
  62. package/dist/core/emitter-utils.d.ts.map +1 -0
  63. package/dist/core/emitter-utils.js +16 -0
  64. package/dist/core/emitter-utils.js.map +1 -0
  65. package/dist/core/formatter-fs.d.ts +21 -0
  66. package/dist/core/formatter-fs.d.ts.map +1 -0
  67. package/dist/core/formatter-fs.js +79 -0
  68. package/dist/core/formatter-fs.js.map +1 -0
  69. package/dist/core/formatter.d.ts +10 -0
  70. package/dist/core/formatter.d.ts.map +1 -0
  71. package/dist/core/formatter.js +24 -0
  72. package/dist/core/formatter.js.map +1 -0
  73. package/dist/core/helpers/discriminator-utils.d.ts +14 -0
  74. package/dist/core/helpers/discriminator-utils.d.ts.map +1 -0
  75. package/dist/core/helpers/discriminator-utils.js +169 -0
  76. package/dist/core/helpers/discriminator-utils.js.map +1 -0
  77. package/dist/core/helpers/index.d.ts +6 -0
  78. package/dist/core/helpers/index.d.ts.map +1 -0
  79. package/dist/core/helpers/index.js +6 -0
  80. package/dist/core/helpers/index.js.map +1 -0
  81. package/dist/core/helpers/operation-utils.d.ts +15 -0
  82. package/dist/core/helpers/operation-utils.d.ts.map +1 -0
  83. package/dist/core/helpers/operation-utils.js +35 -0
  84. package/dist/core/helpers/operation-utils.js.map +1 -0
  85. package/dist/core/helpers/projected-names-utils.d.ts +20 -0
  86. package/dist/core/helpers/projected-names-utils.d.ts.map +1 -0
  87. package/dist/core/helpers/projected-names-utils.js +40 -0
  88. package/dist/core/helpers/projected-names-utils.js.map +1 -0
  89. package/dist/core/helpers/type-name-utils.d.ts +14 -0
  90. package/dist/core/helpers/type-name-utils.d.ts.map +1 -0
  91. package/dist/core/helpers/type-name-utils.js +122 -0
  92. package/dist/core/helpers/type-name-utils.js.map +1 -0
  93. package/dist/core/helpers/usage-resolver.d.ts +20 -0
  94. package/dist/core/helpers/usage-resolver.d.ts.map +1 -0
  95. package/dist/core/helpers/usage-resolver.js +108 -0
  96. package/dist/core/helpers/usage-resolver.js.map +1 -0
  97. package/dist/core/index.d.ts +26 -0
  98. package/dist/core/index.d.ts.map +1 -0
  99. package/dist/core/index.js +26 -0
  100. package/dist/core/index.js.map +1 -0
  101. package/dist/core/install.d.ts +2 -0
  102. package/dist/core/install.d.ts.map +1 -0
  103. package/dist/core/install.js +26 -0
  104. package/dist/core/install.js.map +1 -0
  105. package/dist/core/library.d.ts +34 -0
  106. package/dist/core/library.d.ts.map +1 -0
  107. package/dist/core/library.js +100 -0
  108. package/dist/core/library.js.map +1 -0
  109. package/dist/core/logger/console-sink.browser.d.ts +4 -0
  110. package/dist/core/logger/console-sink.browser.d.ts.map +1 -0
  111. package/dist/core/logger/console-sink.browser.js +14 -0
  112. package/dist/core/logger/console-sink.browser.js.map +1 -0
  113. package/dist/core/logger/console-sink.d.ts +9 -0
  114. package/dist/core/logger/console-sink.d.ts.map +1 -0
  115. package/dist/core/logger/console-sink.js +81 -0
  116. package/dist/core/logger/console-sink.js.map +1 -0
  117. package/dist/core/logger/index.d.ts +3 -0
  118. package/dist/core/logger/index.d.ts.map +1 -0
  119. package/dist/core/logger/index.js +3 -0
  120. package/dist/core/logger/index.js.map +1 -0
  121. package/dist/core/logger/logger.d.ts +7 -0
  122. package/dist/core/logger/logger.d.ts.map +1 -0
  123. package/dist/core/logger/logger.js +32 -0
  124. package/dist/core/logger/logger.js.map +1 -0
  125. package/dist/core/logger/tracer.d.ts +3 -0
  126. package/dist/core/logger/tracer.d.ts.map +1 -0
  127. package/dist/core/logger/tracer.js +91 -0
  128. package/dist/core/logger/tracer.js.map +1 -0
  129. package/dist/core/manifest.d.ts +21 -0
  130. package/dist/core/manifest.d.ts.map +1 -0
  131. package/dist/core/manifest.js +8 -0
  132. package/dist/core/manifest.js.map +1 -0
  133. package/dist/core/messages.d.ts +2253 -0
  134. package/dist/core/messages.d.ts.map +1 -0
  135. package/dist/core/messages.js +749 -0
  136. package/dist/core/messages.js.map +1 -0
  137. package/dist/core/module-resolver.d.ts +84 -0
  138. package/dist/core/module-resolver.d.ts.map +1 -0
  139. package/dist/core/module-resolver.js +170 -0
  140. package/dist/core/module-resolver.js.map +1 -0
  141. package/dist/core/node-host.browser.d.ts +2 -0
  142. package/dist/core/node-host.browser.d.ts.map +1 -0
  143. package/dist/core/node-host.browser.js +2 -0
  144. package/dist/core/node-host.browser.js.map +1 -0
  145. package/dist/core/node-host.d.ts +7 -0
  146. package/dist/core/node-host.d.ts.map +1 -0
  147. package/dist/core/node-host.js +43 -0
  148. package/dist/core/node-host.js.map +1 -0
  149. package/dist/core/nonascii.d.ts +2 -0
  150. package/dist/core/nonascii.d.ts.map +1 -0
  151. package/dist/core/nonascii.js +712 -0
  152. package/dist/core/nonascii.js.map +1 -0
  153. package/dist/core/options.d.ts +46 -0
  154. package/dist/core/options.d.ts.map +1 -0
  155. package/dist/core/options.js +2 -0
  156. package/dist/core/options.js.map +1 -0
  157. package/dist/core/parser.d.ts +17 -0
  158. package/dist/core/parser.d.ts.map +1 -0
  159. package/dist/core/parser.js +2561 -0
  160. package/dist/core/parser.js.map +1 -0
  161. package/dist/core/path-utils.d.ts +193 -0
  162. package/dist/core/path-utils.d.ts.map +1 -0
  163. package/dist/core/path-utils.js +427 -0
  164. package/dist/core/path-utils.js.map +1 -0
  165. package/dist/core/program.d.ts +104 -0
  166. package/dist/core/program.d.ts.map +1 -0
  167. package/dist/core/program.js +898 -0
  168. package/dist/core/program.js.map +1 -0
  169. package/dist/core/projection-members.d.ts +8 -0
  170. package/dist/core/projection-members.d.ts.map +1 -0
  171. package/dist/core/projection-members.js +387 -0
  172. package/dist/core/projection-members.js.map +1 -0
  173. package/dist/core/projector.d.ts +26 -0
  174. package/dist/core/projector.d.ts.map +1 -0
  175. package/dist/core/projector.js +523 -0
  176. package/dist/core/projector.js.map +1 -0
  177. package/dist/core/scanner.d.ts +125 -0
  178. package/dist/core/scanner.d.ts.map +1 -0
  179. package/dist/core/scanner.js +1012 -0
  180. package/dist/core/scanner.js.map +1 -0
  181. package/dist/core/schema-validator.d.ts +6 -0
  182. package/dist/core/schema-validator.d.ts.map +1 -0
  183. package/dist/core/schema-validator.js +38 -0
  184. package/dist/core/schema-validator.js.map +1 -0
  185. package/dist/core/semantic-walker.d.ts +53 -0
  186. package/dist/core/semantic-walker.d.ts.map +1 -0
  187. package/dist/core/semantic-walker.js +355 -0
  188. package/dist/core/semantic-walker.js.map +1 -0
  189. package/dist/core/type-utils.d.ts +49 -0
  190. package/dist/core/type-utils.d.ts.map +1 -0
  191. package/dist/core/type-utils.js +95 -0
  192. package/dist/core/type-utils.js.map +1 -0
  193. package/dist/core/types.d.ts +1345 -0
  194. package/dist/core/types.d.ts.map +1 -0
  195. package/dist/core/types.js +105 -0
  196. package/dist/core/types.js.map +1 -0
  197. package/dist/core/util.d.ts +150 -0
  198. package/dist/core/util.d.ts.map +1 -0
  199. package/dist/core/util.js +417 -0
  200. package/dist/core/util.js.map +1 -0
  201. package/dist/emitter-framework/asset-emitter.d.ts +5 -0
  202. package/dist/emitter-framework/asset-emitter.d.ts.map +1 -0
  203. package/dist/emitter-framework/asset-emitter.js +610 -0
  204. package/dist/emitter-framework/asset-emitter.js.map +1 -0
  205. package/dist/emitter-framework/builders/array-builder.d.ts +7 -0
  206. package/dist/emitter-framework/builders/array-builder.d.ts.map +1 -0
  207. package/dist/emitter-framework/builders/array-builder.js +45 -0
  208. package/dist/emitter-framework/builders/array-builder.js.map +1 -0
  209. package/dist/emitter-framework/builders/object-builder.d.ts +9 -0
  210. package/dist/emitter-framework/builders/object-builder.d.ts.map +1 -0
  211. package/dist/emitter-framework/builders/object-builder.js +30 -0
  212. package/dist/emitter-framework/builders/object-builder.js.map +1 -0
  213. package/dist/emitter-framework/builders/string-builder.d.ts +13 -0
  214. package/dist/emitter-framework/builders/string-builder.d.ts.map +1 -0
  215. package/dist/emitter-framework/builders/string-builder.js +98 -0
  216. package/dist/emitter-framework/builders/string-builder.js.map +1 -0
  217. package/dist/emitter-framework/custom-key-map.d.ts +29 -0
  218. package/dist/emitter-framework/custom-key-map.d.ts.map +1 -0
  219. package/dist/emitter-framework/custom-key-map.js +62 -0
  220. package/dist/emitter-framework/custom-key-map.js.map +1 -0
  221. package/dist/emitter-framework/index.d.ts +8 -0
  222. package/dist/emitter-framework/index.d.ts.map +1 -0
  223. package/dist/emitter-framework/index.js +8 -0
  224. package/dist/emitter-framework/index.js.map +1 -0
  225. package/dist/emitter-framework/placeholder.d.ts +12 -0
  226. package/dist/emitter-framework/placeholder.d.ts.map +1 -0
  227. package/dist/emitter-framework/placeholder.js +27 -0
  228. package/dist/emitter-framework/placeholder.js.map +1 -0
  229. package/dist/emitter-framework/type-emitter.d.ts +314 -0
  230. package/dist/emitter-framework/type-emitter.d.ts.map +1 -0
  231. package/dist/emitter-framework/type-emitter.js +612 -0
  232. package/dist/emitter-framework/type-emitter.js.map +1 -0
  233. package/dist/emitter-framework/types.d.ts +124 -0
  234. package/dist/emitter-framework/types.d.ts.map +1 -0
  235. package/dist/emitter-framework/types.js +39 -0
  236. package/dist/emitter-framework/types.js.map +1 -0
  237. package/dist/formatter/index.d.ts +11 -0
  238. package/dist/formatter/index.d.ts.map +1 -0
  239. package/dist/formatter/index.js +28 -0
  240. package/dist/formatter/index.js.map +1 -0
  241. package/dist/formatter/parser.d.ts +16 -0
  242. package/dist/formatter/parser.d.ts.map +1 -0
  243. package/dist/formatter/parser.js +23 -0
  244. package/dist/formatter/parser.js.map +1 -0
  245. package/dist/formatter/print/comment-handler.d.ts +7 -0
  246. package/dist/formatter/print/comment-handler.d.ts.map +1 -0
  247. package/dist/formatter/print/comment-handler.js +81 -0
  248. package/dist/formatter/print/comment-handler.js.map +1 -0
  249. package/dist/formatter/print/index.d.ts +3 -0
  250. package/dist/formatter/print/index.d.ts.map +1 -0
  251. package/dist/formatter/print/index.js +3 -0
  252. package/dist/formatter/print/index.js.map +1 -0
  253. package/dist/formatter/print/needs-parens.d.ts +10 -0
  254. package/dist/formatter/print/needs-parens.d.ts.map +1 -0
  255. package/dist/formatter/print/needs-parens.js +27 -0
  256. package/dist/formatter/print/needs-parens.js.map +1 -0
  257. package/dist/formatter/print/printer.d.ts +62 -0
  258. package/dist/formatter/print/printer.d.ts.map +1 -0
  259. package/dist/formatter/print/printer.js +1025 -0
  260. package/dist/formatter/print/printer.js.map +1 -0
  261. package/dist/formatter/print/types.d.ts +9 -0
  262. package/dist/formatter/print/types.d.ts.map +1 -0
  263. package/dist/formatter/print/types.js +2 -0
  264. package/dist/formatter/print/types.js.map +1 -0
  265. package/dist/init/index.d.ts +2 -0
  266. package/dist/init/index.d.ts.map +1 -0
  267. package/dist/init/index.js +2 -0
  268. package/dist/init/index.js.map +1 -0
  269. package/dist/init/init-template.d.ts +45 -0
  270. package/dist/init/init-template.d.ts.map +1 -0
  271. package/dist/init/init-template.js +45 -0
  272. package/dist/init/init-template.js.map +1 -0
  273. package/dist/init/init.d.ts +49 -0
  274. package/dist/init/init.d.ts.map +1 -0
  275. package/dist/init/init.js +224 -0
  276. package/dist/init/init.js.map +1 -0
  277. package/dist/lib/decorators.d.ts +222 -0
  278. package/dist/lib/decorators.d.ts.map +1 -0
  279. package/dist/lib/decorators.js +745 -0
  280. package/dist/lib/decorators.js.map +1 -0
  281. package/dist/lib/service.d.ts +38 -0
  282. package/dist/lib/service.d.ts.map +1 -0
  283. package/dist/lib/service.js +78 -0
  284. package/dist/lib/service.js.map +1 -0
  285. package/dist/manifest.js +4 -0
  286. package/dist/server/completion.d.ts +10 -0
  287. package/dist/server/completion.d.ts.map +1 -0
  288. package/dist/server/completion.js +207 -0
  289. package/dist/server/completion.js.map +1 -0
  290. package/dist/server/index.d.ts +3 -0
  291. package/dist/server/index.d.ts.map +1 -0
  292. package/dist/server/index.js +3 -0
  293. package/dist/server/index.js.map +1 -0
  294. package/dist/server/language-config.d.ts +195 -0
  295. package/dist/server/language-config.d.ts.map +1 -0
  296. package/dist/server/language-config.js +102 -0
  297. package/dist/server/language-config.js.map +1 -0
  298. package/dist/server/server.d.ts +2 -0
  299. package/dist/server/server.d.ts.map +1 -0
  300. package/dist/server/server.js +131 -0
  301. package/dist/server/server.js.map +1 -0
  302. package/dist/server/serverlib.d.ts +72 -0
  303. package/dist/server/serverlib.d.ts.map +1 -0
  304. package/dist/server/serverlib.js +1034 -0
  305. package/dist/server/serverlib.js.map +1 -0
  306. package/dist/server/symbol-structure.d.ts +4 -0
  307. package/dist/server/symbol-structure.d.ts.map +1 -0
  308. package/dist/server/symbol-structure.js +121 -0
  309. package/dist/server/symbol-structure.js.map +1 -0
  310. package/dist/server/tmlanguage.d.ts +3 -0
  311. package/dist/server/tmlanguage.d.ts.map +1 -0
  312. package/dist/server/tmlanguage.js +713 -0
  313. package/dist/server/tmlanguage.js.map +1 -0
  314. package/dist/server/type-details.d.ts +11 -0
  315. package/dist/server/type-details.d.ts.map +1 -0
  316. package/dist/server/type-details.js +72 -0
  317. package/dist/server/type-details.js.map +1 -0
  318. package/dist/server/type-signature.d.ts +2 -0
  319. package/dist/server/type-signature.d.ts.map +1 -0
  320. package/dist/server/type-signature.js +108 -0
  321. package/dist/server/type-signature.js.map +1 -0
  322. package/dist/testing/expect.d.ts +49 -0
  323. package/dist/testing/expect.d.ts.map +1 -0
  324. package/dist/testing/expect.js +83 -0
  325. package/dist/testing/expect.js.map +1 -0
  326. package/dist/testing/index.d.ts +6 -0
  327. package/dist/testing/index.d.ts.map +1 -0
  328. package/dist/testing/index.js +6 -0
  329. package/dist/testing/index.js.map +1 -0
  330. package/dist/testing/test-host.d.ts +14 -0
  331. package/dist/testing/test-host.d.ts.map +1 -0
  332. package/dist/testing/test-host.js +271 -0
  333. package/dist/testing/test-host.js.map +1 -0
  334. package/dist/testing/test-server-host.d.ts +39 -0
  335. package/dist/testing/test-server-host.d.ts.map +1 -0
  336. package/dist/testing/test-server-host.js +112 -0
  337. package/dist/testing/test-server-host.js.map +1 -0
  338. package/dist/testing/test-utils.d.ts +22 -0
  339. package/dist/testing/test-utils.d.ts.map +1 -0
  340. package/dist/testing/test-utils.js +60 -0
  341. package/dist/testing/test-utils.js.map +1 -0
  342. package/dist/testing/types.d.ts +69 -0
  343. package/dist/testing/types.d.ts.map +1 -0
  344. package/dist/testing/types.js +7 -0
  345. package/dist/testing/types.js.map +1 -0
  346. package/dist/typespec.tmLanguage +1760 -0
  347. package/lib/decorators.tsp +420 -0
  348. package/lib/lib.tsp +158 -0
  349. package/lib/main.tsp +4 -0
  350. package/lib/projected-names.tsp +94 -0
  351. package/lib/reflection.tsp +10 -0
  352. package/package.json +119 -0
@@ -0,0 +1,4070 @@
1
+ import { getDeprecated, getIndexer } from "../lib/decorators.js";
2
+ import { createSymbol, createSymbolTable } from "./binder.js";
3
+ import { compilerAssert, ProjectionError } from "./diagnostics.js";
4
+ import { validateInheritanceDiscriminatedUnions } from "./helpers/discriminator-utils.js";
5
+ import { getNamespaceFullName, getTypeName } from "./helpers/index.js";
6
+ import { createDiagnostic } from "./messages.js";
7
+ import { getIdentifierContext, hasParseError, visitChildren } from "./parser.js";
8
+ import { createProjectionMembers } from "./projection-members.js";
9
+ import { getParentTemplateNode, isNeverType, isTemplateInstance, isUnknownType, isVoidType, } from "./type-utils.js";
10
+ import { IdentifierKind, SyntaxKind, } from "./types.js";
11
+ import { isArray, MultiKeyMap, mutate } from "./util.js";
12
+ /**
13
+ * Maps type arguments to type instantiation.
14
+ */
15
+ const TypeInstantiationMap = class extends MultiKeyMap {
16
+ };
17
+ let currentSymbolId = 0;
18
+ export function createChecker(program) {
19
+ const stdTypes = {};
20
+ const symbolLinks = new Map();
21
+ const mergedSymbols = new Map();
22
+ const augmentDecoratorsForSym = new Map();
23
+ const augmentedSymbolTables = new Map();
24
+ const referenceSymCache = new WeakMap();
25
+ let onCheckerDiagnostic = (x) => {
26
+ program.reportDiagnostic(x);
27
+ };
28
+ const typePrototype = {
29
+ get projections() {
30
+ return (projectionsByTypeKind.get(this.kind) || []).concat(projectionsByType.get(this) || []);
31
+ },
32
+ projectionsByName(name) {
33
+ return this.projections.filter((p) => p.id.sv === name);
34
+ },
35
+ };
36
+ const globalNamespaceNode = createGlobalNamespaceNode();
37
+ const globalNamespaceType = createGlobalNamespaceType();
38
+ let typespecNamespaceNode;
39
+ const errorType = createType({ kind: "Intrinsic", name: "ErrorType" });
40
+ const voidType = createType({ kind: "Intrinsic", name: "void" });
41
+ const neverType = createType({ kind: "Intrinsic", name: "never" });
42
+ const unknownType = createType({ kind: "Intrinsic", name: "unknown" });
43
+ const nullType = createType({ kind: "Intrinsic", name: "null" });
44
+ const nullSym = createSymbol(undefined, "null", 0 /* SymbolFlags.None */);
45
+ const projectionsByTypeKind = new Map([
46
+ ["Model", []],
47
+ ["Union", []],
48
+ ["Operation", []],
49
+ ["Interface", []],
50
+ ["Enum", []],
51
+ ]);
52
+ const projectionsByType = new Map();
53
+ // whether we've checked this specific projection statement before
54
+ // and added it to the various projection maps.
55
+ const processedProjections = new Set();
56
+ // interpreter state
57
+ let currentProjectionDirection;
58
+ /**
59
+ * Set keeping track of node pending type resolution.
60
+ * Key is the SymId of a node. It can be retrieved with getNodeSymId(node)
61
+ */
62
+ const pendingResolutions = new Set();
63
+ for (const file of program.jsSourceFiles.values()) {
64
+ mergeSourceFile(file);
65
+ }
66
+ for (const file of program.sourceFiles.values()) {
67
+ mergeSourceFile(file);
68
+ }
69
+ for (const file of program.sourceFiles.values()) {
70
+ setUsingsForFile(file);
71
+ }
72
+ const typespecNamespaceBinding = globalNamespaceNode.symbol.exports.get("TypeSpec");
73
+ if (typespecNamespaceBinding) {
74
+ // the typespec namespace binding will be absent if we've passed
75
+ // the no-std-lib option.
76
+ // the first declaration here is the JS file for the typespec script.
77
+ typespecNamespaceNode = typespecNamespaceBinding.declarations[1];
78
+ initializeTypeSpecIntrinsics();
79
+ for (const file of program.sourceFiles.values()) {
80
+ addUsingSymbols(typespecNamespaceBinding.exports, file.locals);
81
+ }
82
+ }
83
+ let evalContext = undefined;
84
+ const checker = {
85
+ getTypeForNode,
86
+ checkProgram,
87
+ checkSourceFile,
88
+ getLiteralType,
89
+ getTypeName,
90
+ getNamespaceString: getNamespaceFullName,
91
+ getGlobalNamespaceType,
92
+ getGlobalNamespaceNode,
93
+ setUsingsForFile,
94
+ getMergedSymbol,
95
+ mergeSourceFile,
96
+ cloneType,
97
+ resolveIdentifier,
98
+ resolveCompletions,
99
+ evalProjection: evalProjectionStatement,
100
+ project,
101
+ neverType,
102
+ errorType,
103
+ anyType: unknownType,
104
+ voidType,
105
+ typePrototype,
106
+ createType,
107
+ createAndFinishType,
108
+ createFunctionType,
109
+ createLiteralType,
110
+ finishType,
111
+ isTypeAssignableTo,
112
+ isStdType,
113
+ getStdType,
114
+ resolveTypeReference,
115
+ };
116
+ const projectionMembers = createProjectionMembers(checker);
117
+ return checker;
118
+ function reportCheckerDiagnostic(diagnostic) {
119
+ onCheckerDiagnostic(diagnostic);
120
+ }
121
+ function reportCheckerDiagnostics(diagnostics) {
122
+ diagnostics.forEach((x) => reportCheckerDiagnostic(x));
123
+ }
124
+ function initializeTypeSpecIntrinsics() {
125
+ // a utility function to log strings or numbers
126
+ mutate(typespecNamespaceBinding.exports).set("log", {
127
+ flags: 131072 /* SymbolFlags.Function */,
128
+ name: "log",
129
+ value(p, ...strs) {
130
+ program.trace("projection.log", strs.join(" "));
131
+ return voidType;
132
+ },
133
+ declarations: [],
134
+ });
135
+ // Until we have an `unit` type for `null`
136
+ mutate(typespecNamespaceBinding.exports).set("null", nullSym);
137
+ mutate(nullSym).type = nullType;
138
+ getSymbolLinks(nullSym).type = nullType;
139
+ }
140
+ function getStdType(name) {
141
+ var _a;
142
+ const type = stdTypes[name];
143
+ if (type !== undefined) {
144
+ return type;
145
+ }
146
+ const sym = (_a = typespecNamespaceBinding === null || typespecNamespaceBinding === void 0 ? void 0 : typespecNamespaceBinding.exports) === null || _a === void 0 ? void 0 : _a.get(name);
147
+ if (sym && sym.flags & 2 /* SymbolFlags.Model */) {
148
+ checkModelStatement(sym.declarations[0], undefined);
149
+ }
150
+ else {
151
+ checkScalar(sym.declarations[0], undefined);
152
+ }
153
+ const loadedType = stdTypes[name];
154
+ compilerAssert(loadedType, `TypeSpec std type "${name}" should have been initalized before using array syntax.`);
155
+ return loadedType;
156
+ }
157
+ function mergeSourceFile(file) {
158
+ mergeSymbolTable(file.symbol.exports, mutate(globalNamespaceNode.symbol.exports));
159
+ }
160
+ function setUsingsForFile(file) {
161
+ const usedUsing = new Set();
162
+ for (const using of file.usings) {
163
+ const parentNs = using.parent;
164
+ const sym = resolveTypeReferenceSym(using.name, undefined);
165
+ if (!sym) {
166
+ continue;
167
+ }
168
+ if (!(sym.flags & 4096 /* SymbolFlags.Namespace */)) {
169
+ reportCheckerDiagnostic(createDiagnostic({ code: "using-invalid-ref", target: using }));
170
+ }
171
+ const namespaceSym = getMergedSymbol(sym);
172
+ if (usedUsing.has(namespaceSym)) {
173
+ reportCheckerDiagnostic(createDiagnostic({
174
+ code: "duplicate-using",
175
+ format: { usingName: memberExpressionToString(using.name) },
176
+ target: using,
177
+ }));
178
+ continue;
179
+ }
180
+ usedUsing.add(namespaceSym);
181
+ addUsingSymbols(sym.exports, parentNs.locals);
182
+ }
183
+ if (typespecNamespaceNode) {
184
+ addUsingSymbols(typespecNamespaceBinding.exports, file.locals);
185
+ }
186
+ }
187
+ function applyAugmentDecorators(node) {
188
+ if (!node.statements || !isArray(node.statements)) {
189
+ return;
190
+ }
191
+ const augmentDecorators = node.statements.filter((x) => x.kind === SyntaxKind.AugmentDecoratorStatement);
192
+ for (const decNode of augmentDecorators) {
193
+ const ref = resolveTypeReferenceSym(decNode.targetType, undefined);
194
+ if (ref) {
195
+ if (ref.flags & 4096 /* SymbolFlags.Namespace */) {
196
+ const links = getSymbolLinks(getMergedSymbol(ref));
197
+ const type = links.type;
198
+ const decApp = checkDecorator(type, decNode, undefined);
199
+ if (decApp) {
200
+ type.decorators.push(decApp);
201
+ applyDecoratorToType(program, decApp, type);
202
+ }
203
+ }
204
+ else if (ref.flags & 16777216 /* SymbolFlags.LateBound */) {
205
+ reportCheckerDiagnostic(createDiagnostic({
206
+ code: "augment-decorator-target",
207
+ messageId: "noInstance",
208
+ target: decNode.target,
209
+ }));
210
+ }
211
+ else {
212
+ let list = augmentDecoratorsForSym.get(ref);
213
+ if (list === undefined) {
214
+ list = [];
215
+ augmentDecoratorsForSym.set(ref, list);
216
+ }
217
+ list.unshift(decNode);
218
+ }
219
+ }
220
+ }
221
+ }
222
+ function addUsingSymbols(source, destination) {
223
+ const augmented = getOrCreateAugmentedSymbolTable(destination);
224
+ for (const symbolSource of source.values()) {
225
+ const sym = {
226
+ flags: 524288 /* SymbolFlags.Using */,
227
+ declarations: [],
228
+ name: symbolSource.name,
229
+ symbolSource: symbolSource,
230
+ };
231
+ augmented.set(sym.name, sym);
232
+ }
233
+ }
234
+ /**
235
+ * We cannot inject symbols into the symbol tables hanging off syntax tree nodes as
236
+ * syntax tree nodes can be shared by other programs. This is called as a copy-on-write
237
+ * to inject using and late-bound symbols, and then we use the copy when resolving
238
+ * in the table.
239
+ */
240
+ function getOrCreateAugmentedSymbolTable(table) {
241
+ let augmented = augmentedSymbolTables.get(table);
242
+ if (!augmented) {
243
+ augmented = createSymbolTable(table);
244
+ augmentedSymbolTables.set(table, augmented);
245
+ }
246
+ return mutate(augmented);
247
+ }
248
+ /**
249
+ * Create the link for the given type to the symbol links.
250
+ * If currently instantiating a template it will link to the instantiations.
251
+ * Else will link to the declaredType.
252
+ * @param links Symbol link
253
+ * @param type Type
254
+ * @param mapper Type mapper if in an template instantiation
255
+ */
256
+ function linkType(links, type, mapper) {
257
+ if (mapper === undefined) {
258
+ links.declaredType = type;
259
+ links.instantiations = new TypeInstantiationMap();
260
+ }
261
+ else if (links.instantiations) {
262
+ links.instantiations.set(mapper.args, type);
263
+ }
264
+ }
265
+ function linkMemberType(links, type, mapper) {
266
+ if (mapper === undefined) {
267
+ links.declaredType = type;
268
+ }
269
+ }
270
+ /**
271
+ * Check a member symbol.
272
+ * @param sym Symbol binding a member node.
273
+ * @param mapper Type mapper.
274
+ * @returns Checked type for the given member symbol.
275
+ */
276
+ function checkMemberSym(sym, mapper) {
277
+ var _a;
278
+ const symbolLinks = getSymbolLinks(sym);
279
+ const memberContainer = getTypeForNode(sym.parent.declarations[0], mapper);
280
+ const type = (_a = symbolLinks.declaredType) !== null && _a !== void 0 ? _a : symbolLinks.type;
281
+ if (type) {
282
+ return type;
283
+ }
284
+ else {
285
+ return checkMember(sym.declarations[0], mapper, memberContainer);
286
+ }
287
+ }
288
+ /**
289
+ * Check a member node
290
+ * @param node Member node to check
291
+ * @param mapper Type mapper
292
+ * @param containerType Member node container type(Interface, Model, Union, etc.)
293
+ * @returns Checked member
294
+ */
295
+ function checkMember(node, mapper, containerType) {
296
+ switch (node.kind) {
297
+ case SyntaxKind.ModelProperty:
298
+ return checkModelProperty(node, mapper);
299
+ case SyntaxKind.EnumMember:
300
+ return checkEnumMember(node, mapper, containerType);
301
+ case SyntaxKind.OperationStatement:
302
+ return checkOperation(node, mapper, containerType);
303
+ case SyntaxKind.UnionVariant:
304
+ return checkUnionVariant(node, mapper);
305
+ }
306
+ }
307
+ function getTypeForNode(node, mapper) {
308
+ switch (node.kind) {
309
+ case SyntaxKind.ModelExpression:
310
+ return checkModel(node, mapper);
311
+ case SyntaxKind.ModelStatement:
312
+ return checkModel(node, mapper);
313
+ case SyntaxKind.ModelProperty:
314
+ return checkModelProperty(node, mapper);
315
+ case SyntaxKind.ScalarStatement:
316
+ return checkScalar(node, mapper);
317
+ case SyntaxKind.AliasStatement:
318
+ return checkAlias(node, mapper);
319
+ case SyntaxKind.EnumStatement:
320
+ return checkEnum(node, mapper);
321
+ case SyntaxKind.EnumMember:
322
+ return checkEnumMember(node, mapper);
323
+ case SyntaxKind.InterfaceStatement:
324
+ return checkInterface(node, mapper);
325
+ case SyntaxKind.UnionStatement:
326
+ return checkUnion(node, mapper);
327
+ case SyntaxKind.UnionVariant:
328
+ return checkUnionVariant(node, mapper);
329
+ case SyntaxKind.NamespaceStatement:
330
+ return checkNamespace(node);
331
+ case SyntaxKind.OperationStatement:
332
+ return checkOperation(node, mapper);
333
+ case SyntaxKind.NumericLiteral:
334
+ return checkNumericLiteral(node);
335
+ case SyntaxKind.BooleanLiteral:
336
+ return checkBooleanLiteral(node);
337
+ case SyntaxKind.TupleExpression:
338
+ return checkTupleExpression(node, mapper);
339
+ case SyntaxKind.StringLiteral:
340
+ return checkStringLiteral(node);
341
+ case SyntaxKind.ArrayExpression:
342
+ return checkArrayExpression(node, mapper);
343
+ case SyntaxKind.UnionExpression:
344
+ return checkUnionExpression(node, mapper);
345
+ case SyntaxKind.IntersectionExpression:
346
+ return checkIntersectionExpression(node, mapper);
347
+ case SyntaxKind.DecoratorDeclarationStatement:
348
+ return checkDecoratorDeclaration(node, mapper);
349
+ case SyntaxKind.FunctionDeclarationStatement:
350
+ return checkFunctionDeclaration(node, mapper);
351
+ case SyntaxKind.TypeReference:
352
+ return checkTypeReference(node, mapper);
353
+ case SyntaxKind.TemplateParameterDeclaration:
354
+ return checkTemplateParameterDeclaration(node, mapper);
355
+ case SyntaxKind.ProjectionStatement:
356
+ return checkProjectionDeclaration(node);
357
+ case SyntaxKind.VoidKeyword:
358
+ return voidType;
359
+ case SyntaxKind.NeverKeyword:
360
+ return neverType;
361
+ case SyntaxKind.UnknownKeyword:
362
+ return unknownType;
363
+ }
364
+ // we don't emit an error here as we blindly call this function
365
+ // with any node type, but some nodes don't produce a type
366
+ // (e.g. imports). errorType should result in an error if it
367
+ // bubbles out somewhere its not supposed to be.
368
+ return errorType;
369
+ }
370
+ function getFullyQualifiedSymbolName(sym) {
371
+ if (!sym)
372
+ return "";
373
+ if (sym.symbolSource)
374
+ sym = sym.symbolSource;
375
+ const parent = sym.parent;
376
+ const name = sym.flags & 16384 /* SymbolFlags.Decorator */ ? sym.name.slice(1) : sym.name;
377
+ return parent && parent.name !== "" && !(parent.flags & 2097152 /* SymbolFlags.SourceFile */)
378
+ ? `${getFullyQualifiedSymbolName(parent)}.${name}`
379
+ : name;
380
+ }
381
+ /**
382
+ * Return a fully qualified id of node
383
+ */
384
+ function getNodeSymId(node) {
385
+ var _a;
386
+ // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain
387
+ return (_a = node.symbol) === null || _a === void 0 ? void 0 : _a.id;
388
+ }
389
+ /**
390
+ * Check if the given namespace is the standard library `TypeSpec` namespace.
391
+ */
392
+ function isTypeSpecNamespace(namespace) {
393
+ var _a;
394
+ return (namespace.name === "TypeSpec" &&
395
+ (namespace.namespace === globalNamespaceType ||
396
+ ((_a = namespace.namespace) === null || _a === void 0 ? void 0 : _a.projectionBase) === globalNamespaceType));
397
+ }
398
+ /**
399
+ * Check if the given type is defined right in the TypeSpec namespace.
400
+ */
401
+ function isInTypeSpecNamespace(type) {
402
+ return Boolean(type.namespace && isTypeSpecNamespace(type.namespace));
403
+ }
404
+ function checkTemplateParameterDeclaration(node, mapper) {
405
+ var _a;
406
+ const parentNode = node.parent;
407
+ const grandParentNode = parentNode.parent;
408
+ const links = getSymbolLinks(node.symbol);
409
+ let type = links.declaredType;
410
+ if (type === undefined) {
411
+ if (grandParentNode) {
412
+ if ((_a = grandParentNode.locals) === null || _a === void 0 ? void 0 : _a.has(node.id.sv)) {
413
+ reportCheckerDiagnostic(createDiagnostic({
414
+ code: "shadow",
415
+ format: { name: node.id.sv },
416
+ target: node,
417
+ }));
418
+ }
419
+ }
420
+ const index = parentNode.templateParameters.findIndex((v) => v === node);
421
+ type = links.declaredType = createAndFinishType({
422
+ kind: "TemplateParameter",
423
+ node: node,
424
+ });
425
+ if (node.constraint) {
426
+ type.constraint = getTypeForNode(node.constraint);
427
+ }
428
+ if (node.default) {
429
+ type.default = checkTemplateParameterDefault(node.default, parentNode.templateParameters, index, type.constraint);
430
+ }
431
+ }
432
+ return mapper ? mapper.getMappedType(type) : type;
433
+ }
434
+ function getResolvedTypeParameterDefault(declaredType, node, mapper) {
435
+ if (declaredType.default === undefined) {
436
+ return undefined;
437
+ }
438
+ if (isErrorType(declaredType.default)) {
439
+ return declaredType.default;
440
+ }
441
+ return getTypeForNode(node.default, mapper);
442
+ }
443
+ function checkTemplateParameterDefault(nodeDefault, templateParameters, index, constraint) {
444
+ var _a;
445
+ function visit(node) {
446
+ const type = getTypeForNode(node);
447
+ let hasError = false;
448
+ if (type.kind === "TemplateParameter") {
449
+ for (let i = index; i < templateParameters.length; i++) {
450
+ if (type.node.symbol === templateParameters[i].symbol) {
451
+ reportCheckerDiagnostic(createDiagnostic({ code: "invalid-template-default", target: node }));
452
+ return undefined;
453
+ }
454
+ }
455
+ return type;
456
+ }
457
+ visitChildren(node, (x) => {
458
+ const visited = visit(x);
459
+ if (visited === undefined) {
460
+ hasError = true;
461
+ }
462
+ });
463
+ return hasError ? undefined : type;
464
+ }
465
+ const type = (_a = visit(nodeDefault)) !== null && _a !== void 0 ? _a : errorType;
466
+ if (!isErrorType(type) && constraint) {
467
+ checkTypeAssignable(type, constraint, nodeDefault);
468
+ }
469
+ return type;
470
+ }
471
+ /**
472
+ * Check and resolve a type for the given type reference node.
473
+ * @param node Node.
474
+ * @param mapper Type mapper for template instantiation context.
475
+ * @param instantiateTemplate If templated type should be instantiated if they haven't yet.
476
+ * @returns Resolved type.
477
+ */
478
+ function checkTypeReference(node, mapper, instantiateTemplate = true) {
479
+ const sym = resolveTypeReferenceSym(node, mapper);
480
+ if (!sym) {
481
+ return errorType;
482
+ }
483
+ const type = checkTypeReferenceSymbol(sym, node, mapper, instantiateTemplate);
484
+ checkDeprecated(type, node);
485
+ return type;
486
+ }
487
+ function resolveTypeReference(node) {
488
+ const oldDiagnosticHook = onCheckerDiagnostic;
489
+ const diagnostics = [];
490
+ onCheckerDiagnostic = (x) => diagnostics.push(x);
491
+ const type = checkTypeReference(node, undefined, false);
492
+ onCheckerDiagnostic = oldDiagnosticHook;
493
+ return [type === errorType ? undefined : type, diagnostics];
494
+ }
495
+ function checkDeprecated(type, target) {
496
+ const deprecated = getDeprecated(program, type);
497
+ if (deprecated) {
498
+ reportCheckerDiagnostic(createDiagnostic({
499
+ code: "deprecated",
500
+ format: {
501
+ message: deprecated,
502
+ },
503
+ target,
504
+ }));
505
+ }
506
+ }
507
+ function checkTypeReferenceArgs(node, mapper) {
508
+ const args = [];
509
+ if (node.kind !== SyntaxKind.TypeReference) {
510
+ return args;
511
+ }
512
+ for (const arg of node.arguments) {
513
+ const value = getTypeForNode(arg, mapper);
514
+ args.push([arg, value]);
515
+ }
516
+ return args;
517
+ }
518
+ function checkTemplateInstantiationArgs(node, args, declarations) {
519
+ var _a;
520
+ if (args.length > declarations.length) {
521
+ reportCheckerDiagnostic(createDiagnostic({
522
+ code: "invalid-template-args",
523
+ messageId: "tooMany",
524
+ target: node,
525
+ }));
526
+ // Too many args shouldn't matter for instantiating we can still go ahead
527
+ }
528
+ const values = [];
529
+ const params = [];
530
+ let tooFew = false;
531
+ for (let i = 0; i < declarations.length; i++) {
532
+ const declaration = declarations[i];
533
+ const declaredType = getTypeForNode(declaration);
534
+ params.push(declaredType);
535
+ if (i < args.length) {
536
+ let [valueNode, value] = args[i];
537
+ if (declaredType.constraint) {
538
+ if (!checkTypeAssignable(value, declaredType.constraint, valueNode)) {
539
+ value = declaredType.constraint;
540
+ }
541
+ }
542
+ values.push(value);
543
+ }
544
+ else {
545
+ const mapper = createTypeMapper(params, values);
546
+ const defaultValue = getResolvedTypeParameterDefault(declaredType, declaration, mapper);
547
+ if (defaultValue) {
548
+ values.push(defaultValue);
549
+ }
550
+ else {
551
+ tooFew = true;
552
+ values.push((_a = declaredType.constraint) !== null && _a !== void 0 ? _a : unknownType);
553
+ }
554
+ }
555
+ }
556
+ if (tooFew) {
557
+ reportCheckerDiagnostic(createDiagnostic({
558
+ code: "invalid-template-args",
559
+ messageId: "tooFew",
560
+ target: node,
561
+ }));
562
+ }
563
+ return [params, values];
564
+ }
565
+ /**
566
+ * Check and resolve the type for the given symbol + node.
567
+ * @param sym Symbol
568
+ * @param node Node
569
+ * @param mapper Type mapper for template instantiation context.
570
+ * @param instantiateTemplates If a templated type should be instantiated if not yet @default true
571
+ * @returns resolved type.
572
+ */
573
+ function checkTypeReferenceSymbol(sym, node, mapper, instantiateTemplates = true) {
574
+ if (sym.flags & 16384 /* SymbolFlags.Decorator */) {
575
+ reportCheckerDiagnostic(createDiagnostic({ code: "invalid-type-ref", messageId: "decorator", target: sym }));
576
+ return errorType;
577
+ }
578
+ if (sym.flags & 131072 /* SymbolFlags.Function */) {
579
+ reportCheckerDiagnostic(createDiagnostic({ code: "invalid-type-ref", messageId: "function", target: sym }));
580
+ return errorType;
581
+ }
582
+ const symbolLinks = getSymbolLinks(sym);
583
+ let baseType;
584
+ const args = checkTypeReferenceArgs(node, mapper);
585
+ if (sym.flags &
586
+ (2 /* SymbolFlags.Model */ |
587
+ 8 /* SymbolFlags.Scalar */ |
588
+ 2048 /* SymbolFlags.Alias */ |
589
+ 128 /* SymbolFlags.Interface */ |
590
+ 16 /* SymbolFlags.Operation */ |
591
+ 512 /* SymbolFlags.Union */)) {
592
+ const decl = sym.declarations[0];
593
+ if (!isTemplatedNode(decl)) {
594
+ if (args.length > 0) {
595
+ reportCheckerDiagnostic(createDiagnostic({
596
+ code: "invalid-template-args",
597
+ messageId: "notTemplate",
598
+ target: node,
599
+ }));
600
+ }
601
+ if (sym.flags & 16777216 /* SymbolFlags.LateBound */) {
602
+ compilerAssert(sym.type, "Expected late bound symbol to have type");
603
+ return sym.type;
604
+ }
605
+ else if (symbolLinks.declaredType) {
606
+ baseType = symbolLinks.declaredType;
607
+ }
608
+ else if (sym.flags & 1348 /* SymbolFlags.Member */) {
609
+ baseType = checkMemberSym(sym, mapper);
610
+ }
611
+ else {
612
+ baseType = checkDeclaredType(sym, decl, mapper);
613
+ }
614
+ }
615
+ else {
616
+ const declaredType = getOrCheckDeclaredType(sym, decl, mapper);
617
+ const templateParameters = decl.templateParameters;
618
+ const [params, instantiationArgs] = checkTemplateInstantiationArgs(node, args, templateParameters);
619
+ baseType = getOrInstantiateTemplate(decl, params, instantiationArgs, declaredType.templateMapper, instantiateTemplates);
620
+ }
621
+ }
622
+ else {
623
+ // some other kind of reference
624
+ if (args.length > 0) {
625
+ reportCheckerDiagnostic(createDiagnostic({
626
+ code: "invalid-template-args",
627
+ messageId: "notTemplate",
628
+ target: node,
629
+ }));
630
+ }
631
+ if (sym.flags & 16777216 /* SymbolFlags.LateBound */) {
632
+ compilerAssert(sym.type, "Expected late bound symbol to have type");
633
+ return sym.type;
634
+ }
635
+ else if (sym.flags & 32768 /* SymbolFlags.TemplateParameter */) {
636
+ baseType = checkTemplateParameterDeclaration(sym.declarations[0], mapper);
637
+ }
638
+ else if (symbolLinks.type) {
639
+ // Have a cached type for non-declarations
640
+ baseType = symbolLinks.type;
641
+ }
642
+ else if (symbolLinks.declaredType) {
643
+ baseType = symbolLinks.declaredType;
644
+ }
645
+ else {
646
+ if (sym.flags & 1348 /* SymbolFlags.Member */) {
647
+ baseType = checkMemberSym(sym, mapper);
648
+ }
649
+ else {
650
+ // don't have a cached type for this symbol, so go grab it and cache it
651
+ baseType = getTypeForNode(sym.declarations[0], mapper);
652
+ symbolLinks.type = baseType;
653
+ }
654
+ }
655
+ }
656
+ return baseType;
657
+ }
658
+ /**
659
+ * Get or check the declared type of a templatable node.
660
+ * @param node Declaration node
661
+ * @param sym Node Symbol
662
+ * @param mapper Type mapper for template resolution
663
+ * @returns The declared type for the given node.
664
+ */
665
+ function getOrCheckDeclaredType(sym, decl, mapper) {
666
+ const symbolLinks = getSymbolLinks(sym);
667
+ if (symbolLinks.declaredType) {
668
+ return symbolLinks.declaredType;
669
+ }
670
+ if (sym.flags & 16777216 /* SymbolFlags.LateBound */) {
671
+ compilerAssert(sym.type, "Expected late bound symbol to have type");
672
+ return sym.type;
673
+ }
674
+ return checkDeclaredType(sym, decl, mapper);
675
+ }
676
+ /**
677
+ * Check the declared type of a templatable node.
678
+ * @param node Declaration node
679
+ * @param sym Node Symbol
680
+ * @param mapper Type mapper for template resolution
681
+ * @returns The declared type for the given node.
682
+ */
683
+ function checkDeclaredType(sym, node, mapper) {
684
+ return sym.flags & 2 /* SymbolFlags.Model */
685
+ ? checkModelStatement(node, mapper)
686
+ : sym.flags & 8 /* SymbolFlags.Scalar */
687
+ ? checkScalar(node, mapper)
688
+ : sym.flags & 2048 /* SymbolFlags.Alias */
689
+ ? checkAlias(node, mapper)
690
+ : sym.flags & 128 /* SymbolFlags.Interface */
691
+ ? checkInterface(node, mapper)
692
+ : sym.flags & 16 /* SymbolFlags.Operation */
693
+ ? checkOperation(node, mapper)
694
+ : checkUnion(node, mapper);
695
+ }
696
+ function getOrInstantiateTemplate(templateNode, params, args, parentMapper, instantiateTempalates = true) {
697
+ var _a;
698
+ const symbolLinks = templateNode.kind === SyntaxKind.OperationStatement &&
699
+ templateNode.parent.kind === SyntaxKind.InterfaceStatement
700
+ ? getSymbolLinksForMember(templateNode)
701
+ : getSymbolLinks(templateNode.symbol);
702
+ compilerAssert(symbolLinks, `Unexpected checker error. symbolLinks was not defined for ${SyntaxKind[templateNode.kind]}`);
703
+ if (symbolLinks.instantiations === undefined) {
704
+ const type = getTypeForNode(templateNode);
705
+ if (isErrorType(type)) {
706
+ return errorType;
707
+ }
708
+ else {
709
+ compilerAssert(false, `Unexpected checker error. symbolLinks.instantiations was not defined for ${SyntaxKind[templateNode.kind]}`);
710
+ }
711
+ }
712
+ const cached = (_a = symbolLinks.instantiations) === null || _a === void 0 ? void 0 : _a.get(args);
713
+ if (cached) {
714
+ return cached;
715
+ }
716
+ if (instantiateTempalates) {
717
+ return instantiateTemplate(symbolLinks.instantiations, templateNode, params, args, parentMapper);
718
+ }
719
+ else {
720
+ return errorType;
721
+ }
722
+ }
723
+ /**
724
+ * Builds a model type from a template and its template arguments.
725
+ * Adds the template node to a set we can check when we bind template
726
+ * parameters to access type type arguments.
727
+ *
728
+ * This will fall over if the same template is ever being instantiated
729
+ * twice at the same time, or if template parameters from more than one template
730
+ * are ever in scope at once.
731
+ */
732
+ function instantiateTemplate(instantiations, templateNode, params, args, parentMapper) {
733
+ const mapper = createTypeMapper(params, args, parentMapper);
734
+ const type = getTypeForNode(templateNode, mapper);
735
+ if (!instantiations.get(args)) {
736
+ instantiations.set(args, type);
737
+ }
738
+ if (type.kind === "Model") {
739
+ type.templateNode = templateNode;
740
+ }
741
+ return type;
742
+ }
743
+ function checkUnionExpression(node, mapper) {
744
+ const unionType = createAndFinishType({
745
+ kind: "Union",
746
+ node,
747
+ get options() {
748
+ return Array.from(this.variants.values()).map((v) => v.type);
749
+ },
750
+ expression: true,
751
+ variants: new Map(),
752
+ decorators: [],
753
+ });
754
+ for (const o of node.options) {
755
+ const type = getTypeForNode(o, mapper);
756
+ // The type `A | never` is just `A`
757
+ if (type === neverType) {
758
+ continue;
759
+ }
760
+ if (type.kind === "Union" && type.expression) {
761
+ for (const [name, variant] of type.variants) {
762
+ unionType.variants.set(name, variant);
763
+ }
764
+ }
765
+ else {
766
+ const variant = createType({
767
+ kind: "UnionVariant",
768
+ type,
769
+ name: Symbol("name"),
770
+ decorators: [],
771
+ node: undefined,
772
+ union: unionType,
773
+ });
774
+ unionType.variants.set(variant.name, variant);
775
+ }
776
+ }
777
+ return unionType;
778
+ }
779
+ /**
780
+ * Intersection produces a model type from the properties of its operands.
781
+ * So this doesn't work if we don't have a known set of properties (e.g.
782
+ * with unions). The resulting model is anonymous.
783
+ */
784
+ function checkIntersectionExpression(node, mapper) {
785
+ const options = node.options.map((o) => [o, getTypeForNode(o, mapper)]);
786
+ return mergeModelTypes(node, options, mapper);
787
+ }
788
+ function checkDecoratorDeclaration(node, mapper) {
789
+ const symbol = getMergedSymbol(node.symbol);
790
+ const links = getSymbolLinks(symbol);
791
+ if (links.declaredType && mapper === undefined) {
792
+ // we're not instantiating this operation and we've already checked it
793
+ return links.declaredType;
794
+ }
795
+ const namespace = getParentNamespaceType(node);
796
+ compilerAssert(namespace, `Decorator ${node.id.sv} should have resolved a namespace or found the global namespace.`);
797
+ const name = node.id.sv;
798
+ if (!(node.modifierFlags & 2 /* ModifierFlags.Extern */)) {
799
+ reportCheckerDiagnostic(createDiagnostic({ code: "decorator-extern", target: node }));
800
+ }
801
+ const implementation = symbol.value;
802
+ if (implementation === undefined) {
803
+ reportCheckerDiagnostic(createDiagnostic({ code: "missing-implementation", target: node }));
804
+ }
805
+ const decoratorType = createType({
806
+ kind: "Decorator",
807
+ name: `@${name}`,
808
+ namespace,
809
+ node,
810
+ target: checkFunctionParameter(node.target, mapper),
811
+ parameters: node.parameters.map((x) => checkFunctionParameter(x, mapper)),
812
+ implementation: implementation !== null && implementation !== void 0 ? implementation : (() => { }),
813
+ });
814
+ namespace.decoratorDeclarations.set(name, decoratorType);
815
+ linkType(links, decoratorType, mapper);
816
+ return decoratorType;
817
+ }
818
+ function checkFunctionDeclaration(node, mapper) {
819
+ const symbol = getMergedSymbol(node.symbol);
820
+ const links = getSymbolLinks(symbol);
821
+ if (links.declaredType && mapper === undefined) {
822
+ // we're not instantiating this operation and we've already checked it
823
+ return links.declaredType;
824
+ }
825
+ const namespace = getParentNamespaceType(node);
826
+ compilerAssert(namespace, `Decorator ${node.id.sv} should have resolved a namespace or found the global namespace.`);
827
+ const name = node.id.sv;
828
+ if (!(node.modifierFlags & 2 /* ModifierFlags.Extern */)) {
829
+ reportCheckerDiagnostic(createDiagnostic({ code: "function-extern", target: node }));
830
+ }
831
+ const implementation = symbol.value;
832
+ if (implementation === undefined) {
833
+ reportCheckerDiagnostic(createDiagnostic({ code: "missing-implementation", target: node }));
834
+ }
835
+ const functionType = createType({
836
+ kind: "Function",
837
+ name,
838
+ namespace,
839
+ node,
840
+ parameters: node.parameters.map((x) => checkFunctionParameter(x, mapper)),
841
+ returnType: node.returnType ? getTypeForNode(node.returnType, mapper) : unknownType,
842
+ implementation: implementation !== null && implementation !== void 0 ? implementation : (() => { }),
843
+ });
844
+ namespace.functionDeclarations.set(name, functionType);
845
+ linkType(links, functionType, mapper);
846
+ return functionType;
847
+ }
848
+ function checkFunctionParameter(node, mapper) {
849
+ const links = getSymbolLinks(node.symbol);
850
+ if (links.declaredType) {
851
+ return links.declaredType;
852
+ }
853
+ if (node.rest && node.type && node.type.kind !== SyntaxKind.ArrayExpression) {
854
+ reportCheckerDiagnostic(createDiagnostic({ code: "rest-parameter-array", target: node.type }));
855
+ }
856
+ const type = node.type ? getTypeForNode(node.type) : unknownType;
857
+ const parameterType = createType({
858
+ kind: "FunctionParameter",
859
+ node,
860
+ name: node.id.sv,
861
+ optional: node.optional,
862
+ rest: node.rest,
863
+ type,
864
+ implementation: node.symbol.value,
865
+ });
866
+ linkType(links, parameterType, mapper);
867
+ return parameterType;
868
+ }
869
+ function mergeModelTypes(node, options, mapper) {
870
+ const properties = new Map();
871
+ const intersection = createType({
872
+ kind: "Model",
873
+ node,
874
+ name: "",
875
+ namespace: getParentNamespaceType(node),
876
+ properties: properties,
877
+ decorators: [],
878
+ derivedModels: [],
879
+ });
880
+ const indexers = [];
881
+ for (const [optionNode, option] of options) {
882
+ if (option.kind === "TemplateParameter") {
883
+ continue;
884
+ }
885
+ if (option.kind !== "Model") {
886
+ reportCheckerDiagnostic(createDiagnostic({ code: "intersect-non-model", target: optionNode }));
887
+ continue;
888
+ }
889
+ if (option.indexer) {
890
+ if (option.indexer.key.name === "integer") {
891
+ reportCheckerDiagnostic(createDiagnostic({
892
+ code: "intersect-invalid-index",
893
+ messageId: "array",
894
+ target: optionNode,
895
+ }));
896
+ }
897
+ else {
898
+ indexers.push(option.indexer);
899
+ }
900
+ }
901
+ if (indexers.length === 1) {
902
+ intersection.indexer = indexers[0];
903
+ }
904
+ else if (indexers.length > 1) {
905
+ intersection.indexer = {
906
+ key: indexers[0].key,
907
+ value: mergeModelTypes(node, indexers.map((x) => [x.value.node, x.value]), mapper),
908
+ };
909
+ }
910
+ const allProps = walkPropertiesInherited(option);
911
+ for (const prop of allProps) {
912
+ if (properties.has(prop.name)) {
913
+ reportCheckerDiagnostic(createDiagnostic({
914
+ code: "intersect-duplicate-property",
915
+ format: { propName: prop.name },
916
+ target: node,
917
+ }));
918
+ continue;
919
+ }
920
+ const newPropType = cloneType(prop, {
921
+ sourceProperty: prop,
922
+ model: intersection,
923
+ });
924
+ properties.set(prop.name, newPropType);
925
+ }
926
+ }
927
+ return finishType(intersection, mapper);
928
+ }
929
+ function checkArrayExpression(node, mapper) {
930
+ const elementType = getTypeForNode(node.elementType, mapper);
931
+ const arrayType = getStdType("Array");
932
+ const arrayNode = arrayType.node;
933
+ const param = getTypeForNode(arrayNode.templateParameters[0]);
934
+ return getOrInstantiateTemplate(arrayNode, [param], [elementType], undefined);
935
+ }
936
+ function checkNamespace(node) {
937
+ const links = getSymbolLinks(getMergedSymbol(node.symbol));
938
+ let type = links.type;
939
+ if (!type) {
940
+ type = initializeTypeForNamespace(node);
941
+ }
942
+ if (isArray(node.statements)) {
943
+ node.statements.forEach((x) => getTypeForNode(x));
944
+ }
945
+ else if (node.statements) {
946
+ const subNs = checkNamespace(node.statements);
947
+ type.namespaces.set(subNs.name, subNs);
948
+ }
949
+ return type;
950
+ }
951
+ function initializeTypeForNamespace(node) {
952
+ compilerAssert(node.symbol, "Namespace is unbound.", node);
953
+ const mergedSymbol = getMergedSymbol(node.symbol);
954
+ const symbolLinks = getSymbolLinks(mergedSymbol);
955
+ if (!symbolLinks.type) {
956
+ // haven't seen this namespace before
957
+ const namespace = getParentNamespaceType(node);
958
+ const name = node.id.sv;
959
+ const type = createType({
960
+ kind: "Namespace",
961
+ name,
962
+ namespace,
963
+ node,
964
+ models: new Map(),
965
+ scalars: new Map(),
966
+ operations: new Map(),
967
+ namespaces: new Map(),
968
+ interfaces: new Map(),
969
+ unions: new Map(),
970
+ enums: new Map(),
971
+ decoratorDeclarations: new Map(),
972
+ functionDeclarations: new Map(),
973
+ decorators: [],
974
+ });
975
+ symbolLinks.type = type;
976
+ for (const sourceNode of mergedSymbol.declarations) {
977
+ // namespaces created from typespec scripts don't have decorators
978
+ if (sourceNode.kind !== SyntaxKind.NamespaceStatement)
979
+ continue;
980
+ type.decorators = type.decorators.concat(checkDecorators(type, sourceNode, undefined));
981
+ }
982
+ finishType(type);
983
+ namespace === null || namespace === void 0 ? void 0 : namespace.namespaces.set(name, type);
984
+ }
985
+ return symbolLinks.type;
986
+ }
987
+ function getParentNamespaceType(node) {
988
+ if (node === globalNamespaceType.node)
989
+ return undefined;
990
+ if (node.kind === SyntaxKind.ModelExpression ||
991
+ node.kind === SyntaxKind.IntersectionExpression) {
992
+ let parent = node.parent;
993
+ while (parent !== undefined) {
994
+ if (parent.kind === SyntaxKind.ModelStatement ||
995
+ parent.kind === SyntaxKind.ScalarStatement ||
996
+ parent.kind === SyntaxKind.OperationStatement ||
997
+ parent.kind === SyntaxKind.EnumStatement ||
998
+ parent.kind === SyntaxKind.InterfaceStatement ||
999
+ parent.kind === SyntaxKind.UnionStatement ||
1000
+ parent.kind === SyntaxKind.ModelExpression ||
1001
+ parent.kind === SyntaxKind.IntersectionExpression) {
1002
+ return getParentNamespaceType(parent);
1003
+ }
1004
+ else {
1005
+ parent = parent.parent;
1006
+ }
1007
+ }
1008
+ return undefined;
1009
+ }
1010
+ if (node.kind === SyntaxKind.OperationStatement &&
1011
+ node.parent &&
1012
+ node.parent.kind === SyntaxKind.InterfaceStatement) {
1013
+ return getParentNamespaceType(node.parent);
1014
+ }
1015
+ if (!node.symbol.parent) {
1016
+ return globalNamespaceType;
1017
+ }
1018
+ if (node.symbol.parent.declarations[0].kind === SyntaxKind.TypeSpecScript ||
1019
+ node.symbol.parent.declarations[0].kind === SyntaxKind.JsSourceFile) {
1020
+ return globalNamespaceType;
1021
+ }
1022
+ const mergedSymbol = getMergedSymbol(node.symbol.parent);
1023
+ const symbolLinks = getSymbolLinks(mergedSymbol);
1024
+ if (!symbolLinks.type) {
1025
+ // in general namespaces should be typed before anything calls this function.
1026
+ // However, one case where this is not true is when a decorator on a namespace
1027
+ // refers to a model in another namespace. In this case, we need to evaluate
1028
+ // the namespace here.
1029
+ const namespaceNode = mergedSymbol.declarations.find((x) => x.kind === SyntaxKind.NamespaceStatement);
1030
+ compilerAssert(namespaceNode, "Can't find namespace declaration node.", node);
1031
+ symbolLinks.type = initializeTypeForNamespace(namespaceNode);
1032
+ }
1033
+ return symbolLinks.type;
1034
+ }
1035
+ function checkOperation(node, mapper, parentInterface) {
1036
+ var _a;
1037
+ const inInterface = ((_a = node.parent) === null || _a === void 0 ? void 0 : _a.kind) === SyntaxKind.InterfaceStatement;
1038
+ const links = inInterface ? getSymbolLinksForMember(node) : getSymbolLinks(node.symbol);
1039
+ if (links) {
1040
+ if (links.declaredType && mapper === undefined) {
1041
+ // we're not instantiating this operation and we've already checked it
1042
+ return links.declaredType;
1043
+ }
1044
+ }
1045
+ if (mapper === undefined && inInterface) {
1046
+ compilerAssert(parentInterface, "Operation in interface should already have been checked.");
1047
+ }
1048
+ // If we are instantating operation inside of interface
1049
+ if (isTemplatedNode(node) && mapper !== undefined && parentInterface) {
1050
+ mapper = { ...mapper, partial: true };
1051
+ }
1052
+ const namespace = getParentNamespaceType(node);
1053
+ const name = node.id.sv;
1054
+ let decorators = [];
1055
+ // Is this a definition or reference?
1056
+ let parameters, returnType;
1057
+ if (node.signature.kind === SyntaxKind.OperationSignatureReference) {
1058
+ // Attempt to resolve the operation
1059
+ const baseOperation = checkOperationIs(node, node.signature.baseOperation, mapper);
1060
+ if (!baseOperation) {
1061
+ return errorType;
1062
+ }
1063
+ // Reference the same return type and create the parameters type
1064
+ parameters = cloneType(baseOperation.parameters);
1065
+ returnType = baseOperation.returnType;
1066
+ // Copy decorators from the base operation, inserting the base decorators first
1067
+ decorators = [...baseOperation.decorators];
1068
+ }
1069
+ else {
1070
+ parameters = getTypeForNode(node.signature.parameters, mapper);
1071
+ returnType = getTypeForNode(node.signature.returnType, mapper);
1072
+ }
1073
+ const operationType = createType({
1074
+ kind: "Operation",
1075
+ name,
1076
+ namespace,
1077
+ node,
1078
+ parameters,
1079
+ returnType,
1080
+ decorators,
1081
+ interface: parentInterface,
1082
+ });
1083
+ decorators.push(...checkDecorators(operationType, node, mapper));
1084
+ operationType.parameters.namespace = namespace;
1085
+ const parent = node.parent;
1086
+ if (parent.kind === SyntaxKind.InterfaceStatement) {
1087
+ if (shouldCreateTypeForTemplate(parent, mapper) &&
1088
+ shouldCreateTypeForTemplate(node, mapper)) {
1089
+ finishType(operationType, mapper);
1090
+ }
1091
+ }
1092
+ else {
1093
+ if (shouldCreateTypeForTemplate(node, mapper)) {
1094
+ finishType(operationType, mapper);
1095
+ }
1096
+ namespace === null || namespace === void 0 ? void 0 : namespace.operations.set(name, operationType);
1097
+ }
1098
+ if (links) {
1099
+ linkType(links, operationType, mapper);
1100
+ }
1101
+ return operationType;
1102
+ }
1103
+ function checkOperationIs(operation, opReference, mapper) {
1104
+ if (!opReference)
1105
+ return undefined;
1106
+ // Ensure that we don't end up with a circular reference to the same operation
1107
+ const opSymId = getNodeSymId(operation);
1108
+ if (opSymId) {
1109
+ pendingResolutions.add(opSymId);
1110
+ }
1111
+ const target = resolveTypeReferenceSym(opReference, mapper);
1112
+ if (target === undefined) {
1113
+ return undefined;
1114
+ }
1115
+ // Did we encounter a circular operation reference?
1116
+ if (pendingResolutions.has(getNodeSymId(target.declarations[0]))) {
1117
+ if (mapper === undefined) {
1118
+ reportCheckerDiagnostic(createDiagnostic({
1119
+ code: "circular-op-signature",
1120
+ format: { typeName: target.declarations[0].id.sv },
1121
+ target: opReference,
1122
+ }));
1123
+ }
1124
+ return undefined;
1125
+ }
1126
+ // Resolve the base operation type
1127
+ const baseOperation = checkTypeReferenceSymbol(target, opReference, mapper);
1128
+ if (opSymId) {
1129
+ pendingResolutions.delete(opSymId);
1130
+ }
1131
+ if (isErrorType(baseOperation)) {
1132
+ return undefined;
1133
+ }
1134
+ // Was the wrong type referenced?
1135
+ if (baseOperation.kind !== "Operation") {
1136
+ reportCheckerDiagnostic(createDiagnostic({ code: "is-operation", target: opReference }));
1137
+ return;
1138
+ }
1139
+ return baseOperation;
1140
+ }
1141
+ function getGlobalNamespaceType() {
1142
+ return globalNamespaceType;
1143
+ }
1144
+ function getGlobalNamespaceNode() {
1145
+ return globalNamespaceNode;
1146
+ }
1147
+ function checkTupleExpression(node, mapper) {
1148
+ return createAndFinishType({
1149
+ kind: "Tuple",
1150
+ node: node,
1151
+ values: node.values.map((v) => getTypeForNode(v, mapper)),
1152
+ });
1153
+ }
1154
+ function getSymbolLinks(s) {
1155
+ const id = getSymbolId(s);
1156
+ if (symbolLinks.has(id)) {
1157
+ return symbolLinks.get(id);
1158
+ }
1159
+ const links = {};
1160
+ symbolLinks.set(id, links);
1161
+ return links;
1162
+ }
1163
+ function getSymbolId(s) {
1164
+ if (s.id === undefined) {
1165
+ mutate(s).id = currentSymbolId++;
1166
+ }
1167
+ return s.id;
1168
+ }
1169
+ function resolveIdentifierInTable(node, table, resolveDecorator = false) {
1170
+ var _a, _b;
1171
+ if (!table) {
1172
+ return undefined;
1173
+ }
1174
+ table = (_a = augmentedSymbolTables.get(table)) !== null && _a !== void 0 ? _a : table;
1175
+ let sym;
1176
+ if (resolveDecorator) {
1177
+ sym = table.get("@" + node.sv);
1178
+ }
1179
+ else {
1180
+ sym = table.get(node.sv);
1181
+ }
1182
+ if (!sym)
1183
+ return sym;
1184
+ if (sym.flags & 1048576 /* SymbolFlags.DuplicateUsing */) {
1185
+ reportAmbiguousIdentifier(node, [...((_b = table.duplicates.get(sym)) !== null && _b !== void 0 ? _b : [])]);
1186
+ return sym;
1187
+ }
1188
+ return getMergedSymbol(sym);
1189
+ }
1190
+ function reportAmbiguousIdentifier(node, symbols) {
1191
+ const duplicateNames = symbols.map(getFullyQualifiedSymbolName).join(", ");
1192
+ reportCheckerDiagnostic(createDiagnostic({
1193
+ code: "ambiguous-symbol",
1194
+ format: { name: node.sv, duplicateNames },
1195
+ target: node,
1196
+ }));
1197
+ }
1198
+ function resolveIdentifier(id, mapper) {
1199
+ var _a, _b, _c;
1200
+ let sym;
1201
+ const { node, kind } = getIdentifierContext(id);
1202
+ switch (kind) {
1203
+ case IdentifierKind.Declaration:
1204
+ if (node.symbol && (!isTemplatedNode(node) || mapper === undefined)) {
1205
+ sym = getMergedSymbol(node.symbol);
1206
+ break;
1207
+ }
1208
+ compilerAssert(node.parent, "Parent expected.");
1209
+ const containerType = getTypeForNode(node.parent, mapper);
1210
+ if (isAnonymous(containerType)) {
1211
+ return undefined; // member of anonymous type cannot be referenced.
1212
+ }
1213
+ lateBindMemberContainer(containerType);
1214
+ let container = node.parent.symbol;
1215
+ if (!container && "symbol" in containerType && containerType.symbol) {
1216
+ container = containerType.symbol;
1217
+ }
1218
+ if (!container) {
1219
+ return undefined;
1220
+ }
1221
+ lateBindMembers(containerType, container);
1222
+ sym = resolveIdentifierInTable(id, (_a = container.exports) !== null && _a !== void 0 ? _a : container.members);
1223
+ break;
1224
+ case IdentifierKind.Other:
1225
+ return undefined;
1226
+ case IdentifierKind.Decorator:
1227
+ case IdentifierKind.Function:
1228
+ case IdentifierKind.Using:
1229
+ case IdentifierKind.TypeReference:
1230
+ let ref = id;
1231
+ let resolveDecorator = kind === IdentifierKind.Decorator;
1232
+ if (((_b = id.parent) === null || _b === void 0 ? void 0 : _b.kind) === SyntaxKind.MemberExpression) {
1233
+ if (id.parent.id === id) {
1234
+ // If the identifier is Y in X.Y, then resolve (X.Y).
1235
+ ref = id.parent;
1236
+ }
1237
+ else {
1238
+ // If the identifier is X in X.Y then we are resolving a
1239
+ // namespace, which is never a decorator.
1240
+ resolveDecorator = false;
1241
+ }
1242
+ }
1243
+ sym = resolveTypeReferenceSym(ref, mapper, resolveDecorator);
1244
+ break;
1245
+ default:
1246
+ const _assertNever = kind;
1247
+ compilerAssert(false, "Unreachable");
1248
+ }
1249
+ return (_c = sym === null || sym === void 0 ? void 0 : sym.symbolSource) !== null && _c !== void 0 ? _c : sym;
1250
+ }
1251
+ function resolveCompletions(identifier) {
1252
+ var _a, _b;
1253
+ const completions = new Map();
1254
+ const { kind } = getIdentifierContext(identifier);
1255
+ switch (kind) {
1256
+ case IdentifierKind.Using:
1257
+ case IdentifierKind.Decorator:
1258
+ case IdentifierKind.Function:
1259
+ case IdentifierKind.TypeReference:
1260
+ break; // supported
1261
+ case IdentifierKind.Other:
1262
+ return completions; // not implemented
1263
+ case IdentifierKind.Declaration:
1264
+ return completions; // cannot complete, name can be chosen arbitrarily
1265
+ default:
1266
+ const _assertNever = kind;
1267
+ compilerAssert(false, "Unreachable");
1268
+ }
1269
+ if (identifier.parent && identifier.parent.kind === SyntaxKind.MemberExpression) {
1270
+ let base = resolveTypeReferenceSym(identifier.parent.base, undefined, false);
1271
+ if (base) {
1272
+ if (base.flags & 2048 /* SymbolFlags.Alias */) {
1273
+ base = getAliasedSymbol(base, undefined);
1274
+ }
1275
+ if (isTemplatedNode(base.declarations[0])) {
1276
+ const type = (_a = base.type) !== null && _a !== void 0 ? _a : getTypeForNode(base.declarations[0], undefined);
1277
+ if (isTemplateInstance(type)) {
1278
+ lateBindMemberContainer(type);
1279
+ lateBindMembers(type, base);
1280
+ }
1281
+ }
1282
+ addCompletions((_b = base.exports) !== null && _b !== void 0 ? _b : base.members);
1283
+ }
1284
+ }
1285
+ else {
1286
+ let scope = identifier.parent;
1287
+ while (scope && scope.kind !== SyntaxKind.TypeSpecScript) {
1288
+ if (scope.symbol && scope.symbol.exports) {
1289
+ const mergedSymbol = getMergedSymbol(scope.symbol);
1290
+ addCompletions(mergedSymbol.exports);
1291
+ }
1292
+ if ("locals" in scope) {
1293
+ addCompletions(scope.locals);
1294
+ }
1295
+ scope = scope.parent;
1296
+ }
1297
+ if (scope && scope.kind === SyntaxKind.TypeSpecScript) {
1298
+ // check any blockless namespace decls
1299
+ for (const ns of scope.inScopeNamespaces) {
1300
+ const mergedSymbol = getMergedSymbol(ns.symbol);
1301
+ addCompletions(mergedSymbol.exports);
1302
+ }
1303
+ // check "global scope" declarations
1304
+ addCompletions(globalNamespaceNode.symbol.exports);
1305
+ // check "global scope" usings
1306
+ addCompletions(scope.locals);
1307
+ }
1308
+ }
1309
+ return completions;
1310
+ function addCompletions(table) {
1311
+ var _a;
1312
+ if (!table) {
1313
+ return;
1314
+ }
1315
+ table = (_a = augmentedSymbolTables.get(table)) !== null && _a !== void 0 ? _a : table;
1316
+ for (const [key, sym] of table) {
1317
+ if (sym.flags & 1048576 /* SymbolFlags.DuplicateUsing */) {
1318
+ const duplicates = table.duplicates.get(sym);
1319
+ for (const duplicate of duplicates) {
1320
+ if (duplicate.flags & 524288 /* SymbolFlags.Using */) {
1321
+ const fqn = getFullyQualifiedSymbolName(duplicate.symbolSource);
1322
+ addCompletion(fqn, duplicate);
1323
+ }
1324
+ }
1325
+ }
1326
+ else {
1327
+ addCompletion(key, sym);
1328
+ }
1329
+ }
1330
+ }
1331
+ function addCompletion(key, sym) {
1332
+ if (sym.symbolSource) {
1333
+ sym = sym.symbolSource;
1334
+ }
1335
+ if (!shouldAddCompletion(sym)) {
1336
+ return;
1337
+ }
1338
+ if (key.startsWith("@")) {
1339
+ key = key.slice(1);
1340
+ }
1341
+ if (!completions.has(key)) {
1342
+ completions.set(key, { sym });
1343
+ }
1344
+ }
1345
+ function shouldAddCompletion(sym) {
1346
+ switch (kind) {
1347
+ case IdentifierKind.Decorator:
1348
+ // Only return decorators and namespaces when completing decorator
1349
+ return !!(sym.flags & (16384 /* SymbolFlags.Decorator */ | 4096 /* SymbolFlags.Namespace */));
1350
+ case IdentifierKind.Using:
1351
+ // Only return namespaces when completing using
1352
+ return !!(sym.flags & 4096 /* SymbolFlags.Namespace */);
1353
+ case IdentifierKind.TypeReference:
1354
+ // Do not return functions or decorators when completing types
1355
+ return !(sym.flags & (131072 /* SymbolFlags.Function */ | 16384 /* SymbolFlags.Decorator */));
1356
+ default:
1357
+ compilerAssert(false, "We should have bailed up-front on other kinds.");
1358
+ }
1359
+ }
1360
+ }
1361
+ function resolveIdentifierInScope(node, mapper, resolveDecorator = false) {
1362
+ var _a;
1363
+ compilerAssert(((_a = node.parent) === null || _a === void 0 ? void 0 : _a.kind) !== SyntaxKind.MemberExpression || node.parent.id !== node, "This function should not be used to resolve Y in member expression X.Y. Use resolveIdentifier() to resolve an arbitrary identifier.");
1364
+ if (hasParseError(node)) {
1365
+ // Don't report synthetic identifiers used for parser error recovery.
1366
+ // The parse error is the root cause and will already have been logged.
1367
+ return undefined;
1368
+ }
1369
+ let scope = node.parent;
1370
+ let binding;
1371
+ while (scope && scope.kind !== SyntaxKind.TypeSpecScript) {
1372
+ if (scope.symbol && "exports" in scope.symbol) {
1373
+ const mergedSymbol = getMergedSymbol(scope.symbol);
1374
+ binding = resolveIdentifierInTable(node, mergedSymbol.exports, resolveDecorator);
1375
+ if (binding)
1376
+ return binding;
1377
+ }
1378
+ if ("locals" in scope) {
1379
+ binding = resolveIdentifierInTable(node, scope.locals, resolveDecorator);
1380
+ if (binding)
1381
+ return binding;
1382
+ }
1383
+ scope = scope.parent;
1384
+ }
1385
+ if (!binding && scope && scope.kind === SyntaxKind.TypeSpecScript) {
1386
+ // check any blockless namespace decls
1387
+ for (const ns of scope.inScopeNamespaces) {
1388
+ const mergedSymbol = getMergedSymbol(ns.symbol);
1389
+ binding = resolveIdentifierInTable(node, mergedSymbol.exports, resolveDecorator);
1390
+ if (binding)
1391
+ return binding;
1392
+ }
1393
+ // check "global scope" declarations
1394
+ binding = resolveIdentifierInTable(node, globalNamespaceNode.symbol.exports, resolveDecorator);
1395
+ if (binding)
1396
+ return binding;
1397
+ // check using types
1398
+ binding = resolveIdentifierInTable(node, scope.locals, resolveDecorator);
1399
+ if (binding)
1400
+ return binding.flags & 1048576 /* SymbolFlags.DuplicateUsing */ ? undefined : binding;
1401
+ }
1402
+ if (mapper === undefined) {
1403
+ reportCheckerDiagnostic(createDiagnostic({ code: "unknown-identifier", format: { id: node.sv }, target: node }));
1404
+ }
1405
+ return undefined;
1406
+ }
1407
+ function resolveTypeReferenceSym(node, mapper, resolveDecorator = false) {
1408
+ if (mapper === undefined && referenceSymCache.has(node)) {
1409
+ return referenceSymCache.get(node);
1410
+ }
1411
+ const sym = resolveTypeReferenceSymInternal(node, mapper, resolveDecorator);
1412
+ referenceSymCache.set(node, sym);
1413
+ return sym;
1414
+ }
1415
+ function resolveTypeReferenceSymInternal(node, mapper, resolveDecorator = false) {
1416
+ if (hasParseError(node)) {
1417
+ // Don't report synthetic identifiers used for parser error recovery.
1418
+ // The parse error is the root cause and will already have been logged.
1419
+ return undefined;
1420
+ }
1421
+ if (node.kind === SyntaxKind.TypeReference) {
1422
+ return resolveTypeReferenceSym(node.target, mapper, resolveDecorator);
1423
+ }
1424
+ if (node.kind === SyntaxKind.MemberExpression) {
1425
+ let base = resolveTypeReferenceSym(node.base, mapper);
1426
+ if (!base) {
1427
+ return undefined;
1428
+ }
1429
+ // when resolving a type reference based on an alias, unwrap the alias.
1430
+ if (base.flags & 2048 /* SymbolFlags.Alias */) {
1431
+ base = getAliasedSymbol(base, mapper);
1432
+ }
1433
+ if (base.flags & 4096 /* SymbolFlags.Namespace */) {
1434
+ const symbol = resolveIdentifierInTable(node.id, base.exports, resolveDecorator);
1435
+ if (!symbol) {
1436
+ reportCheckerDiagnostic(createDiagnostic({
1437
+ code: "invalid-ref",
1438
+ messageId: "underNamespace",
1439
+ format: {
1440
+ namespace: getFullyQualifiedSymbolName(base),
1441
+ id: node.id.sv,
1442
+ },
1443
+ target: node,
1444
+ }));
1445
+ return undefined;
1446
+ }
1447
+ return symbol;
1448
+ }
1449
+ else if (base.flags & 16384 /* SymbolFlags.Decorator */) {
1450
+ reportCheckerDiagnostic(createDiagnostic({
1451
+ code: "invalid-ref",
1452
+ messageId: "inDecorator",
1453
+ format: { id: node.id.sv },
1454
+ target: node,
1455
+ }));
1456
+ return undefined;
1457
+ }
1458
+ else if (base.flags & 131072 /* SymbolFlags.Function */) {
1459
+ reportCheckerDiagnostic(createDiagnostic({
1460
+ code: "invalid-ref",
1461
+ messageId: "node",
1462
+ format: { id: node.id.sv, nodeName: "function" },
1463
+ target: node,
1464
+ }));
1465
+ return undefined;
1466
+ }
1467
+ else if (base.flags & 674 /* SymbolFlags.MemberContainer */) {
1468
+ if (isTemplatedNode(base.declarations[0])) {
1469
+ const type = base.flags & 16777216 /* SymbolFlags.LateBound */
1470
+ ? base.type
1471
+ : getTypeForNode(base.declarations[0], mapper);
1472
+ if (isTemplateInstance(type)) {
1473
+ lateBindMembers(type, base);
1474
+ }
1475
+ }
1476
+ const sym = resolveIdentifierInTable(node.id, base.members, resolveDecorator);
1477
+ if (!sym) {
1478
+ reportCheckerDiagnostic(createDiagnostic({
1479
+ code: "invalid-ref",
1480
+ messageId: "underContainer",
1481
+ format: { kind: getMemberKindName(base.declarations[0]), id: node.id.sv },
1482
+ target: node,
1483
+ }));
1484
+ return undefined;
1485
+ }
1486
+ return sym;
1487
+ }
1488
+ else {
1489
+ reportCheckerDiagnostic(createDiagnostic({
1490
+ code: "invalid-ref",
1491
+ messageId: "node",
1492
+ format: {
1493
+ id: node.id.sv,
1494
+ nodeName: base.declarations[0]
1495
+ ? SyntaxKind[base.declarations[0].kind]
1496
+ : "Unknown node",
1497
+ },
1498
+ target: node,
1499
+ }));
1500
+ return undefined;
1501
+ }
1502
+ }
1503
+ if (node.kind === SyntaxKind.Identifier) {
1504
+ const sym = resolveIdentifierInScope(node, mapper, resolveDecorator);
1505
+ if (!sym)
1506
+ return undefined;
1507
+ return sym.flags & 524288 /* SymbolFlags.Using */ ? sym.symbolSource : sym;
1508
+ }
1509
+ compilerAssert(false, "Unknown type reference kind", node);
1510
+ }
1511
+ function getMemberKindName(node) {
1512
+ switch (node.kind) {
1513
+ case SyntaxKind.ModelStatement:
1514
+ case SyntaxKind.ModelExpression:
1515
+ return "Model";
1516
+ case SyntaxKind.EnumStatement:
1517
+ return "Enum";
1518
+ case SyntaxKind.InterfaceStatement:
1519
+ return "Interface";
1520
+ case SyntaxKind.UnionStatement:
1521
+ return "Union";
1522
+ default:
1523
+ return "Type";
1524
+ }
1525
+ }
1526
+ /**
1527
+ * Return the symbol that is aliased by this alias declaration. If no such symbol is aliased,
1528
+ * return the symbol for the alias instead. For member containers which need to be late bound
1529
+ * (i.e. they contain symbols we don't know until we've instantiated the type and the type is an
1530
+ * instantiation) we late bind the container which creates the symbol that will hold its members.
1531
+ */
1532
+ function getAliasedSymbol(aliasSymbol, mapper) {
1533
+ var _a;
1534
+ const aliasType = checkAlias(aliasSymbol.declarations[0], mapper);
1535
+ switch (aliasType.kind) {
1536
+ case "Model":
1537
+ case "Interface":
1538
+ case "Union":
1539
+ if (isTemplateInstance(aliasType)) {
1540
+ // this is an alias for some instantiation, so late-bind the instantiation
1541
+ lateBindMemberContainer(aliasType);
1542
+ return aliasType.symbol;
1543
+ }
1544
+ // fallthrough
1545
+ default:
1546
+ // get the symbol from the node aliased type's node, or just return the base
1547
+ // if it doesn't have a symbol (which will likely result in an error later on)
1548
+ return (_a = aliasType.node.symbol) !== null && _a !== void 0 ? _a : aliasSymbol;
1549
+ }
1550
+ }
1551
+ function checkStringLiteral(str) {
1552
+ return getLiteralType(str);
1553
+ }
1554
+ function checkNumericLiteral(num) {
1555
+ return getLiteralType(num);
1556
+ }
1557
+ function checkBooleanLiteral(bool) {
1558
+ return getLiteralType(bool);
1559
+ }
1560
+ function checkProgram() {
1561
+ var _a, _b;
1562
+ program.reportDuplicateSymbols(globalNamespaceNode.symbol.exports);
1563
+ for (const file of program.sourceFiles.values()) {
1564
+ bindAllMembers(file);
1565
+ }
1566
+ for (const file of program.sourceFiles.values()) {
1567
+ for (const ns of file.namespaces) {
1568
+ const exports = (_b = (_a = mergedSymbols.get(ns.symbol)) === null || _a === void 0 ? void 0 : _a.exports) !== null && _b !== void 0 ? _b : ns.symbol.exports;
1569
+ program.reportDuplicateSymbols(exports);
1570
+ initializeTypeForNamespace(ns);
1571
+ }
1572
+ }
1573
+ for (const file of program.sourceFiles.values()) {
1574
+ applyAugmentDecoratorsInScope(file);
1575
+ }
1576
+ for (const file of program.sourceFiles.values()) {
1577
+ checkSourceFile(file);
1578
+ }
1579
+ internalDecoratorValidation();
1580
+ }
1581
+ /**
1582
+ * Post checking validation for internal decorators.
1583
+ */
1584
+ function internalDecoratorValidation() {
1585
+ validateInheritanceDiscriminatedUnions(program);
1586
+ }
1587
+ function applyAugmentDecoratorsInScope(scope) {
1588
+ applyAugmentDecorators(scope);
1589
+ if (scope.statements === undefined) {
1590
+ return;
1591
+ }
1592
+ if (isArray(scope.statements)) {
1593
+ for (const statement of scope.statements) {
1594
+ if (statement.kind === SyntaxKind.NamespaceStatement) {
1595
+ applyAugmentDecoratorsInScope(statement);
1596
+ }
1597
+ }
1598
+ }
1599
+ else {
1600
+ applyAugmentDecoratorsInScope(scope.statements);
1601
+ }
1602
+ }
1603
+ function checkSourceFile(file) {
1604
+ for (const statement of file.statements) {
1605
+ getTypeForNode(statement, undefined);
1606
+ }
1607
+ }
1608
+ function checkModel(node, mapper) {
1609
+ if (node.kind === SyntaxKind.ModelStatement) {
1610
+ return checkModelStatement(node, mapper);
1611
+ }
1612
+ else {
1613
+ return checkModelExpression(node, mapper);
1614
+ }
1615
+ }
1616
+ function checkModelStatement(node, mapper) {
1617
+ var _a;
1618
+ const links = getSymbolLinks(node.symbol);
1619
+ if (links.declaredType && mapper === undefined) {
1620
+ // we're not instantiating this model and we've already checked it
1621
+ return links.declaredType;
1622
+ }
1623
+ const decorators = [];
1624
+ const type = createType({
1625
+ kind: "Model",
1626
+ name: node.id.sv,
1627
+ node: node,
1628
+ properties: new Map(),
1629
+ namespace: getParentNamespaceType(node),
1630
+ decorators,
1631
+ derivedModels: [],
1632
+ });
1633
+ linkType(links, type, mapper);
1634
+ const isBase = checkModelIs(node, node.is, mapper);
1635
+ if (isBase) {
1636
+ checkDeprecated(isBase, node.is);
1637
+ // copy decorators
1638
+ decorators.push(...isBase.decorators);
1639
+ if (isBase.indexer) {
1640
+ type.indexer = isBase.indexer;
1641
+ }
1642
+ }
1643
+ decorators.push(...checkDecorators(type, node, mapper));
1644
+ if (isBase) {
1645
+ for (const prop of isBase.properties.values()) {
1646
+ const newProp = cloneType(prop, {
1647
+ sourceProperty: prop,
1648
+ model: type,
1649
+ });
1650
+ linkIndirectMember(node, newProp, mapper);
1651
+ type.properties.set(prop.name, newProp);
1652
+ }
1653
+ }
1654
+ if (isBase) {
1655
+ type.baseModel = isBase.baseModel;
1656
+ }
1657
+ else if (node.extends) {
1658
+ type.baseModel = checkClassHeritage(node, node.extends, mapper);
1659
+ if (type.baseModel) {
1660
+ checkDeprecated(type.baseModel, node.extends);
1661
+ }
1662
+ }
1663
+ if (type.baseModel) {
1664
+ type.baseModel.derivedModels.push(type);
1665
+ }
1666
+ // Hold on to the model type that's being defined so that it
1667
+ // can be referenced
1668
+ if (mapper === undefined) {
1669
+ (_a = type.namespace) === null || _a === void 0 ? void 0 : _a.models.set(type.name, type);
1670
+ }
1671
+ // Evaluate the properties after
1672
+ checkModelProperties(node, type.properties, type, mapper);
1673
+ for (const prop of walkPropertiesInherited(type)) {
1674
+ const table = getOrCreateAugmentedSymbolTable(node.symbol.members);
1675
+ const sym = table.get(prop.name);
1676
+ if (sym) {
1677
+ mutate(sym).type = prop;
1678
+ }
1679
+ }
1680
+ if (shouldCreateTypeForTemplate(node, mapper)) {
1681
+ finishType(type, mapper);
1682
+ }
1683
+ const indexer = getIndexer(program, type);
1684
+ if (type.name === "Array" && isInTypeSpecNamespace(type)) {
1685
+ stdTypes.Array = type;
1686
+ }
1687
+ else if (type.name === "Record" && isInTypeSpecNamespace(type)) {
1688
+ stdTypes.Record = type;
1689
+ }
1690
+ if (indexer) {
1691
+ type.indexer = indexer;
1692
+ }
1693
+ return type;
1694
+ }
1695
+ function shouldCreateTypeForTemplate(node, mapper) {
1696
+ // Node is not a template we should create the type.
1697
+ if (node.templateParameters.length === 0) {
1698
+ return true;
1699
+ }
1700
+ // There is no mapper so we shouldn't be instantiating the template.
1701
+ if (mapper === undefined) {
1702
+ return false;
1703
+ }
1704
+ // Some of the mapper args are still template parameter so we shouldn't create the type.
1705
+ return mapper.args.every((t) => t.kind !== "TemplateParameter");
1706
+ }
1707
+ function checkModelExpression(node, mapper) {
1708
+ const properties = new Map();
1709
+ const type = createType({
1710
+ kind: "Model",
1711
+ name: "",
1712
+ node: node,
1713
+ properties,
1714
+ indexer: undefined,
1715
+ namespace: getParentNamespaceType(node),
1716
+ decorators: [],
1717
+ derivedModels: [],
1718
+ });
1719
+ checkModelProperties(node, properties, type, mapper);
1720
+ return finishType(type);
1721
+ }
1722
+ function checkPropertyCompatibleWithIndexer(parentModel, property, diagnosticTarget) {
1723
+ if (parentModel.indexer === undefined) {
1724
+ return;
1725
+ }
1726
+ const [valid, diagnostics] = isTypeAssignableTo(property.type, parentModel.indexer.value, diagnosticTarget.kind === SyntaxKind.ModelSpreadProperty
1727
+ ? diagnosticTarget
1728
+ : diagnosticTarget.value);
1729
+ if (!valid)
1730
+ reportCheckerDiagnostics(diagnostics);
1731
+ }
1732
+ function checkModelProperties(node, properties, parentModel, mapper) {
1733
+ for (const prop of node.properties) {
1734
+ if ("id" in prop) {
1735
+ const newProp = checkModelProperty(prop, mapper);
1736
+ newProp.model = parentModel;
1737
+ checkPropertyCompatibleWithIndexer(parentModel, newProp, prop);
1738
+ defineProperty(properties, newProp);
1739
+ }
1740
+ else {
1741
+ // spread property
1742
+ const newProperties = checkSpreadProperty(prop.target, parentModel, mapper);
1743
+ for (const newProp of newProperties) {
1744
+ linkIndirectMember(node, newProp, mapper);
1745
+ checkPropertyCompatibleWithIndexer(parentModel, newProp, prop);
1746
+ defineProperty(properties, newProp, prop);
1747
+ }
1748
+ }
1749
+ }
1750
+ }
1751
+ function defineProperty(properties, newProp, diagnosticTarget) {
1752
+ if (properties.has(newProp.name)) {
1753
+ reportCheckerDiagnostic(createDiagnostic({
1754
+ code: "duplicate-property",
1755
+ format: { propName: newProp.name },
1756
+ target: diagnosticTarget !== null && diagnosticTarget !== void 0 ? diagnosticTarget : newProp,
1757
+ }));
1758
+ return;
1759
+ }
1760
+ const overriddenProp = getOverriddenProperty(newProp);
1761
+ if (overriddenProp) {
1762
+ const [isAssignable, _] = isTypeAssignableTo(newProp.type, overriddenProp.type, newProp);
1763
+ const parentScalar = overriddenProp.type.kind === "Scalar";
1764
+ const parentType = getTypeName(overriddenProp.type);
1765
+ const newPropType = getTypeName(newProp.type);
1766
+ if (!parentScalar) {
1767
+ reportCheckerDiagnostic(createDiagnostic({
1768
+ code: "override-property-intrinsic",
1769
+ format: { propName: newProp.name, propType: newPropType, parentType: parentType },
1770
+ target: diagnosticTarget !== null && diagnosticTarget !== void 0 ? diagnosticTarget : newProp,
1771
+ }));
1772
+ return;
1773
+ }
1774
+ if (!isAssignable) {
1775
+ reportCheckerDiagnostic(createDiagnostic({
1776
+ code: "override-property-mismatch",
1777
+ format: { propName: newProp.name, propType: newPropType, parentType: parentType },
1778
+ target: diagnosticTarget !== null && diagnosticTarget !== void 0 ? diagnosticTarget : newProp,
1779
+ }));
1780
+ return;
1781
+ }
1782
+ }
1783
+ properties.set(newProp.name, newProp);
1784
+ }
1785
+ function bindAllMembers(node) {
1786
+ const bound = new Set();
1787
+ if (node.symbol) {
1788
+ bindMembers(node, node.symbol);
1789
+ }
1790
+ visitChildren(node, (child) => {
1791
+ bindAllMembers(child);
1792
+ });
1793
+ function bindMembers(node, containerSym) {
1794
+ if (bound.has(containerSym)) {
1795
+ return;
1796
+ }
1797
+ bound.add(containerSym);
1798
+ let containerMembers;
1799
+ switch (node.kind) {
1800
+ case SyntaxKind.ModelStatement:
1801
+ if (node.extends && node.extends.kind === SyntaxKind.TypeReference) {
1802
+ resolveAndCopyMembers(node.extends);
1803
+ }
1804
+ if (node.is && node.is.kind === SyntaxKind.TypeReference) {
1805
+ resolveAndCopyMembers(node.is);
1806
+ }
1807
+ for (const prop of node.properties) {
1808
+ if (prop.kind === SyntaxKind.ModelSpreadProperty) {
1809
+ resolveAndCopyMembers(prop.target);
1810
+ }
1811
+ else {
1812
+ const name = prop.id.sv;
1813
+ bindMember(name, prop, 4 /* SymbolFlags.ModelProperty */);
1814
+ }
1815
+ }
1816
+ break;
1817
+ case SyntaxKind.EnumStatement:
1818
+ for (const member of node.members.values()) {
1819
+ if (member.kind === SyntaxKind.EnumSpreadMember) {
1820
+ resolveAndCopyMembers(member.target);
1821
+ }
1822
+ else {
1823
+ const name = member.id.sv;
1824
+ bindMember(name, member, 64 /* SymbolFlags.EnumMember */);
1825
+ }
1826
+ }
1827
+ break;
1828
+ case SyntaxKind.InterfaceStatement:
1829
+ for (const member of node.operations.values()) {
1830
+ bindMember(member.id.sv, member, 256 /* SymbolFlags.InterfaceMember */ | 16 /* SymbolFlags.Operation */);
1831
+ }
1832
+ if (node.extends) {
1833
+ for (const ext of node.extends) {
1834
+ resolveAndCopyMembers(ext);
1835
+ }
1836
+ }
1837
+ break;
1838
+ case SyntaxKind.UnionStatement:
1839
+ for (const variant of node.options.values()) {
1840
+ const name = variant.id.sv;
1841
+ bindMember(name, variant, 1024 /* SymbolFlags.UnionVariant */);
1842
+ }
1843
+ break;
1844
+ }
1845
+ function resolveAndCopyMembers(node) {
1846
+ let ref = resolveTypeReferenceSym(node, undefined);
1847
+ if (ref && ref.flags & 2048 /* SymbolFlags.Alias */) {
1848
+ ref = resolveAliasedSymbol(ref);
1849
+ }
1850
+ if (ref && ref.members) {
1851
+ bindMembers(ref.declarations[0], ref);
1852
+ copyMembers(ref.members);
1853
+ }
1854
+ }
1855
+ function resolveAliasedSymbol(ref) {
1856
+ const node = ref.declarations[0];
1857
+ switch (node.value.kind) {
1858
+ case SyntaxKind.MemberExpression:
1859
+ case SyntaxKind.TypeReference:
1860
+ case SyntaxKind.Identifier:
1861
+ const resolvedSym = resolveTypeReferenceSym(node.value, undefined);
1862
+ if (resolvedSym && resolvedSym.flags & 2048 /* SymbolFlags.Alias */) {
1863
+ return resolveAliasedSymbol(resolvedSym);
1864
+ }
1865
+ return resolvedSym;
1866
+ default:
1867
+ return undefined;
1868
+ }
1869
+ }
1870
+ function copyMembers(table) {
1871
+ var _a;
1872
+ const members = (_a = augmentedSymbolTables.get(table)) !== null && _a !== void 0 ? _a : table;
1873
+ for (const member of members.values()) {
1874
+ bindMember(member.name, member.declarations[0], member.flags);
1875
+ }
1876
+ }
1877
+ function bindMember(name, node, kind) {
1878
+ const sym = createSymbol(node, name, kind, containerSym);
1879
+ compilerAssert(containerSym.members, "containerSym.members is undefined");
1880
+ containerMembers !== null && containerMembers !== void 0 ? containerMembers : (containerMembers = getOrCreateAugmentedSymbolTable(containerSym.members));
1881
+ containerMembers.set(name, sym);
1882
+ }
1883
+ }
1884
+ }
1885
+ /**
1886
+ * Initializes a late bound symbol for the type. This is generally necessary when attempting to
1887
+ * access a symbol for a type that is created during the check phase.
1888
+ */
1889
+ function lateBindMemberContainer(type) {
1890
+ if (type.symbol)
1891
+ return;
1892
+ switch (type.kind) {
1893
+ case "Model":
1894
+ type.symbol = createSymbol(type.node, type.name, 2 /* SymbolFlags.Model */ | 16777216 /* SymbolFlags.LateBound */);
1895
+ mutate(type.symbol).type = type;
1896
+ break;
1897
+ case "Interface":
1898
+ type.symbol = createSymbol(type.node, type.name, 128 /* SymbolFlags.Interface */ | 16777216 /* SymbolFlags.LateBound */);
1899
+ mutate(type.symbol).type = type;
1900
+ break;
1901
+ case "Union":
1902
+ if (!type.name)
1903
+ return; // don't make a symbol for anonymous unions
1904
+ type.symbol = createSymbol(type.node, type.name, 512 /* SymbolFlags.Union */ | 16777216 /* SymbolFlags.LateBound */);
1905
+ mutate(type.symbol).type = type;
1906
+ break;
1907
+ }
1908
+ }
1909
+ function lateBindMembers(type, containerSym) {
1910
+ let containerMembers;
1911
+ switch (type.kind) {
1912
+ case "Model":
1913
+ for (const prop of walkPropertiesInherited(type)) {
1914
+ lateBindMember(prop, 4 /* SymbolFlags.ModelProperty */);
1915
+ }
1916
+ break;
1917
+ case "Enum":
1918
+ for (const member of type.members.values()) {
1919
+ lateBindMember(member, 64 /* SymbolFlags.EnumMember */);
1920
+ }
1921
+ break;
1922
+ case "Interface":
1923
+ for (const member of type.operations.values()) {
1924
+ lateBindMember(member, 256 /* SymbolFlags.InterfaceMember */ | 16 /* SymbolFlags.Operation */);
1925
+ }
1926
+ break;
1927
+ case "Union":
1928
+ for (const variant of type.variants.values()) {
1929
+ lateBindMember(variant, 1024 /* SymbolFlags.UnionVariant */);
1930
+ }
1931
+ break;
1932
+ }
1933
+ function lateBindMember(member, kind) {
1934
+ if (!member.node || typeof member.name !== "string") {
1935
+ // don't bind anything for union expressions
1936
+ return;
1937
+ }
1938
+ const sym = createSymbol(member.node, member.name, kind | 16777216 /* SymbolFlags.LateBound */, containerSym);
1939
+ mutate(sym).type = member;
1940
+ compilerAssert(containerSym.members, "containerSym.members is undefined");
1941
+ containerMembers !== null && containerMembers !== void 0 ? containerMembers : (containerMembers = getOrCreateAugmentedSymbolTable(containerSym.members));
1942
+ containerMembers.set(member.name, sym);
1943
+ }
1944
+ }
1945
+ function checkClassHeritage(model, heritageRef, mapper) {
1946
+ if (heritageRef.kind === SyntaxKind.ModelExpression) {
1947
+ reportCheckerDiagnostic(createDiagnostic({
1948
+ code: "extend-model",
1949
+ messageId: "modelExpression",
1950
+ target: heritageRef,
1951
+ }));
1952
+ return undefined;
1953
+ }
1954
+ if (heritageRef.kind !== SyntaxKind.TypeReference) {
1955
+ reportCheckerDiagnostic(createDiagnostic({
1956
+ code: "extend-model",
1957
+ target: heritageRef,
1958
+ }));
1959
+ return undefined;
1960
+ }
1961
+ const modelSymId = getNodeSymId(model);
1962
+ pendingResolutions.add(modelSymId);
1963
+ const target = resolveTypeReferenceSym(heritageRef, mapper);
1964
+ if (target === undefined) {
1965
+ return undefined;
1966
+ }
1967
+ if (pendingResolutions.has(getNodeSymId(target.declarations[0]))) {
1968
+ if (mapper === undefined) {
1969
+ reportCheckerDiagnostic(createDiagnostic({
1970
+ code: "circular-base-type",
1971
+ format: { typeName: target.declarations[0].id.sv },
1972
+ target: target,
1973
+ }));
1974
+ }
1975
+ return undefined;
1976
+ }
1977
+ const heritageType = checkTypeReferenceSymbol(target, heritageRef, mapper);
1978
+ pendingResolutions.delete(modelSymId);
1979
+ if (isErrorType(heritageType)) {
1980
+ compilerAssert(program.hasError(), "Should already have reported an error.", heritageRef);
1981
+ return undefined;
1982
+ }
1983
+ if (heritageType.kind !== "Model") {
1984
+ reportCheckerDiagnostic(createDiagnostic({ code: "extend-model", target: heritageRef }));
1985
+ return undefined;
1986
+ }
1987
+ if (heritageType.name === "") {
1988
+ reportCheckerDiagnostic(createDiagnostic({
1989
+ code: "extend-model",
1990
+ messageId: "modelExpression",
1991
+ target: heritageRef,
1992
+ }));
1993
+ }
1994
+ return heritageType;
1995
+ }
1996
+ function checkModelIs(model, isExpr, mapper) {
1997
+ if (!isExpr)
1998
+ return undefined;
1999
+ const modelSymId = getNodeSymId(model);
2000
+ pendingResolutions.add(modelSymId);
2001
+ let isType;
2002
+ if (isExpr.kind === SyntaxKind.ModelExpression) {
2003
+ reportCheckerDiagnostic(createDiagnostic({
2004
+ code: "is-model",
2005
+ messageId: "modelExpression",
2006
+ target: isExpr,
2007
+ }));
2008
+ return undefined;
2009
+ }
2010
+ else if (isExpr.kind === SyntaxKind.ArrayExpression) {
2011
+ isType = checkArrayExpression(isExpr, mapper);
2012
+ }
2013
+ else if (isExpr.kind === SyntaxKind.TypeReference) {
2014
+ const target = resolveTypeReferenceSym(isExpr, mapper);
2015
+ if (target === undefined) {
2016
+ return undefined;
2017
+ }
2018
+ if (pendingResolutions.has(getNodeSymId(target.declarations[0]))) {
2019
+ if (mapper === undefined) {
2020
+ reportCheckerDiagnostic(createDiagnostic({
2021
+ code: "circular-base-type",
2022
+ format: { typeName: target.declarations[0].id.sv },
2023
+ target: target,
2024
+ }));
2025
+ }
2026
+ return undefined;
2027
+ }
2028
+ isType = checkTypeReferenceSymbol(target, isExpr, mapper);
2029
+ }
2030
+ else {
2031
+ reportCheckerDiagnostic(createDiagnostic({ code: "is-model", target: isExpr }));
2032
+ return undefined;
2033
+ }
2034
+ pendingResolutions.delete(modelSymId);
2035
+ if (isType.kind !== "Model") {
2036
+ reportCheckerDiagnostic(createDiagnostic({ code: "is-model", target: isExpr }));
2037
+ return;
2038
+ }
2039
+ if (isType.name === "") {
2040
+ reportCheckerDiagnostic(createDiagnostic({ code: "is-model", messageId: "modelExpression", target: isExpr }));
2041
+ return undefined;
2042
+ }
2043
+ return isType;
2044
+ }
2045
+ function checkSpreadProperty(targetNode, parentModel, mapper) {
2046
+ const targetType = getTypeForNode(targetNode, mapper);
2047
+ if (targetType.kind === "TemplateParameter" || isErrorType(targetType)) {
2048
+ return [];
2049
+ }
2050
+ if (targetType.kind !== "Model") {
2051
+ reportCheckerDiagnostic(createDiagnostic({ code: "spread-model", target: targetNode }));
2052
+ return [];
2053
+ }
2054
+ const props = [];
2055
+ // copy each property
2056
+ for (const prop of walkPropertiesInherited(targetType)) {
2057
+ props.push(cloneType(prop, {
2058
+ sourceProperty: prop,
2059
+ model: parentModel,
2060
+ }));
2061
+ }
2062
+ return props;
2063
+ }
2064
+ /**
2065
+ * Link an indirect model property(included via spread or model is) to its model member symbols.
2066
+ * @param containerNode Model Node
2067
+ * @param member New Property
2068
+ * @param mapper Type Mapper.
2069
+ */
2070
+ function linkIndirectMember(containerNode, member, mapper) {
2071
+ if (mapper !== undefined) {
2072
+ return;
2073
+ }
2074
+ compilerAssert(typeof member.name === "string", "Cannot link unmapped unions");
2075
+ if (containerNode.symbol === undefined) {
2076
+ return;
2077
+ }
2078
+ compilerAssert(containerNode.symbol.members, `Expected container node ${SyntaxKind[containerNode.kind]} to have members.`);
2079
+ const memberSym = getOrCreateAugmentedSymbolTable(containerNode.symbol.members).get(member.name);
2080
+ if (memberSym) {
2081
+ const links = getSymbolLinks(memberSym);
2082
+ linkMemberType(links, member, mapper);
2083
+ }
2084
+ }
2085
+ function checkModelProperty(prop, mapper) {
2086
+ const links = getSymbolLinksForMember(prop);
2087
+ if (links && links.declaredType && mapper === undefined) {
2088
+ return links.declaredType;
2089
+ }
2090
+ const name = prop.id.sv;
2091
+ const valueType = getTypeForNode(prop.value, mapper);
2092
+ const defaultValue = prop.default && checkDefault(prop.default, valueType);
2093
+ const type = createType({
2094
+ kind: "ModelProperty",
2095
+ name,
2096
+ node: prop,
2097
+ optional: prop.optional,
2098
+ type: valueType,
2099
+ decorators: [],
2100
+ default: defaultValue,
2101
+ });
2102
+ if (links) {
2103
+ linkType(links, type, mapper);
2104
+ }
2105
+ type.decorators = checkDecorators(type, prop, mapper);
2106
+ const parentTemplate = getParentTemplateNode(prop);
2107
+ if (!parentTemplate || shouldCreateTypeForTemplate(parentTemplate, mapper)) {
2108
+ finishType(type, mapper);
2109
+ }
2110
+ return type;
2111
+ }
2112
+ function isValueType(type) {
2113
+ const valueTypes = new Set(["String", "Number", "Boolean", "EnumMember", "Tuple"]);
2114
+ return valueTypes.has(type.kind);
2115
+ }
2116
+ function checkDefault(defaultNode, type) {
2117
+ const defaultType = getTypeForNode(defaultNode, undefined);
2118
+ if (isErrorType(type)) {
2119
+ return errorType;
2120
+ }
2121
+ if (!isValueType(defaultType)) {
2122
+ reportCheckerDiagnostic(createDiagnostic({
2123
+ code: "unsupported-default",
2124
+ format: { type: type.kind },
2125
+ target: defaultType,
2126
+ }));
2127
+ return errorType;
2128
+ }
2129
+ const [related, diagnostics] = isTypeAssignableTo(defaultType, type, defaultNode);
2130
+ if (!related) {
2131
+ reportCheckerDiagnostics(diagnostics);
2132
+ return errorType;
2133
+ }
2134
+ else {
2135
+ return defaultType;
2136
+ }
2137
+ }
2138
+ function checkDecorator(targetType, decNode, mapper) {
2139
+ var _a;
2140
+ const sym = resolveTypeReferenceSym(decNode.target, undefined, true);
2141
+ if (!sym) {
2142
+ reportCheckerDiagnostic(createDiagnostic({
2143
+ code: "unknown-decorator",
2144
+ target: decNode,
2145
+ }));
2146
+ return undefined;
2147
+ }
2148
+ if (!(sym.flags & 16384 /* SymbolFlags.Decorator */)) {
2149
+ reportCheckerDiagnostic(createDiagnostic({
2150
+ code: "invalid-decorator",
2151
+ format: { id: sym.name },
2152
+ target: decNode,
2153
+ }));
2154
+ return undefined;
2155
+ }
2156
+ const symbolLinks = getSymbolLinks(sym);
2157
+ const args = checkDecoratorArguments(decNode, mapper);
2158
+ let hasError = false;
2159
+ if (symbolLinks.declaredType === undefined) {
2160
+ const decoratorDeclNode = sym.declarations.find((x) => x.kind === SyntaxKind.DecoratorDeclarationStatement);
2161
+ if (decoratorDeclNode) {
2162
+ checkDecoratorDeclaration(decoratorDeclNode, mapper);
2163
+ }
2164
+ }
2165
+ if (symbolLinks.declaredType) {
2166
+ compilerAssert(symbolLinks.declaredType.kind === "Decorator", "Expected to find a decorator type.");
2167
+ // Means we have a decorator declaration.
2168
+ hasError = checkDecoratorUsage(targetType, symbolLinks.declaredType, args, decNode);
2169
+ }
2170
+ if (hasError) {
2171
+ return undefined;
2172
+ }
2173
+ return {
2174
+ decorator: (_a = sym.value) !== null && _a !== void 0 ? _a : ((...args) => { }),
2175
+ node: decNode,
2176
+ args,
2177
+ };
2178
+ }
2179
+ function checkDecoratorUsage(targetType, declaration, args, decoratorNode) {
2180
+ var _a, _b;
2181
+ let hasError = false;
2182
+ const [targetValid] = isTypeAssignableTo(targetType, declaration.target.type, decoratorNode);
2183
+ if (!targetValid) {
2184
+ hasError = true;
2185
+ reportCheckerDiagnostic(createDiagnostic({
2186
+ code: "decorator-wrong-target",
2187
+ messageId: "withExpected",
2188
+ format: {
2189
+ decorator: declaration.name,
2190
+ to: getTypeName(targetType),
2191
+ expected: getTypeName(declaration.target.type),
2192
+ },
2193
+ target: decoratorNode,
2194
+ }));
2195
+ }
2196
+ const minArgs = declaration.parameters.filter((x) => !x.optional && !x.rest).length;
2197
+ const maxArgs = ((_a = declaration.parameters[declaration.parameters.length - 1]) === null || _a === void 0 ? void 0 : _a.rest)
2198
+ ? undefined
2199
+ : declaration.parameters.length;
2200
+ if (args.length < minArgs || (maxArgs !== undefined && args.length > maxArgs)) {
2201
+ if (maxArgs === undefined) {
2202
+ reportCheckerDiagnostic(createDiagnostic({
2203
+ code: "invalid-argument-count",
2204
+ messageId: "atLeast",
2205
+ format: { actual: args.length.toString(), expected: minArgs.toString() },
2206
+ target: decoratorNode,
2207
+ }));
2208
+ }
2209
+ else {
2210
+ const expected = minArgs === maxArgs ? minArgs.toString() : `${minArgs}-${maxArgs}`;
2211
+ reportCheckerDiagnostic(createDiagnostic({
2212
+ code: "invalid-argument-count",
2213
+ format: { actual: args.length.toString(), expected },
2214
+ target: decoratorNode,
2215
+ }));
2216
+ }
2217
+ }
2218
+ for (const [index, parameter] of declaration.parameters.entries()) {
2219
+ if (parameter.rest) {
2220
+ const restType = parameter.type.kind === "Model" ? (_b = parameter.type.indexer) === null || _b === void 0 ? void 0 : _b.value : undefined;
2221
+ if (restType) {
2222
+ for (let i = index; i < args.length; i++) {
2223
+ const arg = args[i];
2224
+ if (arg && arg.value) {
2225
+ if (!checkArgumentAssignable(arg.value, restType, arg.node)) {
2226
+ hasError = true;
2227
+ }
2228
+ }
2229
+ }
2230
+ }
2231
+ break;
2232
+ }
2233
+ const arg = args[index];
2234
+ if (arg && arg.value) {
2235
+ if (!checkArgumentAssignable(arg.value, parameter.type, arg.node)) {
2236
+ hasError = true;
2237
+ }
2238
+ }
2239
+ }
2240
+ return hasError;
2241
+ }
2242
+ function checkArgumentAssignable(argumentType, parameterType, diagnosticTarget) {
2243
+ const [valid] = isTypeAssignableTo(argumentType, parameterType, diagnosticTarget);
2244
+ if (!valid) {
2245
+ reportCheckerDiagnostic(createDiagnostic({
2246
+ code: "invalid-argument",
2247
+ format: {
2248
+ value: getTypeName(argumentType),
2249
+ expected: getTypeName(parameterType),
2250
+ },
2251
+ target: diagnosticTarget,
2252
+ }));
2253
+ }
2254
+ return valid;
2255
+ }
2256
+ function checkDecorators(targetType, node, mapper) {
2257
+ var _a, _b;
2258
+ const sym = isMemberNode(node) ? (_a = getSymbolForMember(node)) !== null && _a !== void 0 ? _a : node.symbol : node.symbol;
2259
+ const decorators = [];
2260
+ const decoratorNodes = [
2261
+ ...((_b = (sym && augmentDecoratorsForSym.get(sym))) !== null && _b !== void 0 ? _b : []),
2262
+ ...node.decorators,
2263
+ ];
2264
+ for (const decNode of decoratorNodes) {
2265
+ const decorator = checkDecorator(targetType, decNode, mapper);
2266
+ if (decorator) {
2267
+ decorators.unshift(decorator);
2268
+ }
2269
+ }
2270
+ return decorators;
2271
+ }
2272
+ function checkDecoratorArguments(decorator, mapper) {
2273
+ return decorator.arguments.map((argNode) => {
2274
+ const type = getTypeForNode(argNode, mapper);
2275
+ return {
2276
+ value: type,
2277
+ node: argNode,
2278
+ };
2279
+ });
2280
+ }
2281
+ function checkScalar(node, mapper) {
2282
+ var _a;
2283
+ const links = getSymbolLinks(node.symbol);
2284
+ if (links.declaredType && mapper === undefined) {
2285
+ // we're not instantiating this model and we've already checked it
2286
+ return links.declaredType;
2287
+ }
2288
+ const decorators = [];
2289
+ const type = createType({
2290
+ kind: "Scalar",
2291
+ name: node.id.sv,
2292
+ node: node,
2293
+ namespace: getParentNamespaceType(node),
2294
+ decorators,
2295
+ derivedScalars: [],
2296
+ });
2297
+ linkType(links, type, mapper);
2298
+ if (node.extends) {
2299
+ type.baseScalar = checkScalarExtends(node, node.extends, mapper);
2300
+ if (type.baseScalar) {
2301
+ checkDeprecated(type.baseScalar, node.extends);
2302
+ type.baseScalar.derivedScalars.push(type);
2303
+ }
2304
+ }
2305
+ decorators.push(...checkDecorators(type, node, mapper));
2306
+ if (mapper === undefined) {
2307
+ (_a = type.namespace) === null || _a === void 0 ? void 0 : _a.scalars.set(type.name, type);
2308
+ }
2309
+ if (shouldCreateTypeForTemplate(node, mapper)) {
2310
+ finishType(type, mapper);
2311
+ }
2312
+ if (isInTypeSpecNamespace(type)) {
2313
+ stdTypes[type.name] = type;
2314
+ }
2315
+ return type;
2316
+ }
2317
+ function checkScalarExtends(scalar, extendsRef, mapper) {
2318
+ const symId = getNodeSymId(scalar);
2319
+ pendingResolutions.add(symId);
2320
+ const target = resolveTypeReferenceSym(extendsRef, mapper);
2321
+ if (target === undefined) {
2322
+ return undefined;
2323
+ }
2324
+ if (pendingResolutions.has(getNodeSymId(target.declarations[0]))) {
2325
+ if (mapper === undefined) {
2326
+ reportCheckerDiagnostic(createDiagnostic({
2327
+ code: "circular-base-type",
2328
+ format: { typeName: target.declarations[0].id.sv },
2329
+ target: target,
2330
+ }));
2331
+ }
2332
+ return undefined;
2333
+ }
2334
+ const extendsType = checkTypeReferenceSymbol(target, extendsRef, mapper);
2335
+ pendingResolutions.delete(symId);
2336
+ if (isErrorType(extendsType)) {
2337
+ compilerAssert(program.hasError(), "Should already have reported an error.", extendsRef);
2338
+ return undefined;
2339
+ }
2340
+ if (extendsType.kind !== "Scalar") {
2341
+ reportCheckerDiagnostic(createDiagnostic({ code: "extend-model", target: extendsRef }));
2342
+ return undefined;
2343
+ }
2344
+ return extendsType;
2345
+ }
2346
+ function checkAlias(node, mapper) {
2347
+ const links = getSymbolLinks(node.symbol);
2348
+ if (links.declaredType && mapper === undefined) {
2349
+ return links.declaredType;
2350
+ }
2351
+ const aliasSymId = getNodeSymId(node);
2352
+ if (pendingResolutions.has(aliasSymId)) {
2353
+ if (mapper === undefined) {
2354
+ reportCheckerDiagnostic(createDiagnostic({
2355
+ code: "circular-alias-type",
2356
+ format: { typeName: node.id.sv },
2357
+ target: node,
2358
+ }));
2359
+ }
2360
+ links.declaredType = errorType;
2361
+ return errorType;
2362
+ }
2363
+ pendingResolutions.add(aliasSymId);
2364
+ const type = getTypeForNode(node.value, mapper);
2365
+ linkType(links, type, mapper);
2366
+ pendingResolutions.delete(aliasSymId);
2367
+ return type;
2368
+ }
2369
+ function checkEnum(node, mapper) {
2370
+ var _a;
2371
+ const links = getSymbolLinks(node.symbol);
2372
+ if (!links.type) {
2373
+ const enumType = (links.type = createType({
2374
+ kind: "Enum",
2375
+ name: node.id.sv,
2376
+ node,
2377
+ members: new Map(),
2378
+ decorators: [],
2379
+ }));
2380
+ const memberNames = new Set();
2381
+ for (const member of node.members) {
2382
+ if (member.kind === SyntaxKind.EnumMember) {
2383
+ const memberType = checkEnumMember(member, mapper, enumType);
2384
+ if (memberNames.has(memberType.name)) {
2385
+ reportCheckerDiagnostic(createDiagnostic({
2386
+ code: "enum-member-duplicate",
2387
+ format: { name: memberType.name },
2388
+ target: node,
2389
+ }));
2390
+ continue;
2391
+ }
2392
+ memberNames.add(memberType.name);
2393
+ enumType.members.set(memberType.name, memberType);
2394
+ }
2395
+ else {
2396
+ const members = checkEnumSpreadMember(enumType, member.target, mapper, memberNames);
2397
+ for (const memberType of members) {
2398
+ linkIndirectMember(node, memberType, mapper);
2399
+ enumType.members.set(memberType.name, memberType);
2400
+ }
2401
+ }
2402
+ }
2403
+ const namespace = getParentNamespaceType(node);
2404
+ enumType.namespace = namespace;
2405
+ (_a = enumType.namespace) === null || _a === void 0 ? void 0 : _a.enums.set(enumType.name, enumType);
2406
+ enumType.decorators = checkDecorators(enumType, node, mapper);
2407
+ finishType(enumType, mapper);
2408
+ }
2409
+ return links.type;
2410
+ }
2411
+ function checkInterface(node, mapper) {
2412
+ var _a;
2413
+ const links = getSymbolLinks(node.symbol);
2414
+ if (links.declaredType && mapper === undefined) {
2415
+ // we're not instantiating this interface and we've already checked it
2416
+ return links.declaredType;
2417
+ }
2418
+ const interfaceType = createType({
2419
+ kind: "Interface",
2420
+ decorators: [],
2421
+ node,
2422
+ namespace: getParentNamespaceType(node),
2423
+ operations: new Map(),
2424
+ name: node.id.sv,
2425
+ });
2426
+ interfaceType.decorators = checkDecorators(interfaceType, node, mapper);
2427
+ linkType(links, interfaceType, mapper);
2428
+ const ownMembers = checkInterfaceMembers(node, mapper, interfaceType);
2429
+ for (const extendsNode of node.extends) {
2430
+ const extendsType = getTypeForNode(extendsNode, mapper);
2431
+ if (extendsType.kind !== "Interface") {
2432
+ reportCheckerDiagnostic(createDiagnostic({ code: "extends-interface", target: extendsNode }));
2433
+ continue;
2434
+ }
2435
+ for (const member of extendsType.operations.values()) {
2436
+ if (interfaceType.operations.has(member.name)) {
2437
+ reportCheckerDiagnostic(createDiagnostic({
2438
+ code: "extends-interface-duplicate",
2439
+ format: { name: member.name },
2440
+ target: extendsNode,
2441
+ }));
2442
+ }
2443
+ const newMember = cloneType(member, { interface: interfaceType });
2444
+ // Don't link it it is overritten
2445
+ if (!ownMembers.has(member.name)) {
2446
+ linkIndirectMember(node, newMember, mapper);
2447
+ }
2448
+ interfaceType.operations.set(newMember.name, newMember);
2449
+ }
2450
+ }
2451
+ for (const [key, value] of ownMembers) {
2452
+ interfaceType.operations.set(key, value);
2453
+ }
2454
+ if (shouldCreateTypeForTemplate(node, mapper)) {
2455
+ finishType(interfaceType, mapper);
2456
+ }
2457
+ if (mapper === undefined) {
2458
+ (_a = interfaceType.namespace) === null || _a === void 0 ? void 0 : _a.interfaces.set(interfaceType.name, interfaceType);
2459
+ }
2460
+ return interfaceType;
2461
+ }
2462
+ function checkInterfaceMembers(node, mapper, interfaceType) {
2463
+ const ownMembers = new Map();
2464
+ for (const opNode of node.operations) {
2465
+ const opType = checkOperation(opNode, mapper, interfaceType);
2466
+ if (opType.kind === "Operation") {
2467
+ if (ownMembers.has(opType.name)) {
2468
+ reportCheckerDiagnostic(createDiagnostic({
2469
+ code: "interface-duplicate",
2470
+ format: { name: opType.name },
2471
+ target: opNode,
2472
+ }));
2473
+ continue;
2474
+ }
2475
+ ownMembers.set(opType.name, opType);
2476
+ }
2477
+ }
2478
+ return ownMembers;
2479
+ }
2480
+ function checkUnion(node, mapper) {
2481
+ var _a;
2482
+ const links = getSymbolLinks(node.symbol);
2483
+ if (links.declaredType && mapper === undefined) {
2484
+ // we're not instantiating this union and we've already checked it
2485
+ return links.declaredType;
2486
+ }
2487
+ const variants = new Map();
2488
+ const unionType = createType({
2489
+ kind: "Union",
2490
+ decorators: [],
2491
+ node,
2492
+ namespace: getParentNamespaceType(node),
2493
+ name: node.id.sv,
2494
+ variants,
2495
+ get options() {
2496
+ return Array.from(this.variants.values()).map((v) => v.type);
2497
+ },
2498
+ expression: false,
2499
+ });
2500
+ unionType.decorators = checkDecorators(unionType, node, mapper);
2501
+ checkUnionVariants(unionType, node, variants, mapper);
2502
+ if (shouldCreateTypeForTemplate(node, mapper)) {
2503
+ finishType(unionType, mapper);
2504
+ }
2505
+ linkType(links, unionType, mapper);
2506
+ if (mapper === undefined) {
2507
+ (_a = unionType.namespace) === null || _a === void 0 ? void 0 : _a.unions.set(unionType.name, unionType);
2508
+ }
2509
+ return unionType;
2510
+ }
2511
+ function checkUnionVariants(parentUnion, node, variants, mapper) {
2512
+ for (const variantNode of node.options) {
2513
+ const variantType = checkUnionVariant(variantNode, mapper);
2514
+ variantType.union = parentUnion;
2515
+ if (variants.has(variantType.name)) {
2516
+ reportCheckerDiagnostic(createDiagnostic({
2517
+ code: "union-duplicate",
2518
+ format: { name: variantType.name.toString() },
2519
+ target: variantNode,
2520
+ }));
2521
+ continue;
2522
+ }
2523
+ variants.set(variantType.name, variantType);
2524
+ }
2525
+ }
2526
+ function checkUnionVariant(variantNode, mapper) {
2527
+ const links = getSymbolLinksForMember(variantNode);
2528
+ if (links && links.declaredType && mapper === undefined) {
2529
+ // we're not instantiating this union variant and we've already checked it
2530
+ return links.declaredType;
2531
+ }
2532
+ const name = variantNode.id.sv;
2533
+ const type = getTypeForNode(variantNode.value, mapper);
2534
+ const variantType = createType({
2535
+ kind: "UnionVariant",
2536
+ name,
2537
+ node: variantNode,
2538
+ decorators: [],
2539
+ type,
2540
+ union: undefined,
2541
+ });
2542
+ variantType.decorators = checkDecorators(variantType, variantNode, mapper);
2543
+ if (shouldCreateTypeForTemplate(variantNode.parent, mapper)) {
2544
+ finishType(variantType, mapper);
2545
+ }
2546
+ if (links) {
2547
+ linkType(links, variantType, mapper);
2548
+ }
2549
+ return variantType;
2550
+ }
2551
+ function isMemberNode(node) {
2552
+ return (node.kind === SyntaxKind.ModelProperty ||
2553
+ node.kind === SyntaxKind.EnumMember ||
2554
+ node.kind === SyntaxKind.OperationStatement ||
2555
+ node.kind === SyntaxKind.UnionVariant);
2556
+ }
2557
+ function getSymbolForMember(node) {
2558
+ var _a;
2559
+ const name = node.id.sv;
2560
+ const parentSym = (_a = node.parent) === null || _a === void 0 ? void 0 : _a.symbol;
2561
+ return parentSym ? getOrCreateAugmentedSymbolTable(parentSym.members).get(name) : undefined;
2562
+ }
2563
+ function getSymbolLinksForMember(node) {
2564
+ const sym = getSymbolForMember(node);
2565
+ return sym ? (sym.declarations[0] === node ? getSymbolLinks(sym) : undefined) : undefined;
2566
+ }
2567
+ function checkEnumMember(node, mapper, parentEnum) {
2568
+ const name = node.id.sv;
2569
+ const links = getSymbolLinksForMember(node);
2570
+ if (links === null || links === void 0 ? void 0 : links.type) {
2571
+ return links.type;
2572
+ }
2573
+ compilerAssert(parentEnum, "Enum member should already have been checked.");
2574
+ const value = node.value ? node.value.value : undefined;
2575
+ const member = createType({
2576
+ kind: "EnumMember",
2577
+ enum: parentEnum,
2578
+ name,
2579
+ node,
2580
+ value,
2581
+ decorators: [],
2582
+ });
2583
+ if (links) {
2584
+ links.type = member;
2585
+ }
2586
+ member.decorators = checkDecorators(member, node, mapper);
2587
+ return finishType(member);
2588
+ }
2589
+ function checkEnumSpreadMember(parentEnum, targetNode, mapper, existingMemberNames) {
2590
+ const members = [];
2591
+ const targetType = getTypeForNode(targetNode, mapper);
2592
+ if (!isErrorType(targetType)) {
2593
+ if (targetType.kind !== "Enum") {
2594
+ reportCheckerDiagnostic(createDiagnostic({ code: "spread-enum", target: targetNode }));
2595
+ return members;
2596
+ }
2597
+ for (const member of targetType.members.values()) {
2598
+ if (existingMemberNames.has(member.name)) {
2599
+ reportCheckerDiagnostic(createDiagnostic({
2600
+ code: "enum-member-duplicate",
2601
+ format: { name: member.name },
2602
+ target: targetNode,
2603
+ }));
2604
+ }
2605
+ else {
2606
+ existingMemberNames.add(member.name);
2607
+ const clonedMember = cloneType(member, {
2608
+ enum: parentEnum,
2609
+ sourceMember: member,
2610
+ });
2611
+ if (clonedMember) {
2612
+ members.push(clonedMember);
2613
+ }
2614
+ }
2615
+ }
2616
+ }
2617
+ return members;
2618
+ }
2619
+ // the types here aren't ideal and could probably be refactored.
2620
+ function createAndFinishType(typeDef) {
2621
+ createType(typeDef);
2622
+ return finishType(typeDef);
2623
+ }
2624
+ /**
2625
+ * Given the own-properties of a type, returns a fully-initialized type.
2626
+ * So far, that amounts to setting the prototype to typePrototype which
2627
+ * contains the `projections` getter.
2628
+ */
2629
+ function createType(typeDef) {
2630
+ Object.setPrototypeOf(typeDef, typePrototype);
2631
+ return typeDef;
2632
+ }
2633
+ function finishType(typeDef, mapper) {
2634
+ return finishTypeForProgramAndChecker(program, typePrototype, typeDef, mapper);
2635
+ }
2636
+ function getLiteralType(node) {
2637
+ return createLiteralType(node.value, node);
2638
+ }
2639
+ function mergeSymbolTable(source, target) {
2640
+ for (const [sym, duplicates] of source.duplicates) {
2641
+ const targetSet = target.duplicates.get(sym);
2642
+ if (targetSet === undefined) {
2643
+ mutate(target.duplicates).set(sym, new Set([...duplicates]));
2644
+ }
2645
+ else {
2646
+ for (const duplicate of duplicates) {
2647
+ mutate(targetSet).add(duplicate);
2648
+ }
2649
+ }
2650
+ }
2651
+ for (const [key, sourceBinding] of source) {
2652
+ if (sourceBinding.flags & 4096 /* SymbolFlags.Namespace */) {
2653
+ let targetBinding = target.get(key);
2654
+ if (!targetBinding) {
2655
+ targetBinding = {
2656
+ ...sourceBinding,
2657
+ declarations: [],
2658
+ exports: createSymbolTable(),
2659
+ };
2660
+ target.set(key, targetBinding);
2661
+ }
2662
+ if (targetBinding.flags & 4096 /* SymbolFlags.Namespace */) {
2663
+ mergedSymbols.set(sourceBinding, targetBinding);
2664
+ mutate(targetBinding.declarations).push(...sourceBinding.declarations);
2665
+ mergeSymbolTable(sourceBinding.exports, mutate(targetBinding.exports));
2666
+ }
2667
+ else {
2668
+ // this will set a duplicate error
2669
+ target.set(key, sourceBinding);
2670
+ }
2671
+ }
2672
+ else if (sourceBinding.flags & 4194304 /* SymbolFlags.Declaration */ ||
2673
+ sourceBinding.flags & 8388608 /* SymbolFlags.Implementation */) {
2674
+ if (sourceBinding.flags & 16384 /* SymbolFlags.Decorator */) {
2675
+ mergeDeclarationOrImplementation(key, sourceBinding, target, 16384 /* SymbolFlags.Decorator */);
2676
+ }
2677
+ else if (sourceBinding.flags & 131072 /* SymbolFlags.Function */) {
2678
+ mergeDeclarationOrImplementation(key, sourceBinding, target, 131072 /* SymbolFlags.Function */);
2679
+ }
2680
+ else {
2681
+ target.set(key, sourceBinding);
2682
+ }
2683
+ }
2684
+ else {
2685
+ target.set(key, sourceBinding);
2686
+ }
2687
+ }
2688
+ }
2689
+ function mergeDeclarationOrImplementation(key, sourceBinding, target, expectTargetFlags) {
2690
+ const targetBinding = target.get(key);
2691
+ if (!targetBinding || !(targetBinding.flags & expectTargetFlags)) {
2692
+ target.set(key, sourceBinding);
2693
+ return;
2694
+ }
2695
+ const isSourceDeclaration = sourceBinding.flags & 4194304 /* SymbolFlags.Declaration */;
2696
+ const isSourceImplementation = sourceBinding.flags & 8388608 /* SymbolFlags.Implementation */;
2697
+ const isTargetDeclaration = targetBinding.flags & 4194304 /* SymbolFlags.Declaration */;
2698
+ const isTargetImplementation = targetBinding.flags & 8388608 /* SymbolFlags.Implementation */;
2699
+ if (isTargetDeclaration && isTargetImplementation) {
2700
+ // If the target already has both a declration and implementation set the symbol which will mark it as duplicate
2701
+ target.set(key, sourceBinding);
2702
+ }
2703
+ else if (isTargetDeclaration && isSourceImplementation) {
2704
+ mergedSymbols.set(sourceBinding, targetBinding);
2705
+ mutate(targetBinding).value = sourceBinding.value;
2706
+ mutate(targetBinding).flags |= sourceBinding.flags;
2707
+ mutate(targetBinding.declarations).push(...sourceBinding.declarations);
2708
+ }
2709
+ else if (isTargetImplementation && isSourceDeclaration) {
2710
+ mergedSymbols.set(sourceBinding, targetBinding);
2711
+ mutate(targetBinding).flags |= sourceBinding.flags;
2712
+ mutate(targetBinding.declarations).unshift(...sourceBinding.declarations);
2713
+ }
2714
+ else {
2715
+ // this will set a duplicate error
2716
+ target.set(key, sourceBinding);
2717
+ }
2718
+ }
2719
+ function getMergedSymbol(sym) {
2720
+ if (!sym)
2721
+ return sym;
2722
+ return mergedSymbols.get(sym) || sym;
2723
+ }
2724
+ function createGlobalNamespaceNode() {
2725
+ const nsId = {
2726
+ kind: SyntaxKind.Identifier,
2727
+ pos: 0,
2728
+ end: 0,
2729
+ sv: "global",
2730
+ symbol: undefined,
2731
+ flags: 8 /* NodeFlags.Synthetic */,
2732
+ };
2733
+ const nsNode = {
2734
+ kind: SyntaxKind.NamespaceStatement,
2735
+ decorators: [],
2736
+ pos: 0,
2737
+ end: 0,
2738
+ id: nsId,
2739
+ symbol: undefined,
2740
+ locals: createSymbolTable(),
2741
+ flags: 8 /* NodeFlags.Synthetic */,
2742
+ };
2743
+ mutate(nsNode).symbol = createSymbol(nsNode, nsId.sv, 4096 /* SymbolFlags.Namespace */);
2744
+ mutate(nsNode.symbol.exports).set(nsId.sv, nsNode.symbol);
2745
+ return nsNode;
2746
+ }
2747
+ function createGlobalNamespaceType() {
2748
+ const type = createAndFinishType({
2749
+ kind: "Namespace",
2750
+ name: "",
2751
+ node: globalNamespaceNode,
2752
+ models: new Map(),
2753
+ scalars: new Map(),
2754
+ operations: new Map(),
2755
+ namespaces: new Map(),
2756
+ interfaces: new Map(),
2757
+ unions: new Map(),
2758
+ enums: new Map(),
2759
+ decoratorDeclarations: new Map(),
2760
+ functionDeclarations: new Map(),
2761
+ decorators: [],
2762
+ });
2763
+ getSymbolLinks(globalNamespaceNode.symbol).type = type;
2764
+ return type;
2765
+ }
2766
+ /**
2767
+ * Clone a type, resulting in an identical type with all the same decorators
2768
+ * applied. Decorators are re-run on the clone to achieve this.
2769
+ *
2770
+ * Care is taken to clone nested data structures that are part of the type.
2771
+ * Any type with e.g. a map or an array property must recreate the map or array
2772
+ * so that clones don't share the same object.
2773
+ *
2774
+ * For types which have sub-types that are part of it, e.g. enums with members,
2775
+ * unions with variants, or models with properties, the sub-types are cloned
2776
+ * as well.
2777
+ *
2778
+ * If the entire type graph needs to be cloned, then cloneType must be called
2779
+ * recursively by the caller.
2780
+ */
2781
+ function cloneType(type, additionalProps = {}) {
2782
+ // TODO: this needs to handle other types
2783
+ let clone;
2784
+ switch (type.kind) {
2785
+ case "Model":
2786
+ const newModel = createType({
2787
+ ...type,
2788
+ decorators: [...type.decorators],
2789
+ properties: undefined,
2790
+ ...additionalProps,
2791
+ });
2792
+ if (!("properties" in additionalProps)) {
2793
+ newModel.properties = new Map(Array.from(type.properties.entries()).map(([key, prop]) => [
2794
+ key,
2795
+ cloneType(prop, { model: newModel }),
2796
+ ]));
2797
+ }
2798
+ clone = finishType(newModel);
2799
+ break;
2800
+ case "Union":
2801
+ const newUnion = createType({
2802
+ ...type,
2803
+ decorators: [...type.decorators],
2804
+ variants: undefined,
2805
+ get options() {
2806
+ return Array.from(this.variants.values()).map((v) => v.type);
2807
+ },
2808
+ ...additionalProps,
2809
+ });
2810
+ if (!("variants" in additionalProps)) {
2811
+ newUnion.variants = new Map(Array.from(type.variants.entries()).map(([key, prop]) => [
2812
+ key,
2813
+ cloneType(prop, { union: newUnion }),
2814
+ ]));
2815
+ }
2816
+ clone = finishType(newUnion);
2817
+ break;
2818
+ case "Interface":
2819
+ const newInterface = createType({
2820
+ ...type,
2821
+ decorators: [...type.decorators],
2822
+ operations: undefined,
2823
+ ...additionalProps,
2824
+ });
2825
+ if (!("operations" in additionalProps)) {
2826
+ newInterface.operations = new Map(Array.from(type.operations.entries()).map(([key, prop]) => [
2827
+ key,
2828
+ cloneType(prop, { interface: newInterface }),
2829
+ ]));
2830
+ }
2831
+ clone = finishType(newInterface);
2832
+ break;
2833
+ case "Enum":
2834
+ const newEnum = createType({
2835
+ ...type,
2836
+ decorators: [...type.decorators],
2837
+ members: undefined,
2838
+ ...additionalProps,
2839
+ });
2840
+ if (!("members" in additionalProps)) {
2841
+ newEnum.members = new Map(Array.from(type.members.entries()).map(([key, prop]) => [
2842
+ key,
2843
+ cloneType(prop, { enum: newEnum }),
2844
+ ]));
2845
+ }
2846
+ clone = finishType(newEnum);
2847
+ break;
2848
+ default:
2849
+ clone = createAndFinishType({
2850
+ ...type,
2851
+ ...("decorators" in type ? { decorators: [...type.decorators] } : {}),
2852
+ ...additionalProps,
2853
+ });
2854
+ break;
2855
+ }
2856
+ const projection = projectionsByType.get(type);
2857
+ if (projection) {
2858
+ projectionsByType.set(clone, projection);
2859
+ }
2860
+ compilerAssert(clone.kind === type.kind, "cloneType must not change type kind");
2861
+ return clone;
2862
+ }
2863
+ function checkProjectionDeclaration(node) {
2864
+ // todo: check for duplicate projection decls on individual types
2865
+ // right now you can declare the same projection on a specific type
2866
+ // this could maybe go in the binder? But right now we don't know
2867
+ // what an identifier resolves to until check time.
2868
+ const links = getSymbolLinks(node.symbol);
2869
+ if (processedProjections.has(node)) {
2870
+ return links.declaredType;
2871
+ }
2872
+ processedProjections.add(node);
2873
+ reportCheckerDiagnostic(createDiagnostic({ code: "projections-are-experimental", target: node }));
2874
+ let type;
2875
+ if (links.declaredType) {
2876
+ type = links.declaredType;
2877
+ }
2878
+ else {
2879
+ type = links.declaredType = createType({
2880
+ kind: "Projection",
2881
+ node: undefined,
2882
+ nodeByKind: new Map(),
2883
+ nodeByType: new Map(),
2884
+ });
2885
+ }
2886
+ switch (node.selector.kind) {
2887
+ case SyntaxKind.ProjectionModelSelector:
2888
+ projectionsByTypeKind.get("Model").push(node);
2889
+ type.nodeByKind.set("Model", node);
2890
+ break;
2891
+ case SyntaxKind.ProjectionOperationSelector:
2892
+ projectionsByTypeKind.get("Operation").push(node);
2893
+ type.nodeByKind.set("Operation", node);
2894
+ break;
2895
+ case SyntaxKind.ProjectionUnionSelector:
2896
+ projectionsByTypeKind.get("Union").push(node);
2897
+ type.nodeByKind.set("Union", node);
2898
+ break;
2899
+ case SyntaxKind.ProjectionInterfaceSelector:
2900
+ projectionsByTypeKind.get("Interface").push(node);
2901
+ type.nodeByKind.set("Interface", node);
2902
+ break;
2903
+ case SyntaxKind.ProjectionEnumSelector:
2904
+ projectionsByTypeKind.get("Enum").push(node);
2905
+ type.nodeByKind.set("Enum", node);
2906
+ break;
2907
+ default:
2908
+ const projected = checkTypeReference(node.selector, undefined);
2909
+ let current = projectionsByType.get(projected);
2910
+ if (!current) {
2911
+ current = [];
2912
+ projectionsByType.set(projected, current);
2913
+ }
2914
+ current.push(node);
2915
+ type.nodeByType.set(projected, node);
2916
+ break;
2917
+ }
2918
+ return type;
2919
+ }
2920
+ function evalProjectionNode(node) {
2921
+ switch (node.kind) {
2922
+ case SyntaxKind.ProjectionExpressionStatement:
2923
+ return evalProjectionExpressionStatement(node);
2924
+ case SyntaxKind.ProjectionCallExpression:
2925
+ return evalProjectionCallExpression(node);
2926
+ case SyntaxKind.ProjectionMemberExpression:
2927
+ return evalProjectionMemberExpression(node);
2928
+ case SyntaxKind.ProjectionDecoratorReferenceExpression:
2929
+ return evalProjectionDecoratorReference(node);
2930
+ case SyntaxKind.Identifier:
2931
+ return evalProjectionIdentifier(node);
2932
+ case SyntaxKind.ProjectionLambdaExpression:
2933
+ return evalProjectionLambdaExpression(node);
2934
+ case SyntaxKind.StringLiteral:
2935
+ return evalStringLiteral(node);
2936
+ case SyntaxKind.NumericLiteral:
2937
+ return evalNumericLiteral(node);
2938
+ case SyntaxKind.BooleanLiteral:
2939
+ return evalBooleanLiteral(node);
2940
+ case SyntaxKind.ProjectionBlockExpression:
2941
+ return evalProjectionBlockExpression(node);
2942
+ case SyntaxKind.ProjectionArithmeticExpression:
2943
+ return evalProjectionArithmeticExpression(node);
2944
+ case SyntaxKind.ProjectionIfExpression:
2945
+ return evalProjectionIfExpression(node);
2946
+ case SyntaxKind.ProjectionEqualityExpression:
2947
+ return evalProjectionEqualityExpression(node);
2948
+ case SyntaxKind.ProjectionUnaryExpression:
2949
+ return evalProjectionUnaryExpression(node);
2950
+ case SyntaxKind.ProjectionRelationalExpression:
2951
+ return evalProjectionRelationalExpression(node);
2952
+ case SyntaxKind.ProjectionModelExpression:
2953
+ return evalProjectionModelExpression(node);
2954
+ case SyntaxKind.VoidKeyword:
2955
+ return voidType;
2956
+ case SyntaxKind.NeverKeyword:
2957
+ return neverType;
2958
+ case SyntaxKind.UnknownKeyword:
2959
+ return unknownType;
2960
+ case SyntaxKind.Return:
2961
+ return evalReturnKeyword(node);
2962
+ default:
2963
+ compilerAssert(false, `Can't eval the node ${SyntaxKind[node.kind]}`);
2964
+ }
2965
+ }
2966
+ function evalReturnKeyword(node) {
2967
+ const value = evalProjectionNode(node.value);
2968
+ if (value.kind === "Return") {
2969
+ return value;
2970
+ }
2971
+ return {
2972
+ kind: "Return",
2973
+ value,
2974
+ };
2975
+ }
2976
+ function evalProjectionModelExpression(node) {
2977
+ const modelType = createType({
2978
+ kind: "Model",
2979
+ name: "",
2980
+ node: node,
2981
+ decorators: [],
2982
+ properties: new Map(),
2983
+ derivedModels: [],
2984
+ });
2985
+ for (const propNode of node.properties) {
2986
+ if (propNode.kind === SyntaxKind.ProjectionModelProperty) {
2987
+ const prop = evalProjectionModelProperty(propNode, modelType);
2988
+ if (prop.kind === "Return") {
2989
+ return prop;
2990
+ }
2991
+ modelType.properties.set(prop.name, prop);
2992
+ }
2993
+ else {
2994
+ const props = evalProjectionModelSpreadProperty(propNode);
2995
+ if (!Array.isArray(props)) {
2996
+ // return record
2997
+ return props;
2998
+ }
2999
+ for (const newProp of props) {
3000
+ modelType.properties.set(newProp.name, newProp);
3001
+ }
3002
+ }
3003
+ }
3004
+ return modelType;
3005
+ }
3006
+ function evalProjectionModelProperty(node, model) {
3007
+ const type = evalProjectionNode(node.value);
3008
+ if (type.kind === "Return") {
3009
+ return type;
3010
+ }
3011
+ return createType({
3012
+ kind: "ModelProperty",
3013
+ name: node.id.sv,
3014
+ node: node,
3015
+ decorators: [],
3016
+ optional: node.optional,
3017
+ type,
3018
+ model,
3019
+ });
3020
+ }
3021
+ function evalProjectionModelSpreadProperty(node) {
3022
+ const target = evalProjectionNode(node.target);
3023
+ if (target.kind === "Return") {
3024
+ return target;
3025
+ }
3026
+ if (target.kind !== "Model") {
3027
+ throw new ProjectionError(`Can only spread models`);
3028
+ }
3029
+ const props = [];
3030
+ // copy each property
3031
+ for (const prop of walkPropertiesInherited(target)) {
3032
+ const newProp = cloneType(prop, { sourceProperty: prop });
3033
+ props.push(newProp);
3034
+ }
3035
+ return props;
3036
+ }
3037
+ function evalProjectionRelationalExpression(node) {
3038
+ const left = evalProjectionNode(node.left);
3039
+ if (left.kind === "Return") {
3040
+ return left;
3041
+ }
3042
+ else if (left.kind !== "Number" && left.kind !== "String") {
3043
+ throw new ProjectionError("Can only compare numbers or strings");
3044
+ }
3045
+ const right = evalProjectionNode(node.right);
3046
+ if (right.kind === "Return") {
3047
+ return right;
3048
+ }
3049
+ else if (right.kind !== "Number" && right.kind !== "String") {
3050
+ throw new ProjectionError("Can only compare numbers or strings");
3051
+ }
3052
+ if (left.kind !== right.kind) {
3053
+ throw new ProjectionError("Can't compare numbers and strings");
3054
+ }
3055
+ switch (node.op) {
3056
+ case "<":
3057
+ return createLiteralType(left.value < right.value);
3058
+ case "<=":
3059
+ return createLiteralType(left.value <= right.value);
3060
+ case ">":
3061
+ return createLiteralType(left.value > right.value);
3062
+ case ">=":
3063
+ return createLiteralType(left.value >= right.value);
3064
+ }
3065
+ }
3066
+ function evalProjectionUnaryExpression(node) {
3067
+ const target = evalProjectionNode(node.target);
3068
+ if (target.kind !== "Boolean") {
3069
+ throw new ProjectionError("Can't negate a non-boolean");
3070
+ }
3071
+ switch (node.op) {
3072
+ case "!":
3073
+ return createLiteralType(!target.value);
3074
+ }
3075
+ }
3076
+ function evalProjectionEqualityExpression(node) {
3077
+ const left = evalProjectionNode(node.left);
3078
+ if (left.kind === "Return") {
3079
+ return left;
3080
+ }
3081
+ else if (left.kind !== "Number" && left.kind !== "String") {
3082
+ throw new ProjectionError("Comparisons must be strings or numbers");
3083
+ }
3084
+ const right = evalProjectionNode(node.right);
3085
+ if (right.kind === "Return") {
3086
+ return right;
3087
+ }
3088
+ else if (right.kind !== "Number" && right.kind !== "String") {
3089
+ throw new ProjectionError("Comparisons must be strings or numbers");
3090
+ }
3091
+ if (right.kind !== left.kind) {
3092
+ throw new ProjectionError("Can't compare number and string");
3093
+ }
3094
+ switch (node.op) {
3095
+ case "==":
3096
+ return createLiteralType(left.value === right.value);
3097
+ case "!=":
3098
+ return createLiteralType(left.value !== right.value);
3099
+ }
3100
+ }
3101
+ function evalProjectionIfExpression(node) {
3102
+ let ifExpr = node;
3103
+ while (ifExpr) {
3104
+ const test = evalProjectionNode(ifExpr.test);
3105
+ if (test.kind === "Return") {
3106
+ return test;
3107
+ }
3108
+ if (typeIsTruthy(test)) {
3109
+ return evalProjectionBlockExpression(ifExpr.consequent);
3110
+ }
3111
+ else if (ifExpr.alternate &&
3112
+ ifExpr.alternate.kind === SyntaxKind.ProjectionBlockExpression) {
3113
+ return evalProjectionBlockExpression(ifExpr.alternate);
3114
+ }
3115
+ else {
3116
+ ifExpr = ifExpr.alternate;
3117
+ }
3118
+ }
3119
+ return voidType;
3120
+ }
3121
+ function typeIsTruthy(t) {
3122
+ switch (t.kind) {
3123
+ case "Boolean":
3124
+ return t.value;
3125
+ case "Number":
3126
+ return !!t.value;
3127
+ case "String":
3128
+ return !!t.value;
3129
+ default:
3130
+ return true;
3131
+ }
3132
+ }
3133
+ function createEvalContext(node, parent) {
3134
+ return {
3135
+ node,
3136
+ locals: new Map(),
3137
+ parent,
3138
+ };
3139
+ }
3140
+ function evalProjectionBlockExpression(node) {
3141
+ let lastVal = voidType;
3142
+ for (const stmt of node.statements) {
3143
+ const stmtValue = evalProjectionNode(stmt);
3144
+ if (stmtValue.kind === "Return") {
3145
+ return stmtValue;
3146
+ }
3147
+ lastVal = stmtValue;
3148
+ }
3149
+ return lastVal;
3150
+ }
3151
+ function evalProjectionArithmeticExpression(node) {
3152
+ const lhs = evalProjectionNode(node.left);
3153
+ if (lhs.kind === "Return") {
3154
+ return lhs;
3155
+ }
3156
+ if (lhs.kind !== "Number" && lhs.kind !== "String") {
3157
+ throw new ProjectionError(`Operator ${node.op} can only apply to strings or numbers`);
3158
+ }
3159
+ const rhs = evalProjectionNode(node.right);
3160
+ if (rhs.kind === "Return") {
3161
+ return rhs;
3162
+ }
3163
+ if (rhs.kind !== "Number" && rhs.kind !== "String") {
3164
+ throw new ProjectionError(`Operator ${node.op} can only apply to strings or numbers`);
3165
+ }
3166
+ if (rhs.kind !== lhs.kind) {
3167
+ throw new ProjectionError(`Operator ${node.op}'s operands need to be the same type`);
3168
+ }
3169
+ if (lhs.kind === "String") {
3170
+ return createLiteralType(lhs.value + rhs.value);
3171
+ }
3172
+ else {
3173
+ return createLiteralType(lhs.value + rhs.value);
3174
+ }
3175
+ }
3176
+ function evalProjectionStatement(node, target, args) {
3177
+ let topLevelProjection = false;
3178
+ if (!currentProjectionDirection) {
3179
+ topLevelProjection = true;
3180
+ currentProjectionDirection = node.direction;
3181
+ }
3182
+ if (currentProjectionDirection === "from" && !target.projectionSource) {
3183
+ // this model wasn't projected, so we'll just return the target
3184
+ return target;
3185
+ }
3186
+ const originalContext = evalContext;
3187
+ evalContext = createEvalContext(node);
3188
+ for (const [i, param] of node.parameters.entries()) {
3189
+ if (!args[i]) {
3190
+ throw new ProjectionError("need argument for parameter " + SyntaxKind[node.parameters[i].kind]);
3191
+ }
3192
+ const argVal = args[i];
3193
+ let typeVal;
3194
+ if (typeof argVal === "number" || typeof argVal === "string" || typeof argVal === "boolean") {
3195
+ typeVal = createLiteralType(argVal);
3196
+ }
3197
+ else {
3198
+ typeVal = argVal;
3199
+ }
3200
+ evalContext.locals.set(param.id.sv, typeVal);
3201
+ }
3202
+ evalContext.locals.set("self", target);
3203
+ let lastVal = voidType;
3204
+ for (const item of node.body) {
3205
+ lastVal = evalProjectionNode(item);
3206
+ if (lastVal.kind === "Return") {
3207
+ break;
3208
+ }
3209
+ }
3210
+ if (topLevelProjection) {
3211
+ currentProjectionDirection = undefined;
3212
+ }
3213
+ const selfResult = evalContext.locals.get("self");
3214
+ evalContext = originalContext;
3215
+ if (lastVal.kind === "Return") {
3216
+ return lastVal.value;
3217
+ }
3218
+ else {
3219
+ return selfResult;
3220
+ }
3221
+ }
3222
+ function evalProjectionExpressionStatement(node) {
3223
+ return evalProjectionNode(node.expr);
3224
+ }
3225
+ function evalProjectionCallExpression(node) {
3226
+ const target = evalProjectionNode(node.target);
3227
+ if (!target)
3228
+ throw new ProjectionError("target undefined");
3229
+ const args = [];
3230
+ for (const arg of node.arguments) {
3231
+ args.push(evalProjectionNode(arg));
3232
+ }
3233
+ if (target.kind !== "Function") {
3234
+ throw new ProjectionError("Can't call non-function, got type " + target.kind);
3235
+ }
3236
+ return target.implementation(...args);
3237
+ }
3238
+ function evalProjectionMemberExpression(node) {
3239
+ const base = evalProjectionNode(node.base);
3240
+ if (base.kind === "Return") {
3241
+ return base;
3242
+ }
3243
+ const member = node.id.sv;
3244
+ const selector = node.selector;
3245
+ if (selector === ".") {
3246
+ switch (base.kind) {
3247
+ case "Namespace":
3248
+ const sym = base.node.symbol.exports.get(member);
3249
+ if (sym) {
3250
+ const links = getSymbolLinks(sym);
3251
+ return links.declaredType || links.type || errorType;
3252
+ }
3253
+ else {
3254
+ throw new ProjectionError(`Namespace doesn't have member ${member}`);
3255
+ }
3256
+ case "Model":
3257
+ const prop = base.properties.get(member);
3258
+ if (!prop) {
3259
+ throw new ProjectionError(`Model doesn't have property ${member}`);
3260
+ }
3261
+ return prop;
3262
+ case "Enum":
3263
+ const enumMember = base.members.get(member);
3264
+ if (!enumMember) {
3265
+ throw new ProjectionError(`Enum doesn't have member ${member}`);
3266
+ }
3267
+ return enumMember;
3268
+ case "Union":
3269
+ const variant = base.variants.get(member);
3270
+ if (!variant) {
3271
+ throw new ProjectionError(`Union doesn't have variant ${member}`);
3272
+ }
3273
+ return variant;
3274
+ default:
3275
+ throw new ProjectionError(`Can't get member "${member}" of type ${base.kind} because it has no members. Did you mean to use "::" instead of "."?`);
3276
+ }
3277
+ }
3278
+ switch (base.kind) {
3279
+ case "Object":
3280
+ return base.properties[member] || errorType;
3281
+ default:
3282
+ const typeOps = projectionMembers[base.kind];
3283
+ if (!typeOps) {
3284
+ throw new ProjectionError(`${base.kind} doesn't have an object model member named ${member}`);
3285
+ }
3286
+ // any cast needed to ensure we don't get a too complex union error on the call
3287
+ // to op further down.
3288
+ const op = typeOps[member];
3289
+ if (!op) {
3290
+ throw new ProjectionError(`${base.kind} doesn't have an object model member named ${member}`);
3291
+ }
3292
+ return op(base);
3293
+ }
3294
+ }
3295
+ function createFunctionType(fn) {
3296
+ const parameters = [];
3297
+ return createType({
3298
+ kind: "Function",
3299
+ name: "",
3300
+ parameters,
3301
+ returnType: unknownType,
3302
+ implementation: fn,
3303
+ });
3304
+ }
3305
+ function createLiteralType(value, node) {
3306
+ if (program.literalTypes.has(value)) {
3307
+ return program.literalTypes.get(value);
3308
+ }
3309
+ let type;
3310
+ switch (typeof value) {
3311
+ case "string":
3312
+ type = createType({ kind: "String", value });
3313
+ break;
3314
+ case "boolean":
3315
+ type = createType({ kind: "Boolean", value });
3316
+ break;
3317
+ case "number":
3318
+ type = createType({
3319
+ kind: "Number",
3320
+ value,
3321
+ });
3322
+ break;
3323
+ }
3324
+ program.literalTypes.set(value, type);
3325
+ return type;
3326
+ }
3327
+ function evalProjectionDecoratorReference(node) {
3328
+ const ref = resolveTypeReferenceSym(node.target, undefined, true);
3329
+ if (!ref)
3330
+ throw new ProjectionError("Can't find decorator.");
3331
+ compilerAssert(ref.flags & 16384 /* SymbolFlags.Decorator */, "should only resolve decorator symbols");
3332
+ return createFunctionType((...args) => {
3333
+ ref.value({ program }, ...marshalArgumentsForJS(args));
3334
+ return voidType;
3335
+ });
3336
+ }
3337
+ function evalProjectionIdentifier(node) {
3338
+ // first check the eval context
3339
+ let currentContext = evalContext;
3340
+ while (currentContext) {
3341
+ if (currentContext.locals.has(node.sv)) {
3342
+ return currentContext.locals.get(node.sv);
3343
+ }
3344
+ currentContext = currentContext.parent;
3345
+ }
3346
+ // next, resolve outside
3347
+ const ref = resolveTypeReferenceSym(node, undefined);
3348
+ if (!ref)
3349
+ throw new ProjectionError("Unknown identifier " + node.sv);
3350
+ if (ref.flags & 16384 /* SymbolFlags.Decorator */) {
3351
+ // shouldn't ever resolve a decorator symbol here (without passing
3352
+ // true to resolveTypeReference)
3353
+ return errorType;
3354
+ }
3355
+ else if (ref.flags & 131072 /* SymbolFlags.Function */) {
3356
+ // TODO: store this in a symbol link probably?
3357
+ const t = createFunctionType((...args) => {
3358
+ const retval = ref.value(program, ...marshalArgumentsForJS(args));
3359
+ return marshalProjectionReturn(retval, { functionName: node.sv });
3360
+ });
3361
+ return t;
3362
+ }
3363
+ else {
3364
+ const links = getSymbolLinks(ref);
3365
+ compilerAssert(links.declaredType, "Should have checked all types by now");
3366
+ return links.declaredType;
3367
+ }
3368
+ }
3369
+ function marshalProjectionReturn(value, options = {}) {
3370
+ if (typeof value === "boolean" || typeof value === "string" || typeof value === "number") {
3371
+ return createLiteralType(value);
3372
+ }
3373
+ if (typeof value === "object" && value !== null) {
3374
+ if ("kind" in value) {
3375
+ return value;
3376
+ }
3377
+ else {
3378
+ // this could probably be more robust
3379
+ return createType({
3380
+ kind: "Object",
3381
+ properties: value,
3382
+ });
3383
+ }
3384
+ }
3385
+ if (options.functionName) {
3386
+ throw new ProjectionError(`Can't marshal value "${value}" returned from JS function "${options.functionName}" into typespec`);
3387
+ }
3388
+ else {
3389
+ throw new ProjectionError(`Can't marshal value "${value}" into typespec`);
3390
+ }
3391
+ }
3392
+ function evalProjectionLambdaExpression(node) {
3393
+ return createFunctionType((...args) => {
3394
+ return callLambdaExpression(node, args);
3395
+ });
3396
+ }
3397
+ function callLambdaExpression(node, args) {
3398
+ const originalContext = evalContext;
3399
+ evalContext = createEvalContext(node, originalContext);
3400
+ for (const [i, param] of node.parameters.entries()) {
3401
+ evalContext.locals.set(param.id.sv, args[i]);
3402
+ }
3403
+ const retval = evalProjectionBlockExpression(node.body);
3404
+ evalContext = originalContext;
3405
+ if (retval.kind === "Return") {
3406
+ return retval.value;
3407
+ }
3408
+ return retval;
3409
+ }
3410
+ function evalStringLiteral(node) {
3411
+ return createLiteralType(node.value, node);
3412
+ }
3413
+ function evalNumericLiteral(node) {
3414
+ return createLiteralType(node.value, node);
3415
+ }
3416
+ function evalBooleanLiteral(node) {
3417
+ return createLiteralType(node.value, node);
3418
+ }
3419
+ function project(target, projection, args = []) {
3420
+ return evalProjectionStatement(projection, target, args.map((x) => marshalProjectionReturn(x)));
3421
+ }
3422
+ function memberExpressionToString(expr) {
3423
+ let current = expr;
3424
+ const parts = [];
3425
+ while (current.kind === SyntaxKind.MemberExpression) {
3426
+ parts.push(current.id.sv);
3427
+ current = current.base;
3428
+ }
3429
+ parts.push(current.sv);
3430
+ return parts.reverse().join(".");
3431
+ }
3432
+ /**
3433
+ * Check if the source type can be assigned to the target type and emit diagnostics
3434
+ * @param source Source type
3435
+ * @param target Target type
3436
+ * @param diagnosticTarget Target for the diagnostic, unless something better can be inferred.
3437
+ */
3438
+ function checkTypeAssignable(source, target, diagnosticTarget) {
3439
+ const [related, diagnostics] = isTypeAssignableTo(source, target, diagnosticTarget);
3440
+ if (!related) {
3441
+ reportCheckerDiagnostics(diagnostics);
3442
+ }
3443
+ return related;
3444
+ }
3445
+ /**
3446
+ * Check if the source type can be assigned to the target type.
3447
+ * @param source Source type
3448
+ * @param target Target type
3449
+ * @param diagnosticTarget Target for the diagnostic, unless something better can be inferred.
3450
+ */
3451
+ function isTypeAssignableTo(source, target, diagnosticTarget) {
3452
+ var _a;
3453
+ if (source === target)
3454
+ return [true, []];
3455
+ if (source.kind === "TemplateParameter") {
3456
+ source = (_a = source.constraint) !== null && _a !== void 0 ? _a : unknownType;
3457
+ }
3458
+ const isSimpleTypeRelated = isSimpleTypeAssignableTo(source, target);
3459
+ if (isSimpleTypeRelated === true) {
3460
+ return [true, []];
3461
+ }
3462
+ else if (isSimpleTypeRelated === false) {
3463
+ return [false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
3464
+ }
3465
+ if (source.kind === "Union") {
3466
+ for (const variant of source.variants.values()) {
3467
+ const [variantAssignable] = isTypeAssignableTo(variant.type, target, diagnosticTarget);
3468
+ if (!variantAssignable) {
3469
+ return [false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
3470
+ }
3471
+ }
3472
+ return [true, []];
3473
+ }
3474
+ if (target.kind === "Model" && target.indexer !== undefined && source.kind === "Model") {
3475
+ return isIndexerValid(source, target, diagnosticTarget);
3476
+ }
3477
+ else if (target.kind === "Model" && source.kind === "Model") {
3478
+ return isModelRelatedTo(source, target, diagnosticTarget);
3479
+ }
3480
+ else if (target.kind === "Model" && target.indexer && source.kind === "Tuple") {
3481
+ for (const item of source.values) {
3482
+ const [related, diagnostics] = isTypeAssignableTo(item, target.indexer.value, diagnosticTarget);
3483
+ if (!related) {
3484
+ return [false, diagnostics];
3485
+ }
3486
+ }
3487
+ return [true, []];
3488
+ }
3489
+ else if (target.kind === "Tuple" && source.kind === "Tuple") {
3490
+ return isTupleAssignableToTuple(source, target, diagnosticTarget);
3491
+ }
3492
+ else if (target.kind === "Union") {
3493
+ return isAssignableToUnion(source, target, diagnosticTarget);
3494
+ }
3495
+ else if (target.kind === "Enum") {
3496
+ return isAssignableToEnum(source, target, diagnosticTarget);
3497
+ }
3498
+ return [false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
3499
+ }
3500
+ function isReflectionType(type) {
3501
+ var _a, _b, _c;
3502
+ return (type.kind === "Model" &&
3503
+ ((_a = type.namespace) === null || _a === void 0 ? void 0 : _a.name) === "Reflection" &&
3504
+ ((_c = (_b = type.namespace) === null || _b === void 0 ? void 0 : _b.namespace) === null || _c === void 0 ? void 0 : _c.name) === "TypeSpec");
3505
+ }
3506
+ function isRelatedToScalar(source, target) {
3507
+ switch (source.kind) {
3508
+ case "Number":
3509
+ return isNumericLiteralRelatedTo(source, target);
3510
+ case "String":
3511
+ return areScalarsRelated(target, getStdType("string"));
3512
+ case "Boolean":
3513
+ return areScalarsRelated(target, getStdType("boolean"));
3514
+ case "Scalar":
3515
+ return areScalarsRelated(source, target);
3516
+ case "Union":
3517
+ return undefined;
3518
+ default:
3519
+ return false;
3520
+ }
3521
+ }
3522
+ function areScalarsRelated(source, target) {
3523
+ let current = source;
3524
+ while (current) {
3525
+ if (current === target) {
3526
+ return true;
3527
+ }
3528
+ current = current.baseScalar;
3529
+ }
3530
+ return false;
3531
+ }
3532
+ function isSimpleTypeAssignableTo(source, target) {
3533
+ if (isVoidType(target) || isNeverType(target))
3534
+ return false;
3535
+ if (isUnknownType(target))
3536
+ return true;
3537
+ if (isReflectionType(target)) {
3538
+ return source.kind === ReflectionNameToKind[target.name];
3539
+ }
3540
+ if (target.kind === "Scalar") {
3541
+ return isRelatedToScalar(source, target);
3542
+ }
3543
+ if (source.kind === "Scalar" && target.kind === "Model") {
3544
+ return false;
3545
+ }
3546
+ if (target.kind === "String") {
3547
+ return source.kind === "String" && target.value === source.value;
3548
+ }
3549
+ if (target.kind === "Number") {
3550
+ return source.kind === "Number" && target.value === source.value;
3551
+ }
3552
+ return undefined;
3553
+ }
3554
+ function isNumericLiteralRelatedTo(source, target) {
3555
+ // if the target does not derive from numeric, then it can't be assigned a numeric literal
3556
+ if (!areScalarsRelated(target, getStdType("numeric"))) {
3557
+ return false;
3558
+ }
3559
+ // With respect to literal assignability a custom numeric scalar is
3560
+ // equivalent to its nearest TypeSpec.* base. Adjust target accordingly.
3561
+ while (!target.namespace || !isTypeSpecNamespace(target.namespace)) {
3562
+ compilerAssert(target.baseScalar, "Should not be possible to be derived from TypeSpec.numeric and not have a base when not in TypeSpec namespace.");
3563
+ target = target.baseScalar;
3564
+ }
3565
+ if (target.name === "numeric")
3566
+ return true;
3567
+ const isInt = Number.isInteger(source.value);
3568
+ if (target.name === "integer")
3569
+ return isInt;
3570
+ if (target.name === "float")
3571
+ return true;
3572
+ if (!(target.name in numericRanges))
3573
+ return false;
3574
+ const [low, high, options] = numericRanges[target.name];
3575
+ return source.value >= low && source.value <= high && (!options.int || isInt);
3576
+ }
3577
+ function isModelRelatedTo(source, target, diagnosticTarget) {
3578
+ const diagnostics = [];
3579
+ for (const prop of walkPropertiesInherited(target)) {
3580
+ const sourceProperty = getProperty(source, prop.name);
3581
+ if (sourceProperty === undefined) {
3582
+ if (!prop.optional) {
3583
+ diagnostics.push(createDiagnostic({
3584
+ code: "missing-property",
3585
+ format: {
3586
+ propertyName: prop.name,
3587
+ sourceType: getTypeName(source),
3588
+ targetType: getTypeName(target),
3589
+ },
3590
+ target: source,
3591
+ }));
3592
+ }
3593
+ }
3594
+ else {
3595
+ const [related, propDiagnostics] = isTypeAssignableTo(sourceProperty.type, prop.type, diagnosticTarget);
3596
+ if (!related) {
3597
+ diagnostics.push(...propDiagnostics);
3598
+ }
3599
+ }
3600
+ }
3601
+ return [diagnostics.length === 0, diagnostics];
3602
+ }
3603
+ function getProperty(model, name) {
3604
+ var _a;
3605
+ return ((_a = model.properties.get(name)) !== null && _a !== void 0 ? _a : (model.baseModel !== undefined ? getProperty(model.baseModel, name) : undefined));
3606
+ }
3607
+ function isIndexerValid(source, target, diagnosticTarget) {
3608
+ // Model expressions should be able to be assigned.
3609
+ if (source.name === "") {
3610
+ return isIndexConstraintValid(target.indexer.value, source, diagnosticTarget);
3611
+ }
3612
+ else {
3613
+ if (source.indexer === undefined || source.indexer.key !== target.indexer.key) {
3614
+ return [
3615
+ false,
3616
+ [
3617
+ createDiagnostic({
3618
+ code: "missing-index",
3619
+ format: {
3620
+ indexType: getTypeName(target.indexer.key),
3621
+ sourceType: getTypeName(source),
3622
+ },
3623
+ target,
3624
+ }),
3625
+ ],
3626
+ ];
3627
+ }
3628
+ return isTypeAssignableTo(source.indexer.value, target.indexer.value, diagnosticTarget);
3629
+ }
3630
+ }
3631
+ /**
3632
+ * @param constraintType Type of the constraints(All properties must have this type).
3633
+ * @param type Type of the model that should be respecting the constraint.
3634
+ * @param diagnosticTarget Diagnostic target unless something better can be inferred.
3635
+ */
3636
+ function isIndexConstraintValid(constraintType, type, diagnosticTarget) {
3637
+ for (const prop of type.properties.values()) {
3638
+ const [related, diagnostics] = isTypeAssignableTo(prop.type, constraintType, diagnosticTarget);
3639
+ if (!related) {
3640
+ return [false, diagnostics];
3641
+ }
3642
+ }
3643
+ if (type.baseModel) {
3644
+ const [related, diagnostics] = isIndexConstraintValid(constraintType, type.baseModel, diagnosticTarget);
3645
+ if (!related) {
3646
+ return [false, diagnostics];
3647
+ }
3648
+ }
3649
+ return [true, []];
3650
+ }
3651
+ function isTupleAssignableToTuple(source, target, diagnosticTarget) {
3652
+ if (source.values.length !== target.values.length) {
3653
+ return [
3654
+ false,
3655
+ [
3656
+ createDiagnostic({
3657
+ code: "unassignable",
3658
+ messageId: "withDetails",
3659
+ format: {
3660
+ sourceType: getTypeName(source),
3661
+ targetType: getTypeName(target),
3662
+ details: `Source has ${source.values.length} element(s) but target requires ${target.values.length}.`,
3663
+ },
3664
+ target: diagnosticTarget,
3665
+ }),
3666
+ ],
3667
+ ];
3668
+ }
3669
+ for (const [index, sourceItem] of source.values.entries()) {
3670
+ const targetItem = target.values[index];
3671
+ const [related, diagnostics] = isTypeAssignableTo(sourceItem, targetItem, diagnosticTarget);
3672
+ if (!related) {
3673
+ return [false, diagnostics];
3674
+ }
3675
+ }
3676
+ return [true, []];
3677
+ }
3678
+ function isAssignableToUnion(source, target, diagnosticTarget) {
3679
+ for (const option of target.options) {
3680
+ const [related] = isTypeAssignableTo(source, option, diagnosticTarget);
3681
+ if (related) {
3682
+ return [true, []];
3683
+ }
3684
+ }
3685
+ return [false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
3686
+ }
3687
+ function isAssignableToEnum(source, target, diagnosticTarget) {
3688
+ switch (source.kind) {
3689
+ case "Enum":
3690
+ if (source === target) {
3691
+ return [true, []];
3692
+ }
3693
+ else {
3694
+ return [false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
3695
+ }
3696
+ case "EnumMember":
3697
+ if (source.enum === target) {
3698
+ return [true, []];
3699
+ }
3700
+ else {
3701
+ return [false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
3702
+ }
3703
+ default:
3704
+ return [false, [createUnassignableDiagnostic(source, target, diagnosticTarget)]];
3705
+ }
3706
+ }
3707
+ function createUnassignableDiagnostic(source, target, diagnosticTarget) {
3708
+ return createDiagnostic({
3709
+ code: "unassignable",
3710
+ format: { targetType: getTypeName(target), value: getTypeName(source) },
3711
+ target: diagnosticTarget,
3712
+ });
3713
+ }
3714
+ function isStdType(type, stdType) {
3715
+ var _a;
3716
+ type = (_a = type.projectionBase) !== null && _a !== void 0 ? _a : type;
3717
+ if ((type.kind !== "Model" && type.kind !== "Scalar") ||
3718
+ type.namespace === undefined ||
3719
+ !isTypeSpecNamespace(type.namespace))
3720
+ return false;
3721
+ if (type.kind === "Scalar")
3722
+ return stdType === undefined || stdType === type.name;
3723
+ if (stdType === "Array" && type === stdTypes["Array"])
3724
+ return true;
3725
+ if (stdType === "Record" && type === stdTypes["Record"])
3726
+ return true;
3727
+ if (type.kind === "Model")
3728
+ return stdType === undefined || stdType === type.name;
3729
+ return false;
3730
+ }
3731
+ }
3732
+ function isAnonymous(type) {
3733
+ return !("name" in type) || typeof type.name !== "string" || !type.name;
3734
+ }
3735
+ function isErrorType(type) {
3736
+ return type.kind === "Intrinsic" && type.name === "ErrorType";
3737
+ }
3738
+ const numericRanges = {
3739
+ int64: [BigInt("-9223372036854775807"), BigInt("9223372036854775808"), { int: true }],
3740
+ int32: [-2147483648, 2147483647, { int: true }],
3741
+ int16: [-32768, 32767, { int: true }],
3742
+ int8: [-128, 127, { int: true }],
3743
+ uint64: [0, BigInt("18446744073709551615"), { int: true }],
3744
+ uint32: [0, 4294967295, { int: true }],
3745
+ uint16: [0, 65535, { int: true }],
3746
+ uint8: [0, 255, { int: true }],
3747
+ safeint: [Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER, { int: true }],
3748
+ float32: [-3.4e38, 3.4e38, { int: false }],
3749
+ float64: [Number.MIN_VALUE, Number.MAX_VALUE, { int: false }],
3750
+ };
3751
+ /**
3752
+ * Find all named models that could have been the source of the given
3753
+ * property. This includes the named parents of all property sources in a
3754
+ * chain.
3755
+ */
3756
+ function getNamedSourceModels(property) {
3757
+ var _a;
3758
+ if (!property.sourceProperty) {
3759
+ return undefined;
3760
+ }
3761
+ const set = new Set();
3762
+ for (let p = property; p; p = p.sourceProperty) {
3763
+ if ((_a = p.model) === null || _a === void 0 ? void 0 : _a.name) {
3764
+ set.add(p.model);
3765
+ }
3766
+ }
3767
+ return set;
3768
+ }
3769
+ /**
3770
+ * Find derived types of `models` in `possiblyDerivedModels` and add them to
3771
+ * `models`.
3772
+ */
3773
+ function addDerivedModels(models, possiblyDerivedModels) {
3774
+ for (const element of possiblyDerivedModels) {
3775
+ if (!models.has(element)) {
3776
+ for (let t = element.baseModel; t; t = t.baseModel) {
3777
+ if (models.has(t)) {
3778
+ models.add(element);
3779
+ break;
3780
+ }
3781
+ }
3782
+ }
3783
+ }
3784
+ }
3785
+ function createTypeMapper(parameters, args, parentMapper) {
3786
+ var _a;
3787
+ const map = new Map((_a = parentMapper === null || parentMapper === void 0 ? void 0 : parentMapper.map) !== null && _a !== void 0 ? _a : []);
3788
+ for (const [index, param] of parameters.entries()) {
3789
+ map.set(param, args[index]);
3790
+ }
3791
+ return {
3792
+ partial: false,
3793
+ args,
3794
+ getMappedType: (type) => {
3795
+ var _a;
3796
+ return (_a = map.get(type)) !== null && _a !== void 0 ? _a : type;
3797
+ },
3798
+ map,
3799
+ };
3800
+ }
3801
+ /**
3802
+ * If the input is anonymous (or the provided filter removes properties)
3803
+ * and there exists a named model with the same set of properties
3804
+ * (ignoring filtered properties), then return that named model.
3805
+ * Otherwise, return the input unchanged.
3806
+ *
3807
+ * This can be used by emitters to find a better name for a set of
3808
+ * properties after filtering. For example, given `{ @metadata prop:
3809
+ * string} & SomeName`, and an emitter that wishes to discard properties
3810
+ * marked with `@metadata`, the emitter can use this to recover that the
3811
+ * best name for the remaining properties is `SomeName`.
3812
+ *
3813
+ * @param model The input model
3814
+ * @param filter An optional filter to apply to the input model's
3815
+ * properties.
3816
+ */
3817
+ export function getEffectiveModelType(program, model, filter) {
3818
+ if (filter) {
3819
+ model = filterModelProperties(program, model, filter);
3820
+ }
3821
+ if (model.name) {
3822
+ // named model
3823
+ return model;
3824
+ }
3825
+ // We would need to change the algorithm if this doesn't hold. We
3826
+ // assume model has no inherited properties below.
3827
+ compilerAssert(!model.baseModel, "Anonymous model with base model.");
3828
+ if (model.properties.size === 0) {
3829
+ // empty model
3830
+ return model;
3831
+ }
3832
+ // Find the candidate set of named model types that could have been the
3833
+ // source of every property in the model.
3834
+ let candidates;
3835
+ for (const property of model.properties.values()) {
3836
+ const sources = getNamedSourceModels(property);
3837
+ if (!sources) {
3838
+ // unsourced property: no possible match
3839
+ return model;
3840
+ }
3841
+ if (!candidates) {
3842
+ // first sourced property: initialize candidates to its sources
3843
+ candidates = sources;
3844
+ continue;
3845
+ }
3846
+ // Add derived sources as we encounter them. If a model is sourced from
3847
+ // a base property, then it can also be sourced from a derived model.
3848
+ //
3849
+ // (Unless it is overridden, but then the presence of the overridden
3850
+ // property will still cause the the base model to be excluded from the
3851
+ // candidates.)
3852
+ //
3853
+ // Note: We depend on the order of that spread and intersect source
3854
+ // properties here, which is that we see properties sourced from derived
3855
+ // types before properties sourced from their base types.
3856
+ addDerivedModels(sources, candidates);
3857
+ // remove candidates that are not common to this property.
3858
+ for (const candidate of candidates) {
3859
+ if (!sources.has(candidate)) {
3860
+ candidates.delete(candidate);
3861
+ }
3862
+ }
3863
+ }
3864
+ // Search for a candidate that has no additional properties (ignoring
3865
+ // filtered properties). If so, it is effectively the same type as the
3866
+ // input model. Consider a candidate that meets this test without
3867
+ // ignoring filtering as a better match than one that requires filtering
3868
+ // to meet this test.
3869
+ let match;
3870
+ for (const candidate of candidates !== null && candidates !== void 0 ? candidates : []) {
3871
+ if (model.properties.size === countPropertiesInherited(candidate)) {
3872
+ match = candidate;
3873
+ break; // exact match
3874
+ }
3875
+ if (filter && !match && model.properties.size === countPropertiesInherited(candidate, filter)) {
3876
+ match = candidate;
3877
+ continue; // match with filter: keep searching for exact match
3878
+ }
3879
+ }
3880
+ return match !== null && match !== void 0 ? match : model;
3881
+ }
3882
+ /**
3883
+ * Applies a filter to the properties of a given type. If no properties
3884
+ * are filtered out, then return the input unchanged. Otherwise, return
3885
+ * a new anonymous model with only the filtered properties.
3886
+ *
3887
+ * @param model The input model to filter.
3888
+ * @param filter The filter to apply. Properties are kept when this returns true.
3889
+ */
3890
+ export function filterModelProperties(program, model, filter) {
3891
+ let filtered = false;
3892
+ for (const property of walkPropertiesInherited(model)) {
3893
+ if (!filter(property)) {
3894
+ filtered = true;
3895
+ break;
3896
+ }
3897
+ }
3898
+ if (!filtered) {
3899
+ return model;
3900
+ }
3901
+ const properties = new Map();
3902
+ const newModel = program.checker.createType({
3903
+ kind: "Model",
3904
+ node: undefined,
3905
+ name: "",
3906
+ indexer: undefined,
3907
+ properties,
3908
+ decorators: [],
3909
+ derivedModels: [],
3910
+ });
3911
+ for (const property of walkPropertiesInherited(model)) {
3912
+ if (filter(property)) {
3913
+ const newProperty = program.checker.cloneType(property, {
3914
+ sourceProperty: property,
3915
+ model: newModel,
3916
+ });
3917
+ properties.set(property.name, newProperty);
3918
+ }
3919
+ }
3920
+ return finishTypeForProgram(program, newModel);
3921
+ }
3922
+ /**
3923
+ * Gets the property from the nearest base type that is overridden by the
3924
+ * given property, if any.
3925
+ */
3926
+ export function getOverriddenProperty(property) {
3927
+ compilerAssert(property.model, "Parent model must be set before overridden property can be found.");
3928
+ for (let current = property.model.baseModel; current; current = current.baseModel) {
3929
+ const overridden = current.properties.get(property.name);
3930
+ if (overridden) {
3931
+ return overridden;
3932
+ }
3933
+ }
3934
+ return undefined;
3935
+ }
3936
+ /**
3937
+ * Enumerates the properties declared by model or inherited from its base.
3938
+ *
3939
+ * Properties declared by more derived types are enumerated before properties
3940
+ * of less derived types.
3941
+ *
3942
+ * Properties that are overridden are not enumerated.
3943
+ */
3944
+ export function* walkPropertiesInherited(model) {
3945
+ const returned = new Set();
3946
+ for (let current = model; current; current = current.baseModel) {
3947
+ for (const property of current.properties.values()) {
3948
+ if (returned.has(property.name)) {
3949
+ // skip properties that have been overridden
3950
+ continue;
3951
+ }
3952
+ returned.add(property.name);
3953
+ yield property;
3954
+ }
3955
+ }
3956
+ }
3957
+ function countPropertiesInherited(model, filter) {
3958
+ let count = 0;
3959
+ for (const property of walkPropertiesInherited(model)) {
3960
+ if (!filter || filter(property)) {
3961
+ count++;
3962
+ }
3963
+ }
3964
+ return count;
3965
+ }
3966
+ export function finishTypeForProgram(program, typeDef, mapper) {
3967
+ return finishTypeForProgramAndChecker(program, program.checker.typePrototype, typeDef, mapper);
3968
+ }
3969
+ function finishTypeForProgramAndChecker(program, typePrototype, typeDef, mapper) {
3970
+ if (mapper) {
3971
+ compilerAssert(!typeDef.templateArguments, "Mapper provided but template arguments already set.");
3972
+ typeDef.templateMapper = mapper;
3973
+ typeDef.templateArguments = mapper.args;
3974
+ }
3975
+ if ("decorators" in typeDef) {
3976
+ for (const decApp of typeDef.decorators) {
3977
+ applyDecoratorToType(program, decApp, typeDef);
3978
+ }
3979
+ }
3980
+ Object.setPrototypeOf(typeDef, typePrototype);
3981
+ return typeDef;
3982
+ }
3983
+ function applyDecoratorToType(program, decApp, target) {
3984
+ var _a;
3985
+ compilerAssert("decorators" in target, "Cannot apply decorator to non-decoratable type", target);
3986
+ for (const arg of decApp.args) {
3987
+ if (isErrorType(arg.value)) {
3988
+ // If one of the decorator argument is an error don't run it.
3989
+ return;
3990
+ }
3991
+ }
3992
+ // peel `fn` off to avoid setting `this`.
3993
+ try {
3994
+ const args = marshalArgumentsForJS(decApp.args.map((x) => x.value));
3995
+ const fn = decApp.decorator;
3996
+ const context = createDecoratorContext(program, decApp);
3997
+ fn(context, target, ...args);
3998
+ }
3999
+ catch (error) {
4000
+ // do not fail the language server for exceptions in decorators
4001
+ if (program.compilerOptions.designTimeBuild) {
4002
+ program.reportDiagnostic(createDiagnostic({
4003
+ code: "decorator-fail",
4004
+ format: { decoratorName: decApp.decorator.name, error: error.stack },
4005
+ target: (_a = decApp.node) !== null && _a !== void 0 ? _a : target,
4006
+ }));
4007
+ }
4008
+ else {
4009
+ throw error;
4010
+ }
4011
+ }
4012
+ }
4013
+ function createDecoratorContext(program, decApp) {
4014
+ function createPassThruContext(program, decApp) {
4015
+ return {
4016
+ program,
4017
+ decoratorTarget: decApp.node,
4018
+ getArgumentTarget: () => decApp.node,
4019
+ call: (decorator, target, ...args) => {
4020
+ return decorator(createPassThruContext(program, decApp), target, ...args);
4021
+ },
4022
+ };
4023
+ }
4024
+ return {
4025
+ program,
4026
+ decoratorTarget: decApp.node,
4027
+ getArgumentTarget: (index) => {
4028
+ var _a;
4029
+ return (_a = decApp.args[index]) === null || _a === void 0 ? void 0 : _a.node;
4030
+ },
4031
+ call: (decorator, target, ...args) => {
4032
+ return decorator(createPassThruContext(program, decApp), target, ...args);
4033
+ },
4034
+ };
4035
+ }
4036
+ /**
4037
+ * Convert typespec argument to JS argument.
4038
+ */
4039
+ function marshalArgumentsForJS(args) {
4040
+ return args.map((arg) => {
4041
+ if (arg.kind === "Boolean" || arg.kind === "String" || arg.kind === "Number") {
4042
+ return literalTypeToValue(arg);
4043
+ }
4044
+ return arg;
4045
+ });
4046
+ }
4047
+ function literalTypeToValue(type) {
4048
+ return type.value;
4049
+ }
4050
+ function isTemplatedNode(node) {
4051
+ return "templateParameters" in node && node.templateParameters.length > 0;
4052
+ }
4053
+ /**
4054
+ * Mapping from the reflection models to Type["kind"] value
4055
+ */
4056
+ const ReflectionNameToKind = {
4057
+ Model: "Model",
4058
+ ModelProperty: "ModelProperty",
4059
+ Interface: "Interface",
4060
+ Enum: "Enum",
4061
+ EnumMember: "EnumMember",
4062
+ TemplateParameter: "TemplateParameter",
4063
+ Namespace: "Namespace",
4064
+ Operation: "Operation",
4065
+ Tuple: "Tuple",
4066
+ Union: "Union",
4067
+ UnionVariant: "UnionVariant",
4068
+ };
4069
+ const _assertReflectionNameToKind = ReflectionNameToKind;
4070
+ //# sourceMappingURL=checker.js.map