tsc-ts 0.0.3 → 0.0.5

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 (596) hide show
  1. package/README.md +46 -0
  2. package/dist/api/compiler/ast-utilities.d.ts +82 -0
  3. package/dist/api/compiler/ast-utilities.js +462 -0
  4. package/dist/api/compiler/ast.d.ts +2350 -0
  5. package/dist/api/compiler/ast.js +11206 -0
  6. package/dist/api/compiler/astnav.d.ts +37 -0
  7. package/dist/api/compiler/astnav.js +767 -0
  8. package/dist/api/compiler/binder-utilities.d.ts +182 -0
  9. package/dist/api/compiler/binder-utilities.js +1240 -0
  10. package/dist/api/compiler/binder.d.ts +33 -0
  11. package/dist/api/compiler/binder.js +2358 -0
  12. package/dist/api/compiler/character-codes.d.ts +161 -0
  13. package/dist/api/compiler/character-codes.js +160 -0
  14. package/dist/api/compiler/checker-calls.d.ts +46 -0
  15. package/dist/api/compiler/checker-calls.js +1640 -0
  16. package/dist/api/compiler/checker-classes.d.ts +30 -0
  17. package/dist/api/compiler/checker-classes.js +582 -0
  18. package/dist/api/compiler/checker-contextual.d.ts +77 -0
  19. package/dist/api/compiler/checker-contextual.js +1136 -0
  20. package/dist/api/compiler/checker-declaration-order.d.ts +12 -0
  21. package/dist/api/compiler/checker-declaration-order.js +356 -0
  22. package/dist/api/compiler/checker-declarations.d.ts +33 -0
  23. package/dist/api/compiler/checker-declarations.js +888 -0
  24. package/dist/api/compiler/checker-declared-types.d.ts +48 -0
  25. package/dist/api/compiler/checker-declared-types.js +787 -0
  26. package/dist/api/compiler/checker-decorators.d.ts +26 -0
  27. package/dist/api/compiler/checker-decorators.js +562 -0
  28. package/dist/api/compiler/checker-deprecation.d.ts +33 -0
  29. package/dist/api/compiler/checker-deprecation.js +315 -0
  30. package/dist/api/compiler/checker-destructuring.d.ts +34 -0
  31. package/dist/api/compiler/checker-destructuring.js +584 -0
  32. package/dist/api/compiler/checker-elaboration.d.ts +15 -0
  33. package/dist/api/compiler/checker-elaboration.js +290 -0
  34. package/dist/api/compiler/checker-emit-helpers.d.ts +58 -0
  35. package/dist/api/compiler/checker-emit-helpers.js +154 -0
  36. package/dist/api/compiler/checker-emit-resolver.d.ts +75 -0
  37. package/dist/api/compiler/checker-emit-resolver.js +579 -0
  38. package/dist/api/compiler/checker-evaluator.d.ts +27 -0
  39. package/dist/api/compiler/checker-evaluator.js +188 -0
  40. package/dist/api/compiler/checker-expressions.d.ts +67 -0
  41. package/dist/api/compiler/checker-expressions.js +1351 -0
  42. package/dist/api/compiler/checker-features.d.ts +6 -0
  43. package/dist/api/compiler/checker-features.js +354 -0
  44. package/dist/api/compiler/checker-flow.d.ts +86 -0
  45. package/dist/api/compiler/checker-flow.js +169 -0
  46. package/dist/api/compiler/checker-functions.d.ts +43 -0
  47. package/dist/api/compiler/checker-functions.js +1002 -0
  48. package/dist/api/compiler/checker-generated-code.d.ts +25 -0
  49. package/dist/api/compiler/checker-generated-code.js +168 -0
  50. package/dist/api/compiler/checker-globals.d.ts +14 -0
  51. package/dist/api/compiler/checker-globals.js +37 -0
  52. package/dist/api/compiler/checker-grammar.d.ts +35 -0
  53. package/dist/api/compiler/checker-grammar.js +2573 -0
  54. package/dist/api/compiler/checker-heritage.d.ts +28 -0
  55. package/dist/api/compiler/checker-heritage.js +900 -0
  56. package/dist/api/compiler/checker-inference.d.ts +179 -0
  57. package/dist/api/compiler/checker-inference.js +2105 -0
  58. package/dist/api/compiler/checker-iteration.d.ts +115 -0
  59. package/dist/api/compiler/checker-iteration.js +857 -0
  60. package/dist/api/compiler/checker-javascript.d.ts +42 -0
  61. package/dist/api/compiler/checker-javascript.js +441 -0
  62. package/dist/api/compiler/checker-jsdoc.d.ts +30 -0
  63. package/dist/api/compiler/checker-jsdoc.js +320 -0
  64. package/dist/api/compiler/checker-jsx.d.ts +94 -0
  65. package/dist/api/compiler/checker-jsx.js +1433 -0
  66. package/dist/api/compiler/checker-literals.d.ts +6 -0
  67. package/dist/api/compiler/checker-literals.js +43 -0
  68. package/dist/api/compiler/checker-members.d.ts +198 -0
  69. package/dist/api/compiler/checker-members.js +2126 -0
  70. package/dist/api/compiler/checker-modules.d.ts +85 -0
  71. package/dist/api/compiler/checker-modules.js +2141 -0
  72. package/dist/api/compiler/checker-narrowing.d.ts +120 -0
  73. package/dist/api/compiler/checker-narrowing.js +2797 -0
  74. package/dist/api/compiler/checker-object-literals.d.ts +14 -0
  75. package/dist/api/compiler/checker-object-literals.js +479 -0
  76. package/dist/api/compiler/checker-operators.d.ts +33 -0
  77. package/dist/api/compiler/checker-operators.js +1040 -0
  78. package/dist/api/compiler/checker-overloads.d.ts +7 -0
  79. package/dist/api/compiler/checker-overloads.js +270 -0
  80. package/dist/api/compiler/checker-property-access.d.ts +34 -0
  81. package/dist/api/compiler/checker-property-access.js +672 -0
  82. package/dist/api/compiler/checker-services.d.ts +49 -0
  83. package/dist/api/compiler/checker-services.js +995 -0
  84. package/dist/api/compiler/checker-signatures.d.ts +55 -0
  85. package/dist/api/compiler/checker-signatures.js +788 -0
  86. package/dist/api/compiler/checker-source-file.d.ts +27 -0
  87. package/dist/api/compiler/checker-source-file.js +619 -0
  88. package/dist/api/compiler/checker-statements.d.ts +18 -0
  89. package/dist/api/compiler/checker-statements.js +226 -0
  90. package/dist/api/compiler/checker-super.d.ts +13 -0
  91. package/dist/api/compiler/checker-super.js +241 -0
  92. package/dist/api/compiler/checker-symbol-types.d.ts +67 -0
  93. package/dist/api/compiler/checker-symbol-types.js +1885 -0
  94. package/dist/api/compiler/checker-symbols.d.ts +181 -0
  95. package/dist/api/compiler/checker-symbols.js +1782 -0
  96. package/dist/api/compiler/checker-type-factory.d.ts +142 -0
  97. package/dist/api/compiler/checker-type-factory.js +2501 -0
  98. package/dist/api/compiler/checker-type-nodes.d.ts +26 -0
  99. package/dist/api/compiler/checker-type-nodes.js +828 -0
  100. package/dist/api/compiler/checker-type-operators.d.ts +109 -0
  101. package/dist/api/compiler/checker-type-operators.js +1842 -0
  102. package/dist/api/compiler/checker-types.d.ts +1027 -0
  103. package/dist/api/compiler/checker-types.js +1697 -0
  104. package/dist/api/compiler/checker-unused.d.ts +19 -0
  105. package/dist/api/compiler/checker-unused.js +524 -0
  106. package/dist/api/compiler/checker-utilities.d.ts +33 -0
  107. package/dist/api/compiler/checker-utilities.js +141 -0
  108. package/dist/api/compiler/checker.d.ts +491 -0
  109. package/dist/api/compiler/checker.js +912 -0
  110. package/dist/api/compiler/command-line.d.ts +32 -0
  111. package/dist/api/compiler/command-line.js +383 -0
  112. package/dist/api/compiler/compile-program.d.ts +118 -0
  113. package/dist/api/compiler/compile-program.js +384 -0
  114. package/dist/api/compiler/diagnostic-locales.d.ts +22 -0
  115. package/dist/api/compiler/diagnostic-locales.js +64 -0
  116. package/dist/api/compiler/diagnostic-messages.d.ts +2166 -0
  117. package/dist/api/compiler/diagnostic-messages.js +184 -0
  118. package/dist/api/compiler/diagnostics.d.ts +167 -0
  119. package/dist/api/compiler/diagnostics.js +820 -0
  120. package/dist/api/compiler/emitter.d.ts +71 -0
  121. package/dist/api/compiler/emitter.js +327 -0
  122. package/dist/api/compiler/file-include.d.ts +117 -0
  123. package/dist/api/compiler/file-include.js +536 -0
  124. package/dist/api/compiler/file-loader.d.ts +261 -0
  125. package/dist/api/compiler/file-loader.js +1257 -0
  126. package/dist/api/compiler/file-system.d.ts +51 -0
  127. package/dist/api/compiler/file-system.js +132 -0
  128. package/dist/api/compiler/flow.d.ts +60 -0
  129. package/dist/api/compiler/flow.js +45 -0
  130. package/dist/api/compiler/instantiation.d.ts +74 -0
  131. package/dist/api/compiler/instantiation.js +799 -0
  132. package/dist/api/compiler/jsdoc.d.ts +75 -0
  133. package/dist/api/compiler/jsdoc.js +1229 -0
  134. package/dist/api/compiler/link-tables.d.ts +36 -0
  135. package/dist/api/compiler/link-tables.js +83 -0
  136. package/dist/api/compiler/locale-data.d.ts +24 -0
  137. package/dist/api/compiler/locale-data.js +183 -0
  138. package/dist/api/compiler/locale.d.ts +4 -0
  139. package/dist/api/compiler/locale.js +317 -0
  140. package/dist/api/compiler/locales/cs-CZ.d.ts +2 -0
  141. package/dist/api/compiler/locales/cs-CZ.js +3 -0
  142. package/dist/api/compiler/locales/de-DE.d.ts +2 -0
  143. package/dist/api/compiler/locales/de-DE.js +3 -0
  144. package/dist/api/compiler/locales/es-ES.d.ts +2 -0
  145. package/dist/api/compiler/locales/es-ES.js +3 -0
  146. package/dist/api/compiler/locales/fr-FR.d.ts +2 -0
  147. package/dist/api/compiler/locales/fr-FR.js +3 -0
  148. package/dist/api/compiler/locales/it-IT.d.ts +2 -0
  149. package/dist/api/compiler/locales/it-IT.js +3 -0
  150. package/dist/api/compiler/locales/ja-JP.d.ts +2 -0
  151. package/dist/api/compiler/locales/ja-JP.js +3 -0
  152. package/dist/api/compiler/locales/ko-KR.d.ts +2 -0
  153. package/dist/api/compiler/locales/ko-KR.js +3 -0
  154. package/dist/api/compiler/locales/pl-PL.d.ts +2 -0
  155. package/dist/api/compiler/locales/pl-PL.js +3 -0
  156. package/dist/api/compiler/locales/pt-BR.d.ts +2 -0
  157. package/dist/api/compiler/locales/pt-BR.js +3 -0
  158. package/dist/api/compiler/locales/ru-RU.d.ts +2 -0
  159. package/dist/api/compiler/locales/ru-RU.js +3 -0
  160. package/dist/api/compiler/locales/tr-TR.d.ts +2 -0
  161. package/dist/api/compiler/locales/tr-TR.js +3 -0
  162. package/dist/api/compiler/locales/zh-CN.d.ts +2 -0
  163. package/dist/api/compiler/locales/zh-CN.js +3 -0
  164. package/dist/api/compiler/locales/zh-TW.d.ts +2 -0
  165. package/dist/api/compiler/locales/zh-TW.js +3 -0
  166. package/dist/api/compiler/module-resolution-types.d.ts +83 -0
  167. package/dist/api/compiler/module-resolution-types.js +176 -0
  168. package/dist/api/compiler/module-resolution.d.ts +71 -0
  169. package/dist/api/compiler/module-resolution.js +1598 -0
  170. package/dist/api/compiler/module-specifiers.d.ts +64 -0
  171. package/dist/api/compiler/module-specifiers.js +1101 -0
  172. package/dist/api/compiler/name-resolver.d.ts +43 -0
  173. package/dist/api/compiler/name-resolver.js +509 -0
  174. package/dist/api/compiler/node-builder-names.d.ts +32 -0
  175. package/dist/api/compiler/node-builder-names.js +854 -0
  176. package/dist/api/compiler/node-builder-pseudo.d.ts +36 -0
  177. package/dist/api/compiler/node-builder-pseudo.js +744 -0
  178. package/dist/api/compiler/node-builder-reuse.d.ts +4 -0
  179. package/dist/api/compiler/node-builder-reuse.js +647 -0
  180. package/dist/api/compiler/node-builder.d.ts +270 -0
  181. package/dist/api/compiler/node-builder.js +2645 -0
  182. package/dist/api/compiler/option-declarations.d.ts +90 -0
  183. package/dist/api/compiler/option-declarations.js +1460 -0
  184. package/dist/api/compiler/options.d.ts +289 -0
  185. package/dist/api/compiler/options.js +1197 -0
  186. package/dist/api/compiler/output-paths.d.ts +42 -0
  187. package/dist/api/compiler/output-paths.js +195 -0
  188. package/dist/api/compiler/package-json.d.ts +175 -0
  189. package/dist/api/compiler/package-json.js +1015 -0
  190. package/dist/api/compiler/parallel-parse.d.ts +219 -0
  191. package/dist/api/compiler/parallel-parse.js +537 -0
  192. package/dist/api/compiler/parser.d.ts +587 -0
  193. package/dist/api/compiler/parser.js +6407 -0
  194. package/dist/api/compiler/path.d.ts +91 -0
  195. package/dist/api/compiler/path.js +705 -0
  196. package/dist/api/compiler/printer/async-helpers.d.ts +22 -0
  197. package/dist/api/compiler/printer/async-helpers.js +91 -0
  198. package/dist/api/compiler/printer/auto-generate.d.ts +13 -0
  199. package/dist/api/compiler/printer/auto-generate.js +20 -0
  200. package/dist/api/compiler/printer/decorator-helpers.d.ts +24 -0
  201. package/dist/api/compiler/printer/decorator-helpers.js +118 -0
  202. package/dist/api/compiler/printer/emit-context.d.ts +154 -0
  203. package/dist/api/compiler/printer/emit-context.js +576 -0
  204. package/dist/api/compiler/printer/emit-flags.d.ts +60 -0
  205. package/dist/api/compiler/printer/emit-flags.js +2 -0
  206. package/dist/api/compiler/printer/factory-base.d.ts +171 -0
  207. package/dist/api/compiler/printer/factory-base.js +1505 -0
  208. package/dist/api/compiler/printer/factory.d.ts +147 -0
  209. package/dist/api/compiler/printer/factory.js +542 -0
  210. package/dist/api/compiler/printer/helpers.d.ts +27 -0
  211. package/dist/api/compiler/printer/helpers.js +164 -0
  212. package/dist/api/compiler/printer/name-generator.d.ts +41 -0
  213. package/dist/api/compiler/printer/name-generator.js +283 -0
  214. package/dist/api/compiler/printer/printer.d.ts +411 -0
  215. package/dist/api/compiler/printer/printer.js +4517 -0
  216. package/dist/api/compiler/printer/text-writer.d.ts +46 -0
  217. package/dist/api/compiler/printer/text-writer.js +172 -0
  218. package/dist/api/compiler/printer/utilities.d.ts +82 -0
  219. package/dist/api/compiler/printer/utilities.js +817 -0
  220. package/dist/api/compiler/program-checker.d.ts +156 -0
  221. package/dist/api/compiler/program-checker.js +526 -0
  222. package/dist/api/compiler/program-utilities.d.ts +52 -0
  223. package/dist/api/compiler/program-utilities.js +365 -0
  224. package/dist/api/compiler/program.d.ts +180 -0
  225. package/dist/api/compiler/program.js +1011 -0
  226. package/dist/api/compiler/pseudo-bigint.d.ts +5 -0
  227. package/dist/api/compiler/pseudo-bigint.js +61 -0
  228. package/dist/api/compiler/regexp-checker.d.ts +38 -0
  229. package/dist/api/compiler/regexp-checker.js +942 -0
  230. package/dist/api/compiler/relations.d.ts +263 -0
  231. package/dist/api/compiler/relations.js +4002 -0
  232. package/dist/api/compiler/reparser.d.ts +48 -0
  233. package/dist/api/compiler/reparser.js +1323 -0
  234. package/dist/api/compiler/scanner.d.ts +256 -0
  235. package/dist/api/compiler/scanner.js +2853 -0
  236. package/dist/api/compiler/side-state.d.ts +16 -0
  237. package/dist/api/compiler/side-state.js +89 -0
  238. package/dist/api/compiler/sourcemap.d.ts +55 -0
  239. package/dist/api/compiler/sourcemap.js +340 -0
  240. package/dist/api/compiler/spelling.d.ts +14 -0
  241. package/dist/api/compiler/spelling.js +128 -0
  242. package/dist/api/compiler/symbol-accessibility.d.ts +57 -0
  243. package/dist/api/compiler/symbol-accessibility.js +894 -0
  244. package/dist/api/compiler/symbol.d.ts +240 -0
  245. package/dist/api/compiler/symbol.js +228 -0
  246. package/dist/api/compiler/symlinks.d.ts +32 -0
  247. package/dist/api/compiler/symlinks.js +114 -0
  248. package/dist/api/compiler/syntax-kind.d.ts +389 -0
  249. package/dist/api/compiler/syntax-kind.js +2 -0
  250. package/dist/api/compiler/timeline.d.ts +9 -0
  251. package/dist/api/compiler/timeline.js +54 -0
  252. package/dist/api/compiler/transformers/alias-references.d.ts +39 -0
  253. package/dist/api/compiler/transformers/alias-references.js +676 -0
  254. package/dist/api/compiler/transformers/async-utilities.d.ts +51 -0
  255. package/dist/api/compiler/transformers/async-utilities.js +260 -0
  256. package/dist/api/compiler/transformers/async.d.ts +53 -0
  257. package/dist/api/compiler/transformers/async.js +645 -0
  258. package/dist/api/compiler/transformers/class-fields.d.ts +206 -0
  259. package/dist/api/compiler/transformers/class-fields.js +2418 -0
  260. package/dist/api/compiler/transformers/class-utilities.d.ts +46 -0
  261. package/dist/api/compiler/transformers/class-utilities.js +261 -0
  262. package/dist/api/compiler/transformers/commonjs-module.d.ts +103 -0
  263. package/dist/api/compiler/transformers/commonjs-module.js +1180 -0
  264. package/dist/api/compiler/transformers/const-enum-inliner.d.ts +11 -0
  265. package/dist/api/compiler/transformers/const-enum-inliner.js +36 -0
  266. package/dist/api/compiler/transformers/declarations-diagnostics.d.ts +52 -0
  267. package/dist/api/compiler/transformers/declarations-diagnostics.js +538 -0
  268. package/dist/api/compiler/transformers/declarations-pseudo.d.ts +160 -0
  269. package/dist/api/compiler/transformers/declarations-pseudo.js +797 -0
  270. package/dist/api/compiler/transformers/declarations-resolver.d.ts +152 -0
  271. package/dist/api/compiler/transformers/declarations-resolver.js +35 -0
  272. package/dist/api/compiler/transformers/declarations-syntactic.d.ts +119 -0
  273. package/dist/api/compiler/transformers/declarations-syntactic.js +1582 -0
  274. package/dist/api/compiler/transformers/declarations-tracker.d.ts +46 -0
  275. package/dist/api/compiler/transformers/declarations-tracker.js +197 -0
  276. package/dist/api/compiler/transformers/declarations.d.ts +175 -0
  277. package/dist/api/compiler/transformers/declarations.js +2380 -0
  278. package/dist/api/compiler/transformers/decorator-metadata.d.ts +54 -0
  279. package/dist/api/compiler/transformers/decorator-metadata.js +554 -0
  280. package/dist/api/compiler/transformers/decorator-utilities.d.ts +38 -0
  281. package/dist/api/compiler/transformers/decorator-utilities.js +238 -0
  282. package/dist/api/compiler/transformers/destructuring.d.ts +25 -0
  283. package/dist/api/compiler/transformers/destructuring.js +626 -0
  284. package/dist/api/compiler/transformers/downlevel.d.ts +6 -0
  285. package/dist/api/compiler/transformers/downlevel.js +45 -0
  286. package/dist/api/compiler/transformers/emit-resolver.d.ts +61 -0
  287. package/dist/api/compiler/transformers/emit-resolver.js +197 -0
  288. package/dist/api/compiler/transformers/es-decorators.d.ts +118 -0
  289. package/dist/api/compiler/transformers/es-decorators.js +1901 -0
  290. package/dist/api/compiler/transformers/exponentiation.d.ts +11 -0
  291. package/dist/api/compiler/transformers/exponentiation.js +76 -0
  292. package/dist/api/compiler/transformers/external-module-info.d.ts +35 -0
  293. package/dist/api/compiler/transformers/external-module-info.js +351 -0
  294. package/dist/api/compiler/transformers/for-await.d.ts +43 -0
  295. package/dist/api/compiler/transformers/for-await.js +469 -0
  296. package/dist/api/compiler/transformers/import-elision.d.ts +16 -0
  297. package/dist/api/compiler/transformers/import-elision.js +124 -0
  298. package/dist/api/compiler/transformers/jsx-entities.d.ts +1 -0
  299. package/dist/api/compiler/transformers/jsx-entities.js +256 -0
  300. package/dist/api/compiler/transformers/jsx.d.ts +71 -0
  301. package/dist/api/compiler/transformers/jsx.js +700 -0
  302. package/dist/api/compiler/transformers/legacy-decorators.d.ts +56 -0
  303. package/dist/api/compiler/transformers/legacy-decorators.js +564 -0
  304. package/dist/api/compiler/transformers/logical-assignment.d.ts +14 -0
  305. package/dist/api/compiler/transformers/logical-assignment.js +62 -0
  306. package/dist/api/compiler/transformers/module-utilities.d.ts +9 -0
  307. package/dist/api/compiler/transformers/module-utilities.js +36 -0
  308. package/dist/api/compiler/transformers/module.d.ts +49 -0
  309. package/dist/api/compiler/transformers/module.js +296 -0
  310. package/dist/api/compiler/transformers/named-evaluation.d.ts +26 -0
  311. package/dist/api/compiler/transformers/named-evaluation.js +266 -0
  312. package/dist/api/compiler/transformers/nullish-coalescing.d.ts +9 -0
  313. package/dist/api/compiler/transformers/nullish-coalescing.js +26 -0
  314. package/dist/api/compiler/transformers/object-rest-spread.d.ts +34 -0
  315. package/dist/api/compiler/transformers/object-rest-spread.js +411 -0
  316. package/dist/api/compiler/transformers/optional-catch.d.ts +9 -0
  317. package/dist/api/compiler/transformers/optional-catch.js +20 -0
  318. package/dist/api/compiler/transformers/optional-chain.d.ts +14 -0
  319. package/dist/api/compiler/transformers/optional-chain.js +188 -0
  320. package/dist/api/compiler/transformers/reference-resolver.d.ts +128 -0
  321. package/dist/api/compiler/transformers/reference-resolver.js +1155 -0
  322. package/dist/api/compiler/transformers/runtime-syntax.d.ts +71 -0
  323. package/dist/api/compiler/transformers/runtime-syntax.js +753 -0
  324. package/dist/api/compiler/transformers/subtree-facts.d.ts +9 -0
  325. package/dist/api/compiler/transformers/subtree-facts.js +203 -0
  326. package/dist/api/compiler/transformers/syntax-facts.d.ts +51 -0
  327. package/dist/api/compiler/transformers/syntax-facts.js +254 -0
  328. package/dist/api/compiler/transformers/tagged-template.d.ts +17 -0
  329. package/dist/api/compiler/transformers/tagged-template.js +148 -0
  330. package/dist/api/compiler/transformers/transformer.d.ts +17 -0
  331. package/dist/api/compiler/transformers/transformer.js +54 -0
  332. package/dist/api/compiler/transformers/type-eraser.d.ts +21 -0
  333. package/dist/api/compiler/transformers/type-eraser.js +346 -0
  334. package/dist/api/compiler/transformers/type-serialization.d.ts +20 -0
  335. package/dist/api/compiler/transformers/type-serialization.js +347 -0
  336. package/dist/api/compiler/transformers/using.d.ts +56 -0
  337. package/dist/api/compiler/transformers/using.js +453 -0
  338. package/dist/api/compiler/transformers/utilities.d.ts +50 -0
  339. package/dist/api/compiler/transformers/utilities.js +347 -0
  340. package/dist/api/compiler/transformers/visitor-base.d.ts +6 -0
  341. package/dist/api/compiler/transformers/visitor-base.js +817 -0
  342. package/dist/api/compiler/transformers/visitor-hooks.d.ts +29 -0
  343. package/dist/api/compiler/transformers/visitor-hooks.js +189 -0
  344. package/dist/api/compiler/tsconfig.d.ts +177 -0
  345. package/dist/api/compiler/tsconfig.js +1311 -0
  346. package/dist/api/compiler/type-printer.d.ts +15 -0
  347. package/dist/api/compiler/type-printer.js +74 -0
  348. package/dist/api/compiler/types.d.ts +87 -0
  349. package/dist/api/compiler/types.js +23 -0
  350. package/dist/api/compiler/unicode-identifiers.d.ts +2 -0
  351. package/dist/api/compiler/unicode-identifiers.js +209 -0
  352. package/dist/api/compiler/unicode-properties.d.ts +8 -0
  353. package/dist/api/compiler/unicode-properties.js +531 -0
  354. package/dist/api/compiler/vfs-match.d.ts +24 -0
  355. package/dist/api/compiler/vfs-match.js +587 -0
  356. package/dist/api/library/ast.d.ts +74 -0
  357. package/dist/api/library/ast.generated.d.ts +1145 -0
  358. package/dist/api/library/ast.generated.js +3 -0
  359. package/dist/api/library/ast.js +5 -0
  360. package/dist/api/library/checker.d.ts +51 -0
  361. package/dist/api/library/checker.js +318 -0
  362. package/dist/api/library/compiler-options.generated.d.ts +108 -0
  363. package/dist/api/library/compiler-options.generated.js +3 -0
  364. package/dist/api/library/diagnostics.d.ts +13 -0
  365. package/dist/api/library/diagnostics.js +50 -0
  366. package/dist/api/library/disk.d.ts +13 -0
  367. package/dist/api/library/disk.js +66 -0
  368. package/dist/api/library/enums.generated.d.ts +891 -0
  369. package/dist/api/library/enums.generated.js +916 -0
  370. package/dist/api/library/errors.d.ts +13 -0
  371. package/dist/api/library/errors.js +24 -0
  372. package/dist/api/library/host.d.ts +24 -0
  373. package/dist/api/library/host.js +52 -0
  374. package/dist/api/library/index.d.ts +14 -0
  375. package/dist/api/library/index.js +15 -0
  376. package/dist/api/library/nodes.d.ts +51 -0
  377. package/dist/api/library/nodes.js +196 -0
  378. package/dist/api/library/options.d.ts +144 -0
  379. package/dist/api/library/options.js +308 -0
  380. package/dist/api/library/parse.d.ts +19 -0
  381. package/dist/api/library/parse.js +41 -0
  382. package/dist/api/library/program.d.ts +21 -0
  383. package/dist/api/library/program.js +234 -0
  384. package/dist/api/library/symbols.d.ts +8 -0
  385. package/dist/api/library/symbols.js +11 -0
  386. package/dist/api/library/types.d.ts +313 -0
  387. package/dist/api/library/types.js +6 -0
  388. package/package.json +22 -8
  389. package/src/compiler/ast-utilities.ts +548 -0
  390. package/src/compiler/ast.ts +12862 -0
  391. package/src/compiler/astnav.ts +799 -0
  392. package/src/compiler/binder-utilities.ts +1392 -0
  393. package/src/compiler/binder.ts +2703 -0
  394. package/src/compiler/build-info.ts +1197 -0
  395. package/src/compiler/character-codes.ts +323 -0
  396. package/src/compiler/checker-calls.ts +2155 -0
  397. package/src/compiler/checker-classes.ts +706 -0
  398. package/src/compiler/checker-contextual.ts +1457 -0
  399. package/src/compiler/checker-declaration-order.ts +438 -0
  400. package/src/compiler/checker-declarations.ts +1194 -0
  401. package/src/compiler/checker-declared-types.ts +919 -0
  402. package/src/compiler/checker-decorators.ts +694 -0
  403. package/src/compiler/checker-deprecation.ts +359 -0
  404. package/src/compiler/checker-destructuring.ts +805 -0
  405. package/src/compiler/checker-elaboration.ts +477 -0
  406. package/src/compiler/checker-emit-helpers.ts +224 -0
  407. package/src/compiler/checker-emit-resolver.ts +769 -0
  408. package/src/compiler/checker-evaluator.ts +243 -0
  409. package/src/compiler/checker-expressions.ts +1831 -0
  410. package/src/compiler/checker-features.ts +361 -0
  411. package/src/compiler/checker-flow.ts +394 -0
  412. package/src/compiler/checker-functions.ts +1296 -0
  413. package/src/compiler/checker-generated-code.ts +227 -0
  414. package/src/compiler/checker-globals.ts +52 -0
  415. package/src/compiler/checker-grammar.ts +3584 -0
  416. package/src/compiler/checker-heritage.ts +1233 -0
  417. package/src/compiler/checker-inference.ts +2576 -0
  418. package/src/compiler/checker-iteration.ts +1206 -0
  419. package/src/compiler/checker-javascript.ts +502 -0
  420. package/src/compiler/checker-jsdoc.ts +360 -0
  421. package/src/compiler/checker-jsx.ts +1924 -0
  422. package/src/compiler/checker-literals.ts +61 -0
  423. package/src/compiler/checker-members.ts +2436 -0
  424. package/src/compiler/checker-modules.ts +2886 -0
  425. package/src/compiler/checker-narrowing.ts +3230 -0
  426. package/src/compiler/checker-object-literals.ts +575 -0
  427. package/src/compiler/checker-operators.ts +1422 -0
  428. package/src/compiler/checker-overloads.ts +328 -0
  429. package/src/compiler/checker-property-access.ts +906 -0
  430. package/src/compiler/checker-services.ts +1149 -0
  431. package/src/compiler/checker-signatures.ts +1032 -0
  432. package/src/compiler/checker-source-file.ts +732 -0
  433. package/src/compiler/checker-statements.ts +292 -0
  434. package/src/compiler/checker-super.ts +261 -0
  435. package/src/compiler/checker-symbol-types.ts +2107 -0
  436. package/src/compiler/checker-symbols.ts +2150 -0
  437. package/src/compiler/checker-type-factory.ts +2579 -0
  438. package/src/compiler/checker-type-nodes.ts +1033 -0
  439. package/src/compiler/checker-type-operators.ts +2502 -0
  440. package/src/compiler/checker-types.ts +2340 -0
  441. package/src/compiler/checker-unused.ts +642 -0
  442. package/src/compiler/checker-utilities.ts +161 -0
  443. package/src/compiler/checker.ts +1116 -0
  444. package/src/compiler/command-line.ts +436 -0
  445. package/src/compiler/compile-program.ts +439 -0
  446. package/src/compiler/decoder.ts +1209 -0
  447. package/src/compiler/diagnostic-locales.ts +86 -0
  448. package/src/compiler/diagnostic-messages.ts +2349 -0
  449. package/src/compiler/diagnostics.ts +897 -0
  450. package/src/compiler/emitter.ts +434 -0
  451. package/src/compiler/encoder.ts +1945 -0
  452. package/src/compiler/file-include.ts +673 -0
  453. package/src/compiler/file-loader.ts +1528 -0
  454. package/src/compiler/file-system.ts +143 -0
  455. package/src/compiler/flow.ts +89 -0
  456. package/src/compiler/help.ts +473 -0
  457. package/src/compiler/incremental.ts +2784 -0
  458. package/src/compiler/init.ts +141 -0
  459. package/src/compiler/instantiation.ts +894 -0
  460. package/src/compiler/jsdoc.ts +1386 -0
  461. package/src/compiler/link-tables.ts +98 -0
  462. package/src/compiler/locale-data.ts +203 -0
  463. package/src/compiler/locale.ts +307 -0
  464. package/src/compiler/locales/cs-CZ.ts +5 -0
  465. package/src/compiler/locales/de-DE.ts +5 -0
  466. package/src/compiler/locales/es-ES.ts +5 -0
  467. package/src/compiler/locales/fr-FR.ts +5 -0
  468. package/src/compiler/locales/it-IT.ts +5 -0
  469. package/src/compiler/locales/ja-JP.ts +5 -0
  470. package/src/compiler/locales/ko-KR.ts +5 -0
  471. package/src/compiler/locales/pl-PL.ts +5 -0
  472. package/src/compiler/locales/pt-BR.ts +5 -0
  473. package/src/compiler/locales/ru-RU.ts +5 -0
  474. package/src/compiler/locales/tr-TR.ts +5 -0
  475. package/src/compiler/locales/zh-CN.ts +5 -0
  476. package/src/compiler/locales/zh-TW.ts +5 -0
  477. package/src/compiler/module-resolution-types.ts +243 -0
  478. package/src/compiler/module-resolution.ts +2072 -0
  479. package/src/compiler/module-specifiers.ts +1491 -0
  480. package/src/compiler/name-resolver.ts +646 -0
  481. package/src/compiler/node-builder-names.ts +1069 -0
  482. package/src/compiler/node-builder-pseudo.ts +892 -0
  483. package/src/compiler/node-builder-reuse.ts +764 -0
  484. package/src/compiler/node-builder.ts +3425 -0
  485. package/src/compiler/option-declarations.ts +1560 -0
  486. package/src/compiler/options.ts +1576 -0
  487. package/src/compiler/output-paths.ts +334 -0
  488. package/src/compiler/package-json.ts +1083 -0
  489. package/src/compiler/parallel-check.ts +1951 -0
  490. package/src/compiler/parallel-parse.ts +590 -0
  491. package/src/compiler/parse-thread.ts +140 -0
  492. package/src/compiler/parser.ts +7716 -0
  493. package/src/compiler/path.ts +717 -0
  494. package/src/compiler/printer/async-helpers.ts +183 -0
  495. package/src/compiler/printer/auto-generate.ts +27 -0
  496. package/src/compiler/printer/decorator-helpers.ts +218 -0
  497. package/src/compiler/printer/emit-context.ts +679 -0
  498. package/src/compiler/printer/emit-flags.ts +64 -0
  499. package/src/compiler/printer/factory-base.ts +2577 -0
  500. package/src/compiler/printer/factory.ts +764 -0
  501. package/src/compiler/printer/helpers.ts +291 -0
  502. package/src/compiler/printer/name-generator.ts +372 -0
  503. package/src/compiler/printer/printer.ts +5072 -0
  504. package/src/compiler/printer/text-writer.ts +183 -0
  505. package/src/compiler/printer/utilities.ts +884 -0
  506. package/src/compiler/program-checker.ts +592 -0
  507. package/src/compiler/program-utilities.ts +435 -0
  508. package/src/compiler/program.ts +1419 -0
  509. package/src/compiler/pseudo-bigint.ts +62 -0
  510. package/src/compiler/regexp-checker.ts +1142 -0
  511. package/src/compiler/relations.ts +5149 -0
  512. package/src/compiler/reparser.ts +1566 -0
  513. package/src/compiler/scanner.ts +2951 -0
  514. package/src/compiler/show-config.ts +239 -0
  515. package/src/compiler/side-state.ts +125 -0
  516. package/src/compiler/sourcemap.ts +366 -0
  517. package/src/compiler/spelling.ts +122 -0
  518. package/src/compiler/symbol-accessibility.ts +1071 -0
  519. package/src/compiler/symbol.ts +439 -0
  520. package/src/compiler/symlinks.ts +137 -0
  521. package/src/compiler/syntax-kind.ts +391 -0
  522. package/src/compiler/thread-entry.ts +191 -0
  523. package/src/compiler/timeline.ts +53 -0
  524. package/src/compiler/transformers/alias-references.ts +757 -0
  525. package/src/compiler/transformers/async-utilities.ts +335 -0
  526. package/src/compiler/transformers/async.ts +838 -0
  527. package/src/compiler/transformers/class-fields.ts +2967 -0
  528. package/src/compiler/transformers/class-utilities.ts +324 -0
  529. package/src/compiler/transformers/commonjs-module.ts +1621 -0
  530. package/src/compiler/transformers/const-enum-inliner.ts +50 -0
  531. package/src/compiler/transformers/declarations-diagnostics.ts +832 -0
  532. package/src/compiler/transformers/declarations-pseudo.ts +966 -0
  533. package/src/compiler/transformers/declarations-resolver.ts +249 -0
  534. package/src/compiler/transformers/declarations-syntactic.ts +1859 -0
  535. package/src/compiler/transformers/declarations-tracker.ts +269 -0
  536. package/src/compiler/transformers/declarations.ts +3120 -0
  537. package/src/compiler/transformers/decorator-metadata.ts +697 -0
  538. package/src/compiler/transformers/decorator-utilities.ts +283 -0
  539. package/src/compiler/transformers/destructuring.ts +708 -0
  540. package/src/compiler/transformers/downlevel.ts +50 -0
  541. package/src/compiler/transformers/emit-resolver.ts +258 -0
  542. package/src/compiler/transformers/es-decorators.ts +2682 -0
  543. package/src/compiler/transformers/exponentiation.ts +80 -0
  544. package/src/compiler/transformers/external-module-info.ts +412 -0
  545. package/src/compiler/transformers/for-await.ts +687 -0
  546. package/src/compiler/transformers/import-elision.ts +152 -0
  547. package/src/compiler/transformers/jsx-entities.ts +256 -0
  548. package/src/compiler/transformers/jsx.ts +824 -0
  549. package/src/compiler/transformers/legacy-decorators.ts +726 -0
  550. package/src/compiler/transformers/logical-assignment.ts +75 -0
  551. package/src/compiler/transformers/module-utilities.ts +42 -0
  552. package/src/compiler/transformers/module.ts +474 -0
  553. package/src/compiler/transformers/named-evaluation.ts +389 -0
  554. package/src/compiler/transformers/nullish-coalescing.ts +35 -0
  555. package/src/compiler/transformers/object-rest-spread.ts +577 -0
  556. package/src/compiler/transformers/optional-catch.ts +29 -0
  557. package/src/compiler/transformers/optional-chain.ts +246 -0
  558. package/src/compiler/transformers/reference-resolver.ts +1201 -0
  559. package/src/compiler/transformers/runtime-syntax.ts +942 -0
  560. package/src/compiler/transformers/subtree-facts.ts +245 -0
  561. package/src/compiler/transformers/syntax-facts.ts +353 -0
  562. package/src/compiler/transformers/tagged-template.ts +167 -0
  563. package/src/compiler/transformers/transformer.ts +56 -0
  564. package/src/compiler/transformers/type-eraser.ts +520 -0
  565. package/src/compiler/transformers/type-serialization.ts +374 -0
  566. package/src/compiler/transformers/using.ts +613 -0
  567. package/src/compiler/transformers/utilities.ts +419 -0
  568. package/src/compiler/transformers/visitor-base.ts +1601 -0
  569. package/src/compiler/transformers/visitor-hooks.ts +252 -0
  570. package/src/compiler/tsc-build.ts +1418 -0
  571. package/src/compiler/tsc-cli.ts +666 -0
  572. package/src/compiler/tsc-compile.ts +437 -0
  573. package/src/compiler/tsc-watch.ts +854 -0
  574. package/src/compiler/tsconfig.ts +1574 -0
  575. package/src/compiler/type-printer.ts +110 -0
  576. package/src/compiler/types.ts +115 -0
  577. package/src/compiler/unicode-identifiers.ts +212 -0
  578. package/src/compiler/unicode-properties.ts +537 -0
  579. package/src/compiler/vfs-match.ts +597 -0
  580. package/src/compiler/xxh3.ts +650 -0
  581. package/src/library/ast.generated.ts +1685 -0
  582. package/src/library/ast.ts +104 -0
  583. package/src/library/checker.ts +384 -0
  584. package/src/library/compiler-options.generated.ts +114 -0
  585. package/src/library/diagnostics.ts +72 -0
  586. package/src/library/disk.ts +73 -0
  587. package/src/library/enums.generated.ts +1024 -0
  588. package/src/library/errors.ts +26 -0
  589. package/src/library/host.ts +63 -0
  590. package/src/library/index.ts +71 -0
  591. package/src/library/nodes.ts +232 -0
  592. package/src/library/options.ts +449 -0
  593. package/src/library/parse.ts +63 -0
  594. package/src/library/program.ts +293 -0
  595. package/src/library/symbols.ts +15 -0
  596. package/src/library/types.ts +359 -0
@@ -0,0 +1,2703 @@
1
+ // The binder: declares a symbol for each declaration in its container's table, merges
2
+ // declarations, reports binding errors, and builds the control flow graph.
3
+ //
4
+ // Fields of `instanceof`-narrowed nodes are read through `as` casts: scriptc reads them
5
+ // statically, but reads fields of a narrowed value dynamically.
6
+ import {
7
+ BinaryExpression,
8
+ BindingElement,
9
+ CallExpression,
10
+ CaseBlock,
11
+ CaseOrDefaultClause,
12
+ CatchClause,
13
+ ConditionalTypeNode,
14
+ ConditionalExpression,
15
+ DeleteExpression,
16
+ DoStatement,
17
+ ElementAccessExpression,
18
+ ExportAssignment,
19
+ ExportDeclaration,
20
+ ExpressionStatement,
21
+ ForInOrOfStatement,
22
+ ForStatement,
23
+ FunctionExpression,
24
+ Identifier,
25
+ IfStatement,
26
+ ImportClause,
27
+ KeywordExpression,
28
+ LabeledStatement,
29
+ MetaProperty,
30
+ ModifierFlags,
31
+ ModuleDeclaration,
32
+ type Node,
33
+ NonNullExpression,
34
+ NodeFlags,
35
+ type NodeList,
36
+ NodeVisitor,
37
+ ParameterDeclaration,
38
+ ParenthesizedExpression,
39
+ PatternAmbientModule,
40
+ PostfixUnaryExpression,
41
+ PrefixUnaryExpression,
42
+ PropertyAccessExpression,
43
+ QualifiedName,
44
+ type SourceFile,
45
+ SwitchStatement,
46
+ TryStatement,
47
+ TypeAliasDeclaration,
48
+ VariableDeclaration,
49
+ WhileStatement,
50
+ getArguments,
51
+ getBody,
52
+ getElements,
53
+ getExpression,
54
+ getInitializer,
55
+ getLabel,
56
+ getLocals,
57
+ getModifiers,
58
+ getName,
59
+ getParameters,
60
+ getPostfixToken,
61
+ getProperties,
62
+ getStatements,
63
+ getSymbol,
64
+ getText,
65
+ isDeclarationNode,
66
+ isLocalsContainer,
67
+ setEndFlowNode,
68
+ setFlowNode,
69
+ setLocalSymbol,
70
+ setLocals,
71
+ setNextContainer,
72
+ setReturnFlowNode,
73
+ setSymbol,
74
+ } from './ast.js';
75
+ import {
76
+ isAmbientModule,
77
+ isAssignmentOperator,
78
+ isFunctionLike,
79
+ isGlobalScopeAugmentation,
80
+ isInJSFile,
81
+ isLeftHandSideExpression,
82
+ isRequireCall,
83
+ isStringLiteralLike,
84
+ nodeIsMissing,
85
+ nodeIsPresent,
86
+ } from './ast-utilities.js';
87
+ import {
88
+ JSDeclarationKind,
89
+ ModuleInstanceState,
90
+ declarationNameToString,
91
+ expressionIsAlias,
92
+ getAssignmentDeclarationKind,
93
+ getCombinedModifierFlags,
94
+ getContainingClass,
95
+ getElementOrPropertyAccessName,
96
+ getErrorRangeForNode,
97
+ getImmediatelyInvokedFunctionExpression,
98
+ getModuleInstanceState,
99
+ StatementsByName,
100
+ getNameOfDeclaration,
101
+ getRangeOfTokenAtPosition,
102
+ getSourceTextOfNode,
103
+ hasDynamicName,
104
+ hasSyntacticModifier,
105
+ isAssignmentTarget,
106
+ isAsyncFunction,
107
+ isAutoAccessorPropertyDeclaration,
108
+ isBlockOrCatchScoped,
109
+ isBooleanLiteral,
110
+ isDeclarationStatementKind,
111
+ isDestructuringAssignment,
112
+ isDottedName,
113
+ isEntityNameExpression,
114
+ isEnumConst,
115
+ isExpandoInitializer,
116
+ isExpressionOfOptionalChainRoot,
117
+ isExternalModule,
118
+ isExternalOrCommonJSModule,
119
+ isIdentifierName,
120
+ isImplicitlyExportedJSDocDeclaration,
121
+ isInTopLevelContext,
122
+ isJsonSourceFile,
123
+ isLogicalExpression,
124
+ isLogicalOrCoalescingAssignmentExpression,
125
+ isLogicalOrCoalescingAssignmentOperator,
126
+ isLogicalOrCoalescingBinaryOperator,
127
+ isModuleAugmentationExternal,
128
+ isNullishCoalesce,
129
+ isObjectLiteralMethod,
130
+ isObjectLiteralOrClassExpressionMethodOrAccessor,
131
+ isOptionalChain,
132
+ isOptionalChainRoot,
133
+ isOutermostOptionalChain,
134
+ isParameterPropertyDeclaration,
135
+ isPartOfParameterDeclaration,
136
+ isPartOfTypeQuery,
137
+ isPotentiallyExecutableNode,
138
+ isPrologueDirective,
139
+ isPropertyNameLiteral,
140
+ isPushOrUnshiftIdentifier,
141
+ isSignedNumericLiteral,
142
+ isStatic,
143
+ isStringOrNumericLiteralLike,
144
+ isVariableDeclarationInitializedToRequire,
145
+ moduleExportNameIsDefault,
146
+ nodeText,
147
+ skipParentheses,
148
+ } from './binder-utilities.js';
149
+ import { Diagnostic, type DiagnosticMessage, Diagnostics } from './diagnostics.js';
150
+ import { FlowFlags, FlowNode, FlowReduceLabel, FlowSwitchClause } from './flow.js';
151
+ import { removeFileExtension } from './path.js';
152
+ import { getIdentifierToken, tokenToString } from './scanner.js';
153
+ import {
154
+ InternalSymbolName,
155
+ Symbol,
156
+ SymbolFlags,
157
+ type SymbolTable,
158
+ addDeclaration,
159
+ getExports,
160
+ getMembers,
161
+ getSymbolId,
162
+ internalSymbolNamePrefix,
163
+ } from './symbol.js';
164
+ import { SyntaxKind } from './syntax-kind.js';
165
+
166
+ /** How a node scopes declarations and control flow. */
167
+ export const enum ContainerFlags {
168
+ None = 0,
169
+ /** Sets the container and block-scope container, e.g. classes, object literals, interfaces. */
170
+ IsContainer = 1 << 0,
171
+ /** Sets only the block-scope container, e.g. blocks, catch clauses, `for` statements. */
172
+ IsBlockScopedContainer = 1 << 1,
173
+ /** Starts a new control flow graph. */
174
+ IsControlFlowContainer = 1 << 2,
175
+ IsFunctionLike = 1 << 3,
176
+ IsFunctionExpression = 1 << 4,
177
+ HasLocals = 1 << 5,
178
+ IsInterface = 1 << 6,
179
+ IsObjectLiteralOrClassExpressionMethodOrAccessor = 1 << 7,
180
+ IsThisContainer = 1 << 8,
181
+ PropagatesThisKeyword = 1 << 9,
182
+ }
183
+
184
+ export function getContainerFlags(node: Node): ContainerFlags {
185
+ switch (node.kind) {
186
+ case SyntaxKind.ClassExpression:
187
+ case SyntaxKind.ClassDeclaration:
188
+ case SyntaxKind.EnumDeclaration:
189
+ case SyntaxKind.ObjectLiteralExpression:
190
+ case SyntaxKind.TypeLiteral:
191
+ case SyntaxKind.JsxAttributes:
192
+ return ContainerFlags.IsContainer;
193
+ case SyntaxKind.InterfaceDeclaration:
194
+ return ContainerFlags.IsContainer | ContainerFlags.IsInterface;
195
+ case SyntaxKind.ModuleDeclaration:
196
+ case SyntaxKind.TypeAliasDeclaration:
197
+ case SyntaxKind.JSTypeAliasDeclaration:
198
+ case SyntaxKind.MappedType:
199
+ case SyntaxKind.IndexSignature:
200
+ return ContainerFlags.IsContainer | ContainerFlags.HasLocals;
201
+ case SyntaxKind.SourceFile:
202
+ return ContainerFlags.IsContainer | ContainerFlags.IsControlFlowContainer | ContainerFlags.HasLocals;
203
+ case SyntaxKind.GetAccessor:
204
+ case SyntaxKind.SetAccessor:
205
+ case SyntaxKind.MethodDeclaration:
206
+ if (isObjectLiteralOrClassExpressionMethodOrAccessor(node))
207
+ return (
208
+ ContainerFlags.IsContainer |
209
+ ContainerFlags.IsControlFlowContainer |
210
+ ContainerFlags.HasLocals |
211
+ ContainerFlags.IsFunctionLike |
212
+ ContainerFlags.IsObjectLiteralOrClassExpressionMethodOrAccessor |
213
+ ContainerFlags.IsThisContainer
214
+ );
215
+ return functionContainerFlags;
216
+ case SyntaxKind.Constructor:
217
+ case SyntaxKind.FunctionDeclaration:
218
+ case SyntaxKind.ClassStaticBlockDeclaration:
219
+ return functionContainerFlags;
220
+ case SyntaxKind.MethodSignature:
221
+ case SyntaxKind.CallSignature:
222
+ case SyntaxKind.FunctionType:
223
+ case SyntaxKind.ConstructSignature:
224
+ case SyntaxKind.ConstructorType:
225
+ return (
226
+ ContainerFlags.IsContainer |
227
+ ContainerFlags.IsControlFlowContainer |
228
+ ContainerFlags.HasLocals |
229
+ ContainerFlags.IsFunctionLike |
230
+ ContainerFlags.PropagatesThisKeyword
231
+ );
232
+ case SyntaxKind.FunctionExpression:
233
+ return (
234
+ ContainerFlags.IsContainer |
235
+ ContainerFlags.IsControlFlowContainer |
236
+ ContainerFlags.HasLocals |
237
+ ContainerFlags.IsFunctionLike |
238
+ ContainerFlags.IsFunctionExpression |
239
+ ContainerFlags.IsThisContainer
240
+ );
241
+ case SyntaxKind.ArrowFunction:
242
+ return (
243
+ ContainerFlags.IsContainer |
244
+ ContainerFlags.IsControlFlowContainer |
245
+ ContainerFlags.HasLocals |
246
+ ContainerFlags.IsFunctionLike |
247
+ ContainerFlags.IsFunctionExpression |
248
+ ContainerFlags.PropagatesThisKeyword
249
+ );
250
+ case SyntaxKind.ModuleBlock:
251
+ return ContainerFlags.IsControlFlowContainer;
252
+ case SyntaxKind.PropertyDeclaration:
253
+ return getInitializer(node) !== undefined
254
+ ? ContainerFlags.IsControlFlowContainer | ContainerFlags.IsThisContainer
255
+ : ContainerFlags.None;
256
+ case SyntaxKind.CatchClause:
257
+ case SyntaxKind.ForStatement:
258
+ case SyntaxKind.ForInStatement:
259
+ case SyntaxKind.ForOfStatement:
260
+ case SyntaxKind.CaseBlock:
261
+ return ContainerFlags.IsBlockScopedContainer | ContainerFlags.HasLocals;
262
+ case SyntaxKind.Block: {
263
+ const parent = node.parent!;
264
+ return isFunctionLike(parent) || parent.kind === SyntaxKind.ClassStaticBlockDeclaration
265
+ ? ContainerFlags.None
266
+ : ContainerFlags.IsBlockScopedContainer | ContainerFlags.HasLocals;
267
+ }
268
+ }
269
+ return ContainerFlags.None;
270
+ }
271
+
272
+ const functionContainerFlags =
273
+ ContainerFlags.IsContainer |
274
+ ContainerFlags.IsControlFlowContainer |
275
+ ContainerFlags.HasLocals |
276
+ ContainerFlags.IsFunctionLike |
277
+ ContainerFlags.IsThisContainer;
278
+
279
+ /** A label in scope for `break` and `continue`. */
280
+ class ActiveLabel {
281
+ readonly next: ActiveLabel | undefined;
282
+ readonly name: string;
283
+ readonly breakTarget: FlowNode;
284
+ continueTarget: FlowNode | undefined;
285
+ referenced: boolean;
286
+
287
+ constructor(next: ActiveLabel | undefined, name: string, breakTarget: FlowNode) {
288
+ this.next = next;
289
+ this.name = name;
290
+ this.breakTarget = breakTarget;
291
+ this.continueTarget = undefined;
292
+ this.referenced = false;
293
+ }
294
+ }
295
+
296
+ /** A JavaScript `F.x = …` assignment, bound once the whole file has its declarations. */
297
+ class ExpandoAssignment {
298
+ readonly node: Node;
299
+ readonly container: Node;
300
+ readonly blockScopeContainer: Node;
301
+
302
+ constructor(node: Node, container: Node, blockScopeContainer: Node) {
303
+ this.node = node;
304
+ this.container = container;
305
+ this.blockScopeContainer = blockScopeContainer;
306
+ }
307
+ }
308
+
309
+ /** Binds `file` unless it is already bound. */
310
+ export function bindSourceFile(file: SourceFile): void {
311
+ if (file.isBound) return;
312
+ const binder = new Binder(file);
313
+ binder.bind(file);
314
+ binder.bindDeferredExpandoAssignments(binder.expandoAssignments);
315
+ file.symbolCount = binder.symbolCount;
316
+ file.isBound = true;
317
+ }
318
+
319
+ /** The name of a private member `#description` of the class with symbol `containingClassSymbol`. */
320
+ export function getSymbolNameForPrivateIdentifier(containingClassSymbol: Symbol, description: string): string {
321
+ return internalSymbolNamePrefix + '#' + getSymbolId(containingClassSymbol) + '@' + description;
322
+ }
323
+
324
+ /**
325
+ * Makes `node` the value declaration of `symbol` unless it has one already. Non-assignment
326
+ * declarations win over JavaScript assignments, and other declarations over namespaces.
327
+ */
328
+ export function setValueDeclaration(symbol: Symbol, node: Node): void {
329
+ const valueDeclaration = symbol.valueDeclaration;
330
+ if (
331
+ valueDeclaration === undefined ||
332
+ (isAssignmentDeclaration(valueDeclaration) && !isAssignmentDeclaration(node)) ||
333
+ (valueDeclaration.kind !== node.kind && isEffectiveModuleDeclaration(valueDeclaration))
334
+ )
335
+ symbol.valueDeclaration = node;
336
+ }
337
+
338
+ function isAssignmentDeclaration(declaration: Node): boolean {
339
+ switch (declaration.kind) {
340
+ case SyntaxKind.BinaryExpression:
341
+ case SyntaxKind.PropertyAccessExpression:
342
+ case SyntaxKind.ElementAccessExpression:
343
+ case SyntaxKind.Identifier:
344
+ case SyntaxKind.CallExpression:
345
+ return true;
346
+ }
347
+ return false;
348
+ }
349
+
350
+ function isEffectiveModuleDeclaration(node: Node): boolean {
351
+ return node.kind === SyntaxKind.ModuleDeclaration || node.kind === SyntaxKind.Identifier;
352
+ }
353
+
354
+ class Binder extends NodeVisitor {
355
+ readonly file: SourceFile;
356
+ readonly unreachableFlow: FlowNode;
357
+ container: Node;
358
+ thisContainer: Node | undefined;
359
+ blockScopeContainer: Node;
360
+ lastContainer: Node | undefined;
361
+ currentFlow: FlowNode;
362
+ /**
363
+ * `currentFlow` as an optional value, shared by the nodes that store it: natively, converting a
364
+ * `FlowNode` to `FlowNode | undefined` allocates.
365
+ */
366
+ private storedFlow: FlowNode;
367
+ private storedFlowValue: FlowNode | undefined;
368
+ currentBreakTarget: FlowNode | undefined;
369
+ currentContinueTarget: FlowNode | undefined;
370
+ currentReturnTarget: FlowNode | undefined;
371
+ currentTrueTarget: FlowNode | undefined;
372
+ currentFalseTarget: FlowNode | undefined;
373
+ currentExceptionTarget: FlowNode | undefined;
374
+ preSwitchCaseFlow: FlowNode | undefined;
375
+ activeLabelList: ActiveLabel | undefined;
376
+ emitFlags: NodeFlags;
377
+ seenThisKeyword: boolean;
378
+ hasExplicitReturn: boolean;
379
+ hasFlowEffects: boolean;
380
+ inAssignmentPattern: boolean;
381
+ seenParseError: boolean;
382
+ symbolCount: number;
383
+ readonly notConstEnumOnlyModules: Set<Symbol>;
384
+ readonly expandoAssignments: ExpandoAssignment[];
385
+ /** For the module instance states of the file's module declarations (`getModuleInstanceState`). */
386
+ private readonly statementsByName: StatementsByName;
387
+
388
+ constructor(file: SourceFile) {
389
+ super();
390
+ this.file = file;
391
+ this.unreachableFlow = new FlowNode(FlowFlags.Unreachable, undefined, undefined);
392
+ this.container = file;
393
+ this.thisContainer = undefined;
394
+ this.blockScopeContainer = file;
395
+ this.lastContainer = undefined;
396
+ this.currentFlow = this.unreachableFlow;
397
+ this.storedFlow = this.unreachableFlow;
398
+ this.storedFlowValue = this.unreachableFlow;
399
+ this.currentBreakTarget = undefined;
400
+ this.currentContinueTarget = undefined;
401
+ this.currentReturnTarget = undefined;
402
+ this.currentTrueTarget = undefined;
403
+ this.currentFalseTarget = undefined;
404
+ this.currentExceptionTarget = undefined;
405
+ this.preSwitchCaseFlow = undefined;
406
+ this.activeLabelList = undefined;
407
+ this.emitFlags = NodeFlags.None;
408
+ this.seenThisKeyword = false;
409
+ this.hasExplicitReturn = false;
410
+ this.hasFlowEffects = false;
411
+ this.inAssignmentPattern = false;
412
+ this.seenParseError = false;
413
+ this.symbolCount = 0;
414
+ this.notConstEnumOnlyModules = new Set<Symbol>();
415
+ this.expandoAssignments = [];
416
+ this.statementsByName = new StatementsByName();
417
+ }
418
+
419
+ visitNode(node: Node): boolean {
420
+ this.bind(node);
421
+ return false;
422
+ }
423
+
424
+ /** `currentFlow`, for storing in a node's `flowNode`. */
425
+ currentFlowValue(): FlowNode | undefined {
426
+ if (this.storedFlow !== this.currentFlow) {
427
+ this.storedFlow = this.currentFlow;
428
+ this.storedFlowValue = this.currentFlow;
429
+ }
430
+ return this.storedFlowValue;
431
+ }
432
+
433
+ newSymbol(flags: SymbolFlags, name: string): Symbol {
434
+ this.symbolCount++;
435
+ return new Symbol(flags, name);
436
+ }
437
+
438
+ // Declarations
439
+
440
+ /**
441
+ * Declares `node` in `symbolTable` with flags `includes`, merging with an existing symbol
442
+ * of the same name unless its flags intersect `excludes`, which is reported as a duplicate.
443
+ * Callers pass `parent` as read from the container rather than narrowed, so that its members
444
+ * share the stored value (see `storedFlow`).
445
+ */
446
+ declareSymbol(
447
+ symbolTable: SymbolTable,
448
+ parent: Symbol | undefined,
449
+ node: Node,
450
+ includes: SymbolFlags,
451
+ excludes: SymbolFlags,
452
+ ): Symbol {
453
+ return this.declareSymbolEx(symbolTable, parent, node, includes, excludes, false, false);
454
+ }
455
+
456
+ declareSymbolEx(
457
+ symbolTable: SymbolTable,
458
+ parent: Symbol | undefined,
459
+ node: Node,
460
+ includes: SymbolFlags,
461
+ excludes: SymbolFlags,
462
+ isReplaceableByMethod: boolean,
463
+ isComputedName: boolean,
464
+ ): Symbol {
465
+ const isDefaultExport =
466
+ hasSyntacticModifier(node, ModifierFlags.Default) ||
467
+ (node.kind === SyntaxKind.ExportSpecifier && moduleExportNameIsDefault(getName(node)!));
468
+ // The exported symbol of `export default function/class` is always named "default".
469
+ const name = isComputedName
470
+ ? InternalSymbolName.Computed
471
+ : isDefaultExport && parent !== undefined
472
+ ? InternalSymbolName.Default
473
+ : this.getDeclarationName(node);
474
+ let symbol: Symbol | undefined;
475
+ if (name === InternalSymbolName.Missing) symbol = this.newSymbol(SymbolFlags.None, InternalSymbolName.Missing);
476
+ else {
477
+ // A new symbol starts without flags, so it can't conflict with `excludes`. A conflicting
478
+ // existing symbol gets errors on each declaration, and `node` gets a symbol of its own.
479
+ // A JavaScript constructor property (`isReplaceableByMethod`) always loses a conflict,
480
+ // which allows `this.method = this.method.bind(this)`.
481
+ symbol = symbolTable.get(name);
482
+ if (symbol === undefined) {
483
+ symbol = this.newSymbol(SymbolFlags.None, name);
484
+ symbolTable.set(name, symbol);
485
+ if (isReplaceableByMethod) symbol.flags |= SymbolFlags.ReplaceableByMethod;
486
+ } else if (isReplaceableByMethod && (symbol.flags & SymbolFlags.ReplaceableByMethod) === 0) {
487
+ return symbol;
488
+ } else if ((symbol.flags & excludes) !== 0) {
489
+ if ((symbol.flags & SymbolFlags.ReplaceableByMethod) !== 0) {
490
+ symbol = this.newSymbol(SymbolFlags.None, name);
491
+ symbolTable.set(name, symbol);
492
+ } else if (
493
+ !(
494
+ ((includes & SymbolFlags.Variable) !== 0 && (symbol.flags & SymbolFlags.Assignment) !== 0) ||
495
+ ((includes & SymbolFlags.Assignment) !== 0 && (symbol.flags & SymbolFlags.Variable) !== 0)
496
+ )
497
+ ) {
498
+ // Assignment declarations merge with variables whatever their other flags.
499
+ this.reportDuplicate(symbol, node, includes, isDefaultExport);
500
+ symbol = this.newSymbol(SymbolFlags.None, name);
501
+ }
502
+ }
503
+ }
504
+ this.addDeclarationToSymbol(symbol, node, includes);
505
+ if (symbol.parent === undefined) symbol.parent = parent;
506
+ else if (symbol.parent !== parent) throw new Error('Existing symbol parent should match new one');
507
+ return symbol;
508
+ }
509
+
510
+ reportDuplicate(symbol: Symbol, node: Node, includes: SymbolFlags, isDefaultExport: boolean): void {
511
+ let message =
512
+ (symbol.flags & SymbolFlags.BlockScopedVariable) !== 0
513
+ ? Diagnostics.Cannot_redeclare_block_scoped_variable_0
514
+ : Diagnostics.Duplicate_identifier_0;
515
+ let messageNeedsName = true;
516
+ if ((symbol.flags & SymbolFlags.Enum) !== 0 || (includes & SymbolFlags.Enum) !== 0) {
517
+ message = Diagnostics.Enum_declarations_can_only_merge_with_namespace_or_other_enum_declarations;
518
+ messageNeedsName = false;
519
+ }
520
+ let multipleDefaultExports = false;
521
+ if (symbol.declarations.length !== 0) {
522
+ // A default export (by modifier, or `export default` assignment) after another one.
523
+ if (isDefaultExport || (node instanceof ExportAssignment && !(node as ExportAssignment).isExportEquals)) {
524
+ message = Diagnostics.A_module_cannot_have_multiple_default_exports;
525
+ messageNeedsName = false;
526
+ multipleDefaultExports = true;
527
+ }
528
+ }
529
+ const declarationName = getNameOfDeclaration(node) ?? node;
530
+ const diagnostic = this.createDiagnosticForNode(
531
+ declarationName,
532
+ message,
533
+ messageNeedsName ? [this.getDisplayName(node)] : noArgs,
534
+ );
535
+ if (
536
+ node instanceof TypeAliasDeclaration &&
537
+ nodeIsMissing((node as TypeAliasDeclaration).type) &&
538
+ hasSyntacticModifier(node, ModifierFlags.Export) &&
539
+ (symbol.flags & (SymbolFlags.Alias | SymbolFlags.Type | SymbolFlags.Namespace)) !== 0
540
+ ) {
541
+ // `export type T;` may have meant `export type { T }`.
542
+ diagnostic.addRelatedInfo(
543
+ this.createDiagnosticForNode(node, Diagnostics.Did_you_mean_0, [
544
+ 'export type { ' + (node as TypeAliasDeclaration).name.text + ' }',
545
+ ]),
546
+ );
547
+ }
548
+ const declarations = symbol.declarations;
549
+ for (let index = 0; index < declarations.length; index++) {
550
+ const declaration = declarations[index]!;
551
+ const decl = getNameOfDeclaration(declaration) ?? declaration;
552
+ const d = this.createDiagnosticForNode(
553
+ decl,
554
+ message,
555
+ messageNeedsName ? [this.getDisplayName(declaration)] : noArgs,
556
+ );
557
+ if (multipleDefaultExports)
558
+ d.addRelatedInfo(
559
+ this.createDiagnosticForNode(
560
+ declarationName,
561
+ index === 0 ? Diagnostics.Another_export_default_is_here : Diagnostics.X_and_here,
562
+ noArgs,
563
+ ),
564
+ );
565
+ this.addDiagnostic(d);
566
+ if (multipleDefaultExports)
567
+ diagnostic.addRelatedInfo(
568
+ this.createDiagnosticForNode(decl, Diagnostics.The_first_export_default_is_here, noArgs),
569
+ );
570
+ }
571
+ this.addDiagnostic(diagnostic);
572
+ // An accessor conflicting with a non-accessor or the other accessor kind makes the symbol a
573
+ // full accessor, so later declarations conflict too.
574
+ const accessor = symbol.flags & SymbolFlags.Accessor;
575
+ if (accessor !== 0 && accessor !== (includes & SymbolFlags.Accessor)) symbol.flags |= SymbolFlags.Accessor;
576
+ }
577
+
578
+ /** The symbol name of a declaration. Computed names must be literals or well-known symbols. */
579
+ getDeclarationName(node: Node): string {
580
+ if (node instanceof ExportAssignment)
581
+ return (node as ExportAssignment).isExportEquals ? InternalSymbolName.ExportEquals : InternalSymbolName.Default;
582
+ const name = getNameOfDeclaration(node);
583
+ if (name !== undefined) {
584
+ if (isAmbientModule(node)) {
585
+ if (isGlobalScopeAugmentation(node)) return InternalSymbolName.Global;
586
+ return '"' + nodeText(name) + '"';
587
+ }
588
+ if (name.kind === SyntaxKind.PrivateIdentifier) {
589
+ // Private names are only allowed in classes; elsewhere there is already a parse error.
590
+ const containingClass = getContainingClass(node);
591
+ if (containingClass === undefined) return InternalSymbolName.Missing;
592
+ return getSymbolNameForPrivateIdentifier(getSymbol(containingClass)!, getText(name));
593
+ }
594
+ if (isPropertyNameLiteral(name) || name.kind === SyntaxKind.JsxNamespacedName) return nodeText(name);
595
+ if (name.kind === SyntaxKind.ComputedPropertyName) {
596
+ const expression = getExpression(name)!;
597
+ // A literal computed name is just the literal.
598
+ if (isStringOrNumericLiteralLike(expression)) return getText(expression);
599
+ if (expression instanceof PrefixUnaryExpression && isSignedNumericLiteral(expression)) {
600
+ const unary = expression as PrefixUnaryExpression;
601
+ return tokenToString(unary.operator) + getText(unary.operand);
602
+ }
603
+ throw new Error('Only computed properties with literal names have declaration names');
604
+ }
605
+ return InternalSymbolName.Missing;
606
+ }
607
+ switch (node.kind) {
608
+ case SyntaxKind.Constructor:
609
+ return InternalSymbolName.Constructor;
610
+ case SyntaxKind.FunctionType:
611
+ case SyntaxKind.CallSignature:
612
+ return InternalSymbolName.Call;
613
+ case SyntaxKind.ConstructorType:
614
+ case SyntaxKind.ConstructSignature:
615
+ return InternalSymbolName.New;
616
+ case SyntaxKind.IndexSignature:
617
+ return InternalSymbolName.Index;
618
+ case SyntaxKind.ExportDeclaration:
619
+ return InternalSymbolName.ExportStar;
620
+ case SyntaxKind.SourceFile:
621
+ case SyntaxKind.BinaryExpression:
622
+ return InternalSymbolName.ExportEquals;
623
+ }
624
+ return InternalSymbolName.Missing;
625
+ }
626
+
627
+ getDisplayName(node: Node): string {
628
+ const name = getName(node);
629
+ if (name !== undefined) return declarationNameToString(this.file, name);
630
+ const declarationName = this.getDeclarationName(node);
631
+ return declarationName !== InternalSymbolName.Missing ? declarationName : '(Missing)';
632
+ }
633
+
634
+ /**
635
+ * Declares a module or namespace member. Exported members get two symbols: a local one
636
+ * marked `ExportValue` and the export, so locals and exports of the same name conflict and
637
+ * the checker can tell a reference to the export from its local.
638
+ */
639
+ declareModuleMember(node: Node, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): Symbol {
640
+ const container = this.container;
641
+ const hasExportModifier =
642
+ (getCombinedModifierFlags(node) & ModifierFlags.Export) !== 0 || isImplicitlyExportedJSDocDeclaration(node);
643
+ if ((symbolFlags & SymbolFlags.Alias) !== 0) {
644
+ if (
645
+ node.kind === SyntaxKind.ExportSpecifier ||
646
+ (node.kind === SyntaxKind.ImportEqualsDeclaration && hasExportModifier)
647
+ ) {
648
+ const containerSymbol = getSymbol(container);
649
+ return this.declareSymbol(getExports(containerSymbol!), containerSymbol, node, symbolFlags, symbolExcludes);
650
+ }
651
+ return this.declareSymbol(this.localsOf(container), undefined, node, symbolFlags, symbolExcludes);
652
+ }
653
+ // Nested ambient modules (module augmentations) stay local so they never merge globally.
654
+ if (!isAmbientModule(node) && (hasExportModifier || (container.flags & NodeFlags.ExportContext) !== 0)) {
655
+ const containerSymbol = getSymbol(container);
656
+ // An unnamed default export has no local symbol.
657
+ if (
658
+ !isLocalsContainer(container) ||
659
+ (hasSyntacticModifier(node, ModifierFlags.Default) &&
660
+ this.getDeclarationName(node) === InternalSymbolName.Missing)
661
+ )
662
+ return this.declareSymbol(getExports(containerSymbol!), containerSymbol, node, symbolFlags, symbolExcludes);
663
+ const exportKind = (symbolFlags & SymbolFlags.Value) !== 0 ? SymbolFlags.ExportValue : SymbolFlags.None;
664
+ const local = this.declareSymbol(this.localsOf(container), undefined, node, exportKind, symbolExcludes);
665
+ local.exportSymbol = this.declareSymbol(
666
+ getExports(containerSymbol!),
667
+ containerSymbol,
668
+ node,
669
+ symbolFlags,
670
+ symbolExcludes,
671
+ );
672
+ setLocalSymbol(node, local);
673
+ return local;
674
+ }
675
+ return this.declareSymbol(this.localsOf(container), undefined, node, symbolFlags, symbolExcludes);
676
+ }
677
+
678
+ declareClassMember(node: Node, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): Symbol {
679
+ const classSymbol = getSymbol(this.container);
680
+ const table = isStatic(node) ? getExports(classSymbol!) : getMembers(classSymbol!);
681
+ return this.declareSymbol(table, classSymbol, node, symbolFlags, symbolExcludes);
682
+ }
683
+
684
+ declareSourceFileMember(node: Node, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): Symbol {
685
+ if (isExternalModule(this.file)) return this.declareModuleMember(node, symbolFlags, symbolExcludes);
686
+ return this.declareSymbol(this.localsOf(this.file), undefined, node, symbolFlags, symbolExcludes);
687
+ }
688
+
689
+ declareSymbolAndAddToSymbolTable(node: Node, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): Symbol {
690
+ const container = this.container;
691
+ switch (container.kind) {
692
+ case SyntaxKind.ModuleDeclaration:
693
+ return this.declareModuleMember(node, symbolFlags, symbolExcludes);
694
+ case SyntaxKind.SourceFile:
695
+ return this.declareSourceFileMember(node, symbolFlags, symbolExcludes);
696
+ case SyntaxKind.ClassExpression:
697
+ case SyntaxKind.ClassDeclaration:
698
+ return this.declareClassMember(node, symbolFlags, symbolExcludes);
699
+ case SyntaxKind.EnumDeclaration: {
700
+ const enumSymbol = getSymbol(container);
701
+ return this.declareSymbol(getExports(enumSymbol!), enumSymbol, node, symbolFlags, symbolExcludes);
702
+ }
703
+ case SyntaxKind.TypeLiteral:
704
+ case SyntaxKind.ObjectLiteralExpression:
705
+ case SyntaxKind.InterfaceDeclaration:
706
+ case SyntaxKind.JsxAttributes: {
707
+ const containerSymbol = getSymbol(container);
708
+ return this.declareSymbol(getMembers(containerSymbol!), containerSymbol, node, symbolFlags, symbolExcludes);
709
+ }
710
+ case SyntaxKind.FunctionType:
711
+ case SyntaxKind.ConstructorType:
712
+ case SyntaxKind.CallSignature:
713
+ case SyntaxKind.ConstructSignature:
714
+ case SyntaxKind.IndexSignature:
715
+ case SyntaxKind.MethodDeclaration:
716
+ case SyntaxKind.MethodSignature:
717
+ case SyntaxKind.Constructor:
718
+ case SyntaxKind.GetAccessor:
719
+ case SyntaxKind.SetAccessor:
720
+ case SyntaxKind.FunctionDeclaration:
721
+ case SyntaxKind.FunctionExpression:
722
+ case SyntaxKind.ArrowFunction:
723
+ case SyntaxKind.ClassStaticBlockDeclaration:
724
+ case SyntaxKind.TypeAliasDeclaration:
725
+ case SyntaxKind.JSTypeAliasDeclaration:
726
+ case SyntaxKind.MappedType:
727
+ return this.declareSymbol(this.localsOf(container), undefined, node, symbolFlags, symbolExcludes);
728
+ }
729
+ throw new Error('Unhandled case in declareSymbolAndAddToSymbolTable');
730
+ }
731
+
732
+ /** The locals table of `container`, created if missing. */
733
+ localsOf(container: Node): SymbolTable {
734
+ let locals = getLocals(container);
735
+ if (locals === undefined) {
736
+ locals = new Map<string, Symbol>();
737
+ setLocals(container, locals);
738
+ }
739
+ return locals;
740
+ }
741
+
742
+ addDeclarationToSymbol(symbol: Symbol, node: Node, symbolFlags: SymbolFlags): void {
743
+ symbol.flags |= symbolFlags;
744
+ setSymbol(node, symbol);
745
+ if (symbol.declarations.indexOf(node) < 0) addDeclaration(symbol, node);
746
+ // A const-enum-only namespace merged with a class, function or regular enum isn't one anymore.
747
+ if (
748
+ (symbol.flags & SymbolFlags.ConstEnumOnlyModule) !== 0 &&
749
+ (symbol.flags & (SymbolFlags.Function | SymbolFlags.Class | SymbolFlags.RegularEnum)) !== 0
750
+ ) {
751
+ symbol.flags &= ~SymbolFlags.ConstEnumOnlyModule;
752
+ this.notConstEnumOnlyModules.add(symbol);
753
+ }
754
+ if ((symbolFlags & SymbolFlags.Value) !== 0) setValueDeclaration(symbol, node);
755
+ }
756
+
757
+ bindAnonymousDeclaration(node: Node, symbolFlags: SymbolFlags, name: string): Symbol {
758
+ const symbol = this.newSymbol(symbolFlags, name);
759
+ if ((symbolFlags & (SymbolFlags.EnumMember | SymbolFlags.ClassMember)) !== 0)
760
+ symbol.parent = getSymbol(this.container);
761
+ this.addDeclarationToSymbol(symbol, node, symbolFlags);
762
+ return symbol;
763
+ }
764
+
765
+ bindBlockScopedDeclaration(node: Node, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): Symbol {
766
+ const blockScopeContainer = this.blockScopeContainer;
767
+ switch (blockScopeContainer.kind) {
768
+ case SyntaxKind.ModuleDeclaration:
769
+ return this.declareModuleMember(node, symbolFlags, symbolExcludes);
770
+ case SyntaxKind.SourceFile:
771
+ if (isExternalOrCommonJSModule(this.file)) return this.declareModuleMember(node, symbolFlags, symbolExcludes);
772
+ break;
773
+ }
774
+ return this.declareSymbol(this.localsOf(blockScopeContainer), undefined, node, symbolFlags, symbolExcludes);
775
+ }
776
+
777
+ // Diagnostics
778
+
779
+ createDiagnosticForNode(node: Node, message: DiagnosticMessage, args: readonly string[]): Diagnostic {
780
+ const range = getErrorRangeForNode(this.file, node);
781
+ return new Diagnostic(this.file.diagnosticFile(), range.pos, range.end, message, args);
782
+ }
783
+
784
+ errorOnNode(node: Node, message: DiagnosticMessage, args: readonly string[]): void {
785
+ this.addDiagnostic(this.createDiagnosticForNode(node, message, args));
786
+ }
787
+
788
+ errorOnFirstToken(node: Node, message: DiagnosticMessage, args: readonly string[]): void {
789
+ const range = getRangeOfTokenAtPosition(this.file, node.pos);
790
+ this.addDiagnostic(new Diagnostic(this.file.diagnosticFile(), range.pos, range.end, message, args));
791
+ }
792
+
793
+ addDiagnostic(diagnostic: Diagnostic): void {
794
+ this.file.bindDiagnostics.push(diagnostic);
795
+ }
796
+
797
+ // Traversal
798
+
799
+ bindOptional(node: Node | undefined): void {
800
+ if (node !== undefined) this.bind(node);
801
+ }
802
+
803
+ bind(node: Node): void {
804
+ // Declare the node's symbol in the exports or members of the container's symbol, or in
805
+ // the container's locals; anonymous declarations like type literals go in no table.
806
+ switch (node.kind) {
807
+ case SyntaxKind.Identifier:
808
+ (node as Identifier).flowNode = this.currentFlowValue();
809
+ this.checkContextualIdentifier(node as Identifier);
810
+ break;
811
+ case SyntaxKind.ThisKeyword:
812
+ case SyntaxKind.SuperKeyword:
813
+ if (node.kind === SyntaxKind.ThisKeyword) this.seenThisKeyword = true;
814
+ if (node instanceof KeywordExpression) (node as KeywordExpression).flowNode = this.currentFlowValue();
815
+ break;
816
+ case SyntaxKind.QualifiedName:
817
+ if (isPartOfTypeQuery(node)) (node as QualifiedName).flowNode = this.currentFlowValue();
818
+ break;
819
+ case SyntaxKind.MetaProperty:
820
+ (node as MetaProperty).flowNode = this.currentFlowValue();
821
+ break;
822
+ case SyntaxKind.PrivateIdentifier:
823
+ this.checkPrivateIdentifier(node);
824
+ break;
825
+ case SyntaxKind.PropertyAccessExpression:
826
+ case SyntaxKind.ElementAccessExpression:
827
+ if (isNarrowableReference(node)) setFlowNode(node, this.currentFlowValue());
828
+ break;
829
+ case SyntaxKind.BinaryExpression:
830
+ switch (getAssignmentDeclarationKind(node)) {
831
+ case JSDeclarationKind.ModuleExports:
832
+ this.bindModuleExportsAssignment(node as BinaryExpression);
833
+ break;
834
+ case JSDeclarationKind.ExportsProperty:
835
+ this.bindExportsOrObjectDefineProperty(node);
836
+ break;
837
+ case JSDeclarationKind.Property:
838
+ this.bindExpandoPropertyAssignment(node);
839
+ break;
840
+ case JSDeclarationKind.ThisProperty:
841
+ this.bindThisPropertyAssignment(node as BinaryExpression);
842
+ break;
843
+ }
844
+ this.checkStrictModeBinaryExpression(node as BinaryExpression);
845
+ break;
846
+ case SyntaxKind.CatchClause:
847
+ this.checkStrictModeCatchClause(node as CatchClause);
848
+ break;
849
+ case SyntaxKind.DeleteExpression:
850
+ this.checkStrictModeDeleteExpression(node as DeleteExpression);
851
+ break;
852
+ case SyntaxKind.PostfixUnaryExpression:
853
+ this.checkStrictModeEvalOrArguments(node, (node as PostfixUnaryExpression).operand);
854
+ break;
855
+ case SyntaxKind.PrefixUnaryExpression: {
856
+ const operator = (node as PrefixUnaryExpression).operator;
857
+ if (operator === SyntaxKind.PlusPlusToken || operator === SyntaxKind.MinusMinusToken)
858
+ this.checkStrictModeEvalOrArguments(node, (node as PrefixUnaryExpression).operand);
859
+ break;
860
+ }
861
+ case SyntaxKind.WithStatement:
862
+ this.errorOnFirstToken(node, Diagnostics.X_with_statements_are_not_allowed_in_strict_mode, noArgs);
863
+ break;
864
+ case SyntaxKind.LabeledStatement: {
865
+ const statement = (node as LabeledStatement).statement;
866
+ if (isDeclarationStatementKind(statement.kind) || statement.kind === SyntaxKind.VariableStatement)
867
+ this.errorOnFirstToken((node as LabeledStatement).label, Diagnostics.A_label_is_not_allowed_here, noArgs);
868
+ break;
869
+ }
870
+ case SyntaxKind.ThisType:
871
+ this.seenThisKeyword = true;
872
+ break;
873
+ case SyntaxKind.TypeParameter:
874
+ this.bindTypeParameter(node);
875
+ break;
876
+ case SyntaxKind.Parameter:
877
+ this.bindParameter(node as ParameterDeclaration);
878
+ break;
879
+ case SyntaxKind.VariableDeclaration:
880
+ this.bindVariableDeclarationOrBindingElement(node);
881
+ break;
882
+ case SyntaxKind.BindingElement:
883
+ (node as BindingElement).flowNode = this.currentFlowValue();
884
+ this.bindVariableDeclarationOrBindingElement(node);
885
+ break;
886
+ case SyntaxKind.PropertyDeclaration:
887
+ case SyntaxKind.PropertySignature: {
888
+ const isAutoAccessor = isAutoAccessorPropertyDeclaration(node);
889
+ this.bindPropertyOrMethodOrAccessor(
890
+ node,
891
+ (isAutoAccessor ? SymbolFlags.Accessor : SymbolFlags.Property) | optionalSymbolFlag(node),
892
+ isAutoAccessor ? SymbolFlags.AccessorExcludes : SymbolFlags.PropertyExcludes,
893
+ );
894
+ break;
895
+ }
896
+ case SyntaxKind.PropertyAssignment:
897
+ case SyntaxKind.ShorthandPropertyAssignment:
898
+ this.bindPropertyOrMethodOrAccessor(node, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
899
+ break;
900
+ case SyntaxKind.EnumMember:
901
+ this.bindPropertyOrMethodOrAccessor(node, SymbolFlags.EnumMember, SymbolFlags.EnumMemberExcludes);
902
+ break;
903
+ case SyntaxKind.CallSignature:
904
+ case SyntaxKind.ConstructSignature:
905
+ case SyntaxKind.IndexSignature:
906
+ this.declareSymbolAndAddToSymbolTable(node, SymbolFlags.Signature, SymbolFlags.None);
907
+ break;
908
+ case SyntaxKind.MethodDeclaration:
909
+ case SyntaxKind.MethodSignature:
910
+ this.bindPropertyOrMethodOrAccessor(
911
+ node,
912
+ SymbolFlags.Method | optionalSymbolFlag(node),
913
+ isObjectLiteralMethod(node) ? SymbolFlags.Value : SymbolFlags.MethodExcludes,
914
+ );
915
+ break;
916
+ case SyntaxKind.FunctionDeclaration:
917
+ this.bindFunctionDeclaration(node);
918
+ break;
919
+ case SyntaxKind.Constructor:
920
+ this.declareSymbolAndAddToSymbolTable(node, SymbolFlags.Constructor, SymbolFlags.None);
921
+ break;
922
+ case SyntaxKind.GetAccessor:
923
+ this.bindPropertyOrMethodOrAccessor(node, SymbolFlags.GetAccessor, SymbolFlags.GetAccessorExcludes);
924
+ break;
925
+ case SyntaxKind.SetAccessor:
926
+ this.bindPropertyOrMethodOrAccessor(node, SymbolFlags.SetAccessor, SymbolFlags.SetAccessorExcludes);
927
+ break;
928
+ case SyntaxKind.FunctionType:
929
+ case SyntaxKind.ConstructorType:
930
+ this.bindFunctionOrConstructorType(node);
931
+ break;
932
+ case SyntaxKind.TypeLiteral:
933
+ case SyntaxKind.MappedType:
934
+ this.bindAnonymousDeclaration(node, SymbolFlags.TypeLiteral, InternalSymbolName.Type);
935
+ break;
936
+ case SyntaxKind.ObjectLiteralExpression:
937
+ this.bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, InternalSymbolName.Object);
938
+ break;
939
+ case SyntaxKind.FunctionExpression:
940
+ case SyntaxKind.ArrowFunction:
941
+ this.bindFunctionExpression(node);
942
+ break;
943
+ case SyntaxKind.ClassExpression:
944
+ case SyntaxKind.ClassDeclaration:
945
+ this.bindClassLikeDeclaration(node);
946
+ break;
947
+ case SyntaxKind.InterfaceDeclaration:
948
+ this.bindBlockScopedDeclaration(node, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes);
949
+ break;
950
+ case SyntaxKind.CallExpression:
951
+ switch (getAssignmentDeclarationKind(node)) {
952
+ case JSDeclarationKind.ObjectDefinePropertyValue:
953
+ this.bindExpandoPropertyAssignment(node);
954
+ break;
955
+ case JSDeclarationKind.ObjectDefinePropertyExports:
956
+ this.bindExportsOrObjectDefineProperty(node);
957
+ break;
958
+ }
959
+ // Only to detect CommonJS modules.
960
+ if (isInJSFile(node) && this.file.commonJSModuleIndicator === undefined && isRequireCall(node, false))
961
+ this.setCommonJSModuleIndicator(node);
962
+ break;
963
+ case SyntaxKind.TypeAliasDeclaration:
964
+ this.bindBlockScopedDeclaration(node, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes);
965
+ break;
966
+ case SyntaxKind.JSTypeAliasDeclaration:
967
+ // Top-level ones are bound by bindContainer, after CommonJS module indicators.
968
+ if (this.blockScopeContainer.kind !== SyntaxKind.SourceFile)
969
+ this.bindBlockScopedDeclaration(node, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes);
970
+ break;
971
+ case SyntaxKind.EnumDeclaration:
972
+ if (isEnumConst(node))
973
+ this.bindBlockScopedDeclaration(node, SymbolFlags.ConstEnum, SymbolFlags.ConstEnumExcludes);
974
+ else this.bindBlockScopedDeclaration(node, SymbolFlags.RegularEnum, SymbolFlags.RegularEnumExcludes);
975
+ break;
976
+ case SyntaxKind.ModuleDeclaration:
977
+ this.bindModuleDeclaration(node as ModuleDeclaration);
978
+ break;
979
+ case SyntaxKind.ImportEqualsDeclaration:
980
+ case SyntaxKind.NamespaceImport:
981
+ case SyntaxKind.ImportSpecifier:
982
+ case SyntaxKind.ExportSpecifier:
983
+ this.declareSymbolAndAddToSymbolTable(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes);
984
+ break;
985
+ case SyntaxKind.NamespaceExportDeclaration:
986
+ this.bindNamespaceExportDeclaration(node);
987
+ break;
988
+ case SyntaxKind.ImportClause:
989
+ if ((node as ImportClause).name !== undefined)
990
+ this.declareSymbolAndAddToSymbolTable(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes);
991
+ break;
992
+ case SyntaxKind.ExportDeclaration:
993
+ this.bindExportDeclaration(node as ExportDeclaration);
994
+ break;
995
+ case SyntaxKind.ExportAssignment:
996
+ this.bindExportAssignment(node as ExportAssignment);
997
+ break;
998
+ case SyntaxKind.SourceFile:
999
+ this.bindSourceFileIfExternalModule(node as SourceFile);
1000
+ break;
1001
+ case SyntaxKind.JsxAttributes:
1002
+ this.bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, InternalSymbolName.JSXAttributes);
1003
+ break;
1004
+ case SyntaxKind.JsxAttribute:
1005
+ this.declareSymbolAndAddToSymbolTable(node, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
1006
+ break;
1007
+ }
1008
+ // Then bind the children, tracking the current container. Tokens have no children.
1009
+ let thisNodeOrAnySubnodesHasError = (node.flags & NodeFlags.ThisNodeHasError) !== 0;
1010
+ if (node.kind > SyntaxKind.LastToken) {
1011
+ const saveSeenParseError = this.seenParseError;
1012
+ this.seenParseError = false;
1013
+ const containerFlags = getContainerFlags(node);
1014
+ if (containerFlags === ContainerFlags.None) this.bindChildren(node);
1015
+ else this.bindContainer(node, containerFlags);
1016
+ if (this.seenParseError) thisNodeOrAnySubnodesHasError = true;
1017
+ this.seenParseError = saveSeenParseError;
1018
+ }
1019
+ if (thisNodeOrAnySubnodesHasError) {
1020
+ node.flags |= NodeFlags.ThisNodeOrAnySubNodesHasError;
1021
+ this.seenParseError = true;
1022
+ }
1023
+ }
1024
+
1025
+ /**
1026
+ * Binds the children of a container. Containers are chained in declaration order for the
1027
+ * checker's local name lookups.
1028
+ */
1029
+ bindContainer(node: Node, containerFlags: ContainerFlags): void {
1030
+ const saveContainer = this.container;
1031
+ const saveThisContainer = this.thisContainer;
1032
+ const saveBlockScopeContainer = this.blockScopeContainer;
1033
+ // Locals are created on first use, so block-scoped containers without declarations stay cheap.
1034
+ if ((containerFlags & ContainerFlags.IsContainer) !== 0) {
1035
+ this.container = node;
1036
+ this.blockScopeContainer = node;
1037
+ if ((containerFlags & ContainerFlags.HasLocals) !== 0) this.addToContainerChain(node);
1038
+ } else if ((containerFlags & ContainerFlags.IsBlockScopedContainer) !== 0) {
1039
+ this.blockScopeContainer = node;
1040
+ this.addToContainerChain(node);
1041
+ }
1042
+ if ((containerFlags & ContainerFlags.IsThisContainer) !== 0) this.thisContainer = node;
1043
+ if ((containerFlags & ContainerFlags.IsControlFlowContainer) !== 0)
1044
+ this.bindControlFlowContainer(node, containerFlags);
1045
+ else if ((containerFlags & ContainerFlags.IsInterface) !== 0) {
1046
+ const saveSeenThisKeyword = this.seenThisKeyword;
1047
+ this.seenThisKeyword = false;
1048
+ this.bindChildren(node);
1049
+ // ContainsThis can't overlap with HasExtendedUnicodeEscape, which is for identifiers.
1050
+ if (this.seenThisKeyword) node.flags |= NodeFlags.ContainsThis;
1051
+ else node.flags &= ~NodeFlags.ContainsThis;
1052
+ this.seenThisKeyword = saveSeenThisKeyword;
1053
+ } else this.bindChildren(node);
1054
+ if (node.kind === SyntaxKind.SourceFile) this.finishSourceFile(node as SourceFile);
1055
+ else if (isAmbientModule(node)) this.bindCommonJSTypeExports(getSymbol(node));
1056
+ this.container = saveContainer;
1057
+ this.thisContainer = saveThisContainer;
1058
+ this.blockScopeContainer = saveBlockScopeContainer;
1059
+ }
1060
+
1061
+ bindControlFlowContainer(node: Node, containerFlags: ContainerFlags): void {
1062
+ const saveCurrentFlow = this.currentFlow;
1063
+ const saveBreakTarget = this.currentBreakTarget;
1064
+ const saveContinueTarget = this.currentContinueTarget;
1065
+ const saveReturnTarget = this.currentReturnTarget;
1066
+ const saveExceptionTarget = this.currentExceptionTarget;
1067
+ const saveActiveLabelList = this.activeLabelList;
1068
+ const saveHasExplicitReturn = this.hasExplicitReturn;
1069
+ const saveSeenThisKeyword = this.seenThisKeyword;
1070
+ // A non-async, non-generator IIFE is part of the containing control flow; its returns act
1071
+ // like breaks to a label past the body.
1072
+ const isImmediatelyInvoked =
1073
+ ((containerFlags & ContainerFlags.IsFunctionExpression) !== 0 &&
1074
+ !hasSyntacticModifier(node, ModifierFlags.Async) &&
1075
+ !isGeneratorFunctionExpression(node) &&
1076
+ getImmediatelyInvokedFunctionExpression(node) !== undefined) ||
1077
+ node.kind === SyntaxKind.ClassStaticBlockDeclaration;
1078
+ if (!isImmediatelyInvoked) {
1079
+ const flowStart = new FlowNode(FlowFlags.Start, undefined, undefined);
1080
+ this.currentFlow = flowStart;
1081
+ if (
1082
+ (containerFlags &
1083
+ (ContainerFlags.IsFunctionExpression | ContainerFlags.IsObjectLiteralOrClassExpressionMethodOrAccessor)) !==
1084
+ 0
1085
+ )
1086
+ flowStart.node = node;
1087
+ }
1088
+ // IIFEs and constructors get a return graph; constructors use it to check property initialization.
1089
+ this.currentReturnTarget =
1090
+ isImmediatelyInvoked || node.kind === SyntaxKind.Constructor ? this.createBranchLabel() : undefined;
1091
+ this.currentExceptionTarget = undefined;
1092
+ this.currentBreakTarget = undefined;
1093
+ this.currentContinueTarget = undefined;
1094
+ this.activeLabelList = undefined;
1095
+ this.hasExplicitReturn = false;
1096
+ this.seenThisKeyword = false;
1097
+ this.bindChildren(node);
1098
+ node.flags &= ~(NodeFlags.ReachabilityAndEmitFlags | NodeFlags.ContainsThis);
1099
+ if (
1100
+ (this.currentFlow.flags & FlowFlags.Unreachable) === 0 &&
1101
+ (containerFlags & ContainerFlags.IsFunctionLike) !== 0 &&
1102
+ node.kind !== SyntaxKind.ClassStaticBlockDeclaration &&
1103
+ nodeIsPresent(getBody(node))
1104
+ ) {
1105
+ node.flags |= NodeFlags.HasImplicitReturn;
1106
+ if (this.hasExplicitReturn) node.flags |= NodeFlags.HasExplicitReturn;
1107
+ setEndFlowNode(node, this.currentFlow);
1108
+ }
1109
+ if (this.seenThisKeyword) node.flags |= NodeFlags.ContainsThis;
1110
+ if (node.kind === SyntaxKind.SourceFile) {
1111
+ node.flags |= this.emitFlags;
1112
+ (node as SourceFile).endFlowNode = this.currentFlow;
1113
+ }
1114
+ const returnTarget = this.currentReturnTarget;
1115
+ if (returnTarget !== undefined) {
1116
+ this.addAntecedent(returnTarget, this.currentFlow);
1117
+ this.currentFlow = this.finishFlowLabel(returnTarget);
1118
+ if (node.kind === SyntaxKind.Constructor || node.kind === SyntaxKind.ClassStaticBlockDeclaration)
1119
+ setReturnFlowNode(node, this.currentFlow);
1120
+ }
1121
+ if (!isImmediatelyInvoked) this.currentFlow = saveCurrentFlow;
1122
+ this.currentBreakTarget = saveBreakTarget;
1123
+ this.currentContinueTarget = saveContinueTarget;
1124
+ this.currentReturnTarget = saveReturnTarget;
1125
+ this.currentExceptionTarget = saveExceptionTarget;
1126
+ this.activeLabelList = saveActiveLabelList;
1127
+ this.hasExplicitReturn = saveHasExplicitReturn;
1128
+ this.seenThisKeyword =
1129
+ (containerFlags & ContainerFlags.PropagatesThisKeyword) !== 0
1130
+ ? saveSeenThisKeyword || this.seenThisKeyword
1131
+ : saveSeenThisKeyword;
1132
+ }
1133
+
1134
+ finishSourceFile(file: SourceFile): void {
1135
+ if (isInJSFile(file)) {
1136
+ // Top-level @typedef aliases wait until CommonJS module indicators are known.
1137
+ for (const statement of file.statements.nodes)
1138
+ if (statement.kind === SyntaxKind.JSTypeAliasDeclaration)
1139
+ this.bindBlockScopedDeclaration(statement, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes);
1140
+ if (file.commonJSModuleIndicator !== undefined) {
1141
+ this.declareCommonJSVariable('module');
1142
+ this.declareCommonJSVariable('exports');
1143
+ }
1144
+ }
1145
+ if (isExternalOrCommonJSModule(file)) this.bindCommonJSTypeExports(file.symbol);
1146
+ }
1147
+
1148
+ declareCommonJSVariable(name: string): void {
1149
+ const locals = this.localsOf(this.file);
1150
+ if (locals.has(name)) return;
1151
+ const symbol = this.newSymbol(SymbolFlags.FunctionScopedVariable | SymbolFlags.ModuleExports, name);
1152
+ addDeclaration(symbol, this.file);
1153
+ symbol.valueDeclaration = this.file;
1154
+ if (name === 'module') {
1155
+ const exportsProperty = this.newSymbol(SymbolFlags.ModuleExports | SymbolFlags.Property, 'exports');
1156
+ exportsProperty.declarations = symbol.declarations;
1157
+ exportsProperty.valueDeclaration = this.file;
1158
+ exportsProperty.parent = symbol;
1159
+ getMembers(symbol).set('exports', exportsProperty);
1160
+ }
1161
+ locals.set(name, symbol);
1162
+ }
1163
+
1164
+ addToContainerChain(next: Node): void {
1165
+ const last = this.lastContainer;
1166
+ if (last !== undefined) setNextContainer(last, next);
1167
+ this.lastContainer = next;
1168
+ }
1169
+
1170
+ bindChildren(node: Node): void {
1171
+ const saveInAssignmentPattern = this.inAssignmentPattern;
1172
+ // Most nodes can't be in an assignment pattern; those that can restore it below.
1173
+ this.inAssignmentPattern = false;
1174
+ if (this.currentFlow === this.unreachableFlow) {
1175
+ setFlowNode(node, undefined);
1176
+ if (isPotentiallyExecutableNode(node)) node.flags |= NodeFlags.Unreachable;
1177
+ node.forEachChild(this);
1178
+ this.inAssignmentPattern = saveInAssignmentPattern;
1179
+ return;
1180
+ }
1181
+ if (node.kind >= SyntaxKind.FirstStatement && node.kind <= SyntaxKind.LastStatement)
1182
+ setFlowNode(node, this.currentFlowValue());
1183
+ switch (node.kind) {
1184
+ case SyntaxKind.WhileStatement:
1185
+ this.bindWhileStatement(node as WhileStatement);
1186
+ break;
1187
+ case SyntaxKind.DoStatement:
1188
+ this.bindDoStatement(node as DoStatement);
1189
+ break;
1190
+ case SyntaxKind.ForStatement:
1191
+ this.bindForStatement(node as ForStatement);
1192
+ break;
1193
+ case SyntaxKind.ForInStatement:
1194
+ case SyntaxKind.ForOfStatement:
1195
+ this.bindForInOrForOfStatement(node as ForInOrOfStatement);
1196
+ break;
1197
+ case SyntaxKind.IfStatement:
1198
+ this.bindIfStatement(node as IfStatement);
1199
+ break;
1200
+ case SyntaxKind.ReturnStatement:
1201
+ this.bindOptional(getExpression(node));
1202
+ if (this.currentReturnTarget !== undefined) this.addAntecedent(this.currentReturnTarget, this.currentFlow);
1203
+ this.currentFlow = this.unreachableFlow;
1204
+ this.hasExplicitReturn = true;
1205
+ this.hasFlowEffects = true;
1206
+ break;
1207
+ case SyntaxKind.ThrowStatement:
1208
+ this.bindOptional(getExpression(node));
1209
+ this.currentFlow = this.unreachableFlow;
1210
+ this.hasFlowEffects = true;
1211
+ break;
1212
+ case SyntaxKind.BreakStatement:
1213
+ this.bindBreakOrContinueStatement(getLabel(node), true);
1214
+ break;
1215
+ case SyntaxKind.ContinueStatement:
1216
+ this.bindBreakOrContinueStatement(getLabel(node), false);
1217
+ break;
1218
+ case SyntaxKind.TryStatement:
1219
+ this.bindTryStatement(node as TryStatement);
1220
+ break;
1221
+ case SyntaxKind.SwitchStatement:
1222
+ this.bindSwitchStatement(node as SwitchStatement);
1223
+ break;
1224
+ case SyntaxKind.CaseBlock:
1225
+ this.bindCaseBlock(node as CaseBlock);
1226
+ break;
1227
+ case SyntaxKind.CaseClause:
1228
+ case SyntaxKind.DefaultClause:
1229
+ this.bindCaseOrDefaultClause(node as CaseOrDefaultClause);
1230
+ break;
1231
+ case SyntaxKind.ExpressionStatement: {
1232
+ const expression = (node as ExpressionStatement).expression;
1233
+ this.bind(expression);
1234
+ this.maybeBindExpressionFlowIfCall(expression);
1235
+ break;
1236
+ }
1237
+ case SyntaxKind.LabeledStatement:
1238
+ this.bindLabeledStatement(node as LabeledStatement);
1239
+ break;
1240
+ case SyntaxKind.PrefixUnaryExpression:
1241
+ this.bindPrefixUnaryExpressionFlow(node as PrefixUnaryExpression);
1242
+ break;
1243
+ case SyntaxKind.PostfixUnaryExpression: {
1244
+ node.forEachChild(this);
1245
+ const operator = (node as PostfixUnaryExpression).operator;
1246
+ if (operator === SyntaxKind.PlusPlusToken || operator === SyntaxKind.MinusMinusToken)
1247
+ this.bindAssignmentTargetFlow((node as PostfixUnaryExpression).operand);
1248
+ break;
1249
+ }
1250
+ case SyntaxKind.BinaryExpression:
1251
+ if (isDestructuringAssignment(node)) {
1252
+ // Carry the assignment pattern state into initializers of the pattern.
1253
+ this.inAssignmentPattern = saveInAssignmentPattern;
1254
+ this.bindDestructuringAssignmentFlow(node as BinaryExpression);
1255
+ return;
1256
+ }
1257
+ this.bindBinaryExpressionFlow(node as BinaryExpression);
1258
+ break;
1259
+ case SyntaxKind.DeleteExpression:
1260
+ node.forEachChild(this);
1261
+ if ((node as DeleteExpression).expression.kind === SyntaxKind.PropertyAccessExpression)
1262
+ this.bindAssignmentTargetFlow((node as DeleteExpression).expression);
1263
+ break;
1264
+ case SyntaxKind.ConditionalExpression:
1265
+ this.bindConditionalExpressionFlow(node as ConditionalExpression);
1266
+ break;
1267
+ case SyntaxKind.VariableDeclaration:
1268
+ node.forEachChild(this);
1269
+ if (
1270
+ (node as VariableDeclaration).initializer !== undefined ||
1271
+ isForInOrOfStatementKind(node.parent!.parent!.kind)
1272
+ )
1273
+ this.bindInitializedVariableFlow(node);
1274
+ break;
1275
+ case SyntaxKind.PropertyAccessExpression:
1276
+ case SyntaxKind.ElementAccessExpression:
1277
+ case SyntaxKind.NonNullExpression:
1278
+ if (isOptionalChain(node)) this.bindOptionalChainFlow(node);
1279
+ else node.forEachChild(this);
1280
+ break;
1281
+ case SyntaxKind.CallExpression:
1282
+ this.bindCallExpressionFlow(node as CallExpression);
1283
+ break;
1284
+ case SyntaxKind.SourceFile:
1285
+ this.bindEachStatementFunctionsFirst((node as SourceFile).statements);
1286
+ this.bind((node as SourceFile).endOfFileToken);
1287
+ break;
1288
+ case SyntaxKind.Block:
1289
+ case SyntaxKind.ModuleBlock:
1290
+ this.bindEachStatementFunctionsFirst(getStatements(node)!);
1291
+ break;
1292
+ case SyntaxKind.BindingElement: {
1293
+ // The initializer runs before the binding pattern.
1294
+ const element = node as BindingElement;
1295
+ this.bindOptional(element.dotDotDotToken);
1296
+ this.bindOptional(element.propertyName);
1297
+ this.bindInitializer(element.initializer);
1298
+ this.bindOptional(element.name);
1299
+ break;
1300
+ }
1301
+ case SyntaxKind.Parameter: {
1302
+ const parameter = node as ParameterDeclaration;
1303
+ this.bindNodes(parameter.modifiers);
1304
+ this.bindOptional(parameter.dotDotDotToken);
1305
+ this.bindOptional(parameter.questionToken);
1306
+ this.bindOptional(parameter.type);
1307
+ this.bindInitializer(parameter.initializer);
1308
+ this.bind(parameter.name);
1309
+ break;
1310
+ }
1311
+ case SyntaxKind.ObjectLiteralExpression:
1312
+ case SyntaxKind.ArrayLiteralExpression:
1313
+ case SyntaxKind.PropertyAssignment:
1314
+ case SyntaxKind.SpreadElement:
1315
+ this.inAssignmentPattern = saveInAssignmentPattern;
1316
+ node.forEachChild(this);
1317
+ break;
1318
+ default:
1319
+ node.forEachChild(this);
1320
+ }
1321
+ this.inAssignmentPattern = saveInAssignmentPattern;
1322
+ }
1323
+
1324
+ bindNodes(list: NodeList | undefined): void {
1325
+ if (list === undefined) return;
1326
+ const nodes = list.nodes;
1327
+ for (let i = 0; i < nodes.length; i++) this.bind(nodes[i]!);
1328
+ }
1329
+
1330
+ bindEachStatementFunctionsFirst(statements: NodeList): void {
1331
+ const nodes = statements.nodes;
1332
+ for (let i = 0; i < nodes.length; i++) if (nodes[i]!.kind === SyntaxKind.FunctionDeclaration) this.bind(nodes[i]!);
1333
+ for (let i = 0; i < nodes.length; i++) if (nodes[i]!.kind !== SyntaxKind.FunctionDeclaration) this.bind(nodes[i]!);
1334
+ }
1335
+
1336
+ // Flow graph
1337
+
1338
+ createBranchLabel(): FlowNode {
1339
+ return new FlowNode(FlowFlags.BranchLabel, undefined, undefined);
1340
+ }
1341
+
1342
+ createLoopLabel(): FlowNode {
1343
+ return new FlowNode(FlowFlags.LoopLabel, undefined, undefined);
1344
+ }
1345
+
1346
+ createFlowCondition(flags: FlowFlags, antecedent: FlowNode, expression: Node | undefined): FlowNode {
1347
+ if ((antecedent.flags & FlowFlags.Unreachable) !== 0) return antecedent;
1348
+ if (expression === undefined) return (flags & FlowFlags.TrueCondition) !== 0 ? antecedent : this.unreachableFlow;
1349
+ if (
1350
+ ((expression.kind === SyntaxKind.TrueKeyword && (flags & FlowFlags.FalseCondition) !== 0) ||
1351
+ (expression.kind === SyntaxKind.FalseKeyword && (flags & FlowFlags.TrueCondition) !== 0)) &&
1352
+ !isExpressionOfOptionalChainRoot(expression) &&
1353
+ !isNullishCoalesce(expression.parent!)
1354
+ )
1355
+ return this.unreachableFlow;
1356
+ if (!isNarrowingExpression(expression)) return antecedent;
1357
+ setFlowNodeReferenced(antecedent);
1358
+ return new FlowNode(flags, expression, antecedent);
1359
+ }
1360
+
1361
+ createFlowMutation(flags: FlowFlags, antecedent: FlowNode, node: Node): FlowNode {
1362
+ setFlowNodeReferenced(antecedent);
1363
+ this.hasFlowEffects = true;
1364
+ const result = new FlowNode(flags, node, antecedent);
1365
+ if (this.currentExceptionTarget !== undefined) this.addAntecedent(this.currentExceptionTarget, result);
1366
+ return result;
1367
+ }
1368
+
1369
+ createFlowSwitchClause(
1370
+ antecedent: FlowNode,
1371
+ switchStatement: Node,
1372
+ clauseStart: number,
1373
+ clauseEnd: number,
1374
+ ): FlowNode {
1375
+ setFlowNodeReferenced(antecedent);
1376
+ return new FlowSwitchClause(antecedent, switchStatement, clauseStart, clauseEnd);
1377
+ }
1378
+
1379
+ createFlowCall(antecedent: FlowNode, node: Node): FlowNode {
1380
+ setFlowNodeReferenced(antecedent);
1381
+ this.hasFlowEffects = true;
1382
+ return new FlowNode(FlowFlags.Call, node, antecedent);
1383
+ }
1384
+
1385
+ /** Adds `antecedent` to the end of the label's antecedents, unless unreachable or already there. */
1386
+ addAntecedent(label: FlowNode, antecedent: FlowNode): void {
1387
+ if ((antecedent.flags & FlowFlags.Unreachable) !== 0) return;
1388
+ const antecedents = label.antecedents;
1389
+ if (antecedents === undefined) label.antecedents = [antecedent];
1390
+ else {
1391
+ if (antecedents.indexOf(antecedent) >= 0) return;
1392
+ antecedents.push(antecedent);
1393
+ }
1394
+ setFlowNodeReferenced(antecedent);
1395
+ }
1396
+
1397
+ /** The label, its only antecedent, or unreachable if it has none. */
1398
+ finishFlowLabel(label: FlowNode): FlowNode {
1399
+ const antecedents = label.antecedents;
1400
+ if (antecedents === undefined) return this.unreachableFlow;
1401
+ if (antecedents.length === 1) return antecedents[0]!;
1402
+ return label;
1403
+ }
1404
+
1405
+ setContinueTarget(node: Node, target: FlowNode): FlowNode {
1406
+ let label = this.activeLabelList;
1407
+ let current = node;
1408
+ while (label !== undefined && current.parent!.kind === SyntaxKind.LabeledStatement) {
1409
+ label.continueTarget = target;
1410
+ label = label.next;
1411
+ current = current.parent!;
1412
+ }
1413
+ return target;
1414
+ }
1415
+
1416
+ /** Binds `node` with `trueTarget` and `falseTarget` as the condition's targets. */
1417
+ bindWithTargets(node: Node | undefined, trueTarget: FlowNode | undefined, falseTarget: FlowNode | undefined): void {
1418
+ const savedTrueTarget = this.currentTrueTarget;
1419
+ const savedFalseTarget = this.currentFalseTarget;
1420
+ this.currentTrueTarget = trueTarget;
1421
+ this.currentFalseTarget = falseTarget;
1422
+ this.bindOptional(node);
1423
+ this.currentTrueTarget = savedTrueTarget;
1424
+ this.currentFalseTarget = savedFalseTarget;
1425
+ }
1426
+
1427
+ bindCondition(node: Node | undefined, trueTarget: FlowNode, falseTarget: FlowNode): void {
1428
+ this.bindWithTargets(node, trueTarget, falseTarget);
1429
+ if (
1430
+ node === undefined ||
1431
+ (!isLogicalOrCoalescingAssignmentExpression(skipParentheses(node)) &&
1432
+ !isLogicalExpression(node) &&
1433
+ !(isOptionalChain(node) && isOutermostOptionalChain(node)))
1434
+ ) {
1435
+ this.addAntecedent(trueTarget, this.createFlowCondition(FlowFlags.TrueCondition, this.currentFlow, node));
1436
+ this.addAntecedent(falseTarget, this.createFlowCondition(FlowFlags.FalseCondition, this.currentFlow, node));
1437
+ }
1438
+ }
1439
+
1440
+ bindIterativeStatement(node: Node, breakTarget: FlowNode, continueTarget: FlowNode): void {
1441
+ const saveBreakTarget = this.currentBreakTarget;
1442
+ const saveContinueTarget = this.currentContinueTarget;
1443
+ this.currentBreakTarget = breakTarget;
1444
+ this.currentContinueTarget = continueTarget;
1445
+ this.bind(node);
1446
+ this.currentBreakTarget = saveBreakTarget;
1447
+ this.currentContinueTarget = saveContinueTarget;
1448
+ }
1449
+
1450
+ bindAssignmentTargetFlow(node: Node): void {
1451
+ switch (node.kind) {
1452
+ case SyntaxKind.ArrayLiteralExpression:
1453
+ for (const element of getElements(node)!.nodes) {
1454
+ if (element.kind === SyntaxKind.SpreadElement) this.bindAssignmentTargetFlow(getExpression(element)!);
1455
+ else this.bindDestructuringTargetFlow(element);
1456
+ }
1457
+ break;
1458
+ case SyntaxKind.ObjectLiteralExpression:
1459
+ for (const property of getProperties(node)!.nodes) {
1460
+ switch (property.kind) {
1461
+ case SyntaxKind.PropertyAssignment:
1462
+ this.bindDestructuringTargetFlow(getInitializer(property)!);
1463
+ break;
1464
+ case SyntaxKind.ShorthandPropertyAssignment:
1465
+ this.bindAssignmentTargetFlow(getName(property)!);
1466
+ break;
1467
+ case SyntaxKind.SpreadAssignment:
1468
+ this.bindAssignmentTargetFlow(getExpression(property)!);
1469
+ break;
1470
+ }
1471
+ }
1472
+ break;
1473
+ default:
1474
+ if (isNarrowableReference(node))
1475
+ this.currentFlow = this.createFlowMutation(FlowFlags.Assignment, this.currentFlow, node);
1476
+ }
1477
+ }
1478
+
1479
+ bindDestructuringTargetFlow(node: Node): void {
1480
+ if (node instanceof BinaryExpression && (node as BinaryExpression).operatorToken.kind === SyntaxKind.EqualsToken)
1481
+ this.bindAssignmentTargetFlow((node as BinaryExpression).left);
1482
+ else this.bindAssignmentTargetFlow(node);
1483
+ }
1484
+
1485
+ bindWhileStatement(node: WhileStatement): void {
1486
+ const preWhileLabel = this.setContinueTarget(node, this.createLoopLabel());
1487
+ const preBodyLabel = this.createBranchLabel();
1488
+ const postWhileLabel = this.createBranchLabel();
1489
+ this.addAntecedent(preWhileLabel, this.currentFlow);
1490
+ this.currentFlow = preWhileLabel;
1491
+ this.bindCondition(node.expression, preBodyLabel, postWhileLabel);
1492
+ this.currentFlow = this.finishFlowLabel(preBodyLabel);
1493
+ this.bindIterativeStatement(node.statement, postWhileLabel, preWhileLabel);
1494
+ this.addAntecedent(preWhileLabel, this.currentFlow);
1495
+ this.currentFlow = this.finishFlowLabel(postWhileLabel);
1496
+ }
1497
+
1498
+ bindDoStatement(node: DoStatement): void {
1499
+ const preDoLabel = this.createLoopLabel();
1500
+ const preConditionLabel = this.setContinueTarget(node, this.createBranchLabel());
1501
+ const postDoLabel = this.createBranchLabel();
1502
+ this.addAntecedent(preDoLabel, this.currentFlow);
1503
+ this.currentFlow = preDoLabel;
1504
+ this.bindIterativeStatement(node.statement, postDoLabel, preConditionLabel);
1505
+ this.addAntecedent(preConditionLabel, this.currentFlow);
1506
+ this.currentFlow = this.finishFlowLabel(preConditionLabel);
1507
+ this.bindCondition(node.expression, preDoLabel, postDoLabel);
1508
+ this.currentFlow = this.finishFlowLabel(postDoLabel);
1509
+ }
1510
+
1511
+ bindForStatement(node: ForStatement): void {
1512
+ const preLoopLabel = this.setContinueTarget(node, this.createLoopLabel());
1513
+ const preBodyLabel = this.createBranchLabel();
1514
+ const preIncrementorLabel = this.createBranchLabel();
1515
+ const postLoopLabel = this.createBranchLabel();
1516
+ this.bindOptional(node.initializer);
1517
+ this.addAntecedent(preLoopLabel, this.currentFlow);
1518
+ this.currentFlow = preLoopLabel;
1519
+ this.bindCondition(node.condition, preBodyLabel, postLoopLabel);
1520
+ this.currentFlow = this.finishFlowLabel(preBodyLabel);
1521
+ this.bindIterativeStatement(node.statement, postLoopLabel, preIncrementorLabel);
1522
+ this.addAntecedent(preIncrementorLabel, this.currentFlow);
1523
+ this.currentFlow = this.finishFlowLabel(preIncrementorLabel);
1524
+ this.bindOptional(node.incrementor);
1525
+ this.addAntecedent(preLoopLabel, this.currentFlow);
1526
+ this.currentFlow = this.finishFlowLabel(postLoopLabel);
1527
+ }
1528
+
1529
+ bindForInOrForOfStatement(node: ForInOrOfStatement): void {
1530
+ const preLoopLabel = this.setContinueTarget(node, this.createLoopLabel());
1531
+ const postLoopLabel = this.createBranchLabel();
1532
+ this.bind(node.expression);
1533
+ this.addAntecedent(preLoopLabel, this.currentFlow);
1534
+ this.currentFlow = preLoopLabel;
1535
+ if (node.kind === SyntaxKind.ForOfStatement) this.bindOptional(node.awaitModifier);
1536
+ this.addAntecedent(postLoopLabel, this.currentFlow);
1537
+ this.bind(node.initializer);
1538
+ if (node.initializer.kind !== SyntaxKind.VariableDeclarationList) this.bindAssignmentTargetFlow(node.initializer);
1539
+ this.bindIterativeStatement(node.statement, postLoopLabel, preLoopLabel);
1540
+ this.addAntecedent(preLoopLabel, this.currentFlow);
1541
+ this.currentFlow = this.finishFlowLabel(postLoopLabel);
1542
+ }
1543
+
1544
+ bindIfStatement(node: IfStatement): void {
1545
+ const thenLabel = this.createBranchLabel();
1546
+ const elseLabel = this.createBranchLabel();
1547
+ const postIfLabel = this.createBranchLabel();
1548
+ this.bindCondition(node.expression, thenLabel, elseLabel);
1549
+ this.currentFlow = this.finishFlowLabel(thenLabel);
1550
+ this.bind(node.thenStatement);
1551
+ this.addAntecedent(postIfLabel, this.currentFlow);
1552
+ this.currentFlow = this.finishFlowLabel(elseLabel);
1553
+ this.bindOptional(node.elseStatement);
1554
+ this.addAntecedent(postIfLabel, this.currentFlow);
1555
+ this.currentFlow = this.finishFlowLabel(postIfLabel);
1556
+ }
1557
+
1558
+ bindBreakOrContinueStatement(label: Node | undefined, isBreak: boolean): void {
1559
+ this.bindOptional(label);
1560
+ if (label !== undefined) {
1561
+ const name = getText(label);
1562
+ let activeLabel = this.activeLabelList;
1563
+ while (activeLabel !== undefined && activeLabel.name !== name) activeLabel = activeLabel.next;
1564
+ if (activeLabel !== undefined) {
1565
+ activeLabel.referenced = true;
1566
+ this.bindBreakOrContinueFlow(isBreak ? activeLabel.breakTarget : activeLabel.continueTarget);
1567
+ }
1568
+ } else this.bindBreakOrContinueFlow(isBreak ? this.currentBreakTarget : this.currentContinueTarget);
1569
+ }
1570
+
1571
+ bindBreakOrContinueFlow(flowLabel: FlowNode | undefined): void {
1572
+ if (flowLabel === undefined) return;
1573
+ this.addAntecedent(flowLabel, this.currentFlow);
1574
+ this.currentFlow = this.unreachableFlow;
1575
+ this.hasFlowEffects = true;
1576
+ }
1577
+
1578
+ /**
1579
+ * Any code in a `try` block may throw, but only mutations change narrowed types, so the
1580
+ * exception label collects the mutations (and the flow before them) as antecedents of the
1581
+ * `catch` or `finally` block.
1582
+ */
1583
+ bindTryStatement(node: TryStatement): void {
1584
+ const saveReturnTarget = this.currentReturnTarget;
1585
+ const saveExceptionTarget = this.currentExceptionTarget;
1586
+ const normalExitLabel = this.createBranchLabel();
1587
+ const returnLabel = this.createBranchLabel();
1588
+ let exceptionLabel = this.createBranchLabel();
1589
+ if (node.finallyBlock !== undefined) this.currentReturnTarget = returnLabel;
1590
+ this.addAntecedent(exceptionLabel, this.currentFlow);
1591
+ this.currentExceptionTarget = exceptionLabel;
1592
+ this.bind(node.tryBlock);
1593
+ this.addAntecedent(normalExitLabel, this.currentFlow);
1594
+ if (node.catchClause !== undefined) {
1595
+ // The catch clause starts with the exceptions of the try block and acts like a second try block.
1596
+ this.currentFlow = this.finishFlowLabel(exceptionLabel);
1597
+ exceptionLabel = this.createBranchLabel();
1598
+ this.addAntecedent(exceptionLabel, this.currentFlow);
1599
+ this.currentExceptionTarget = exceptionLabel;
1600
+ this.bind(node.catchClause);
1601
+ this.addAntecedent(normalExitLabel, this.currentFlow);
1602
+ }
1603
+ this.currentReturnTarget = saveReturnTarget;
1604
+ this.currentExceptionTarget = saveExceptionTarget;
1605
+ if (node.finallyBlock === undefined) {
1606
+ this.currentFlow = this.finishFlowLabel(normalExitLabel);
1607
+ return;
1608
+ }
1609
+ // The finally block is reached by normal completion of the try or catch block, by returns in
1610
+ // them, and by exceptions in them. Analysis that starts past the finally block only considers
1611
+ // normal completion, and returns from an IIFE only the returns, so ReduceLabel nodes give the
1612
+ // finally label a reduced set of antecedents for those paths.
1613
+ const finallyLabel = this.createBranchLabel();
1614
+ finallyLabel.antecedents = combineFlowLists(
1615
+ normalExitLabel.antecedents,
1616
+ combineFlowLists(exceptionLabel.antecedents, returnLabel.antecedents),
1617
+ );
1618
+ this.currentFlow = finallyLabel;
1619
+ this.bind(node.finallyBlock);
1620
+ if ((this.currentFlow.flags & FlowFlags.Unreachable) !== 0) {
1621
+ // An unreachable end of the finally block makes the end of the try statement unreachable.
1622
+ this.currentFlow = this.unreachableFlow;
1623
+ return;
1624
+ }
1625
+ // Returns in the try or catch block of an IIFE continue through the finally block.
1626
+ if (this.currentReturnTarget !== undefined && returnLabel.antecedents !== undefined)
1627
+ this.addAntecedent(
1628
+ this.currentReturnTarget,
1629
+ new FlowReduceLabel(finallyLabel, returnLabel.antecedents, this.currentFlow),
1630
+ );
1631
+ // So do exceptions, to an enclosing try statement.
1632
+ if (this.currentExceptionTarget !== undefined && exceptionLabel.antecedents !== undefined)
1633
+ this.addAntecedent(
1634
+ this.currentExceptionTarget,
1635
+ new FlowReduceLabel(finallyLabel, exceptionLabel.antecedents, this.currentFlow),
1636
+ );
1637
+ // `try { return 1; } finally { … }` ends unreachable.
1638
+ this.currentFlow =
1639
+ normalExitLabel.antecedents !== undefined
1640
+ ? new FlowReduceLabel(finallyLabel, normalExitLabel.antecedents, this.currentFlow)
1641
+ : this.unreachableFlow;
1642
+ }
1643
+
1644
+ bindSwitchStatement(node: SwitchStatement): void {
1645
+ const postSwitchLabel = this.createBranchLabel();
1646
+ this.bind(node.expression);
1647
+ const saveBreakTarget = this.currentBreakTarget;
1648
+ const savePreSwitchCaseFlow = this.preSwitchCaseFlow;
1649
+ this.currentBreakTarget = postSwitchLabel;
1650
+ this.preSwitchCaseFlow = this.currentFlow;
1651
+ this.bind(node.caseBlock);
1652
+ this.addAntecedent(postSwitchLabel, this.currentFlow);
1653
+ let hasDefault = false;
1654
+ for (const clause of node.caseBlock.clauses.nodes) if (clause.kind === SyntaxKind.DefaultClause) hasDefault = true;
1655
+ if (!hasDefault)
1656
+ this.addAntecedent(postSwitchLabel, this.createFlowSwitchClause(this.preSwitchCaseFlow, node, 0, 0));
1657
+ this.currentBreakTarget = saveBreakTarget;
1658
+ this.preSwitchCaseFlow = savePreSwitchCaseFlow;
1659
+ this.currentFlow = this.finishFlowLabel(postSwitchLabel);
1660
+ }
1661
+
1662
+ bindCaseBlock(node: CaseBlock): void {
1663
+ const switchStatement = node.parent as SwitchStatement;
1664
+ const clauses = node.clauses.nodes;
1665
+ const switchExpression = switchStatement.expression;
1666
+ const isNarrowingSwitch =
1667
+ switchExpression.kind === SyntaxKind.TrueKeyword || isNarrowingExpression(switchExpression);
1668
+ let fallthroughFlow = this.unreachableFlow;
1669
+ for (let i = 0; i < clauses.length; i++) {
1670
+ const clauseStart = i;
1671
+ while ((clauses[i]! as CaseOrDefaultClause).statements.nodes.length === 0 && i + 1 < clauses.length) {
1672
+ if (fallthroughFlow === this.unreachableFlow) this.currentFlow = this.preSwitchCaseFlow!;
1673
+ this.bind(clauses[i]!);
1674
+ i++;
1675
+ }
1676
+ const preCaseLabel = this.createBranchLabel();
1677
+ const preCaseFlow = isNarrowingSwitch
1678
+ ? this.createFlowSwitchClause(this.preSwitchCaseFlow!, switchStatement, clauseStart, i + 1)
1679
+ : this.preSwitchCaseFlow!;
1680
+ this.addAntecedent(preCaseLabel, preCaseFlow);
1681
+ this.addAntecedent(preCaseLabel, fallthroughFlow);
1682
+ this.currentFlow = this.finishFlowLabel(preCaseLabel);
1683
+ const clause = clauses[i]! as CaseOrDefaultClause;
1684
+ this.bind(clause);
1685
+ fallthroughFlow = this.currentFlow;
1686
+ if ((this.currentFlow.flags & FlowFlags.Unreachable) === 0 && i !== clauses.length - 1)
1687
+ clause.fallthroughFlowNode = this.currentFlow;
1688
+ }
1689
+ }
1690
+
1691
+ bindCaseOrDefaultClause(node: CaseOrDefaultClause): void {
1692
+ if (node.expression !== undefined) {
1693
+ const saveCurrentFlow = this.currentFlow;
1694
+ this.currentFlow = this.preSwitchCaseFlow!;
1695
+ this.bind(node.expression);
1696
+ this.currentFlow = saveCurrentFlow;
1697
+ }
1698
+ this.bindNodes(node.statements);
1699
+ }
1700
+
1701
+ /** A top-level or comma call with a dotted callee may be an assertion, so it joins the flow graph. */
1702
+ maybeBindExpressionFlowIfCall(node: Node): void {
1703
+ if (node instanceof CallExpression) {
1704
+ const call: CallExpression = node;
1705
+ const callee = call.expression;
1706
+ if (callee.kind !== SyntaxKind.SuperKeyword && isDottedName(callee))
1707
+ this.currentFlow = this.createFlowCall(this.currentFlow, node);
1708
+ }
1709
+ }
1710
+
1711
+ bindLabeledStatement(node: LabeledStatement): void {
1712
+ const postStatementLabel = this.createBranchLabel();
1713
+ const activeLabel = new ActiveLabel(this.activeLabelList, node.label.text, postStatementLabel);
1714
+ this.activeLabelList = activeLabel;
1715
+ this.bind(node.label);
1716
+ this.bind(node.statement);
1717
+ // An unused label; the checker decides whether to report it.
1718
+ if (!activeLabel.referenced) node.label.flags |= NodeFlags.Unreachable;
1719
+ this.activeLabelList = activeLabel.next;
1720
+ this.addAntecedent(postStatementLabel, this.currentFlow);
1721
+ this.currentFlow = this.finishFlowLabel(postStatementLabel);
1722
+ }
1723
+
1724
+ bindPrefixUnaryExpressionFlow(node: PrefixUnaryExpression): void {
1725
+ if (node.operator === SyntaxKind.ExclamationToken) {
1726
+ const saveTrueTarget = this.currentTrueTarget;
1727
+ this.currentTrueTarget = this.currentFalseTarget;
1728
+ this.currentFalseTarget = saveTrueTarget;
1729
+ node.forEachChild(this);
1730
+ this.currentFalseTarget = this.currentTrueTarget;
1731
+ this.currentTrueTarget = saveTrueTarget;
1732
+ } else {
1733
+ node.forEachChild(this);
1734
+ if (node.operator === SyntaxKind.PlusPlusToken || node.operator === SyntaxKind.MinusMinusToken)
1735
+ this.bindAssignmentTargetFlow(node.operand);
1736
+ }
1737
+ }
1738
+
1739
+ bindDestructuringAssignmentFlow(node: BinaryExpression): void {
1740
+ if (this.inAssignmentPattern) {
1741
+ this.inAssignmentPattern = false;
1742
+ this.bind(node.operatorToken);
1743
+ this.bind(node.right);
1744
+ this.inAssignmentPattern = true;
1745
+ this.bind(node.left);
1746
+ this.bindOptional(node.type);
1747
+ } else {
1748
+ this.inAssignmentPattern = true;
1749
+ this.bind(node.left);
1750
+ this.bindOptional(node.type);
1751
+ this.inAssignmentPattern = false;
1752
+ this.bind(node.operatorToken);
1753
+ this.bind(node.right);
1754
+ }
1755
+ this.bindAssignmentTargetFlow(node.left);
1756
+ }
1757
+
1758
+ bindBinaryExpressionFlow(node: BinaryExpression): void {
1759
+ const operator = node.operatorToken.kind;
1760
+ if (isLogicalOrCoalescingBinaryOperator(operator) || isLogicalOrCoalescingAssignmentOperator(operator)) {
1761
+ if (isTopLevelLogicalExpression(node)) {
1762
+ const postExpressionLabel = this.createBranchLabel();
1763
+ const saveCurrentFlow = this.currentFlow;
1764
+ const saveHasFlowEffects = this.hasFlowEffects;
1765
+ this.hasFlowEffects = false;
1766
+ this.bindLogicalLikeExpression(node, postExpressionLabel, postExpressionLabel);
1767
+ this.currentFlow = this.hasFlowEffects ? this.finishFlowLabel(postExpressionLabel) : saveCurrentFlow;
1768
+ this.hasFlowEffects = this.hasFlowEffects || saveHasFlowEffects;
1769
+ } else this.bindLogicalLikeExpression(node, this.currentTrueTarget!, this.currentFalseTarget!);
1770
+ return;
1771
+ }
1772
+ this.bind(node.left);
1773
+ this.bindOptional(node.type);
1774
+ if (operator === SyntaxKind.CommaToken) this.maybeBindExpressionFlowIfCall(node.left);
1775
+ this.bind(node.operatorToken);
1776
+ this.bind(node.right);
1777
+ if (operator === SyntaxKind.CommaToken) this.maybeBindExpressionFlowIfCall(node.right);
1778
+ if (isAssignmentOperator(operator) && !isAssignmentTarget(node)) {
1779
+ this.bindAssignmentTargetFlow(node.left);
1780
+ const left = node.left;
1781
+ if (
1782
+ operator === SyntaxKind.EqualsToken &&
1783
+ left instanceof ElementAccessExpression &&
1784
+ isNarrowableOperand((left as ElementAccessExpression).expression)
1785
+ )
1786
+ this.currentFlow = this.createFlowMutation(FlowFlags.ArrayMutation, this.currentFlow, node);
1787
+ }
1788
+ }
1789
+
1790
+ bindLogicalLikeExpression(node: BinaryExpression, trueTarget: FlowNode, falseTarget: FlowNode): void {
1791
+ const preRightLabel = this.createBranchLabel();
1792
+ const operator = node.operatorToken.kind;
1793
+ if (operator === SyntaxKind.AmpersandAmpersandToken || operator === SyntaxKind.AmpersandAmpersandEqualsToken)
1794
+ this.bindCondition(node.left, preRightLabel, falseTarget);
1795
+ else this.bindCondition(node.left, trueTarget, preRightLabel);
1796
+ this.currentFlow = this.finishFlowLabel(preRightLabel);
1797
+ this.bind(node.operatorToken);
1798
+ if (isLogicalOrCoalescingAssignmentOperator(operator)) {
1799
+ this.bindWithTargets(node.right, trueTarget, falseTarget);
1800
+ this.bindAssignmentTargetFlow(node.left);
1801
+ this.addAntecedent(trueTarget, this.createFlowCondition(FlowFlags.TrueCondition, this.currentFlow, node));
1802
+ this.addAntecedent(falseTarget, this.createFlowCondition(FlowFlags.FalseCondition, this.currentFlow, node));
1803
+ } else this.bindCondition(node.right, trueTarget, falseTarget);
1804
+ }
1805
+
1806
+ bindConditionalExpressionFlow(node: ConditionalExpression): void {
1807
+ const trueLabel = this.createBranchLabel();
1808
+ const falseLabel = this.createBranchLabel();
1809
+ const postExpressionLabel = this.createBranchLabel();
1810
+ const saveCurrentFlow = this.currentFlow;
1811
+ const saveHasFlowEffects = this.hasFlowEffects;
1812
+ this.hasFlowEffects = false;
1813
+ this.bindCondition(node.condition, trueLabel, falseLabel);
1814
+ this.currentFlow = this.finishFlowLabel(trueLabel);
1815
+ this.bind(node.questionToken);
1816
+ this.bind(node.whenTrue);
1817
+ this.addAntecedent(postExpressionLabel, this.currentFlow);
1818
+ this.currentFlow = this.finishFlowLabel(falseLabel);
1819
+ this.bind(node.colonToken);
1820
+ this.bind(node.whenFalse);
1821
+ this.addAntecedent(postExpressionLabel, this.currentFlow);
1822
+ this.currentFlow = this.hasFlowEffects ? this.finishFlowLabel(postExpressionLabel) : saveCurrentFlow;
1823
+ this.hasFlowEffects = this.hasFlowEffects || saveHasFlowEffects;
1824
+ }
1825
+
1826
+ bindInitializedVariableFlow(node: Node): void {
1827
+ const name = getName(node);
1828
+ if (
1829
+ name !== undefined &&
1830
+ (name.kind === SyntaxKind.ObjectBindingPattern || name.kind === SyntaxKind.ArrayBindingPattern)
1831
+ ) {
1832
+ for (const element of getElements(name)!.nodes) this.bindInitializedVariableFlow(element);
1833
+ } else this.currentFlow = this.createFlowMutation(FlowFlags.Assignment, this.currentFlow, node);
1834
+ }
1835
+
1836
+ bindOptionalChainFlow(node: Node): void {
1837
+ if (isTopLevelLogicalExpression(node)) {
1838
+ const postExpressionLabel = this.createBranchLabel();
1839
+ const saveCurrentFlow = this.currentFlow;
1840
+ const saveHasFlowEffects = this.hasFlowEffects;
1841
+ this.bindOptionalChain(node, postExpressionLabel, postExpressionLabel);
1842
+ this.currentFlow = this.hasFlowEffects ? this.finishFlowLabel(postExpressionLabel) : saveCurrentFlow;
1843
+ this.hasFlowEffects = this.hasFlowEffects || saveHasFlowEffects;
1844
+ } else this.bindOptionalChain(node, this.currentTrueTarget!, this.currentFalseTarget!);
1845
+ }
1846
+
1847
+ /**
1848
+ * Binds an optional chain like a logical expression: `a?.b.c` as `a && a.b.c`. The chain's
1849
+ * root is the first condition and the rest of the chain is its true branch.
1850
+ */
1851
+ bindOptionalChain(node: Node, trueTarget: FlowNode, falseTarget: FlowNode): void {
1852
+ const preChainLabel = isOptionalChainRoot(node) ? this.createBranchLabel() : undefined;
1853
+ this.bindOptionalExpression(getExpression(node)!, preChainLabel ?? trueTarget, falseTarget);
1854
+ if (preChainLabel !== undefined) this.currentFlow = this.finishFlowLabel(preChainLabel);
1855
+ const savedTrueTarget = this.currentTrueTarget;
1856
+ const savedFalseTarget = this.currentFalseTarget;
1857
+ this.currentTrueTarget = trueTarget;
1858
+ this.currentFalseTarget = falseTarget;
1859
+ this.bindOptionalChainRest(node);
1860
+ this.currentTrueTarget = savedTrueTarget;
1861
+ this.currentFalseTarget = savedFalseTarget;
1862
+ if (isOutermostOptionalChain(node)) {
1863
+ this.addAntecedent(trueTarget, this.createFlowCondition(FlowFlags.TrueCondition, this.currentFlow, node));
1864
+ this.addAntecedent(falseTarget, this.createFlowCondition(FlowFlags.FalseCondition, this.currentFlow, node));
1865
+ }
1866
+ }
1867
+
1868
+ bindOptionalExpression(node: Node, trueTarget: FlowNode, falseTarget: FlowNode): void {
1869
+ this.bindWithTargets(node, trueTarget, falseTarget);
1870
+ if (!isOptionalChain(node) || isOutermostOptionalChain(node)) {
1871
+ this.addAntecedent(trueTarget, this.createFlowCondition(FlowFlags.TrueCondition, this.currentFlow, node));
1872
+ this.addAntecedent(falseTarget, this.createFlowCondition(FlowFlags.FalseCondition, this.currentFlow, node));
1873
+ }
1874
+ }
1875
+
1876
+ bindOptionalChainRest(node: Node): void {
1877
+ if (node instanceof PropertyAccessExpression) {
1878
+ this.bindOptional((node as PropertyAccessExpression).questionDotToken);
1879
+ this.bind((node as PropertyAccessExpression).name);
1880
+ } else if (node instanceof ElementAccessExpression) {
1881
+ this.bindOptional((node as ElementAccessExpression).questionDotToken);
1882
+ this.bind((node as ElementAccessExpression).argumentExpression);
1883
+ } else if (node instanceof CallExpression) {
1884
+ this.bindOptional((node as CallExpression).questionDotToken);
1885
+ this.bindNodes((node as CallExpression).typeArguments);
1886
+ this.bindNodes((node as CallExpression).arguments);
1887
+ }
1888
+ }
1889
+
1890
+ bindCallExpressionFlow(node: CallExpression): void {
1891
+ if (isOptionalChain(node)) this.bindOptionalChainFlow(node);
1892
+ else {
1893
+ // An IIFE's flow node includes the evaluation of its arguments.
1894
+ const callee = skipParentheses(node.expression);
1895
+ if (callee.kind === SyntaxKind.FunctionExpression || callee.kind === SyntaxKind.ArrowFunction) {
1896
+ this.bindNodes(node.typeArguments);
1897
+ this.bindNodes(node.arguments);
1898
+ this.bind(node.expression);
1899
+ } else {
1900
+ node.forEachChild(this);
1901
+ if (node.expression.kind === SyntaxKind.SuperKeyword)
1902
+ this.currentFlow = this.createFlowCall(this.currentFlow, node);
1903
+ }
1904
+ }
1905
+ const callee = node.expression;
1906
+ if (!(callee instanceof PropertyAccessExpression)) return;
1907
+ // Typed locals keep scriptc's field reads static after `instanceof`.
1908
+ const access: PropertyAccessExpression = callee;
1909
+ if (
1910
+ access.name.kind === SyntaxKind.Identifier &&
1911
+ isNarrowableOperand(access.expression) &&
1912
+ isPushOrUnshiftIdentifier(access.name)
1913
+ )
1914
+ this.currentFlow = this.createFlowMutation(FlowFlags.ArrayMutation, this.currentFlow, node);
1915
+ }
1916
+
1917
+ /** Binds a parameter or binding element initializer, which only runs when the value is `undefined`. */
1918
+ bindInitializer(node: Node | undefined): void {
1919
+ if (node === undefined) return;
1920
+ const entryFlow = this.currentFlow;
1921
+ this.bind(node);
1922
+ if (entryFlow === this.unreachableFlow || entryFlow === this.currentFlow) return;
1923
+ const exitFlow = this.createBranchLabel();
1924
+ this.addAntecedent(exitFlow, entryFlow);
1925
+ this.addAntecedent(exitFlow, this.currentFlow);
1926
+ this.currentFlow = this.finishFlowLabel(exitFlow);
1927
+ }
1928
+
1929
+ // Declarations by kind
1930
+
1931
+ bindSourceFileIfExternalModule(file: SourceFile): void {
1932
+ this.setExportContextFlag(file);
1933
+ if (isExternalOrCommonJSModule(file)) this.bindSourceFileAsExternalModule(file);
1934
+ else if (isJsonSourceFile(file)) {
1935
+ this.bindSourceFileAsExternalModule(file);
1936
+ // The equivalent of `module.exports = {…}`.
1937
+ const originalSymbol = file.symbol!;
1938
+ this.declareSymbol(getExports(originalSymbol), originalSymbol, file, SymbolFlags.Property, SymbolFlags.All);
1939
+ file.symbol = originalSymbol;
1940
+ }
1941
+ }
1942
+
1943
+ bindSourceFileAsExternalModule(file: SourceFile): void {
1944
+ this.bindAnonymousDeclaration(file, SymbolFlags.ValueModule, '"' + removeFileExtension(file.fileName) + '"');
1945
+ }
1946
+
1947
+ bindModuleDeclaration(node: ModuleDeclaration): void {
1948
+ this.setExportContextFlag(node);
1949
+ if (isAmbientModule(node)) {
1950
+ if (hasSyntacticModifier(node, ModifierFlags.Export))
1951
+ this.errorOnFirstToken(
1952
+ node,
1953
+ Diagnostics.X_export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always_visible,
1954
+ noArgs,
1955
+ );
1956
+ if (isModuleAugmentationExternal(node)) {
1957
+ this.declareModuleSymbol(node);
1958
+ return;
1959
+ }
1960
+ const symbol = this.declareSymbolAndAddToSymbolTable(
1961
+ node,
1962
+ SymbolFlags.ValueModule,
1963
+ SymbolFlags.ValueModuleExcludes,
1964
+ );
1965
+ const name = node.name;
1966
+ if (name.kind === SyntaxKind.StringLiteral) {
1967
+ const text = getText(name);
1968
+ const starIndex = text.indexOf('*');
1969
+ if (starIndex >= 0 && text.indexOf('*', starIndex + 1) >= 0)
1970
+ this.errorOnFirstToken(name, Diagnostics.Pattern_0_can_have_at_most_one_Asterisk_character, [text]);
1971
+ else if (starIndex >= 0)
1972
+ this.file.patternAmbientModules.push(new PatternAmbientModule(text, starIndex, symbol));
1973
+ }
1974
+ return;
1975
+ }
1976
+ const state = this.declareModuleSymbol(node);
1977
+ if (state === ModuleInstanceState.NonInstantiated) return;
1978
+ const symbol = getSymbol(node)!;
1979
+ // A namespace merged with a function, class or regular enum isn't const-enum-only.
1980
+ const constEnumOnlyModule =
1981
+ (symbol.flags & (SymbolFlags.Function | SymbolFlags.Class | SymbolFlags.RegularEnum)) === 0 &&
1982
+ state === ModuleInstanceState.ConstEnumOnly &&
1983
+ !this.notConstEnumOnlyModules.has(symbol);
1984
+ if (constEnumOnlyModule) symbol.flags |= SymbolFlags.ConstEnumOnlyModule;
1985
+ else {
1986
+ symbol.flags &= ~SymbolFlags.ConstEnumOnlyModule;
1987
+ this.notConstEnumOnlyModules.add(symbol);
1988
+ }
1989
+ }
1990
+
1991
+ declareModuleSymbol(node: ModuleDeclaration): ModuleInstanceState {
1992
+ const state = getModuleInstanceState(node, this.statementsByName);
1993
+ const instantiated = state !== ModuleInstanceState.NonInstantiated;
1994
+ this.declareSymbolAndAddToSymbolTable(
1995
+ node,
1996
+ instantiated ? SymbolFlags.ValueModule : SymbolFlags.NamespaceModule,
1997
+ instantiated ? SymbolFlags.ValueModuleExcludes : SymbolFlags.NamespaceModuleExcludes,
1998
+ );
1999
+ return state;
2000
+ }
2001
+
2002
+ bindNamespaceExportDeclaration(node: Node): void {
2003
+ const parent = node.parent!;
2004
+ if (getModifiers(node) !== undefined) this.errorOnNode(node, Diagnostics.Modifiers_cannot_appear_here, noArgs);
2005
+ if (parent.kind !== SyntaxKind.SourceFile)
2006
+ this.errorOnNode(node, Diagnostics.Global_module_exports_may_only_appear_at_top_level, noArgs);
2007
+ else if (!isExternalModule(parent as SourceFile))
2008
+ this.errorOnNode(node, Diagnostics.Global_module_exports_may_only_appear_in_module_files, noArgs);
2009
+ else if (!(parent as SourceFile).isDeclarationFile)
2010
+ this.errorOnNode(node, Diagnostics.Global_module_exports_may_only_appear_in_declaration_files, noArgs);
2011
+ else {
2012
+ const file = this.file;
2013
+ let globalExports = file.globalExports;
2014
+ if (globalExports === undefined) {
2015
+ globalExports = new Map<string, Symbol>();
2016
+ file.globalExports = globalExports;
2017
+ }
2018
+ this.declareSymbol(globalExports, file.symbol, node, SymbolFlags.Alias, SymbolFlags.AliasExcludes);
2019
+ }
2020
+ }
2021
+
2022
+ bindExportDeclaration(node: ExportDeclaration): void {
2023
+ const containerSymbol = getSymbol(this.container);
2024
+ if (containerSymbol === undefined)
2025
+ // `export *` in a block.
2026
+ this.bindAnonymousDeclaration(node, SymbolFlags.ExportStar, this.getDeclarationName(node));
2027
+ else if (node.exportClause === undefined)
2028
+ // All `export *` declarations go in one symbol.
2029
+ this.declareSymbol(getExports(containerSymbol), containerSymbol, node, SymbolFlags.ExportStar, SymbolFlags.None);
2030
+ else if (node.exportClause.kind === SyntaxKind.NamespaceExport)
2031
+ this.declareSymbol(
2032
+ getExports(containerSymbol),
2033
+ containerSymbol,
2034
+ node.exportClause,
2035
+ SymbolFlags.Alias,
2036
+ SymbolFlags.AliasExcludes,
2037
+ );
2038
+ }
2039
+
2040
+ bindExportAssignment(node: ExportAssignment): void {
2041
+ const containerSymbol = getSymbol(this.container);
2042
+ if (containerSymbol === undefined) {
2043
+ // An export assignment in a block.
2044
+ this.bindAnonymousDeclaration(node, SymbolFlags.Value, this.getDeclarationName(node));
2045
+ return;
2046
+ }
2047
+ // `export default x` aliases x; anything else exported as default is a property.
2048
+ const flags = expressionIsAlias(node.expression) ? SymbolFlags.Alias : SymbolFlags.Property;
2049
+ const symbol = this.declareSymbol(getExports(containerSymbol), containerSymbol, node, flags, SymbolFlags.All);
2050
+ if (node.isExportEquals) setValueDeclaration(symbol, node);
2051
+ }
2052
+
2053
+ /** Ambient files and modules without export declarations export every declaration implicitly. */
2054
+ setExportContextFlag(node: Node): void {
2055
+ if ((node.flags & NodeFlags.Ambient) !== 0 && !hasExportDeclarations(node)) node.flags |= NodeFlags.ExportContext;
2056
+ else node.flags &= ~NodeFlags.ExportContext;
2057
+ }
2058
+
2059
+ bindFunctionDeclaration(node: Node): void {
2060
+ if (!this.file.isDeclarationFile && (node.flags & NodeFlags.Ambient) === 0 && isAsyncFunction(node))
2061
+ this.emitFlags |= NodeFlags.HasAsyncFunctions;
2062
+ this.checkStrictModeFunctionName(node);
2063
+ this.bindBlockScopedDeclaration(node, SymbolFlags.Function, SymbolFlags.FunctionExcludes);
2064
+ }
2065
+
2066
+ bindFunctionExpression(node: Node): void {
2067
+ if (!this.file.isDeclarationFile && (node.flags & NodeFlags.Ambient) === 0 && isAsyncFunction(node))
2068
+ this.emitFlags |= NodeFlags.HasAsyncFunctions;
2069
+ setFlowNode(node, this.currentFlowValue());
2070
+ let bindingName: string = InternalSymbolName.Function;
2071
+ if (node instanceof FunctionExpression) {
2072
+ const name = (node as FunctionExpression).name;
2073
+ if (name !== undefined) {
2074
+ this.checkStrictModeFunctionName(node);
2075
+ bindingName = name.text;
2076
+ }
2077
+ }
2078
+ this.bindAnonymousDeclaration(node, SymbolFlags.Function, bindingName);
2079
+ }
2080
+
2081
+ bindClassLikeDeclaration(node: Node): void {
2082
+ if (node.kind === SyntaxKind.ClassDeclaration)
2083
+ this.bindBlockScopedDeclaration(node, SymbolFlags.Class, SymbolFlags.ClassExcludes);
2084
+ else {
2085
+ const name = getName(node);
2086
+ this.bindAnonymousDeclaration(
2087
+ node,
2088
+ SymbolFlags.Class,
2089
+ name !== undefined ? getText(name) : InternalSymbolName.Class,
2090
+ );
2091
+ }
2092
+ // Every class has a static `prototype` property; declaring another one is an error, checked
2093
+ // here because the class may merge with a namespace that exports `prototype`.
2094
+ const symbol = getSymbol(node)!;
2095
+ const prototypeSymbol = this.newSymbol(SymbolFlags.Property | SymbolFlags.Prototype, 'prototype');
2096
+ const exports = getExports(symbol);
2097
+ const existing = exports.get('prototype');
2098
+ if (existing !== undefined)
2099
+ this.errorOnNode(existing.declarations[0]!, Diagnostics.Duplicate_identifier_0, ['prototype']);
2100
+ exports.set('prototype', prototypeSymbol);
2101
+ prototypeSymbol.parent = symbol;
2102
+ }
2103
+
2104
+ bindPropertyOrMethodOrAccessor(node: Node, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags): void {
2105
+ if (!this.file.isDeclarationFile && (node.flags & NodeFlags.Ambient) === 0 && isAsyncFunction(node))
2106
+ this.emitFlags |= NodeFlags.HasAsyncFunctions;
2107
+ if (isObjectLiteralOrClassExpressionMethodOrAccessor(node)) setFlowNode(node, this.currentFlowValue());
2108
+ if (hasDynamicName(node)) this.bindAnonymousDeclaration(node, symbolFlags, InternalSymbolName.Computed);
2109
+ else this.declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
2110
+ }
2111
+
2112
+ /** Binds `(…) => T` like `{ (…): T }`: a type literal symbol whose only member is the signature. */
2113
+ bindFunctionOrConstructorType(node: Node): void {
2114
+ const symbol = this.newSymbol(SymbolFlags.Signature, this.getDeclarationName(node));
2115
+ this.addDeclarationToSymbol(symbol, node, SymbolFlags.Signature);
2116
+ const typeLiteralSymbol = this.newSymbol(SymbolFlags.TypeLiteral, InternalSymbolName.Type);
2117
+ this.addDeclarationToSymbol(typeLiteralSymbol, node, SymbolFlags.TypeLiteral);
2118
+ getMembers(typeLiteralSymbol).set(symbol.name, symbol);
2119
+ }
2120
+
2121
+ bindVariableDeclarationOrBindingElement(node: Node): void {
2122
+ const name = getName(node);
2123
+ this.checkStrictModeEvalOrArguments(node, name);
2124
+ if (
2125
+ name === undefined ||
2126
+ name.kind === SyntaxKind.ObjectBindingPattern ||
2127
+ name.kind === SyntaxKind.ArrayBindingPattern
2128
+ )
2129
+ return;
2130
+ if (isVariableDeclarationInitializedToRequire(node))
2131
+ this.declareSymbolAndAddToSymbolTable(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes);
2132
+ else if (isBlockOrCatchScoped(node))
2133
+ this.bindBlockScopedDeclaration(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes);
2134
+ else if (isPartOfParameterDeclaration(node))
2135
+ // Parameter excludes report duplicates like `function f([a, a]) {}`.
2136
+ this.declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes);
2137
+ else
2138
+ this.declareSymbolAndAddToSymbolTable(
2139
+ node,
2140
+ SymbolFlags.FunctionScopedVariable,
2141
+ SymbolFlags.FunctionScopedVariableExcludes,
2142
+ );
2143
+ }
2144
+
2145
+ bindParameter(node: ParameterDeclaration): void {
2146
+ // `eval` and `arguments` can't be parameter names in strict mode.
2147
+ if ((node.flags & NodeFlags.Ambient) === 0) this.checkStrictModeEvalOrArguments(node, node.name);
2148
+ const name = node.name;
2149
+ if (name.kind === SyntaxKind.ObjectBindingPattern || name.kind === SyntaxKind.ArrayBindingPattern) {
2150
+ const index = getParameters(node.parent!)!.nodes.indexOf(node);
2151
+ this.bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, '__' + index);
2152
+ } else
2153
+ this.declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes);
2154
+ // A parameter property also declares a property of the class.
2155
+ if (isParameterPropertyDeclaration(node, node.parent!)) {
2156
+ const classSymbol = getSymbol(node.parent!.parent!)!;
2157
+ const flags = SymbolFlags.Property | (node.questionToken !== undefined ? SymbolFlags.Optional : SymbolFlags.None);
2158
+ this.declareSymbol(getMembers(classSymbol), classSymbol, node, flags, SymbolFlags.PropertyExcludes);
2159
+ }
2160
+ }
2161
+
2162
+ bindTypeParameter(node: Node): void {
2163
+ const parent = node.parent!;
2164
+ if (parent.kind !== SyntaxKind.InferType) {
2165
+ this.declareSymbolAndAddToSymbolTable(node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes);
2166
+ return;
2167
+ }
2168
+ // `infer T` declares T in the conditional type whose extends clause contains it.
2169
+ let container: Node | undefined;
2170
+ for (let current: Node | undefined = parent; current !== undefined; current = current.parent) {
2171
+ const p = current.parent;
2172
+ if (p !== undefined && p.kind === SyntaxKind.ConditionalType && getExtendsType(p) === current) {
2173
+ container = p;
2174
+ break;
2175
+ }
2176
+ }
2177
+ if (container !== undefined)
2178
+ this.declareSymbol(
2179
+ this.localsOf(container),
2180
+ undefined,
2181
+ node,
2182
+ SymbolFlags.TypeParameter,
2183
+ SymbolFlags.TypeParameterExcludes,
2184
+ );
2185
+ else this.bindAnonymousDeclaration(node, SymbolFlags.TypeParameter, this.getDeclarationName(node));
2186
+ }
2187
+
2188
+ // JavaScript
2189
+
2190
+ setCommonJSModuleIndicator(node: Node): boolean {
2191
+ const file = this.file;
2192
+ if (file.externalModuleIndicator !== undefined && file.externalModuleIndicator !== file) return false;
2193
+ if (file.commonJSModuleIndicator === undefined) {
2194
+ file.commonJSModuleIndicator = node;
2195
+ if (file.externalModuleIndicator === undefined) this.bindSourceFileAsExternalModule(file);
2196
+ }
2197
+ return true;
2198
+ }
2199
+
2200
+ bindModuleExportsAssignment(node: BinaryExpression): void {
2201
+ if (!this.setCommonJSModuleIndicator(node)) return;
2202
+ const fileSymbol = this.file.symbol!;
2203
+ const flags = expressionIsAlias(node.right) ? SymbolFlags.Alias : SymbolFlags.Property;
2204
+ const symbol = this.declareSymbol(getExports(fileSymbol), fileSymbol, node, flags, SymbolFlags.None);
2205
+ setValueDeclaration(symbol, node);
2206
+ }
2207
+
2208
+ bindExportsOrObjectDefineProperty(node: Node): void {
2209
+ if (!this.setCommonJSModuleIndicator(node)) return;
2210
+ const fileSymbol = this.file.symbol!;
2211
+ const flags =
2212
+ node instanceof BinaryExpression && expressionIsAlias((node as BinaryExpression).right)
2213
+ ? SymbolFlags.Alias
2214
+ : SymbolFlags.FunctionScopedVariable;
2215
+ this.declareSymbol(getExports(fileSymbol), fileSymbol, node, flags, SymbolFlags.FunctionScopedVariableExcludes);
2216
+ }
2217
+
2218
+ bindExpandoPropertyAssignment(node: Node): void {
2219
+ this.expandoAssignments.push(new ExpandoAssignment(node, this.container, this.blockScopeContainer));
2220
+ }
2221
+
2222
+ bindDeferredExpandoAssignments(assignments: readonly ExpandoAssignment[]): void {
2223
+ for (const assignment of assignments) {
2224
+ this.container = assignment.container;
2225
+ this.blockScopeContainer = assignment.blockScopeContainer;
2226
+ this.bindDeferredExpandoAssignment(assignment.node);
2227
+ }
2228
+ }
2229
+
2230
+ bindDeferredExpandoAssignment(node: Node): void {
2231
+ const target =
2232
+ node instanceof BinaryExpression
2233
+ ? getExpression((node as BinaryExpression).left)!
2234
+ : getArguments(node)!.nodes[0]!;
2235
+ const symbol = getInitializerSymbol(
2236
+ this.lookupEntity(target, this.blockScopeContainer) ?? this.lookupEntity(target, this.container),
2237
+ );
2238
+ if (symbol === undefined) return;
2239
+ if (hasDynamicName(node)) {
2240
+ this.bindAnonymousDeclaration(node, SymbolFlags.Property | SymbolFlags.Assignment, InternalSymbolName.Computed);
2241
+ this.addLateBoundAssignmentDeclarationToSymbol(node, symbol);
2242
+ return;
2243
+ }
2244
+ // Expandos are declared only where no other declaration has the name.
2245
+ const exports = getExports(symbol);
2246
+ const existing = exports.get(this.getDeclarationName(node));
2247
+ if (existing === undefined || (existing.flags & SymbolFlags.Assignment) !== 0)
2248
+ this.declareSymbol(
2249
+ exports,
2250
+ symbol,
2251
+ node,
2252
+ SymbolFlags.Property | SymbolFlags.Assignment,
2253
+ SymbolFlags.PropertyExcludes,
2254
+ );
2255
+ }
2256
+
2257
+ addLateBoundAssignmentDeclarationToSymbol(node: Node, symbol: Symbol): void {
2258
+ const exports = getExports(symbol);
2259
+ let assignmentSymbol = exports.get(InternalSymbolName.AssignmentDeclaration);
2260
+ if (assignmentSymbol === undefined) {
2261
+ assignmentSymbol = this.newSymbol(SymbolFlags.None, InternalSymbolName.AssignmentDeclaration);
2262
+ exports.set(InternalSymbolName.AssignmentDeclaration, assignmentSymbol);
2263
+ }
2264
+ addDeclaration(assignmentSymbol, node);
2265
+ }
2266
+
2267
+ /**
2268
+ * With an `export=` symbol, its module's exports with a type or namespace meaning are also
2269
+ * exports of the `export=` symbol, which makes it a namespace.
2270
+ */
2271
+ bindCommonJSTypeExports(moduleSymbol: Symbol | undefined): void {
2272
+ if (moduleSymbol === undefined) return;
2273
+ const moduleExports = moduleSymbol.exports;
2274
+ if (moduleExports === undefined) return;
2275
+ const exportEquals = moduleExports.get(InternalSymbolName.ExportEquals);
2276
+ if (exportEquals === undefined) return;
2277
+ for (const symbol of moduleExports.values()) {
2278
+ if (
2279
+ symbol.name !== InternalSymbolName.ExportEquals &&
2280
+ (symbol.flags & (SymbolFlags.Type | SymbolFlags.Namespace)) !== 0
2281
+ ) {
2282
+ getExports(exportEquals).set(symbol.name, symbol);
2283
+ exportEquals.flags |= SymbolFlags.NamespaceModule;
2284
+ }
2285
+ }
2286
+ }
2287
+
2288
+ bindThisPropertyAssignment(node: BinaryExpression): void {
2289
+ if (!isInJSFile(node)) return;
2290
+ const left = node.left;
2291
+ const thisContainer = this.thisContainer;
2292
+ if (
2293
+ (left instanceof PropertyAccessExpression &&
2294
+ (left as PropertyAccessExpression).name.kind === SyntaxKind.PrivateIdentifier) ||
2295
+ thisContainer === undefined
2296
+ )
2297
+ return;
2298
+ const symbolTable = this.thisSymbolTable();
2299
+ if (symbolTable !== undefined) {
2300
+ const classSymbol = getSymbol(thisContainer.parent!);
2301
+ if (hasDynamicName(node)) {
2302
+ this.declareSymbolEx(symbolTable, classSymbol, node, SymbolFlags.Property, SymbolFlags.None, true, true);
2303
+ this.addLateBoundAssignmentDeclarationToSymbol(node, classSymbol!);
2304
+ } else
2305
+ this.declareSymbolEx(
2306
+ symbolTable,
2307
+ classSymbol,
2308
+ node,
2309
+ SymbolFlags.Property | SymbolFlags.Assignment,
2310
+ SymbolFlags.None,
2311
+ true,
2312
+ false,
2313
+ );
2314
+ } else if (
2315
+ thisContainer.kind !== SyntaxKind.FunctionDeclaration &&
2316
+ thisContainer.kind !== SyntaxKind.FunctionExpression
2317
+ )
2318
+ throw new Error('Unhandled case in bindThisPropertyAssignment');
2319
+ }
2320
+
2321
+ /** For `this.x` in a class member, the class's members, or exports if the member is static. */
2322
+ thisSymbolTable(): SymbolTable | undefined {
2323
+ const thisContainer = this.thisContainer;
2324
+ if (thisContainer === undefined) return undefined;
2325
+ switch (thisContainer.kind) {
2326
+ case SyntaxKind.Constructor:
2327
+ case SyntaxKind.PropertyDeclaration:
2328
+ case SyntaxKind.MethodDeclaration:
2329
+ case SyntaxKind.GetAccessor:
2330
+ case SyntaxKind.SetAccessor:
2331
+ case SyntaxKind.ClassStaticBlockDeclaration: {
2332
+ const classSymbol = getSymbol(thisContainer.parent!)!;
2333
+ return isStatic(thisContainer) ? getExports(classSymbol) : getMembers(classSymbol);
2334
+ }
2335
+ }
2336
+ return undefined;
2337
+ }
2338
+
2339
+ lookupEntity(node: Node, container: Node): Symbol | undefined {
2340
+ if (node.kind === SyntaxKind.Identifier) return lookupName(getText(node), container);
2341
+ const expression = getExpression(node)!;
2342
+ if (expression.kind === SyntaxKind.ThisKeyword) {
2343
+ const symbolTable = this.thisSymbolTable();
2344
+ if (symbolTable === undefined) return undefined;
2345
+ const name = getElementOrPropertyAccessName(node);
2346
+ return name !== undefined ? symbolTable.get(getText(name)) : undefined;
2347
+ }
2348
+ const symbol = getInitializerSymbol(this.lookupEntity(expression, container));
2349
+ if (symbol !== undefined && symbol.exports !== undefined) {
2350
+ const name = getElementOrPropertyAccessName(node);
2351
+ if (name !== undefined) return symbol.exports.get(getText(name));
2352
+ }
2353
+ return undefined;
2354
+ }
2355
+
2356
+ // Strict mode
2357
+
2358
+ /** Reports reserved words used as identifiers, and `await`/`yield` where they are keywords. */
2359
+ checkContextualIdentifier(node: Identifier): void {
2360
+ // Only words starting with a, i, l, p, s or y can be future reserved words, await or yield.
2361
+ const text = node.text;
2362
+ const first = text.charCodeAt(0);
2363
+ if (first !== 0x61 && first !== 0x69 && first !== 0x6c && first !== 0x70 && first !== 0x73 && first !== 0x79)
2364
+ return;
2365
+ if (
2366
+ this.file.diagnostics.length !== 0 ||
2367
+ (node.flags & (NodeFlags.Ambient | NodeFlags.JSDoc)) !== 0 ||
2368
+ isIdentifierName(node)
2369
+ )
2370
+ return;
2371
+ const originalKeywordKind = getIdentifierToken(text);
2372
+ if (originalKeywordKind === SyntaxKind.Identifier) return;
2373
+ if (
2374
+ originalKeywordKind >= SyntaxKind.FirstFutureReservedWord &&
2375
+ originalKeywordKind <= SyntaxKind.LastFutureReservedWord
2376
+ )
2377
+ this.errorOnNode(node, this.getStrictModeIdentifierMessage(node), [declarationNameToString(this.file, node)]);
2378
+ else if (originalKeywordKind === SyntaxKind.AwaitKeyword) {
2379
+ if (isExternalModule(this.file) && isInTopLevelContext(node))
2380
+ this.errorOnNode(node, Diagnostics.Identifier_expected_0_is_a_reserved_word_at_the_top_level_of_a_module, [
2381
+ declarationNameToString(this.file, node),
2382
+ ]);
2383
+ else if ((node.flags & NodeFlags.AwaitContext) !== 0)
2384
+ this.errorOnNode(node, Diagnostics.Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here, [
2385
+ declarationNameToString(this.file, node),
2386
+ ]);
2387
+ } else if (originalKeywordKind === SyntaxKind.YieldKeyword && (node.flags & NodeFlags.YieldContext) !== 0)
2388
+ this.errorOnNode(node, Diagnostics.Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here, [
2389
+ declarationNameToString(this.file, node),
2390
+ ]);
2391
+ }
2392
+
2393
+ checkPrivateIdentifier(node: Node): void {
2394
+ if (getText(node) === '#constructor' && this.file.diagnostics.length === 0)
2395
+ this.errorOnNode(node, Diagnostics.X_constructor_is_a_reserved_word, [declarationNameToString(this.file, node)]);
2396
+ }
2397
+
2398
+ getStrictModeIdentifierMessage(node: Node): DiagnosticMessage {
2399
+ if (getContainingClass(node) !== undefined)
2400
+ return Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode;
2401
+ if (this.file.externalModuleIndicator !== undefined)
2402
+ return Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode;
2403
+ return Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode;
2404
+ }
2405
+
2406
+ checkStrictModeFunctionName(node: Node): void {
2407
+ if ((node.flags & NodeFlags.Ambient) === 0) this.checkStrictModeEvalOrArguments(node, getName(node));
2408
+ }
2409
+
2410
+ checkStrictModeBinaryExpression(node: BinaryExpression): void {
2411
+ // `eval` and `arguments` can't be assigned to.
2412
+ if (isLeftHandSideExpression(node.left) && isAssignmentOperator(node.operatorToken.kind))
2413
+ this.checkStrictModeEvalOrArguments(node, node.left);
2414
+ }
2415
+
2416
+ checkStrictModeCatchClause(node: CatchClause): void {
2417
+ const declaration = node.variableDeclaration;
2418
+ if (declaration !== undefined) this.checkStrictModeEvalOrArguments(node, declaration.name);
2419
+ }
2420
+
2421
+ checkStrictModeDeleteExpression(node: DeleteExpression): void {
2422
+ // Deleting a variable, parameter or function name is an error in strict mode.
2423
+ if (node.expression.kind === SyntaxKind.Identifier)
2424
+ this.errorOnNode(node.expression, Diagnostics.X_delete_cannot_be_called_on_an_identifier_in_strict_mode, noArgs);
2425
+ }
2426
+
2427
+ checkStrictModeEvalOrArguments(contextNode: Node, name: Node | undefined): void {
2428
+ if (name === undefined || name.kind !== SyntaxKind.Identifier) return;
2429
+ const text = getText(name);
2430
+ if (text !== 'eval' && text !== 'arguments') return;
2431
+ let message: DiagnosticMessage;
2432
+ if (getContainingClass(contextNode) !== undefined)
2433
+ message =
2434
+ Diagnostics.Code_contained_in_a_class_is_evaluated_in_JavaScript_s_strict_mode_which_does_not_allow_this_use_of_0_For_more_information_see_https_Colon_Slash_Slashdeveloper_mozilla_org_Slashen_US_Slashdocs_SlashWeb_SlashJavaScript_SlashReference_SlashStrict_mode;
2435
+ else if (this.file.externalModuleIndicator !== undefined)
2436
+ message = Diagnostics.Invalid_use_of_0_Modules_are_automatically_in_strict_mode;
2437
+ else message = Diagnostics.Invalid_use_of_0_in_strict_mode;
2438
+ this.errorOnNode(name, message, [text]);
2439
+ }
2440
+ }
2441
+
2442
+ const noArgs: readonly string[] = [];
2443
+
2444
+ function optionalSymbolFlag(node: Node): SymbolFlags {
2445
+ const postfixToken = getPostfixToken(node);
2446
+ return postfixToken !== undefined && postfixToken.kind === SyntaxKind.QuestionToken
2447
+ ? SymbolFlags.Optional
2448
+ : SymbolFlags.None;
2449
+ }
2450
+
2451
+ function getExtendsType(node: Node): Node | undefined {
2452
+ return node instanceof ConditionalTypeNode ? (node as ConditionalTypeNode).extendsType : undefined;
2453
+ }
2454
+
2455
+ function isGeneratorFunctionExpression(node: Node): boolean {
2456
+ return node instanceof FunctionExpression && (node as FunctionExpression).asteriskToken !== undefined;
2457
+ }
2458
+
2459
+ function isForInOrOfStatementKind(kind: SyntaxKind): boolean {
2460
+ return kind === SyntaxKind.ForInStatement || kind === SyntaxKind.ForOfStatement;
2461
+ }
2462
+
2463
+ function hasExportDeclarations(node: Node): boolean {
2464
+ let statements: NodeList | undefined;
2465
+ if (node.kind === SyntaxKind.SourceFile) statements = (node as SourceFile).statements;
2466
+ else if (node instanceof ModuleDeclaration) {
2467
+ const body = (node as ModuleDeclaration).body;
2468
+ if (body !== undefined && body.kind === SyntaxKind.ModuleBlock) statements = getStatements(body);
2469
+ }
2470
+ if (statements === undefined) return false;
2471
+ for (const statement of statements.nodes)
2472
+ if (statement.kind === SyntaxKind.ExportDeclaration || statement.kind === SyntaxKind.ExportAssignment) return true;
2473
+ return false;
2474
+ }
2475
+
2476
+ /** The symbol in `container`'s locals or its symbol's exports, preferring a local's export symbol. */
2477
+ function lookupName(name: string, container: Node): Symbol | undefined {
2478
+ if (isLocalsContainer(container)) {
2479
+ const locals = getLocals(container);
2480
+ const local = locals !== undefined ? locals.get(name) : undefined;
2481
+ if (local !== undefined) return local.exportSymbol ?? local;
2482
+ }
2483
+ if (isDeclarationNode(container)) {
2484
+ const symbol = getSymbol(container);
2485
+ if (symbol !== undefined && symbol.exports !== undefined) return symbol.exports.get(name);
2486
+ }
2487
+ return undefined;
2488
+ }
2489
+
2490
+ /**
2491
+ * For `fn.x = …`: the symbol that gets expando properties when `fn` is a function, a const
2492
+ * (or JavaScript) variable initialized with a function or class, or a JavaScript class.
2493
+ */
2494
+ function getInitializerSymbol(symbol: Symbol | undefined): Symbol | undefined {
2495
+ if (symbol === undefined) return undefined;
2496
+ const declaration = symbol.valueDeclaration;
2497
+ if (declaration === undefined) return undefined;
2498
+ if (
2499
+ declaration.kind === SyntaxKind.FunctionDeclaration ||
2500
+ (isInJSFile(declaration) && declaration.kind === SyntaxKind.ClassDeclaration)
2501
+ )
2502
+ return symbol;
2503
+ if (declaration instanceof VariableDeclaration) {
2504
+ if (((declaration as VariableDeclaration).parent!.flags & NodeFlags.Const) !== 0 || isInJSFile(declaration)) {
2505
+ const initializer = (declaration as VariableDeclaration).initializer;
2506
+ if (isExpandoInitializer(declaration, initializer)) return getSymbol(initializer!);
2507
+ }
2508
+ return undefined;
2509
+ }
2510
+ if (declaration instanceof BinaryExpression && isInJSFile(declaration)) {
2511
+ const initializer = (declaration as BinaryExpression).right;
2512
+ if (isExpandoInitializer(declaration, initializer)) return getSymbol(initializer);
2513
+ }
2514
+ return undefined;
2515
+ }
2516
+
2517
+ function setFlowNodeReferenced(flow: FlowNode): void {
2518
+ // Referenced on first use, Shared after that.
2519
+ flow.flags |= (flow.flags & FlowFlags.Referenced) === 0 ? FlowFlags.Referenced : FlowFlags.Shared;
2520
+ }
2521
+
2522
+ function combineFlowLists(head: FlowNode[] | undefined, tail: FlowNode[] | undefined): FlowNode[] | undefined {
2523
+ if (head === undefined) return tail;
2524
+ return tail === undefined ? head.slice() : head.concat(tail);
2525
+ }
2526
+
2527
+ function isStatementCondition(node: Node): boolean {
2528
+ const parent = node.parent!;
2529
+ switch (parent.kind) {
2530
+ case SyntaxKind.IfStatement:
2531
+ case SyntaxKind.WhileStatement:
2532
+ case SyntaxKind.DoStatement:
2533
+ return getExpression(parent) === node;
2534
+ case SyntaxKind.ForStatement:
2535
+ return (parent as ForStatement).condition === node;
2536
+ case SyntaxKind.ConditionalExpression:
2537
+ return (parent as ConditionalExpression).condition === node;
2538
+ }
2539
+ return false;
2540
+ }
2541
+
2542
+ function isTopLevelLogicalExpression(node: Node): boolean {
2543
+ let current = node;
2544
+ for (;;) {
2545
+ const parent = current.parent!;
2546
+ if (
2547
+ parent.kind === SyntaxKind.ParenthesizedExpression ||
2548
+ (parent instanceof PrefixUnaryExpression &&
2549
+ (parent as PrefixUnaryExpression).operator === SyntaxKind.ExclamationToken)
2550
+ )
2551
+ current = parent;
2552
+ else break;
2553
+ }
2554
+ const parent = current.parent!;
2555
+ return (
2556
+ !isStatementCondition(current) &&
2557
+ !isLogicalExpression(parent) &&
2558
+ !(isOptionalChain(parent) && getExpression(parent) === current)
2559
+ );
2560
+ }
2561
+
2562
+ // Narrowing
2563
+
2564
+ function isNarrowingExpression(expression: Node): boolean {
2565
+ switch (expression.kind) {
2566
+ case SyntaxKind.Identifier:
2567
+ case SyntaxKind.ThisKeyword:
2568
+ return true;
2569
+ case SyntaxKind.PropertyAccessExpression:
2570
+ case SyntaxKind.ElementAccessExpression:
2571
+ return containsNarrowableReference(expression);
2572
+ case SyntaxKind.CallExpression:
2573
+ return hasNarrowableArgument(expression as CallExpression);
2574
+ case SyntaxKind.ParenthesizedExpression:
2575
+ case SyntaxKind.NonNullExpression:
2576
+ case SyntaxKind.TypeOfExpression:
2577
+ return isNarrowingExpression(getExpression(expression)!);
2578
+ case SyntaxKind.BinaryExpression:
2579
+ return isNarrowingBinaryExpression(expression as BinaryExpression);
2580
+ case SyntaxKind.PrefixUnaryExpression: {
2581
+ const unary = expression as PrefixUnaryExpression;
2582
+ return unary.operator === SyntaxKind.ExclamationToken && isNarrowingExpression(unary.operand);
2583
+ }
2584
+ }
2585
+ return false;
2586
+ }
2587
+
2588
+ function containsNarrowableReference(expression: Node): boolean {
2589
+ if (isNarrowableReference(expression)) return true;
2590
+ if ((expression.flags & NodeFlags.OptionalChain) !== 0) {
2591
+ switch (expression.kind) {
2592
+ case SyntaxKind.PropertyAccessExpression:
2593
+ case SyntaxKind.ElementAccessExpression:
2594
+ case SyntaxKind.CallExpression:
2595
+ case SyntaxKind.NonNullExpression:
2596
+ return containsNarrowableReference(getExpression(expression)!);
2597
+ }
2598
+ }
2599
+ return false;
2600
+ }
2601
+
2602
+ /** A reference whose type control flow analysis can narrow. */
2603
+ export function isNarrowableReference(node: Node): boolean {
2604
+ switch (node.kind) {
2605
+ case SyntaxKind.Identifier:
2606
+ case SyntaxKind.ThisKeyword:
2607
+ case SyntaxKind.SuperKeyword:
2608
+ case SyntaxKind.MetaProperty:
2609
+ return true;
2610
+ case SyntaxKind.PropertyAccessExpression:
2611
+ return isNarrowableReference((node as PropertyAccessExpression).expression);
2612
+ case SyntaxKind.ParenthesizedExpression:
2613
+ return isNarrowableReference((node as ParenthesizedExpression).expression);
2614
+ case SyntaxKind.NonNullExpression:
2615
+ return isNarrowableReference((node as NonNullExpression).expression);
2616
+ case SyntaxKind.ElementAccessExpression: {
2617
+ const access = node as ElementAccessExpression;
2618
+ return (
2619
+ isStringOrNumericLiteralLike(access.argumentExpression) ||
2620
+ (isEntityNameExpression(access.argumentExpression, false) && isNarrowableReference(access.expression))
2621
+ );
2622
+ }
2623
+ case SyntaxKind.BinaryExpression: {
2624
+ const binary = node as BinaryExpression;
2625
+ const operator = binary.operatorToken.kind;
2626
+ return (
2627
+ (operator === SyntaxKind.CommaToken && isNarrowableReference(binary.right)) ||
2628
+ (isAssignmentOperator(operator) && isLeftHandSideExpression(binary.left))
2629
+ );
2630
+ }
2631
+ }
2632
+ return false;
2633
+ }
2634
+
2635
+ function hasNarrowableArgument(call: CallExpression): boolean {
2636
+ for (const argument of call.arguments.nodes) if (containsNarrowableReference(argument)) return true;
2637
+ const callee = call.expression;
2638
+ return (
2639
+ callee instanceof PropertyAccessExpression &&
2640
+ containsNarrowableReference((callee as PropertyAccessExpression).expression)
2641
+ );
2642
+ }
2643
+
2644
+ function isNarrowingBinaryExpression(expression: BinaryExpression): boolean {
2645
+ switch (expression.operatorToken.kind) {
2646
+ case SyntaxKind.EqualsToken:
2647
+ case SyntaxKind.BarBarEqualsToken:
2648
+ case SyntaxKind.AmpersandAmpersandEqualsToken:
2649
+ case SyntaxKind.QuestionQuestionEqualsToken:
2650
+ return containsNarrowableReference(expression.left);
2651
+ case SyntaxKind.EqualsEqualsToken:
2652
+ case SyntaxKind.ExclamationEqualsToken:
2653
+ case SyntaxKind.EqualsEqualsEqualsToken:
2654
+ case SyntaxKind.ExclamationEqualsEqualsToken: {
2655
+ const left = skipParentheses(expression.left);
2656
+ const right = skipParentheses(expression.right);
2657
+ return (
2658
+ isNarrowableOperand(left) ||
2659
+ isNarrowableOperand(right) ||
2660
+ isNarrowingTypeOfOperands(right, left) ||
2661
+ isNarrowingTypeOfOperands(left, right) ||
2662
+ (isBooleanLiteral(right) && isNarrowingExpression(left)) ||
2663
+ (isBooleanLiteral(left) && isNarrowingExpression(right))
2664
+ );
2665
+ }
2666
+ case SyntaxKind.InstanceOfKeyword:
2667
+ return isNarrowableOperand(expression.left);
2668
+ case SyntaxKind.InKeyword:
2669
+ case SyntaxKind.CommaToken:
2670
+ return isNarrowingExpression(expression.right);
2671
+ }
2672
+ return false;
2673
+ }
2674
+
2675
+ function isNarrowableOperand(expression: Node): boolean {
2676
+ if (expression.kind === SyntaxKind.ParenthesizedExpression) return isNarrowableOperand(getExpression(expression)!);
2677
+ if (expression instanceof BinaryExpression) {
2678
+ const binary = expression as BinaryExpression;
2679
+ const operator = binary.operatorToken.kind;
2680
+ if (operator === SyntaxKind.EqualsToken) return isNarrowableOperand(binary.left);
2681
+ if (operator === SyntaxKind.CommaToken) return isNarrowableOperand(binary.right);
2682
+ }
2683
+ return containsNarrowableReference(expression);
2684
+ }
2685
+
2686
+ function isNarrowingTypeOfOperands(expression1: Node, expression2: Node): boolean {
2687
+ return (
2688
+ expression1.kind === SyntaxKind.TypeOfExpression &&
2689
+ isNarrowableOperand(getExpression(expression1)!) &&
2690
+ isStringLiteralLike(expression2)
2691
+ );
2692
+ }
2693
+
2694
+ /** The `"use strict"` prologue directive of `statements`, if any. */
2695
+ export function findUseStrictPrologue(file: SourceFile, statements: readonly Node[]): Node | undefined {
2696
+ for (const statement of statements) {
2697
+ if (!isPrologueDirective(statement)) return undefined;
2698
+ // Exactly `"use strict"` or `'use strict'`, without escapes.
2699
+ const text = getSourceTextOfNode(file, (statement as ExpressionStatement).expression);
2700
+ if (text === '"use strict"' || text === "'use strict'") return statement;
2701
+ }
2702
+ return undefined;
2703
+ }