From 269682e4ab189a12edb29daf8de22310cd9c0ecc Mon Sep 17 00:00:00 2001 From: Egor Aristov Date: Sat, 8 Nov 2025 09:37:30 +0300 Subject: [PATCH] squash --- .gitignore | 5 + LICENSE | 201 + README.md | 66 + example/Makefile | 7 + example/golang/go.mod | 3 + example/golang/main.go | 54 + example/golang/remote.go | 25 + example/ts/dist/goapi.gen.d.ts | 7 + example/ts/dist/goapi.gen.d.ts.map | 1 + example/ts/dist/goapi.gen.js.map | 1 + example/ts/dist/index.d.ts | 2 + example/ts/dist/index.d.ts.map | 1 + example/ts/dist/index.js.map | 1 + example/ts/package-lock.json | 50 + example/ts/package.json | 12 + example/ts/src/index.ts | 30 + example/ts/src/remote.ts | 15 + example/ts/tsconfig.json | 28 + kitcom/Makefile | 56 + kitcom/api/api.go | 35 + kitcom/go.mod | 9 + kitcom/go.sum | 6 + kitcom/golang/go_gen.tmpl | 34 + kitcom/golang/gogen.go | 92 + kitcom/golang/goparser.go | 163 + kitcom/internal/tsgo/ast/ast.go | 11138 ++++++++++++++++ kitcom/internal/tsgo/ast/checkflags.go | 35 + kitcom/internal/tsgo/ast/deepclone.go | 86 + kitcom/internal/tsgo/ast/diagnostic.go | 272 + kitcom/internal/tsgo/ast/flow.go | 75 + kitcom/internal/tsgo/ast/ids.go | 6 + kitcom/internal/tsgo/ast/kind.go | 430 + .../tsgo/ast/kind_stringer_generated.go | 378 + kitcom/internal/tsgo/ast/modifierflags.go | 53 + kitcom/internal/tsgo/ast/nodeflags.go | 65 + kitcom/internal/tsgo/ast/parseoptions.go | 168 + kitcom/internal/tsgo/ast/precedence.go | 714 + kitcom/internal/tsgo/ast/subtreefacts.go | 131 + kitcom/internal/tsgo/ast/symbol.go | 59 + kitcom/internal/tsgo/ast/symbolflags.go | 86 + kitcom/internal/tsgo/ast/tokenflags.go | 31 + kitcom/internal/tsgo/ast/utilities.go | 3892 ++++++ kitcom/internal/tsgo/ast/visitor.go | 278 + kitcom/internal/tsgo/collections/multimap.go | 69 + .../internal/tsgo/collections/ordered_map.go | 317 + .../internal/tsgo/collections/ordered_set.go | 54 + kitcom/internal/tsgo/collections/set.go | 77 + kitcom/internal/tsgo/collections/syncmap.go | 84 + kitcom/internal/tsgo/collections/syncset.go | 67 + kitcom/internal/tsgo/core/bfs.go | 206 + kitcom/internal/tsgo/core/binarysearch.go | 26 + kitcom/internal/tsgo/core/buildoptions.go | 15 + kitcom/internal/tsgo/core/compileroptions.go | 545 + kitcom/internal/tsgo/core/context.go | 36 + kitcom/internal/tsgo/core/core.go | 689 + kitcom/internal/tsgo/core/languagevariant.go | 11 + .../languagevariant_stringer_generated.go | 24 + kitcom/internal/tsgo/core/linkstore.go | 30 + .../core/modulekind_stringer_generated.go | 52 + kitcom/internal/tsgo/core/nodemodules.go | 88 + kitcom/internal/tsgo/core/parsedoptions.go | 10 + kitcom/internal/tsgo/core/pattern.go | 52 + kitcom/internal/tsgo/core/pool.go | 66 + kitcom/internal/tsgo/core/projectreference.go | 20 + kitcom/internal/tsgo/core/scriptkind.go | 21 + .../core/scriptkind_stringer_generated.go | 30 + .../core/scripttarget_stringer_generated.go | 49 + kitcom/internal/tsgo/core/stack.go | 33 + kitcom/internal/tsgo/core/text.go | 66 + kitcom/internal/tsgo/core/textchange.go | 30 + kitcom/internal/tsgo/core/tristate.go | 71 + .../tsgo/core/tristate_stringer_generated.go | 25 + kitcom/internal/tsgo/core/typeacquisition.go | 24 + kitcom/internal/tsgo/core/version.go | 33 + kitcom/internal/tsgo/core/watchoptions.go | 53 + kitcom/internal/tsgo/core/workgroup.go | 125 + kitcom/internal/tsgo/debug/debug.go | 198 + kitcom/internal/tsgo/debug/release.go | 26 + kitcom/internal/tsgo/debug/shared.go | 43 + .../internal/tsgo/diagnostics/diagnostics.go | 63 + .../tsgo/diagnostics/diagnostics_generated.go | 4255 ++++++ .../diagnostics/extraDiagnosticMessages.json | 42 + kitcom/internal/tsgo/diagnostics/generate.go | 183 + .../tsgo/diagnostics/stringer_generated.go | 26 + kitcom/internal/tsgo/jsnum/jsnum.go | 159 + kitcom/internal/tsgo/jsnum/pseudobigint.go | 66 + kitcom/internal/tsgo/jsnum/string.go | 341 + kitcom/internal/tsgo/jsonutil/jsonutil.go | 24 + kitcom/internal/tsgo/parser/jsdoc.go | 1205 ++ kitcom/internal/tsgo/parser/parser.go | 6587 +++++++++ kitcom/internal/tsgo/parser/references.go | 74 + kitcom/internal/tsgo/parser/reparser.go | 619 + kitcom/internal/tsgo/parser/types.go | 14 + kitcom/internal/tsgo/parser/utilities.go | 54 + kitcom/internal/tsgo/repo/paths.go | 63 + kitcom/internal/tsgo/scanner/scanner.go | 2619 ++++ kitcom/internal/tsgo/scanner/utilities.go | 67 + kitcom/internal/tsgo/stringutil/compare.go | 120 + kitcom/internal/tsgo/stringutil/format.go | 19 + kitcom/internal/tsgo/stringutil/util.go | 240 + kitcom/internal/tsgo/tspath/extension.go | 178 + kitcom/internal/tsgo/tspath/ignoredpaths.go | 14 + kitcom/internal/tsgo/tspath/path.go | 1129 ++ kitcom/main.go | 151 + kitcom/ts/ts_gen.tmpl | 25 + kitcom/ts/tsgen.go | 77 + kitcom/ts/tsparser.go | 165 + lib/golang/go.mod | 5 + lib/golang/go.sum | 2 + lib/golang/lib.go | 428 + lib/ts/dist/index.d.ts | 2 + lib/ts/dist/index.d.ts.map | 1 + lib/ts/dist/index.js.map | 1 + lib/ts/dist/lib.d.ts | 60 + lib/ts/dist/lib.d.ts.map | 1 + lib/ts/dist/lib.js.map | 1 + lib/ts/package-lock.json | 38 + lib/ts/package.json | 27 + lib/ts/src/index.ts | 1 + lib/ts/src/lib.ts | 343 + lib/ts/tsconfig.json | 33 + 121 files changed, 41688 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 example/Makefile create mode 100644 example/golang/go.mod create mode 100644 example/golang/main.go create mode 100644 example/golang/remote.go create mode 100644 example/ts/dist/goapi.gen.d.ts create mode 100644 example/ts/dist/goapi.gen.d.ts.map create mode 100644 example/ts/dist/goapi.gen.js.map create mode 100644 example/ts/dist/index.d.ts create mode 100644 example/ts/dist/index.d.ts.map create mode 100644 example/ts/dist/index.js.map create mode 100644 example/ts/package-lock.json create mode 100644 example/ts/package.json create mode 100644 example/ts/src/index.ts create mode 100644 example/ts/src/remote.ts create mode 100644 example/ts/tsconfig.json create mode 100644 kitcom/Makefile create mode 100644 kitcom/api/api.go create mode 100644 kitcom/go.mod create mode 100644 kitcom/go.sum create mode 100644 kitcom/golang/go_gen.tmpl create mode 100644 kitcom/golang/gogen.go create mode 100644 kitcom/golang/goparser.go create mode 100644 kitcom/internal/tsgo/ast/ast.go create mode 100644 kitcom/internal/tsgo/ast/checkflags.go create mode 100644 kitcom/internal/tsgo/ast/deepclone.go create mode 100644 kitcom/internal/tsgo/ast/diagnostic.go create mode 100644 kitcom/internal/tsgo/ast/flow.go create mode 100644 kitcom/internal/tsgo/ast/ids.go create mode 100644 kitcom/internal/tsgo/ast/kind.go create mode 100644 kitcom/internal/tsgo/ast/kind_stringer_generated.go create mode 100644 kitcom/internal/tsgo/ast/modifierflags.go create mode 100644 kitcom/internal/tsgo/ast/nodeflags.go create mode 100644 kitcom/internal/tsgo/ast/parseoptions.go create mode 100644 kitcom/internal/tsgo/ast/precedence.go create mode 100644 kitcom/internal/tsgo/ast/subtreefacts.go create mode 100644 kitcom/internal/tsgo/ast/symbol.go create mode 100644 kitcom/internal/tsgo/ast/symbolflags.go create mode 100644 kitcom/internal/tsgo/ast/tokenflags.go create mode 100644 kitcom/internal/tsgo/ast/utilities.go create mode 100644 kitcom/internal/tsgo/ast/visitor.go create mode 100644 kitcom/internal/tsgo/collections/multimap.go create mode 100644 kitcom/internal/tsgo/collections/ordered_map.go create mode 100644 kitcom/internal/tsgo/collections/ordered_set.go create mode 100644 kitcom/internal/tsgo/collections/set.go create mode 100644 kitcom/internal/tsgo/collections/syncmap.go create mode 100644 kitcom/internal/tsgo/collections/syncset.go create mode 100644 kitcom/internal/tsgo/core/bfs.go create mode 100644 kitcom/internal/tsgo/core/binarysearch.go create mode 100644 kitcom/internal/tsgo/core/buildoptions.go create mode 100644 kitcom/internal/tsgo/core/compileroptions.go create mode 100644 kitcom/internal/tsgo/core/context.go create mode 100644 kitcom/internal/tsgo/core/core.go create mode 100644 kitcom/internal/tsgo/core/languagevariant.go create mode 100644 kitcom/internal/tsgo/core/languagevariant_stringer_generated.go create mode 100644 kitcom/internal/tsgo/core/linkstore.go create mode 100644 kitcom/internal/tsgo/core/modulekind_stringer_generated.go create mode 100644 kitcom/internal/tsgo/core/nodemodules.go create mode 100644 kitcom/internal/tsgo/core/parsedoptions.go create mode 100644 kitcom/internal/tsgo/core/pattern.go create mode 100644 kitcom/internal/tsgo/core/pool.go create mode 100644 kitcom/internal/tsgo/core/projectreference.go create mode 100644 kitcom/internal/tsgo/core/scriptkind.go create mode 100644 kitcom/internal/tsgo/core/scriptkind_stringer_generated.go create mode 100644 kitcom/internal/tsgo/core/scripttarget_stringer_generated.go create mode 100644 kitcom/internal/tsgo/core/stack.go create mode 100644 kitcom/internal/tsgo/core/text.go create mode 100644 kitcom/internal/tsgo/core/textchange.go create mode 100644 kitcom/internal/tsgo/core/tristate.go create mode 100644 kitcom/internal/tsgo/core/tristate_stringer_generated.go create mode 100644 kitcom/internal/tsgo/core/typeacquisition.go create mode 100644 kitcom/internal/tsgo/core/version.go create mode 100644 kitcom/internal/tsgo/core/watchoptions.go create mode 100644 kitcom/internal/tsgo/core/workgroup.go create mode 100644 kitcom/internal/tsgo/debug/debug.go create mode 100644 kitcom/internal/tsgo/debug/release.go create mode 100644 kitcom/internal/tsgo/debug/shared.go create mode 100644 kitcom/internal/tsgo/diagnostics/diagnostics.go create mode 100644 kitcom/internal/tsgo/diagnostics/diagnostics_generated.go create mode 100644 kitcom/internal/tsgo/diagnostics/extraDiagnosticMessages.json create mode 100644 kitcom/internal/tsgo/diagnostics/generate.go create mode 100644 kitcom/internal/tsgo/diagnostics/stringer_generated.go create mode 100644 kitcom/internal/tsgo/jsnum/jsnum.go create mode 100644 kitcom/internal/tsgo/jsnum/pseudobigint.go create mode 100644 kitcom/internal/tsgo/jsnum/string.go create mode 100644 kitcom/internal/tsgo/jsonutil/jsonutil.go create mode 100644 kitcom/internal/tsgo/parser/jsdoc.go create mode 100644 kitcom/internal/tsgo/parser/parser.go create mode 100644 kitcom/internal/tsgo/parser/references.go create mode 100644 kitcom/internal/tsgo/parser/reparser.go create mode 100644 kitcom/internal/tsgo/parser/types.go create mode 100644 kitcom/internal/tsgo/parser/utilities.go create mode 100644 kitcom/internal/tsgo/repo/paths.go create mode 100644 kitcom/internal/tsgo/scanner/scanner.go create mode 100644 kitcom/internal/tsgo/scanner/utilities.go create mode 100644 kitcom/internal/tsgo/stringutil/compare.go create mode 100644 kitcom/internal/tsgo/stringutil/format.go create mode 100644 kitcom/internal/tsgo/stringutil/util.go create mode 100644 kitcom/internal/tsgo/tspath/extension.go create mode 100644 kitcom/internal/tsgo/tspath/ignoredpaths.go create mode 100644 kitcom/internal/tsgo/tspath/path.go create mode 100644 kitcom/main.go create mode 100644 kitcom/ts/ts_gen.tmpl create mode 100644 kitcom/ts/tsgen.go create mode 100644 kitcom/ts/tsparser.go create mode 100644 lib/golang/go.mod create mode 100644 lib/golang/go.sum create mode 100644 lib/golang/lib.go create mode 100644 lib/ts/dist/index.d.ts create mode 100644 lib/ts/dist/index.d.ts.map create mode 100644 lib/ts/dist/index.js.map create mode 100644 lib/ts/dist/lib.d.ts create mode 100644 lib/ts/dist/lib.d.ts.map create mode 100644 lib/ts/dist/lib.js.map create mode 100644 lib/ts/package-lock.json create mode 100644 lib/ts/package.json create mode 100644 lib/ts/src/index.ts create mode 100644 lib/ts/src/lib.ts create mode 100644 lib/ts/tsconfig.json diff --git a/.gitignore b/.gitignore index a09c56d..578e805 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,6 @@ /.idea +/go.work +/go.work.sum +node_modules +*.js +/TODO.md diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..4ea4b83 --- /dev/null +++ b/README.md @@ -0,0 +1,66 @@ +# Readme draft + +1. write code in language A +2. annotate it (see below) +3. launch `kitcom -src path/to/source.A -dest path/to/generated/file.B` +4. Use generated file to IPC + +## Typescript: + +Currently only whole classes are supported. + +### Annotate: + +```typescript +/** + * @kittenipc api + */ +class ClassName {} +``` + +### Usage: + +```typescript +const localApi = new LocalAPI(); // LocalAPI is written by hand +const ipc = new ChildIPC(localApi); +const goApi = new RemoteAPI(ipc); // RemoteAPI is generated by kitcom +await ipc.start(); +// work +await ipc.wait(); +``` + +## Golang: + +Currently only whole structs are supported + +### Annotate + +```go +// kittenipc:api +type StructName struct { +} +``` + +### Usage: + +```go +localApi := LocalAPI{} // LocalAPI is written by hand +cmd := exec.Command(fmt.Sprintf("node %s", "path to compiled js")) +ipc, err := kittenipc.NewParent(cmd, &localApi) +remoteApi := RemoteAPI{Ipc: ipc} // RemoteAPI is generated by kitcom +if err != nil { + log.Panic(err) +} +if err := ipc.Start(); err != nil { + log.Panic(err) +} +// work +if err := kit.Wait(); err != nil { + log.Panic(err) +} +``` + +LocalAPI on one side is RemoteAPI on the other side + +# Library status +Work in progress. No tests, no docs, code is not finished! Not everything is working yet. Code is partly crap. diff --git a/example/Makefile b/example/Makefile new file mode 100644 index 0000000..c7709fe --- /dev/null +++ b/example/Makefile @@ -0,0 +1,7 @@ +default: + +ipc: + @kitcom -src golang -dest ts/src/remote.ts + @kitcom -src ts/src -dest golang/remote.go -pkg main + +.PHONY: ipc diff --git a/example/golang/go.mod b/example/golang/go.mod new file mode 100644 index 0000000..a74d83b --- /dev/null +++ b/example/golang/go.mod @@ -0,0 +1,3 @@ +module efprojects.com/kitten-ipc/example/simple + +go 1.25.1 diff --git a/example/golang/main.go b/example/golang/main.go new file mode 100644 index 0000000..5ef83b8 --- /dev/null +++ b/example/golang/main.go @@ -0,0 +1,54 @@ +package main + +import ( + "fmt" + "log" + "os" + "os/exec" + "path" + + kittenipc "efprojects.com/kitten-ipc" +) + +// kittenipc:api +type GoIpcApi struct { +} + +func (api GoIpcApi) Div(a int, b int) (int, error) { + if b == 0 { + return 0, fmt.Errorf("zero division") + } + return a / b, nil +} + +func main() { + cwd, err := os.Getwd() + if err != nil { + log.Panic(err) + } + + localApi := GoIpcApi{} + + cmdStr := fmt.Sprintf("node %s", path.Join(cwd, "..", "ts/index.js")) + cmd := exec.Command(cmdStr) + + ipc, err := kittenipc.NewParent(cmd, &localApi) + if err != nil { + log.Panic(err) + } + + if err := ipc.Start(); err != nil { + log.Panic(err) + } + + remoteApi := TsIpcApi{Ipc: ipc} + res, err := remoteApi.Div(10, 2) + if err != nil { + log.Panic(err) + } + log.Printf("remote call result = %v", res) + + if err := ipc.Wait(); err != nil { + log.Panic(err) + } +} diff --git a/example/golang/remote.go b/example/golang/remote.go new file mode 100644 index 0000000..2599c79 --- /dev/null +++ b/example/golang/remote.go @@ -0,0 +1,25 @@ +// Code generated by kitcom. DO NOT EDIT. + +package main + +import ( + kittenipc "efprojects.com/kitten-ipc" + "fmt" +) + +type TsIpcApi struct { + Ipc kittenipc.Callable +} + +func (t *TsIpcApi) Div( + a int, b int, +) ( + int, error, +) { + results, err := t.Ipc.Call("TsIpcApi.Div", a, b) + if err != nil { + return 0, fmt.Errorf("call to TsIpcApi.Div failed: %w", err) + } + _ = results + return results[0].(int), nil +} diff --git a/example/ts/dist/goapi.gen.d.ts b/example/ts/dist/goapi.gen.d.ts new file mode 100644 index 0000000..ce4b95f --- /dev/null +++ b/example/ts/dist/goapi.gen.d.ts @@ -0,0 +1,7 @@ +import { ParentIPC, ChildIPC } from "../../lib/ts/lib"; +export default class IpcApi { + private ipc; + constructor(ipc: ParentIPC | ChildIPC); + Div(a: number, b: number): Promise; +} +//# sourceMappingURL=goapi.gen.d.ts.map \ No newline at end of file diff --git a/example/ts/dist/goapi.gen.d.ts.map b/example/ts/dist/goapi.gen.d.ts.map new file mode 100644 index 0000000..bfbe7a5 --- /dev/null +++ b/example/ts/dist/goapi.gen.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"goapi.gen.d.ts","sourceRoot":"","sources":["../src/goapi.gen.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,MAAM,CAAC,OAAO,OAAO,MAAM;IACzB,OAAO,CAAC,GAAG,CAAuB;gBAEtB,GAAG,EAAE,SAAS,GAAG,QAAQ;IAI/B,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAGjD"} \ No newline at end of file diff --git a/example/ts/dist/goapi.gen.js.map b/example/ts/dist/goapi.gen.js.map new file mode 100644 index 0000000..1173516 --- /dev/null +++ b/example/ts/dist/goapi.gen.js.map @@ -0,0 +1 @@ +{"version":3,"file":"goapi.gen.js","sourceRoot":"","sources":["../src/goapi.gen.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,MAAM,CAAC,OAAO,OAAO,MAAM;IACjB,GAAG,CAAuB;IAElC,YAAY,GAAyB;QACnC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,CAAS,EAAE,CAAS;QAC5B,OAAO,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1C,CAAC;CACF"} \ No newline at end of file diff --git a/example/ts/dist/index.d.ts b/example/ts/dist/index.d.ts new file mode 100644 index 0000000..e26a57a --- /dev/null +++ b/example/ts/dist/index.d.ts @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/example/ts/dist/index.d.ts.map b/example/ts/dist/index.d.ts.map new file mode 100644 index 0000000..535b86d --- /dev/null +++ b/example/ts/dist/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""} \ No newline at end of file diff --git a/example/ts/dist/index.js.map b/example/ts/dist/index.js.map new file mode 100644 index 0000000..a746c76 --- /dev/null +++ b/example/ts/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,YAAY,CAAC;AACpC,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAEtC;;GAEG;AACH,MAAM,QAAQ;IACV,GAAG,CAAC,CAAS,EAAE,CAAS;QACpB,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;QACxC,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,CAAC;IACjB,CAAC;CACJ;AAED,KAAK,UAAU,IAAI;IACf,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAC;IAChC,MAAM,GAAG,GAAG,IAAI,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC;IAEhC,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC;IAElB,OAAO,CAAC,GAAG,CAAC,QAAQ,MAAM,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IAE9C,IAAI,CAAC;QACD,MAAM,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAC3B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACT,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACrB,CAAC;IAED,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;AACrB,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;IACb,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACrB,CAAC,CAAC,CAAC"} \ No newline at end of file diff --git a/example/ts/package-lock.json b/example/ts/package-lock.json new file mode 100644 index 0000000..23dee11 --- /dev/null +++ b/example/ts/package-lock.json @@ -0,0 +1,50 @@ +{ + "name": "kitten-ipc-example", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "kitten-ipc-example", + "version": "1.0.0", + "license": "Apache 2.0" + }, + "../../../../../../opt/homebrew/lib/node_modules/list": { + "version": "2.0.19", + "extraneous": true, + "license": "MIT", + "devDependencies": { + "@types/chai": "^4.2.3", + "@types/mocha": "^5.2.7", + "@types/ramda": "^0.26.28", + "babel-cli": "^6.26.0", + "babel-core": "^6.26.3", + "babel-plugin-annotate-pure-calls": "^0.4.0", + "chai": "4.2.0", + "cherry-pick": "^0.5.0", + "codecov": "^3.6.1", + "fast-check": "^1.17.0", + "mocha": "^6.2.1", + "np": "^5.1.0", + "nyc": "^14.1.1", + "prettier": "1.18.2", + "proptest": "0.0.4", + "ramda": "0.26.1", + "source-map-support": "^0.5.13", + "ts-node": "^8.4.1", + "tslint": "^5.20.0", + "typescript": "^3.6.3" + } + }, + "../../lib/ts": { + "name": "kitten-ipc", + "version": "1.0.0", + "extraneous": true, + "license": "Apache 2.0", + "dependencies": { + "@types/node": "^22.10.5", + "ts-events": "^3.4.1" + } + } + } +} diff --git a/example/ts/package.json b/example/ts/package.json new file mode 100644 index 0000000..b3347fd --- /dev/null +++ b/example/ts/package.json @@ -0,0 +1,12 @@ +{ + "name": "kitten-ipc-example", + "version": "1.0.0", + "author": "Egor3f ", + "license": "Apache 2.0", + "description": "", + "main": "index.js", + "type": "module", + "scripts": { + "build": "tsc" + } +} diff --git a/example/ts/src/index.ts b/example/ts/src/index.ts new file mode 100644 index 0000000..6852d53 --- /dev/null +++ b/example/ts/src/index.ts @@ -0,0 +1,30 @@ +import {ChildIPC} from 'kitten-ipc'; +import GoIpcApi from './remote.js'; + +/** + * @kittenipc api + */ +class TsIpcApi { + Div(a: number, b: number): number { + if (b === 0) { + throw new Error('zero division'); + } + return a / b; + } +} + +async function main() { + const localApi = new TsIpcApi(); + const ipc = new ChildIPC(localApi); + const remoteApi = new GoIpcApi(ipc); + + await ipc.start(); + + console.log(`remote call result = ${await remoteApi.Div(10, 2)}`); + + await ipc.wait(); +} + +main().catch(e => { + console.trace(e); +}); diff --git a/example/ts/src/remote.ts b/example/ts/src/remote.ts new file mode 100644 index 0000000..9886d71 --- /dev/null +++ b/example/ts/src/remote.ts @@ -0,0 +1,15 @@ +// Code generated by kitcom. DO NOT EDIT. + +import { ParentIPC, ChildIPC } from "kitten-ipc"; +export default class GoIpcApi { + protected ipc: ParentIPC | ChildIPC; + + constructor(ipc: ParentIPC | ChildIPC) { + this.ipc = ipc; + } + + async Div(a: number, b: number): Promise { + const results = await this.ipc.call("GoIpcApi.Div", a, b); + return results[0] as number; + } +} diff --git a/example/ts/tsconfig.json b/example/ts/tsconfig.json new file mode 100644 index 0000000..4ec4fae --- /dev/null +++ b/example/ts/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "rootDir": "./src", + "outDir": "./dist", + + "module": "nodenext", + "target": "esnext", + + "sourceMap": true, + "declaration": true, + "declarationMap": true, + + "noUncheckedIndexedAccess": true, + "exactOptionalPropertyTypes": true, + + "strict": true, + "noImplicitReturns": true, + "noImplicitOverride": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noPropertyAccessFromIndexSignature": true, + "noUncheckedSideEffectImports": true, + + "moduleDetection": "force", + "verbatimModuleSyntax": true, + } +} diff --git a/kitcom/Makefile b/kitcom/Makefile new file mode 100644 index 0000000..189569d --- /dev/null +++ b/kitcom/Makefile @@ -0,0 +1,56 @@ + +SHELL := /bin/bash +tsgo_dir = ./internal/tsgo +my_package = efprojects.com/kitten-ipc/kitcom/internal/tsgo + + +default: + @echo "Please read Makefile for available targets" + + +vendor_tsgo: + @mkdir -p $(tsgo_dir) + @git clone --depth 1 https://github.com/microsoft/typescript-go + @find ./typescript-go/internal -type file -name "*.go" -exec sed -i -e 's!"github.com/microsoft/typescript-go/internal!"$(my_package)!g' {} \; + @cp -r ./typescript-go/internal/* $(tsgo_dir) + @rm -rf @rm -rf typescript-go + + +remove_tsgo_tests: + @find $(tsgo_dir) -name "*_test.go" -exec rm {} \; + + +# tree shaking. written in make just for "fun" +# caution: may cause eye hazard +remove_tsgo_unused: + @set -e ; \ + dirs=`find $(tsgo_dir) -type d -mindepth 1 -maxdepth 1` ; \ + nessesary_old="parser " ; \ + nessesary="$$nessesary_old" ; \ + while true; do \ + for d in $$dirs; do \ + pkg=`basename "$$d"` ; \ + for usedIn in $$nessesary; do \ + if grep -q -R "$(my_package)/$$pkg" "$(tsgo_dir)/$$usedIn" > /dev/null; then \ + if [[ "$$nessesary" != *"$$pkg "* ]]; then \ + nessesary="$$nessesary $$pkg " ; \ + fi ; \ + break ; \ + fi ; \ + done ; \ + done ; \ + if [[ "$$nessesary" == "$$nessesary_old" ]]; then \ + break ; \ + fi ; \ + nessesary_old="$$nessesary" ; \ + done ; \ + for d in $$dirs; do \ + pkg=`basename $$d` ; \ + if [[ "$$nessesary" != *"$$pkg "* ]]; then \ + echo "removing $$pkg" ; \ + rm -rf $(tsgo_dir)/$$pkg ; \ + fi ; \ + done + + +.PHONY: vendor_tsgo remove_tsgo_tests remove_tsgo_unused diff --git a/kitcom/api/api.go b/kitcom/api/api.go new file mode 100644 index 0000000..8d27360 --- /dev/null +++ b/kitcom/api/api.go @@ -0,0 +1,35 @@ +package api + +// todo check TInt size < 64 +// todo check not float + +type ValType int + +const ( + TInt ValType = 1 + TString ValType = 2 + TBool ValType = 3 + TBlob ValType = 4 + TArray ValType = 5 +) + +type Val struct { + Name string + Type ValType + Children []Val +} + +type Method struct { + Name string + Params []Val + Ret []Val +} + +type Endpoint struct { + Name string + Methods []Method +} + +type Api struct { + Endpoints []Endpoint +} diff --git a/kitcom/go.mod b/kitcom/go.mod new file mode 100644 index 0000000..276376d --- /dev/null +++ b/kitcom/go.mod @@ -0,0 +1,9 @@ +module efprojects.com/kitten-ipc/kitcom + +go 1.25.1 + +require ( + github.com/go-json-experiment/json v0.0.0-20250910080747-cc2cfa0554c3 + golang.org/x/sync v0.17.0 + golang.org/x/text v0.29.0 +) diff --git a/kitcom/go.sum b/kitcom/go.sum new file mode 100644 index 0000000..8162e8d --- /dev/null +++ b/kitcom/go.sum @@ -0,0 +1,6 @@ +github.com/go-json-experiment/json v0.0.0-20250910080747-cc2cfa0554c3 h1:02WINGfSX5w0Mn+F28UyRoSt9uvMhKguwWMlOAh6U/0= +github.com/go-json-experiment/json v0.0.0-20250910080747-cc2cfa0554c3/go.mod h1:uNVvRXArCGbZ508SxYYTC5v1JWoz2voff5pm25jU1Ok= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= diff --git a/kitcom/golang/go_gen.tmpl b/kitcom/golang/go_gen.tmpl new file mode 100644 index 0000000..b83ba5e --- /dev/null +++ b/kitcom/golang/go_gen.tmpl @@ -0,0 +1,34 @@ + +{{- /*gotype: efprojects.com/kitten-ipc/kitcom.goGenData*/ -}} + +// Code generated by kitcom. DO NOT EDIT. + +package {{.PkgName}} + +import ( + "fmt" + kittenipc "efprojects.com/kitten-ipc" +) + +{{range $e := .Api.Endpoints}} + +type {{.Name}} struct { + Ipc kittenipc.Callable +} + +{{range $mtd := $e.Methods}} +func ({{$e.Name | receiver}} *{{$e.Name}}) {{$mtd.Name}}( +{{range $mtd.Params}}{{.Name}} {{.Type | typedef}}, {{end}} +) ( +{{range $mtd.Ret}}{{.Type | typedef}}, {{end}}error, +) { + results, err := {{$e.Name | receiver}}.Ipc.Call("{{$e.Name}}.{{$mtd.Name}}"{{range $mtd.Params}}, {{.Name}}{{end}}) + if err != nil { + return {{range $mtd.Ret}}{{.Type | zerovalue}}, {{end}} fmt.Errorf("call to {{$e.Name}}.{{$mtd.Name}} failed: %w", err) + } + _ = results + return {{range $idx, $ret := $mtd.Ret}}results[{{$idx}}].({{$ret.Type | typedef}}), {{end}}nil +} +{{end}} + +{{end}} diff --git a/kitcom/golang/gogen.go b/kitcom/golang/gogen.go new file mode 100644 index 0000000..89c9181 --- /dev/null +++ b/kitcom/golang/gogen.go @@ -0,0 +1,92 @@ +package golang + +import ( + "bytes" + "fmt" + "go/format" + "os" + "strings" + "text/template" + + "efprojects.com/kitten-ipc/kitcom/api" + _ "embed" +) + +//go:embed go_gen.tmpl +var templateString string + +type goGenData struct { + PkgName string + Api *api.Api +} + +type GoApiGenerator struct { + PkgName string +} + +func (g *GoApiGenerator) Generate(apis *api.Api, destFile string) error { + tplCtx := goGenData{ + PkgName: g.PkgName, + Api: apis, + } + + tpl := template.New("gogen") + tpl = tpl.Funcs(map[string]any{ + "receiver": func(name string) string { + return strings.ToLower(name)[0:1] + }, + "typedef": func(t api.ValType) (string, error) { + td, ok := map[api.ValType]string{ + api.TInt: "int", + api.TString: "string", + api.TBool: "bool", + }[t] + if !ok { + return "", fmt.Errorf("cannot generate type %v", t) + } + return td, nil + }, + "zerovalue": func(t api.ValType) (string, error) { + v, ok := map[api.ValType]string{ + api.TInt: "0", + api.TString: `""`, + api.TBool: "false", + }[t] + if !ok { + return "", fmt.Errorf("cannot generate zero value for type %v", t) + } + return v, nil + }, + }) + tpl = template.Must(tpl.Parse(templateString)) + + var buf bytes.Buffer + + if err := tpl.ExecuteTemplate(&buf, "gogen", tplCtx); err != nil { + return fmt.Errorf("execute template: %w", err) + } + + if err := g.writeDest(destFile, buf.Bytes()); err != nil { + return fmt.Errorf("write file: %w", err) + } + + return nil +} + +func (g *GoApiGenerator) writeDest(destFile string, bytes []byte) error { + f, err := os.OpenFile(destFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) + if err != nil { + return fmt.Errorf("open destination file: %w", err) + } + defer f.Close() + + formatted, err := format.Source(bytes) + if err != nil { + return fmt.Errorf("format source: %w", err) + } + + if _, err := f.Write(formatted); err != nil { + return fmt.Errorf("write formatted source: %w", err) + } + return nil +} diff --git a/kitcom/golang/goparser.go b/kitcom/golang/goparser.go new file mode 100644 index 0000000..4b8c73d --- /dev/null +++ b/kitcom/golang/goparser.go @@ -0,0 +1,163 @@ +package golang + +import ( + "fmt" + "go/ast" + "go/parser" + "go/token" + "regexp" + + "efprojects.com/kitten-ipc/kitcom/api" +) + +var decorComment = regexp.MustCompile(`^//\s?kittenipc:api$`) + +type GoApiParser struct { + files []string +} + +func (g *GoApiParser) AddFile(path string) { + g.files = append(g.files, path) +} + +func (g *GoApiParser) Parse() (*api.Api, error) { + + var apis api.Api + + for _, f := range g.files { + endpoints, err := g.parseFile(f) + if err != nil { + return nil, fmt.Errorf("parse file: %w", err) + } + apis.Endpoints = append(apis.Endpoints, endpoints...) + } + + if len(apis.Endpoints) == 0 { + return nil, fmt.Errorf("no endpoints found") + } + + return &apis, nil +} + +func (g *GoApiParser) parseFile(sourceFile string) ([]api.Endpoint, error) { + var endpoints []api.Endpoint + + fileSet := token.NewFileSet() + astFile, err := parser.ParseFile(fileSet, sourceFile, nil, parser.ParseComments|parser.SkipObjectResolution) + if err != nil { + return nil, fmt.Errorf("parse file: %w", err) + } + + for _, decl := range astFile.Decls { + genDecl, ok := decl.(*ast.GenDecl) + if !ok { + continue + } + + if genDecl.Doc == nil { + continue + } + + // use only last comment. https://tip.golang.org/doc/comment#syntax + lastComment := genDecl.Doc.List[len(genDecl.Doc.List)-1] + if !decorComment.MatchString(lastComment.Text) { + continue + } + + typeSpec, ok := genDecl.Specs[0].(*ast.TypeSpec) + if !ok { + continue + } + + _, isStruct := typeSpec.Type.(*ast.StructType) + _, isIface := typeSpec.Type.(*ast.InterfaceType) + if !isStruct && !isIface { + continue + } + + endpoints = append(endpoints, api.Endpoint{ + Name: typeSpec.Name.Name, + }) + } + + if len(endpoints) == 0 { + return nil, nil + } + + for _, decl := range astFile.Decls { + funcDecl, ok := decl.(*ast.FuncDecl) + if !ok { + continue + } + + if !funcDecl.Name.IsExported() { + continue + } + + if funcDecl.Recv == nil { + continue + } + + reciever := funcDecl.Recv.List[0] + recvType := reciever.Type + + star, isPointer := recvType.(*ast.StarExpr) + if isPointer { + recvType = star.X + } + + recvIdent, ok := recvType.(*ast.Ident) + if !ok { + continue + } + + for i, endpoint := range endpoints { + if recvIdent.Name == endpoint.Name { + var apiMethod api.Method + apiMethod.Name = funcDecl.Name.Name + for _, param := range funcDecl.Type.Params.List { + var apiPar api.Val + ident := param.Type.(*ast.Ident) + switch ident.Name { + case "int": + apiPar.Type = api.TInt + case "string": + apiPar.Type = api.TString + case "bool": + apiPar.Type = api.TBool + default: + return nil, fmt.Errorf("parameter type %s is not supported yet", ident.Name) + } + if len(param.Names) != 1 { + return nil, fmt.Errorf("all parameters in method %s should be named", apiMethod.Name) + } + apiPar.Name = param.Names[0].Name + apiMethod.Params = append(apiMethod.Params, apiPar) + } + for _, ret := range funcDecl.Type.Results.List { + var apiRet api.Val + ident := ret.Type.(*ast.Ident) + switch ident.Name { + case "int": + apiRet.Type = api.TInt + case "string": + apiRet.Type = api.TString + case "bool": + apiRet.Type = api.TBool + case "error": + // errors are processed other way + continue + default: + return nil, fmt.Errorf("return type %s is not supported yet", ident.Name) + } + if len(ret.Names) > 0 { + apiRet.Name = ret.Names[0].Name + } + apiMethod.Ret = append(apiMethod.Ret, apiRet) + } + endpoints[i].Methods = append(endpoints[i].Methods, apiMethod) + } + } + } + return endpoints, nil +} diff --git a/kitcom/internal/tsgo/ast/ast.go b/kitcom/internal/tsgo/ast/ast.go new file mode 100644 index 0000000..853d6d1 --- /dev/null +++ b/kitcom/internal/tsgo/ast/ast.go @@ -0,0 +1,11138 @@ +package ast + +import ( + "fmt" + "iter" + "strings" + "sync" + "sync/atomic" + + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/collections" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/core" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/tspath" +) + +// Visitor + +type Visitor func(*Node) bool + +func visit(v Visitor, node *Node) bool { + if node != nil { + return v(node) + } + return false +} + +func visitNodes(v Visitor, nodes []*Node) bool { + for _, node := range nodes { + if v(node) { + return true + } + } + return false +} + +func visitNodeList(v Visitor, nodeList *NodeList) bool { + if nodeList != nil { + return visitNodes(v, nodeList.Nodes) + } + return false +} + +func visitModifiers(v Visitor, modifiers *ModifierList) bool { + if modifiers != nil { + return visitNodes(v, modifiers.Nodes) + } + return false +} + +// NodeFactory + +type NodeFactory struct { + hooks NodeFactoryHooks + arrayTypeNodePool core.Pool[ArrayTypeNode] + binaryExpressionPool core.Pool[BinaryExpression] + blockPool core.Pool[Block] + callExpressionPool core.Pool[CallExpression] + conditionalExpressionPool core.Pool[ConditionalExpression] + constructSignatureDeclarationPool core.Pool[ConstructSignatureDeclaration] + elementAccessExpressionPool core.Pool[ElementAccessExpression] + expressionStatementPool core.Pool[ExpressionStatement] + expressionWithTypeArgumentsPool core.Pool[ExpressionWithTypeArguments] + functionDeclarationPool core.Pool[FunctionDeclaration] + functionTypeNodePool core.Pool[FunctionTypeNode] + heritageClausePool core.Pool[HeritageClause] + identifierPool core.Pool[Identifier] + ifStatementPool core.Pool[IfStatement] + importSpecifierPool core.Pool[ImportSpecifier] + indexedAccessTypeNodePool core.Pool[IndexedAccessTypeNode] + interfaceDeclarationPool core.Pool[InterfaceDeclaration] + intersectionTypeNodePool core.Pool[IntersectionTypeNode] + jsdocDeprecatedTagPool core.Pool[JSDocDeprecatedTag] + jsdocParameterOrPropertyTagPool core.Pool[JSDocParameterOrPropertyTag] + jsdocPool core.Pool[JSDoc] + jsdocTextPool core.Pool[JSDocText] + jsdocUnknownTagPool core.Pool[JSDocUnknownTag] + keywordExpressionPool core.Pool[KeywordExpression] + keywordTypeNodePool core.Pool[KeywordTypeNode] + literalTypeNodePool core.Pool[LiteralTypeNode] + methodSignatureDeclarationPool core.Pool[MethodSignatureDeclaration] + modifierListPool core.Pool[ModifierList] + nodeListPool core.Pool[NodeList] + numericLiteralPool core.Pool[NumericLiteral] + parameterDeclarationPool core.Pool[ParameterDeclaration] + parenthesizedExpressionPool core.Pool[ParenthesizedExpression] + parenthesizedTypeNodePool core.Pool[ParenthesizedTypeNode] + prefixUnaryExpressionPool core.Pool[PrefixUnaryExpression] + propertyAccessExpressionPool core.Pool[PropertyAccessExpression] + propertyAssignmentPool core.Pool[PropertyAssignment] + propertySignatureDeclarationPool core.Pool[PropertySignatureDeclaration] + returnStatementPool core.Pool[ReturnStatement] + stringLiteralPool core.Pool[StringLiteral] + tokenPool core.Pool[Token] + typeAliasDeclarationPool core.Pool[TypeAliasDeclaration] + typeLiteralNodePool core.Pool[TypeLiteralNode] + typeOperatorNodePool core.Pool[TypeOperatorNode] + typeParameterDeclarationPool core.Pool[TypeParameterDeclaration] + typeReferenceNodePool core.Pool[TypeReferenceNode] + unionTypeNodePool core.Pool[UnionTypeNode] + variableDeclarationListPool core.Pool[VariableDeclarationList] + variableDeclarationPool core.Pool[VariableDeclaration] + variableStatementPool core.Pool[VariableStatement] + + nodeCount int + textCount int +} + +type NodeFactoryHooks struct { + OnCreate func(node *Node) // Hooks the creation of a node. + OnUpdate func(node *Node, original *Node) // Hooks the updating of a node. + OnClone func(node *Node, original *Node) // Hooks the cloning of a node. +} + +type NodeFactoryCoercible interface { + AsNodeFactory() *NodeFactory +} + +func NewNodeFactory(hooks NodeFactoryHooks) *NodeFactory { + return &NodeFactory{hooks: hooks} +} + +func newNode(kind Kind, data nodeData, hooks NodeFactoryHooks) *Node { + n := data.AsNode() + n.Loc = core.UndefinedTextRange() + n.Kind = kind + n.data = data + if hooks.OnCreate != nil { + hooks.OnCreate(n) + } + return n +} + +func (f *NodeFactory) newNode(kind Kind, data nodeData) *Node { + f.nodeCount++ + return newNode(kind, data, f.hooks) +} + +func (f *NodeFactory) NodeCount() int { + return f.nodeCount +} + +func (f *NodeFactory) TextCount() int { + return f.textCount +} + +func (f *NodeFactory) AsNodeFactory() *NodeFactory { + return f +} + +func updateNode(updated *Node, original *Node, hooks NodeFactoryHooks) *Node { + if updated != original { + updated.Flags = original.Flags + updated.Loc = original.Loc + if hooks.OnUpdate != nil { + hooks.OnUpdate(updated, original) + } + } + return updated +} + +func cloneNode(updated *Node, original *Node, hooks NodeFactoryHooks) *Node { + updateNode(updated, original, hooks) + if updated != original && hooks.OnClone != nil { + hooks.OnClone(updated, original) + } + return updated +} + +// NodeList + +type NodeList struct { + Loc core.TextRange + Nodes []*Node +} + +func (f *NodeFactory) NewNodeList(nodes []*Node) *NodeList { + list := f.nodeListPool.New() + list.Loc = core.UndefinedTextRange() + list.Nodes = nodes + return list +} + +func (list *NodeList) Pos() int { return list.Loc.Pos() } +func (list *NodeList) End() int { return list.Loc.End() } + +func (list *NodeList) HasTrailingComma() bool { + if len(list.Nodes) == 0 { + return false + } + last := list.Nodes[len(list.Nodes)-1] + return last.End() < list.End() +} + +func (list *NodeList) Clone(f NodeFactoryCoercible) *NodeList { + result := f.AsNodeFactory().NewNodeList(list.Nodes) + result.Loc = list.Loc + return result +} + +// ModifierList + +type ModifierList struct { + NodeList + ModifierFlags ModifierFlags +} + +func (f *NodeFactory) NewModifierList(nodes []*Node) *ModifierList { + list := f.modifierListPool.New() + list.Loc = core.UndefinedTextRange() + list.Nodes = nodes + list.ModifierFlags = ModifiersToFlags(nodes) + return list +} + +func (list *ModifierList) Clone(f *NodeFactory) *ModifierList { + res := f.modifierListPool.New() + res.Loc = list.Loc + res.Nodes = list.Nodes + res.ModifierFlags = list.ModifierFlags + return res +} + +// AST Node +// Interface values stored in AST nodes are never typed nil values. Construction code must ensure that +// interface valued properties either store a true nil or a reference to a non-nil struct. + +type Node struct { + Kind Kind + Flags NodeFlags + Loc core.TextRange + id atomic.Uint64 + Parent *Node + data nodeData +} + +// Node accessors. Some accessors are implemented as methods on NodeData, others are implemented though +// type switches. Either approach is fine. Interface methods are likely more performant, but have higher +// code size costs because we have hundreds of implementations of the NodeData interface. + +func (n *Node) AsNode() *Node { return n } +func (n *Node) Pos() int { return n.Loc.Pos() } +func (n *Node) End() int { return n.Loc.End() } +func (n *Node) ForEachChild(v Visitor) bool { return n.data.ForEachChild(v) } +func (n *Node) IterChildren() iter.Seq[*Node] { return n.data.IterChildren() } +func (n *Node) Clone(f NodeFactoryCoercible) *Node { return n.data.Clone(f) } +func (n *Node) VisitEachChild(v *NodeVisitor) *Node { return n.data.VisitEachChild(v) } +func (n *Node) Name() *DeclarationName { return n.data.Name() } +func (n *Node) Modifiers() *ModifierList { return n.data.Modifiers() } +func (n *Node) FlowNodeData() *FlowNodeBase { return n.data.FlowNodeData() } +func (n *Node) DeclarationData() *DeclarationBase { return n.data.DeclarationData() } +func (n *Node) ExportableData() *ExportableBase { return n.data.ExportableData() } +func (n *Node) LocalsContainerData() *LocalsContainerBase { return n.data.LocalsContainerData() } +func (n *Node) FunctionLikeData() *FunctionLikeBase { return n.data.FunctionLikeData() } +func (n *Node) ParameterList() *ParameterList { return n.data.FunctionLikeData().Parameters } +func (n *Node) Parameters() []*ParameterDeclarationNode { return n.ParameterList().Nodes } +func (n *Node) ClassLikeData() *ClassLikeBase { return n.data.ClassLikeData() } +func (n *Node) BodyData() *BodyBase { return n.data.BodyData() } +func (n *Node) SubtreeFacts() SubtreeFacts { return n.data.SubtreeFacts() } +func (n *Node) propagateSubtreeFacts() SubtreeFacts { return n.data.propagateSubtreeFacts() } +func (n *Node) LiteralLikeData() *LiteralLikeBase { return n.data.LiteralLikeData() } +func (n *Node) TemplateLiteralLikeData() *TemplateLiteralLikeBase { + return n.data.TemplateLiteralLikeData() +} +func (n *Node) KindString() string { return n.Kind.String() } +func (n *Node) KindValue() int16 { return int16(n.Kind) } + +type mutableNode Node + +func (n *Node) AsMutable() *mutableNode { return (*mutableNode)(n) } +func (n *mutableNode) SetModifiers(modifiers *ModifierList) { n.data.setModifiers(modifiers) } + +func (n *Node) Symbol() *Symbol { + data := n.DeclarationData() + if data != nil { + return data.Symbol + } + return nil +} + +func (n *Node) LocalSymbol() *Symbol { + data := n.ExportableData() + if data != nil { + return data.LocalSymbol + } + return nil +} + +func (n *Node) Locals() SymbolTable { + data := n.LocalsContainerData() + if data != nil { + return data.Locals + } + return nil +} + +func (n *Node) Body() *Node { + data := n.BodyData() + if data != nil { + return data.Body + } + return nil +} + +func (n *Node) Text() string { + switch n.Kind { + case KindIdentifier: + return n.AsIdentifier().Text + case KindPrivateIdentifier: + return n.AsPrivateIdentifier().Text + case KindStringLiteral: + return n.AsStringLiteral().Text + case KindNumericLiteral: + return n.AsNumericLiteral().Text + case KindBigIntLiteral: + return n.AsBigIntLiteral().Text + case KindMetaProperty: + return n.AsMetaProperty().Name().Text() + case KindNoSubstitutionTemplateLiteral: + return n.AsNoSubstitutionTemplateLiteral().Text + case KindTemplateHead: + return n.AsTemplateHead().Text + case KindTemplateMiddle: + return n.AsTemplateMiddle().Text + case KindTemplateTail: + return n.AsTemplateTail().Text + case KindJsxNamespacedName: + return n.AsJsxNamespacedName().Namespace.Text() + ":" + n.AsJsxNamespacedName().name.Text() + case KindRegularExpressionLiteral: + return n.AsRegularExpressionLiteral().Text + case KindJSDocText: + return strings.Join(n.AsJSDocText().text, "") + case KindJSDocLink: + return strings.Join(n.AsJSDocLink().text, "") + case KindJSDocLinkCode: + return strings.Join(n.AsJSDocLinkCode().text, "") + case KindJSDocLinkPlain: + return strings.Join(n.AsJSDocLinkPlain().text, "") + } + panic(fmt.Sprintf("Unhandled case in Node.Text: %T", n.data)) +} + +func (n *Node) Expression() *Node { + switch n.Kind { + case KindPropertyAccessExpression: + return n.AsPropertyAccessExpression().Expression + case KindElementAccessExpression: + return n.AsElementAccessExpression().Expression + case KindParenthesizedExpression: + return n.AsParenthesizedExpression().Expression + case KindCallExpression: + return n.AsCallExpression().Expression + case KindNewExpression: + return n.AsNewExpression().Expression + case KindExpressionWithTypeArguments: + return n.AsExpressionWithTypeArguments().Expression + case KindComputedPropertyName: + return n.AsComputedPropertyName().Expression + case KindNonNullExpression: + return n.AsNonNullExpression().Expression + case KindTypeAssertionExpression: + return n.AsTypeAssertion().Expression + case KindAsExpression: + return n.AsAsExpression().Expression + case KindSatisfiesExpression: + return n.AsSatisfiesExpression().Expression + case KindTypeOfExpression: + return n.AsTypeOfExpression().Expression + case KindSpreadAssignment: + return n.AsSpreadAssignment().Expression + case KindSpreadElement: + return n.AsSpreadElement().Expression + case KindTemplateSpan: + return n.AsTemplateSpan().Expression + case KindDeleteExpression: + return n.AsDeleteExpression().Expression + case KindVoidExpression: + return n.AsVoidExpression().Expression + case KindAwaitExpression: + return n.AsAwaitExpression().Expression + case KindYieldExpression: + return n.AsYieldExpression().Expression + case KindPartiallyEmittedExpression: + return n.AsPartiallyEmittedExpression().Expression + case KindIfStatement: + return n.AsIfStatement().Expression + case KindDoStatement: + return n.AsDoStatement().Expression + case KindWhileStatement: + return n.AsWhileStatement().Expression + case KindWithStatement: + return n.AsWithStatement().Expression + case KindForInStatement, KindForOfStatement: + return n.AsForInOrOfStatement().Expression + case KindSwitchStatement: + return n.AsSwitchStatement().Expression + case KindCaseClause: + return n.AsCaseOrDefaultClause().Expression + case KindExpressionStatement: + return n.AsExpressionStatement().Expression + case KindReturnStatement: + return n.AsReturnStatement().Expression + case KindThrowStatement: + return n.AsThrowStatement().Expression + case KindExternalModuleReference: + return n.AsExternalModuleReference().Expression + case KindExportAssignment, KindJSExportAssignment: + return n.AsExportAssignment().Expression + case KindDecorator: + return n.AsDecorator().Expression + case KindJsxExpression: + return n.AsJsxExpression().Expression + case KindJsxSpreadAttribute: + return n.AsJsxSpreadAttribute().Expression + } + panic("Unhandled case in Node.Expression: " + n.Kind.String()) +} + +func (m *mutableNode) SetExpression(expr *Node) { + n := (*Node)(m) + switch n.Kind { + case KindPropertyAccessExpression: + n.AsPropertyAccessExpression().Expression = expr + case KindElementAccessExpression: + n.AsElementAccessExpression().Expression = expr + case KindParenthesizedExpression: + n.AsParenthesizedExpression().Expression = expr + case KindCallExpression: + n.AsCallExpression().Expression = expr + case KindNewExpression: + n.AsNewExpression().Expression = expr + case KindExpressionWithTypeArguments: + n.AsExpressionWithTypeArguments().Expression = expr + case KindComputedPropertyName: + n.AsComputedPropertyName().Expression = expr + case KindNonNullExpression: + n.AsNonNullExpression().Expression = expr + case KindTypeAssertionExpression: + n.AsTypeAssertion().Expression = expr + case KindAsExpression: + n.AsAsExpression().Expression = expr + case KindSatisfiesExpression: + n.AsSatisfiesExpression().Expression = expr + case KindTypeOfExpression: + n.AsTypeOfExpression().Expression = expr + case KindSpreadAssignment: + n.AsSpreadAssignment().Expression = expr + case KindSpreadElement: + n.AsSpreadElement().Expression = expr + case KindTemplateSpan: + n.AsTemplateSpan().Expression = expr + case KindDeleteExpression: + n.AsDeleteExpression().Expression = expr + case KindVoidExpression: + n.AsVoidExpression().Expression = expr + case KindAwaitExpression: + n.AsAwaitExpression().Expression = expr + case KindYieldExpression: + n.AsYieldExpression().Expression = expr + case KindPartiallyEmittedExpression: + n.AsPartiallyEmittedExpression().Expression = expr + case KindIfStatement: + n.AsIfStatement().Expression = expr + case KindDoStatement: + n.AsDoStatement().Expression = expr + case KindWhileStatement: + n.AsWhileStatement().Expression = expr + case KindWithStatement: + n.AsWithStatement().Expression = expr + case KindForInStatement, KindForOfStatement: + n.AsForInOrOfStatement().Expression = expr + case KindSwitchStatement: + n.AsSwitchStatement().Expression = expr + case KindCaseClause: + n.AsCaseOrDefaultClause().Expression = expr + case KindExpressionStatement: + n.AsExpressionStatement().Expression = expr + case KindReturnStatement: + n.AsReturnStatement().Expression = expr + case KindThrowStatement: + n.AsThrowStatement().Expression = expr + case KindExternalModuleReference: + n.AsExternalModuleReference().Expression = expr + case KindExportAssignment, KindJSExportAssignment: + n.AsExportAssignment().Expression = expr + case KindDecorator: + n.AsDecorator().Expression = expr + case KindJsxExpression: + n.AsJsxExpression().Expression = expr + case KindJsxSpreadAttribute: + n.AsJsxSpreadAttribute().Expression = expr + default: + panic("Unhandled case in mutableNode.SetExpression: " + n.Kind.String()) + } +} + +func (n *Node) ArgumentList() *NodeList { + switch n.Kind { + case KindCallExpression: + return n.AsCallExpression().Arguments + case KindNewExpression: + return n.AsNewExpression().Arguments + } + panic("Unhandled case in Node.Arguments: " + n.Kind.String()) +} + +func (n *Node) Arguments() []*Node { + list := n.ArgumentList() + if list != nil { + return list.Nodes + } + return nil +} + +func (n *Node) TypeArgumentList() *NodeList { + switch n.Kind { + case KindCallExpression: + return n.AsCallExpression().TypeArguments + case KindNewExpression: + return n.AsNewExpression().TypeArguments + case KindTaggedTemplateExpression: + return n.AsTaggedTemplateExpression().TypeArguments + case KindTypeReference: + return n.AsTypeReference().TypeArguments + case KindExpressionWithTypeArguments: + return n.AsExpressionWithTypeArguments().TypeArguments + case KindImportType: + return n.AsImportTypeNode().TypeArguments + case KindTypeQuery: + return n.AsTypeQueryNode().TypeArguments + case KindJsxOpeningElement: + return n.AsJsxOpeningElement().TypeArguments + case KindJsxSelfClosingElement: + return n.AsJsxSelfClosingElement().TypeArguments + } + panic("Unhandled case in Node.TypeArguments") +} + +func (n *Node) TypeArguments() []*Node { + list := n.TypeArgumentList() + if list != nil { + return list.Nodes + } + return nil +} + +func (n *Node) TypeParameterList() *NodeList { + switch n.Kind { + case KindClassDeclaration: + return n.AsClassDeclaration().TypeParameters + case KindClassExpression: + return n.AsClassExpression().TypeParameters + case KindInterfaceDeclaration: + return n.AsInterfaceDeclaration().TypeParameters + case KindTypeAliasDeclaration, KindJSTypeAliasDeclaration: + return n.AsTypeAliasDeclaration().TypeParameters + case KindJSDocTemplateTag: + return n.AsJSDocTemplateTag().TypeParameters + default: + funcLike := n.FunctionLikeData() + if funcLike != nil { + return funcLike.TypeParameters + } + } + panic("Unhandled case in Node.TypeParameterList") +} + +func (n *Node) TypeParameters() []*Node { + list := n.TypeParameterList() + if list != nil { + return list.Nodes + } + return nil +} + +func (n *Node) MemberList() *NodeList { + switch n.Kind { + case KindClassDeclaration: + return n.AsClassDeclaration().Members + case KindClassExpression: + return n.AsClassExpression().Members + case KindInterfaceDeclaration: + return n.AsInterfaceDeclaration().Members + case KindEnumDeclaration: + return n.AsEnumDeclaration().Members + case KindTypeLiteral: + return n.AsTypeLiteralNode().Members + case KindMappedType: + return n.AsMappedTypeNode().Members + } + panic("Unhandled case in Node.MemberList: " + n.Kind.String()) +} + +func (n *Node) Members() []*Node { + list := n.MemberList() + if list != nil { + return list.Nodes + } + return nil +} + +func (n *Node) StatementList() *NodeList { + switch n.Kind { + case KindSourceFile: + return n.AsSourceFile().Statements + case KindBlock: + return n.AsBlock().Statements + case KindModuleBlock: + return n.AsModuleBlock().Statements + } + panic("Unhandled case in Node.StatementList: " + n.Kind.String()) +} + +func (n *Node) Statements() []*Node { + list := n.StatementList() + if list != nil { + return list.Nodes + } + return nil +} + +func (n *Node) ModifierFlags() ModifierFlags { + modifiers := n.Modifiers() + if modifiers != nil { + return modifiers.ModifierFlags + } + return ModifierFlagsNone +} + +func (n *Node) ModifierNodes() []*Node { + modifiers := n.Modifiers() + if modifiers != nil { + return modifiers.Nodes + } + return nil +} + +func (n *Node) Type() *Node { + switch n.Kind { + case KindVariableDeclaration: + return n.AsVariableDeclaration().Type + case KindParameter: + return n.AsParameterDeclaration().Type + case KindPropertySignature: + return n.AsPropertySignatureDeclaration().Type + case KindPropertyDeclaration: + return n.AsPropertyDeclaration().Type + case KindPropertyAssignment: + return n.AsPropertyAssignment().Type + case KindShorthandPropertyAssignment: + return n.AsShorthandPropertyAssignment().Type + case KindTypePredicate: + return n.AsTypePredicateNode().Type + case KindParenthesizedType: + return n.AsParenthesizedTypeNode().Type + case KindTypeOperator: + return n.AsTypeOperatorNode().Type + case KindMappedType: + return n.AsMappedTypeNode().Type + case KindTypeAssertionExpression: + return n.AsTypeAssertion().Type + case KindAsExpression: + return n.AsAsExpression().Type + case KindSatisfiesExpression: + return n.AsSatisfiesExpression().Type + case KindTypeAliasDeclaration, KindJSTypeAliasDeclaration: + return n.AsTypeAliasDeclaration().Type + case KindNamedTupleMember: + return n.AsNamedTupleMember().Type + case KindOptionalType: + return n.AsOptionalTypeNode().Type + case KindRestType: + return n.AsRestTypeNode().Type + case KindTemplateLiteralTypeSpan: + return n.AsTemplateLiteralTypeSpan().Type + case KindJSDocTypeExpression: + return n.AsJSDocTypeExpression().Type + case KindJSDocParameterTag, KindJSDocPropertyTag: + return n.AsJSDocParameterOrPropertyTag().TypeExpression + case KindJSDocNullableType: + return n.AsJSDocNullableType().Type + case KindJSDocNonNullableType: + return n.AsJSDocNonNullableType().Type + case KindJSDocOptionalType: + return n.AsJSDocOptionalType().Type + case KindExportAssignment, KindJSExportAssignment: + return n.AsExportAssignment().Type + case KindCommonJSExport: + return n.AsCommonJSExport().Type + case KindBinaryExpression: + return n.AsBinaryExpression().Type + default: + if funcLike := n.FunctionLikeData(); funcLike != nil { + return funcLike.Type + } + } + return nil +} + +func (m *mutableNode) SetType(t *Node) { + n := (*Node)(m) + switch m.Kind { + case KindVariableDeclaration: + n.AsVariableDeclaration().Type = t + case KindParameter: + n.AsParameterDeclaration().Type = t + case KindPropertySignature: + n.AsPropertySignatureDeclaration().Type = t + case KindPropertyDeclaration: + n.AsPropertyDeclaration().Type = t + case KindPropertyAssignment: + n.AsPropertyAssignment().Type = t + case KindShorthandPropertyAssignment: + n.AsShorthandPropertyAssignment().Type = t + case KindTypePredicate: + n.AsTypePredicateNode().Type = t + case KindParenthesizedType: + n.AsParenthesizedTypeNode().Type = t + case KindTypeOperator: + n.AsTypeOperatorNode().Type = t + case KindMappedType: + n.AsMappedTypeNode().Type = t + case KindTypeAssertionExpression: + n.AsTypeAssertion().Type = t + case KindAsExpression: + n.AsAsExpression().Type = t + case KindSatisfiesExpression: + n.AsSatisfiesExpression().Type = t + case KindTypeAliasDeclaration, KindJSTypeAliasDeclaration: + n.AsTypeAliasDeclaration().Type = t + case KindNamedTupleMember: + n.AsNamedTupleMember().Type = t + case KindOptionalType: + n.AsOptionalTypeNode().Type = t + case KindRestType: + n.AsRestTypeNode().Type = t + case KindTemplateLiteralTypeSpan: + n.AsTemplateLiteralTypeSpan().Type = t + case KindJSDocTypeExpression: + n.AsJSDocTypeExpression().Type = t + case KindJSDocParameterTag, KindJSDocPropertyTag: + n.AsJSDocParameterOrPropertyTag().TypeExpression = t + case KindJSDocNullableType: + n.AsJSDocNullableType().Type = t + case KindJSDocNonNullableType: + n.AsJSDocNonNullableType().Type = t + case KindJSDocOptionalType: + n.AsJSDocOptionalType().Type = t + case KindExportAssignment, KindJSExportAssignment: + n.AsExportAssignment().Type = t + case KindCommonJSExport: + n.AsCommonJSExport().Type = t + case KindBinaryExpression: + n.AsBinaryExpression().Type = t + default: + if funcLike := n.FunctionLikeData(); funcLike != nil { + funcLike.Type = t + } else { + panic("Unhandled case in mutableNode.SetType: " + n.Kind.String()) + } + } +} + +func (n *Node) Initializer() *Node { + switch n.Kind { + case KindVariableDeclaration: + return n.AsVariableDeclaration().Initializer + case KindParameter: + return n.AsParameterDeclaration().Initializer + case KindBindingElement: + return n.AsBindingElement().Initializer + case KindPropertyDeclaration: + return n.AsPropertyDeclaration().Initializer + case KindPropertySignature: + return n.AsPropertySignatureDeclaration().Initializer + case KindPropertyAssignment: + return n.AsPropertyAssignment().Initializer + case KindEnumMember: + return n.AsEnumMember().Initializer + case KindForStatement: + return n.AsForStatement().Initializer + case KindForInStatement, KindForOfStatement: + return n.AsForInOrOfStatement().Initializer + case KindJsxAttribute: + return n.AsJsxAttribute().Initializer + case KindCommonJSExport: + return n.AsCommonJSExport().Initializer + } + panic("Unhandled case in Node.Initializer") +} + +func (m *mutableNode) SetInitializer(initializer *Node) { + n := (*Node)(m) + switch n.Kind { + case KindVariableDeclaration: + n.AsVariableDeclaration().Initializer = initializer + case KindParameter: + n.AsParameterDeclaration().Initializer = initializer + case KindBindingElement: + n.AsBindingElement().Initializer = initializer + case KindPropertyDeclaration: + n.AsPropertyDeclaration().Initializer = initializer + case KindPropertySignature: + n.AsPropertySignatureDeclaration().Initializer = initializer + case KindPropertyAssignment: + n.AsPropertyAssignment().Initializer = initializer + case KindEnumMember: + n.AsEnumMember().Initializer = initializer + case KindForStatement: + n.AsForStatement().Initializer = initializer + case KindForInStatement, KindForOfStatement: + n.AsForInOrOfStatement().Initializer = initializer + case KindJsxAttribute: + n.AsJsxAttribute().Initializer = initializer + case KindCommonJSExport: + n.AsCommonJSExport().Initializer = initializer + default: + panic("Unhandled case in mutableNode.SetInitializer") + } +} + +func (n *Node) TagName() *Node { + switch n.Kind { + case KindJsxOpeningElement: + return n.AsJsxOpeningElement().TagName + case KindJsxClosingElement: + return n.AsJsxClosingElement().TagName + case KindJsxSelfClosingElement: + return n.AsJsxSelfClosingElement().TagName + case KindJSDocTag: + return n.AsJSDocUnknownTag().TagName + case KindJSDocAugmentsTag: + return n.AsJSDocAugmentsTag().TagName + case KindJSDocImplementsTag: + return n.AsJSDocImplementsTag().TagName + case KindJSDocDeprecatedTag: + return n.AsJSDocDeprecatedTag().TagName + case KindJSDocPublicTag: + return n.AsJSDocPublicTag().TagName + case KindJSDocPrivateTag: + return n.AsJSDocPrivateTag().TagName + case KindJSDocProtectedTag: + return n.AsJSDocProtectedTag().TagName + case KindJSDocReadonlyTag: + return n.AsJSDocReadonlyTag().TagName + case KindJSDocOverrideTag: + return n.AsJSDocOverrideTag().TagName + case KindJSDocCallbackTag: + return n.AsJSDocCallbackTag().TagName + case KindJSDocOverloadTag: + return n.AsJSDocOverloadTag().TagName + case KindJSDocParameterTag, KindJSDocPropertyTag: + return n.AsJSDocParameterOrPropertyTag().TagName + case KindJSDocReturnTag: + return n.AsJSDocReturnTag().TagName + case KindJSDocThisTag: + return n.AsJSDocThisTag().TagName + case KindJSDocTypeTag: + return n.AsJSDocTypeTag().TagName + case KindJSDocTemplateTag: + return n.AsJSDocTemplateTag().TagName + case KindJSDocTypedefTag: + return n.AsJSDocTypedefTag().TagName + case KindJSDocSeeTag: + return n.AsJSDocSeeTag().TagName + case KindJSDocSatisfiesTag: + return n.AsJSDocSatisfiesTag().TagName + case KindJSDocImportTag: + return n.AsJSDocImportTag().TagName + } + panic("Unhandled case in Node.TagName: " + n.Kind.String()) +} + +func (n *Node) PropertyName() *Node { + switch n.Kind { + case KindImportSpecifier: + return n.AsImportSpecifier().PropertyName + case KindExportSpecifier: + return n.AsExportSpecifier().PropertyName + case KindBindingElement: + return n.AsBindingElement().PropertyName + } + return nil +} + +func (n *Node) PropertyNameOrName() *Node { + name := n.PropertyName() + if name == nil { + name = n.Name() + } + return name +} + +func (n *Node) IsTypeOnly() bool { + switch n.Kind { + case KindImportEqualsDeclaration: + return n.AsImportEqualsDeclaration().IsTypeOnly + case KindImportSpecifier: + return n.AsImportSpecifier().IsTypeOnly + case KindImportClause: + return n.AsImportClause().PhaseModifier == KindTypeKeyword + case KindExportDeclaration: + return n.AsExportDeclaration().IsTypeOnly + case KindExportSpecifier: + return n.AsExportSpecifier().IsTypeOnly + } + return false +} + +// If updating this function, also update `hasComment`. +func (n *Node) CommentList() *NodeList { + switch n.Kind { + case KindJSDoc: + return n.AsJSDoc().Comment + case KindJSDocTag: + return n.AsJSDocUnknownTag().Comment + case KindJSDocAugmentsTag: + return n.AsJSDocAugmentsTag().Comment + case KindJSDocImplementsTag: + return n.AsJSDocImplementsTag().Comment + case KindJSDocDeprecatedTag: + return n.AsJSDocDeprecatedTag().Comment + case KindJSDocPublicTag: + return n.AsJSDocPublicTag().Comment + case KindJSDocPrivateTag: + return n.AsJSDocPrivateTag().Comment + case KindJSDocProtectedTag: + return n.AsJSDocProtectedTag().Comment + case KindJSDocReadonlyTag: + return n.AsJSDocReadonlyTag().Comment + case KindJSDocOverrideTag: + return n.AsJSDocOverrideTag().Comment + case KindJSDocCallbackTag: + return n.AsJSDocCallbackTag().Comment + case KindJSDocOverloadTag: + return n.AsJSDocOverloadTag().Comment + case KindJSDocParameterTag, KindJSDocPropertyTag: + return n.AsJSDocParameterOrPropertyTag().Comment + case KindJSDocReturnTag: + return n.AsJSDocReturnTag().Comment + case KindJSDocThisTag: + return n.AsJSDocThisTag().Comment + case KindJSDocTypeTag: + return n.AsJSDocTypeTag().Comment + case KindJSDocTemplateTag: + return n.AsJSDocTemplateTag().Comment + case KindJSDocTypedefTag: + return n.AsJSDocTypedefTag().Comment + case KindJSDocSeeTag: + return n.AsJSDocSeeTag().Comment + case KindJSDocSatisfiesTag: + return n.AsJSDocSatisfiesTag().Comment + case KindJSDocImportTag: + return n.AsJSDocImportTag().Comment + } + panic("Unhandled case in Node.CommentList: " + n.Kind.String()) +} + +func (n *Node) Comments() []*Node { + list := n.CommentList() + if list != nil { + return list.Nodes + } + return nil +} + +func (n *Node) Label() *Node { + switch n.Kind { + case KindLabeledStatement: + return n.AsLabeledStatement().Label + case KindBreakStatement: + return n.AsBreakStatement().Label + case KindContinueStatement: + return n.AsContinueStatement().Label + } + panic("Unhandled case in Node.Label: " + n.Kind.String()) +} + +func (n *Node) Attributes() *Node { + switch n.Kind { + case KindJsxOpeningElement: + return n.AsJsxOpeningElement().Attributes + case KindJsxSelfClosingElement: + return n.AsJsxSelfClosingElement().Attributes + } + panic("Unhandled case in Node.Attributes: " + n.Kind.String()) +} + +func (n *Node) Children() *NodeList { + switch n.Kind { + case KindJsxElement: + return n.AsJsxElement().Children + case KindJsxFragment: + return n.AsJsxFragment().Children + } + panic("Unhandled case in Node.Children: " + n.Kind.String()) +} + +func (n *Node) ModuleSpecifier() *Expression { + switch n.Kind { + case KindImportDeclaration, KindJSImportDeclaration: + return n.AsImportDeclaration().ModuleSpecifier + case KindExportDeclaration: + return n.AsExportDeclaration().ModuleSpecifier + case KindJSDocImportTag: + return n.AsJSDocImportTag().ModuleSpecifier + } + panic("Unhandled case in Node.ModuleSpecifier: " + n.Kind.String()) +} + +func (n *Node) ImportClause() *Node { + switch n.Kind { + case KindImportDeclaration, KindJSImportDeclaration: + return n.AsImportDeclaration().ImportClause + case KindJSDocImportTag: + return n.AsJSDocImportTag().ImportClause + } + panic("Unhandled case in Node.ImportClause: " + n.Kind.String()) +} + +func (n *Node) Statement() *Statement { + switch n.Kind { + case KindDoStatement: + return n.AsDoStatement().Statement + case KindWhileStatement: + return n.AsWhileStatement().Statement + case KindForStatement: + return n.AsForStatement().Statement + case KindForInStatement, KindForOfStatement: + return n.AsForInOrOfStatement().Statement + } + panic("Unhandled case in Node.Statement: " + n.Kind.String()) +} + +func (n *Node) PropertyList() *NodeList { + switch n.Kind { + case KindObjectLiteralExpression: + return n.AsObjectLiteralExpression().Properties + case KindJsxAttributes: + return n.AsJsxAttributes().Properties + } + panic("Unhandled case in Node.PropertyList: " + n.Kind.String()) +} + +func (n *Node) Properties() []*Node { + list := n.PropertyList() + if list != nil { + return list.Nodes + } + return nil +} + +func (n *Node) ElementList() *NodeList { + switch n.Kind { + case KindNamedImports: + return n.AsNamedImports().Elements + case KindNamedExports: + return n.AsNamedExports().Elements + case KindObjectBindingPattern, KindArrayBindingPattern: + return n.AsBindingPattern().Elements + } + + panic("Unhandled case in Node.ElementList: " + n.Kind.String()) +} + +func (n *Node) Elements() []*Node { + list := n.ElementList() + if list != nil { + return list.Nodes + } + return nil +} + +func (n *Node) postfixToken() *Node { + switch n.Kind { + case KindEnumMember: + return n.AsEnumMember().PostfixToken + case KindPropertyAssignment: + return n.AsPropertyAssignment().PostfixToken + case KindShorthandPropertyAssignment: + return n.AsShorthandPropertyAssignment().PostfixToken + case KindPropertySignature: + return n.AsPropertySignatureDeclaration().PostfixToken + case KindPropertyDeclaration: + return n.AsPropertyDeclaration().PostfixToken + case KindMethodSignature: + return n.AsMethodSignatureDeclaration().PostfixToken + case KindMethodDeclaration: + return n.AsMethodDeclaration().PostfixToken + case KindGetAccessor: + return n.AsGetAccessorDeclaration().PostfixToken + case KindSetAccessor: + return n.AsSetAccessorDeclaration().PostfixToken + } + return nil +} + +func (n *Node) QuestionToken() *TokenNode { + switch n.Kind { + case KindParameter: + return n.AsParameterDeclaration().QuestionToken + case KindConditionalExpression: + return n.AsConditionalExpression().QuestionToken + case KindMappedType: + return n.AsMappedTypeNode().QuestionToken + case KindNamedTupleMember: + return n.AsNamedTupleMember().QuestionToken + } + postfix := n.postfixToken() + if postfix != nil && postfix.Kind == KindQuestionToken { + return postfix + } + return nil +} + +func (n *Node) QuestionDotToken() *Node { + switch n.Kind { + case KindElementAccessExpression: + return n.AsElementAccessExpression().QuestionDotToken + case KindPropertyAccessExpression: + return n.AsPropertyAccessExpression().QuestionDotToken + case KindCallExpression: + return n.AsCallExpression().QuestionDotToken + case KindTaggedTemplateExpression: + return n.AsTaggedTemplateExpression().QuestionDotToken + } + panic("Unhandled case in Node.QuestionDotToken: " + n.Kind.String()) +} + +func (n *Node) TypeExpression() *Node { + switch n.Kind { + case KindJSDocPropertyTag, KindJSDocParameterTag: + return n.AsJSDocParameterOrPropertyTag().TypeExpression + case KindJSDocReturnTag: + return n.AsJSDocReturnTag().TypeExpression + case KindJSDocTypeTag: + return n.AsJSDocTypeTag().TypeExpression + case KindJSDocTypedefTag: + return n.AsJSDocTypedefTag().TypeExpression + case KindJSDocSatisfiesTag: + return n.AsJSDocSatisfiesTag().TypeExpression + } + panic("Unhandled case in Node.TypeExpression: " + n.Kind.String()) +} + +func (n *Node) ClassName() *Node { + switch n.Kind { + case KindJSDocAugmentsTag: + return n.AsJSDocAugmentsTag().ClassName + case KindJSDocImplementsTag: + return n.AsJSDocImplementsTag().ClassName + } + panic("Unhandled case in Node.ClassName: " + n.Kind.String()) +} + +func (n *Node) PostfixToken() *Node { + switch n.Kind { + case KindParameter: + return n.AsParameterDeclaration().QuestionToken + case KindMethodDeclaration: + return n.AsMethodDeclaration().PostfixToken + case KindShorthandPropertyAssignment: + return n.AsShorthandPropertyAssignment().PostfixToken + case KindMethodSignature: + return n.AsMethodSignatureDeclaration().PostfixToken + case KindPropertySignature: + return n.AsPropertySignatureDeclaration().PostfixToken + case KindPropertyAssignment: + return n.AsPropertyAssignment().PostfixToken + case KindPropertyDeclaration: + return n.AsPropertyDeclaration().PostfixToken + } + return nil +} + +// Determines if `n` contains `descendant` by walking up the `Parent` pointers from `descendant`. This method panics if +// `descendant` or one of its ancestors is not parented except when that node is a `SourceFile`. +func (n *Node) Contains(descendant *Node) bool { + for descendant != nil { + if descendant == n { + return true + } + parent := descendant.Parent + if parent == nil && !IsSourceFile(descendant) { + panic("descendant is not parented") + } + descendant = parent + } + return false +} + +// Node casts + +func (n *Node) AsIdentifier() *Identifier { + return n.data.(*Identifier) +} + +func (n *Node) AsPrivateIdentifier() *PrivateIdentifier { + return n.data.(*PrivateIdentifier) +} + +func (n *Node) AsQualifiedName() *QualifiedName { + return n.data.(*QualifiedName) +} + +func (n *Node) AsSourceFile() *SourceFile { + return n.data.(*SourceFile) +} + +func (n *Node) AsPrefixUnaryExpression() *PrefixUnaryExpression { + return n.data.(*PrefixUnaryExpression) +} + +func (n *Node) AsPostfixUnaryExpression() *PostfixUnaryExpression { + return n.data.(*PostfixUnaryExpression) +} + +func (n *Node) AsParenthesizedExpression() *ParenthesizedExpression { + return n.data.(*ParenthesizedExpression) +} + +func (n *Node) AsTypeAssertion() *TypeAssertion { + return n.data.(*TypeAssertion) +} + +func (n *Node) AsAsExpression() *AsExpression { + return n.data.(*AsExpression) +} + +func (n *Node) AsSatisfiesExpression() *SatisfiesExpression { + return n.data.(*SatisfiesExpression) +} + +func (n *Node) AsExpressionWithTypeArguments() *ExpressionWithTypeArguments { + return n.data.(*ExpressionWithTypeArguments) +} + +func (n *Node) AsNonNullExpression() *NonNullExpression { + return n.data.(*NonNullExpression) +} + +func (n *Node) AsBindingElement() *BindingElement { + return n.data.(*BindingElement) +} + +func (n *Node) AsMissingDeclaration() *MissingDeclaration { + return n.data.(*MissingDeclaration) +} + +func (n *Node) AsImportSpecifier() *ImportSpecifier { + return n.data.(*ImportSpecifier) +} + +func (n *Node) AsArrowFunction() *ArrowFunction { + return n.data.(*ArrowFunction) +} + +func (n *Node) AsCallExpression() *CallExpression { + return n.data.(*CallExpression) +} + +func (n *Node) AsPropertyAccessExpression() *PropertyAccessExpression { + return n.data.(*PropertyAccessExpression) +} + +func (n *Node) AsElementAccessExpression() *ElementAccessExpression { + return n.data.(*ElementAccessExpression) +} + +func (n *Node) AsComputedPropertyName() *ComputedPropertyName { + return n.data.(*ComputedPropertyName) +} + +func (n *Node) AsBinaryExpression() *BinaryExpression { + return n.data.(*BinaryExpression) +} + +func (n *Node) AsModuleDeclaration() *ModuleDeclaration { + return n.data.(*ModuleDeclaration) +} + +func (n *Node) AsStringLiteral() *StringLiteral { + return n.data.(*StringLiteral) +} + +func (n *Node) AsNumericLiteral() *NumericLiteral { + return n.data.(*NumericLiteral) +} + +func (n *Node) AsBigIntLiteral() *BigIntLiteral { + return n.data.(*BigIntLiteral) +} + +func (n *Node) AsNoSubstitutionTemplateLiteral() *NoSubstitutionTemplateLiteral { + return n.data.(*NoSubstitutionTemplateLiteral) +} + +func (n *Node) AsRegularExpressionLiteral() *RegularExpressionLiteral { + return n.data.(*RegularExpressionLiteral) +} + +func (n *Node) AsTemplateHead() *TemplateHead { + return n.data.(*TemplateHead) +} + +func (n *Node) AsTemplateMiddle() *TemplateMiddle { + return n.data.(*TemplateMiddle) +} + +func (n *Node) AsTemplateTail() *TemplateTail { + return n.data.(*TemplateTail) +} + +func (n *Node) AsVariableDeclaration() *VariableDeclaration { + return n.data.(*VariableDeclaration) +} + +func (n *Node) AsExportAssignment() *ExportAssignment { + return n.data.(*ExportAssignment) +} + +func (n *Node) AsCommonJSExport() *CommonJSExport { + return n.data.(*CommonJSExport) +} + +func (n *Node) AsObjectLiteralExpression() *ObjectLiteralExpression { + return n.data.(*ObjectLiteralExpression) +} + +func (n *Node) AsIfStatement() *IfStatement { + return n.data.(*IfStatement) +} + +func (n *Node) AsWhileStatement() *WhileStatement { + return n.data.(*WhileStatement) +} + +func (n *Node) AsDoStatement() *DoStatement { + return n.data.(*DoStatement) +} + +func (n *Node) AsForStatement() *ForStatement { + return n.data.(*ForStatement) +} + +func (n *Node) AsConditionalExpression() *ConditionalExpression { + return n.data.(*ConditionalExpression) +} + +func (n *Node) AsForInOrOfStatement() *ForInOrOfStatement { + return n.data.(*ForInOrOfStatement) +} + +func (n *Node) AsShorthandPropertyAssignment() *ShorthandPropertyAssignment { + return n.data.(*ShorthandPropertyAssignment) +} + +func (n *Node) AsPropertyAssignment() *PropertyAssignment { + return n.data.(*PropertyAssignment) +} + +func (n *Node) AsExpressionStatement() *ExpressionStatement { + return n.data.(*ExpressionStatement) +} + +func (n *Node) AsBlock() *Block { + return n.data.(*Block) +} + +func (n *Node) AsModuleBlock() *ModuleBlock { + return n.data.(*ModuleBlock) +} + +func (n *Node) AsVariableStatement() *VariableStatement { + return n.data.(*VariableStatement) +} + +func (n *Node) AsVariableDeclarationList() *VariableDeclarationList { + return n.data.(*VariableDeclarationList) +} + +func (n *Node) AsMetaProperty() *MetaProperty { + return n.data.(*MetaProperty) +} + +func (n *Node) AsTypeReference() *TypeReferenceNode { + return n.data.(*TypeReferenceNode) +} + +func (n *Node) AsConstructorDeclaration() *ConstructorDeclaration { + return n.data.(*ConstructorDeclaration) +} + +func (n *Node) AsConditionalTypeNode() *ConditionalTypeNode { + return n.data.(*ConditionalTypeNode) +} + +func (n *Node) AsClassExpression() *ClassExpression { + return n.data.(*ClassExpression) +} + +func (n *Node) AsHeritageClause() *HeritageClause { + return n.data.(*HeritageClause) +} + +func (n *Node) AsFunctionExpression() *FunctionExpression { + return n.data.(*FunctionExpression) +} + +func (n *Node) AsParameterDeclaration() *ParameterDeclaration { + return n.data.(*ParameterDeclaration) +} + +func (n *Node) AsDecorator() *Decorator { + return n.data.(*Decorator) +} + +func (n *Node) AsInferTypeNode() *InferTypeNode { + return n.data.(*InferTypeNode) +} + +func (n *Node) AsTypeParameter() *TypeParameterDeclaration { + return n.data.(*TypeParameterDeclaration) +} + +func (n *Node) AsExportSpecifier() *ExportSpecifier { + return n.data.(*ExportSpecifier) +} + +func (n *Node) AsExportDeclaration() *ExportDeclaration { + return n.data.(*ExportDeclaration) +} + +func (n *Node) AsPropertyDeclaration() *PropertyDeclaration { + return n.data.(*PropertyDeclaration) +} + +func (n *Node) AsImportClause() *ImportClause { + return n.data.(*ImportClause) +} + +func (n *Node) AsImportEqualsDeclaration() *ImportEqualsDeclaration { + return n.data.(*ImportEqualsDeclaration) +} + +func (n *Node) AsNamespaceImport() *NamespaceImport { + return n.data.(*NamespaceImport) +} + +func (n *Node) AsPropertySignatureDeclaration() *PropertySignatureDeclaration { + return n.data.(*PropertySignatureDeclaration) +} + +func (n *Node) AsEnumMember() *EnumMember { + return n.data.(*EnumMember) +} + +func (n *Node) AsReturnStatement() *ReturnStatement { + return n.data.(*ReturnStatement) +} + +func (n *Node) AsWithStatement() *WithStatement { + return n.data.(*WithStatement) +} + +func (n *Node) AsSwitchStatement() *SwitchStatement { + return n.data.(*SwitchStatement) +} + +func (n *Node) AsCaseOrDefaultClause() *CaseOrDefaultClause { + return n.data.(*CaseOrDefaultClause) +} + +func (n *Node) AsThrowStatement() *ThrowStatement { + return n.data.(*ThrowStatement) +} + +func (n *Node) AsTemplateSpan() *TemplateSpan { + return n.data.(*TemplateSpan) +} + +func (n *Node) AsImportTypeNode() *ImportTypeNode { + return n.data.(*ImportTypeNode) +} + +func (n *Node) AsNewExpression() *NewExpression { + return n.data.(*NewExpression) +} + +func (n *Node) AsTaggedTemplateExpression() *TaggedTemplateExpression { + return n.data.(*TaggedTemplateExpression) +} + +func (n *Node) AsJsxOpeningElement() *JsxOpeningElement { + return n.data.(*JsxOpeningElement) +} + +func (n *Node) AsJsxSelfClosingElement() *JsxSelfClosingElement { + return n.data.(*JsxSelfClosingElement) +} + +func (n *Node) AsJsxClosingElement() *JsxClosingElement { + return n.data.(*JsxClosingElement) +} + +func (n *Node) AsJsxOpeningFragment() *JsxOpeningFragment { + return n.data.(*JsxOpeningFragment) +} + +func (n *Node) AsJsxClosingFragment() *JsxClosingFragment { + return n.data.(*JsxClosingFragment) +} + +func (n *Node) AsImportDeclaration() *ImportDeclaration { + return n.data.(*ImportDeclaration) +} + +func (n *Node) AsExternalModuleReference() *ExternalModuleReference { + return n.data.(*ExternalModuleReference) +} + +func (n *Node) AsLiteralTypeNode() *LiteralTypeNode { + return n.data.(*LiteralTypeNode) +} + +func (n *Node) AsJsxNamespacedName() *JsxNamespacedName { + return n.data.(*JsxNamespacedName) +} + +func (n *Node) AsClassDeclaration() *ClassDeclaration { + return n.data.(*ClassDeclaration) +} + +func (n *Node) AsInterfaceDeclaration() *InterfaceDeclaration { + return n.data.(*InterfaceDeclaration) +} + +func (n *Node) AsTypeAliasDeclaration() *TypeAliasDeclaration { + return n.data.(*TypeAliasDeclaration) +} + +func (n *Node) AsJsxAttribute() *JsxAttribute { + return n.data.(*JsxAttribute) +} + +func (n *Node) AsJsxAttributes() *JsxAttributes { + return n.data.(*JsxAttributes) +} + +func (n *Node) AsJsxSpreadAttribute() *JsxSpreadAttribute { + return n.data.(*JsxSpreadAttribute) +} + +func (n *Node) AsJsxExpression() *JsxExpression { + return n.data.(*JsxExpression) +} + +func (n *Node) AsJsxText() *JsxText { + return n.data.(*JsxText) +} + +func (n *Node) AsKeywordTypeNode() *KeywordTypeNode { + return n.data.(*KeywordTypeNode) +} + +func (n *Node) AsThisTypeNode() *ThisTypeNode { + return n.data.(*ThisTypeNode) +} + +func (n *Node) AsParenthesizedTypeNode() *ParenthesizedTypeNode { + return n.data.(*ParenthesizedTypeNode) +} + +func (n *Node) AsTypePredicateNode() *TypePredicateNode { + return n.data.(*TypePredicateNode) +} + +func (n *Node) AsTypeOperatorNode() *TypeOperatorNode { + return n.data.(*TypeOperatorNode) +} + +func (n *Node) AsMappedTypeNode() *MappedTypeNode { + return n.data.(*MappedTypeNode) +} + +func (n *Node) AsArrayLiteralExpression() *ArrayLiteralExpression { + return n.data.(*ArrayLiteralExpression) +} + +func (n *Node) AsMethodDeclaration() *MethodDeclaration { + return n.data.(*MethodDeclaration) +} + +func (n *Node) AsMethodSignatureDeclaration() *MethodSignatureDeclaration { + return n.data.(*MethodSignatureDeclaration) +} + +func (n *Node) AsTemplateLiteralTypeSpan() *TemplateLiteralTypeSpan { + return n.data.(*TemplateLiteralTypeSpan) +} + +func (n *Node) AsJsxElement() *JsxElement { + return n.data.(*JsxElement) +} + +func (n *Node) AsJsxFragment() *JsxFragment { + return n.data.(*JsxFragment) +} + +func (n *Node) AsKeywordExpression() *KeywordExpression { + return n.data.(*KeywordExpression) +} + +func (n *Node) AsCatchClause() *CatchClause { + return n.data.(*CatchClause) +} + +func (n *Node) AsDeleteExpression() *DeleteExpression { + return n.data.(*DeleteExpression) +} + +func (n *Node) AsLabeledStatement() *LabeledStatement { + return n.data.(*LabeledStatement) +} + +func (n *Node) AsNamespaceExportDeclaration() *NamespaceExportDeclaration { + return n.data.(*NamespaceExportDeclaration) +} + +func (n *Node) AsNamedImports() *NamedImports { + return n.data.(*NamedImports) +} + +func (n *Node) AsNamedExports() *NamedExports { + return n.data.(*NamedExports) +} + +func (n *Node) AsBreakStatement() *BreakStatement { + return n.data.(*BreakStatement) +} + +func (n *Node) AsContinueStatement() *ContinueStatement { + return n.data.(*ContinueStatement) +} + +func (n *Node) AsCaseBlock() *CaseBlock { + return n.data.(*CaseBlock) +} + +func (n *Node) AsTryStatement() *TryStatement { + return n.data.(*TryStatement) +} + +func (n *Node) AsBindingPattern() *BindingPattern { + return n.data.(*BindingPattern) +} + +func (n *Node) AsFunctionDeclaration() *FunctionDeclaration { + return n.data.(*FunctionDeclaration) +} + +func (n *Node) AsTypeOfExpression() *TypeOfExpression { + return n.data.(*TypeOfExpression) +} + +func (n *Node) AsVoidExpression() *VoidExpression { + return n.data.(*VoidExpression) +} + +func (n *Node) AsAwaitExpression() *AwaitExpression { + return n.data.(*AwaitExpression) +} + +func (n *Node) AsTemplateExpression() *TemplateExpression { + return n.data.(*TemplateExpression) +} + +func (n *Node) AsYieldExpression() *YieldExpression { + return n.data.(*YieldExpression) +} + +func (n *Node) AsPartiallyEmittedExpression() *PartiallyEmittedExpression { + return n.data.(*PartiallyEmittedExpression) +} + +func (n *Node) AsSpreadElement() *SpreadElement { + return n.data.(*SpreadElement) +} + +func (n *Node) AsSpreadAssignment() *SpreadAssignment { + return n.data.(*SpreadAssignment) +} + +func (n *Node) AsArrayTypeNode() *ArrayTypeNode { + return n.data.(*ArrayTypeNode) +} + +func (n *Node) AsTupleTypeNode() *TupleTypeNode { + return n.data.(*TupleTypeNode) +} + +func (n *Node) AsUnionTypeNode() *UnionTypeNode { + return n.data.(*UnionTypeNode) +} + +func (n *Node) AsIntersectionTypeNode() *IntersectionTypeNode { + return n.data.(*IntersectionTypeNode) +} + +func (n *Node) AsRestTypeNode() *RestTypeNode { + return n.data.(*RestTypeNode) +} + +func (n *Node) AsNamedTupleMember() *NamedTupleMember { + return n.data.(*NamedTupleMember) +} + +func (n *Node) AsOptionalTypeNode() *OptionalTypeNode { + return n.data.(*OptionalTypeNode) +} + +func (n *Node) AsTemplateLiteralTypeNode() *TemplateLiteralTypeNode { + return n.data.(*TemplateLiteralTypeNode) +} + +func (n *Node) AsTypeReferenceNode() *TypeReferenceNode { + return n.data.(*TypeReferenceNode) +} + +func (n *Node) AsFunctionTypeNode() *FunctionTypeNode { + return n.data.(*FunctionTypeNode) +} + +func (n *Node) AsConstructorTypeNode() *ConstructorTypeNode { + return n.data.(*ConstructorTypeNode) +} + +func (n *Node) AsTypeQueryNode() *TypeQueryNode { + return n.data.(*TypeQueryNode) +} + +func (n *Node) AsTypeLiteralNode() *TypeLiteralNode { + return n.data.(*TypeLiteralNode) +} + +func (n *Node) AsIndexedAccessTypeNode() *IndexedAccessTypeNode { + return n.data.(*IndexedAccessTypeNode) +} + +func (n *Node) AsGetAccessorDeclaration() *GetAccessorDeclaration { + return n.data.(*GetAccessorDeclaration) +} + +func (n *Node) AsSetAccessorDeclaration() *SetAccessorDeclaration { + return n.data.(*SetAccessorDeclaration) +} + +func (n *Node) AsClassStaticBlockDeclaration() *ClassStaticBlockDeclaration { + return n.data.(*ClassStaticBlockDeclaration) +} + +func (n *Node) AsSemicolonClassElement() *SemicolonClassElement { + return n.data.(*SemicolonClassElement) +} + +func (n *Node) AsCallSignatureDeclaration() *CallSignatureDeclaration { + return n.data.(*CallSignatureDeclaration) +} + +func (n *Node) AsConstructSignatureDeclaration() *ConstructSignatureDeclaration { + return n.data.(*ConstructSignatureDeclaration) +} + +func (n *Node) AsIndexSignatureDeclaration() *IndexSignatureDeclaration { + return n.data.(*IndexSignatureDeclaration) +} + +func (n *Node) AsDebuggerStatement() *DebuggerStatement { + return n.data.(*DebuggerStatement) +} + +func (n *Node) AsEmptyStatement() *EmptyStatement { + return n.data.(*EmptyStatement) +} + +func (n *Node) AsEnumDeclaration() *EnumDeclaration { + return n.data.(*EnumDeclaration) +} + +func (n *Node) AsNotEmittedStatement() *NotEmittedStatement { + return n.data.(*NotEmittedStatement) +} + +func (n *Node) AsNotEmittedTypeElement() *NotEmittedTypeElement { + return n.data.(*NotEmittedTypeElement) +} + +func (n *Node) AsJSDoc() *JSDoc { + return n.data.(*JSDoc) +} + +func (n *Node) AsJSDocTagBase() *JSDocTagBase { + return n.data.(*JSDocTagBase) +} + +func (n *Node) AsJSDocCommentBase() *JSDocCommentBase { + return n.data.(*JSDocCommentBase) +} + +func (n *Node) AsJSDocText() *JSDocText { + return n.data.(*JSDocText) +} + +func (n *Node) AsJSDocLink() *JSDocLink { + return n.data.(*JSDocLink) +} + +func (n *Node) AsJSDocLinkPlain() *JSDocLinkPlain { + return n.data.(*JSDocLinkPlain) +} + +func (n *Node) AsJSDocLinkCode() *JSDocLinkCode { + return n.data.(*JSDocLinkCode) +} + +func (n *Node) AsJSDocTypeExpression() *JSDocTypeExpression { + return n.data.(*JSDocTypeExpression) +} + +func (n *Node) AsJSDocNonNullableType() *JSDocNonNullableType { + return n.data.(*JSDocNonNullableType) +} + +func (n *Node) AsJSDocNullableType() *JSDocNullableType { + return n.data.(*JSDocNullableType) +} + +func (n *Node) AsJSDocAllType() *JSDocAllType { + return n.data.(*JSDocAllType) +} + +func (n *Node) AsJSDocVariadicType() *JSDocVariadicType { + return n.data.(*JSDocVariadicType) +} + +func (n *Node) AsJSDocOptionalType() *JSDocOptionalType { + return n.data.(*JSDocOptionalType) +} + +func (n *Node) AsJSDocTypeTag() *JSDocTypeTag { + return n.data.(*JSDocTypeTag) +} + +func (n *Node) AsJSDocUnknownTag() *JSDocUnknownTag { + return n.data.(*JSDocUnknownTag) +} + +func (n *Node) AsJSDocTemplateTag() *JSDocTemplateTag { + return n.data.(*JSDocTemplateTag) +} + +func (n *Node) AsJSDocParameterOrPropertyTag() *JSDocParameterOrPropertyTag { + return n.data.(*JSDocParameterOrPropertyTag) +} + +func (n *Node) AsJSDocReturnTag() *JSDocReturnTag { + return n.data.(*JSDocReturnTag) +} + +func (n *Node) AsJSDocPublicTag() *JSDocPublicTag { + return n.data.(*JSDocPublicTag) +} + +func (n *Node) AsJSDocPrivateTag() *JSDocPrivateTag { + return n.data.(*JSDocPrivateTag) +} + +func (n *Node) AsJSDocProtectedTag() *JSDocProtectedTag { + return n.data.(*JSDocProtectedTag) +} + +func (n *Node) AsJSDocReadonlyTag() *JSDocReadonlyTag { + return n.data.(*JSDocReadonlyTag) +} + +func (n *Node) AsJSDocOverrideTag() *JSDocOverrideTag { + return n.data.(*JSDocOverrideTag) +} + +func (n *Node) AsJSDocDeprecatedTag() *JSDocDeprecatedTag { + return n.data.(*JSDocDeprecatedTag) +} + +func (n *Node) AsJSDocSeeTag() *JSDocSeeTag { + return n.data.(*JSDocSeeTag) +} + +func (n *Node) AsJSDocImplementsTag() *JSDocImplementsTag { + return n.data.(*JSDocImplementsTag) +} + +func (n *Node) AsJSDocAugmentsTag() *JSDocAugmentsTag { + return n.data.(*JSDocAugmentsTag) +} + +func (n *Node) AsJSDocSatisfiesTag() *JSDocSatisfiesTag { + return n.data.(*JSDocSatisfiesTag) +} + +func (n *Node) AsJSDocThisTag() *JSDocThisTag { + return n.data.(*JSDocThisTag) +} + +func (n *Node) AsJSDocImportTag() *JSDocImportTag { + return n.data.(*JSDocImportTag) +} + +func (n *Node) AsJSDocCallbackTag() *JSDocCallbackTag { + return n.data.(*JSDocCallbackTag) +} + +func (n *Node) AsJSDocOverloadTag() *JSDocOverloadTag { + return n.data.(*JSDocOverloadTag) +} + +func (n *Node) AsJSDocTypedefTag() *JSDocTypedefTag { + return n.data.(*JSDocTypedefTag) +} + +func (n *Node) AsJSDocTypeLiteral() *JSDocTypeLiteral { + return n.data.(*JSDocTypeLiteral) +} + +func (n *Node) AsJSDocSignature() *JSDocSignature { + return n.data.(*JSDocSignature) +} + +func (n *Node) AsJSDocNameReference() *JSDocNameReference { + return n.data.(*JSDocNameReference) +} + +func (n *Node) AsNamespaceExport() *NamespaceExport { + return n.data.(*NamespaceExport) +} + +func (n *Node) AsImportAttribute() *ImportAttribute { + return n.data.(*ImportAttribute) +} + +func (n *Node) AsImportAttributes() *ImportAttributes { + return n.data.(*ImportAttributes) +} + +func (n *Node) AsFlowSwitchClauseData() *FlowSwitchClauseData { + return n.data.(*FlowSwitchClauseData) +} + +func (n *Node) AsFlowReduceLabelData() *FlowReduceLabelData { + return n.data.(*FlowReduceLabelData) +} + +func (n *Node) AsSyntheticExpression() *SyntheticExpression { + return n.data.(*SyntheticExpression) +} + +func (n *Node) AsSyntaxList() *SyntaxList { + return n.data.(*SyntaxList) +} + +func (n *Node) AsSyntheticReferenceExpression() *SyntheticReferenceExpression { + return n.data.(*SyntheticReferenceExpression) +} + +// NodeData + +type nodeData interface { + AsNode() *Node + ForEachChild(v Visitor) bool + IterChildren() iter.Seq[*Node] + VisitEachChild(v *NodeVisitor) *Node + Clone(v NodeFactoryCoercible) *Node + Name() *DeclarationName + Modifiers() *ModifierList + setModifiers(modifiers *ModifierList) + FlowNodeData() *FlowNodeBase + DeclarationData() *DeclarationBase + ExportableData() *ExportableBase + LocalsContainerData() *LocalsContainerBase + FunctionLikeData() *FunctionLikeBase + ClassLikeData() *ClassLikeBase + BodyData() *BodyBase + LiteralLikeData() *LiteralLikeBase + TemplateLiteralLikeData() *TemplateLiteralLikeBase + SubtreeFacts() SubtreeFacts + computeSubtreeFacts() SubtreeFacts + subtreeFactsWorker(self nodeData) SubtreeFacts + propagateSubtreeFacts() SubtreeFacts +} + +// NodeDefault + +type NodeDefault struct { + Node +} + +func invert(yield func(v *Node) bool) Visitor { + return func(n *Node) bool { + return !yield(n) + } +} + +func (node *NodeDefault) AsNode() *Node { return &node.Node } +func (node *NodeDefault) ForEachChild(v Visitor) bool { return false } +func (node *NodeDefault) forEachChildIter(yield func(v *Node) bool) { + node.data.ForEachChild(invert(yield)) // `true` is return early for a ts visitor, `false` is return early for a go iterator yield function +} + +func (node *NodeDefault) IterChildren() iter.Seq[*Node] { + return node.forEachChildIter +} +func (node *NodeDefault) VisitEachChild(v *NodeVisitor) *Node { return node.AsNode() } +func (node *NodeDefault) Clone(v NodeFactoryCoercible) *Node { return nil } +func (node *NodeDefault) Name() *DeclarationName { return nil } +func (node *NodeDefault) Modifiers() *ModifierList { return nil } +func (node *NodeDefault) setModifiers(modifiers *ModifierList) {} +func (node *NodeDefault) FlowNodeData() *FlowNodeBase { return nil } +func (node *NodeDefault) DeclarationData() *DeclarationBase { return nil } +func (node *NodeDefault) ExportableData() *ExportableBase { return nil } +func (node *NodeDefault) LocalsContainerData() *LocalsContainerBase { return nil } +func (node *NodeDefault) FunctionLikeData() *FunctionLikeBase { return nil } +func (node *NodeDefault) ClassLikeData() *ClassLikeBase { return nil } +func (node *NodeDefault) BodyData() *BodyBase { return nil } +func (node *NodeDefault) LiteralLikeData() *LiteralLikeBase { return nil } +func (node *NodeDefault) TemplateLiteralLikeData() *TemplateLiteralLikeBase { return nil } +func (node *NodeDefault) SubtreeFacts() SubtreeFacts { + return node.data.subtreeFactsWorker(node.data) +} + +func (node *NodeDefault) subtreeFactsWorker(self nodeData) SubtreeFacts { + // To avoid excessive conditional checks, the default implementation of subtreeFactsWorker directly invokes + // computeSubtreeFacts. More complex nodes should implement CompositeNodeBase, which overrides this + // method to cache the result. `self` is passed along to ensure we lookup `computeSubtreeFacts` on the + // correct type, as `CompositeNodeBase` does not, itself, inherit from `Node`. + return self.computeSubtreeFacts() +} + +func (node *NodeDefault) computeSubtreeFacts() SubtreeFacts { + return SubtreeFactsNone +} + +func (node *NodeDefault) propagateSubtreeFacts() SubtreeFacts { + return node.data.SubtreeFacts() & ^SubtreeExclusionsNode +} + +// NodeBase + +type NodeBase struct { + NodeDefault +} + +// Aliases for Node unions + +type ( + Statement = Node // Node with StatementBase + Declaration = Node // Node with DeclarationBase + Expression = Node // Node with ExpressionBase + TypeNode = Node // Node with TypeNodeBase + TypeElement = Node // Node with TypeElementBase + ClassElement = Node // Node with ClassElementBase + NamedMember = Node // Node with NamedMemberBase + ObjectLiteralElement = Node // Node with ObjectLiteralElementBase + BlockOrExpression = Node // Block | Expression + AccessExpression = Node // PropertyAccessExpression | ElementAccessExpression + DeclarationName = Node // Identifier | PrivateIdentifier | StringLiteral | NumericLiteral | BigIntLiteral | NoSubstitutionTemplateLiteral | ComputedPropertyName | BindingPattern | ElementAccessExpression + ModuleName = Node // Identifier | StringLiteral + ModuleExportName = Node // Identifier | StringLiteral + PropertyName = Node // Identifier | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | ComputedPropertyName | PrivateIdentifier | BigIntLiteral + ModuleBody = Node // ModuleBlock | ModuleDeclaration + ForInitializer = Node // Expression | MissingDeclaration | VariableDeclarationList + ModuleReference = Node // Identifier | QualifiedName | ExternalModuleReference + NamedImportBindings = Node // NamespaceImport | NamedImports + NamedExportBindings = Node // NamespaceExport | NamedExports + MemberName = Node // Identifier | PrivateIdentifier + EntityName = Node // Identifier | QualifiedName + BindingName = Node // Identifier | BindingPattern + ModifierLike = Node // Modifier | Decorator + JsxChild = Node // JsxText | JsxExpression | JsxElement | JsxSelfClosingElement | JsxFragment + JsxAttributeLike = Node // JsxAttribute | JsxSpreadAttribute + JsxAttributeName = Node // Identifier | JsxNamespacedName + JsxAttributeValue = Node // StringLiteral | JsxExpression | JsxElement | JsxSelfClosingElement | JsxFragment + JsxTagNameExpression = Node // IdentifierReference | KeywordExpression | JsxTagNamePropertyAccess | JsxNamespacedName + ClassLikeDeclaration = Node // ClassDeclaration | ClassExpression + AccessorDeclaration = Node // GetAccessorDeclaration | SetAccessorDeclaration + LiteralLikeNode = Node // StringLiteral | NumericLiteral | BigIntLiteral | RegularExpressionLiteral | TemplateLiteralLikeNode | JsxText + LiteralExpression = Node // StringLiteral | NumericLiteral | BigIntLiteral | RegularExpressionLiteral | NoSubstitutionTemplateLiteral + UnionOrIntersectionTypeNode = Node // UnionTypeNode | IntersectionTypeNode + TemplateLiteralLikeNode = Node // TemplateHead | TemplateMiddle | TemplateTail + TemplateMiddleOrTail = Node // TemplateMiddle | TemplateTail + TemplateLiteral = Node // TemplateExpression | NoSubstitutionTemplateLiteral + TypePredicateParameterName = Node // Identifier | ThisTypeNode + ImportAttributeName = Node // Identifier | StringLiteral + LeftHandSideExpression = Node // subset of Expression + JSDocComment = Node // JSDocText | JSDocLink | JSDocLinkCode | JSDocLinkPlain; + JSDocTag = Node // Node with JSDocTagBase + SignatureDeclaration = Node // CallSignatureDeclaration | ConstructSignatureDeclaration | MethodSignature | IndexSignatureDeclaration | FunctionTypeNode | ConstructorTypeNode | FunctionDeclaration | MethodDeclaration | ConstructorDeclaration | AccessorDeclaration | FunctionExpression | ArrowFunction; + StringLiteralLike = Node // StringLiteral | NoSubstitutionTemplateLiteral + AnyValidImportOrReExport = Node // (ImportDeclaration | ExportDeclaration | JSDocImportTag) & { moduleSpecifier: StringLiteral } | ImportEqualsDeclaration & { moduleReference: ExternalModuleReference & { expression: StringLiteral }} | RequireOrImportCall | ValidImportTypeNode + ValidImportTypeNode = Node // ImportTypeNode & { argument: LiteralTypeNode & { literal: StringLiteral } } + NumericOrStringLikeLiteral = Node // StringLiteralLike | NumericLiteral + TypeOnlyImportDeclaration = Node // ImportClause | ImportEqualsDeclaration | ImportSpecifier | NamespaceImport with isTypeOnly: true + ObjectLiteralLike = Node // ObjectLiteralExpression | ObjectBindingPattern + ObjectTypeDeclaration = Node // ClassLikeDeclaration | InterfaceDeclaration | TypeLiteralNode + JsxOpeningLikeElement = Node // JsxOpeningElement | JsxSelfClosingElement + NamedImportsOrExports = Node // NamedImports | NamedExports + BreakOrContinueStatement = Node // BreakStatement | ContinueStatement + CallLikeExpression = Node // CallExpression | NewExpression | TaggedTemplateExpression | Decorator | JsxCallLike | InstanceofExpression +) + +// Aliases for node singletons + +type ( + IdentifierNode = Node + PrivateIdentifierNode = Node + TokenNode = Node + StringLiteralNode = Node + TemplateHeadNode = Node + TemplateMiddleNode = Node + TemplateTailNode = Node + TemplateSpanNode = Node + TemplateLiteralTypeSpanNode = Node + BlockNode = Node + CatchClauseNode = Node + CaseBlockNode = Node + CaseOrDefaultClauseNode = Node + CaseClauseNode = Node + VariableDeclarationNode = Node + VariableDeclarationListNode = Node + BindingElementNode = Node + TypeParameterDeclarationNode = Node + ParameterDeclarationNode = Node + HeritageClauseNode = Node + ExpressionWithTypeArgumentsNode = Node + EnumDeclarationNode = Node + EnumMemberNode = Node + ModuleDeclarationNode = Node + FunctionDeclarationNode = Node + ImportClauseNode = Node + ImportAttributesNode = Node + ImportAttributeNode = Node + ImportSpecifierNode = Node + ExportSpecifierNode = Node + JsxAttributesNode = Node + JsxOpeningElementNode = Node + JsxClosingElementNode = Node + JsxOpeningFragmentNode = Node + JsxClosingFragmentNode = Node + SourceFileNode = Node + PropertyAccessExpressionNode = Node + TypeLiteral = Node + ObjectLiteralExpressionNode = Node + ConstructorDeclarationNode = Node + NamedExportsNode = Node + UnionType = Node + LiteralType = Node + JSDocNode = Node + BindingPatternNode = Node +) + +type ( + StatementList = NodeList // NodeList[*Statement] + CaseClausesList = NodeList // NodeList[*CaseOrDefaultClause] + VariableDeclarationNodeList = NodeList // NodeList[*VariableDeclaration] + BindingElementList = NodeList // NodeList[*BindingElement] + TypeParameterList = NodeList // NodeList[*TypeParameterDeclaration] + ParameterList = NodeList // NodeList[*ParameterDeclaration] + HeritageClauseList = NodeList // NodeList[*HeritageClause] + ClassElementList = NodeList // NodeList[*ClassElement] + TypeElementList = NodeList // NodeList[*TypeElement] + ExpressionWithTypeArgumentsList = NodeList // NodeList[*ExpressionWithTypeArguments] + EnumMemberList = NodeList // NodeList[*EnumMember] + ImportSpecifierList = NodeList // NodeList[*ImportSpecifier] + ExportSpecifierList = NodeList // NodeList[*ExportSpecifier] + TypeArgumentList = NodeList // NodeList[*TypeNode] + ArgumentList = NodeList // NodeList[*Expression] + TemplateSpanList = NodeList // NodeList[*TemplateSpan] + ElementList = NodeList // NodeList[*Expression] + PropertyDefinitionList = NodeList // NodeList[*ObjectLiteralElement] + TypeList = NodeList // NodeList[*TypeNode] + ImportAttributeList = NodeList // NodeList[*ImportAttributeNode] + TemplateLiteralTypeSpanList = NodeList // NodeList[*TemplateLiteralTypeSpan] + JsxChildList = NodeList // NodeList[*JsxChild] + JsxAttributeList = NodeList // NodeList[*JsxAttributeLike] +) + +func IsWriteOnlyAccess(node *Node) bool { + return accessKind(node) == AccessKindWrite +} + +func IsWriteAccess(node *Node) bool { + return accessKind(node) != AccessKindRead +} + +func IsWriteAccessForReference(node *Node) bool { + decl := getDeclarationFromName(node) + return (decl != nil && declarationIsWriteAccess(decl)) || node.Kind == KindDefaultKeyword || IsWriteAccess(node) +} + +func getDeclarationFromName(name *Node) *Declaration { + if name == nil || name.Parent == nil { + return nil + } + parent := name.Parent + switch name.Kind { + case KindStringLiteral, KindNoSubstitutionTemplateLiteral, KindNumericLiteral: + if IsComputedPropertyName(parent) { + return parent.Parent + } + fallthrough + case KindIdentifier: + if IsDeclaration(parent) { + if parent.Name() == name { + return parent + } + return nil + } + if IsQualifiedName(parent) { + tag := parent.Parent + if IsJSDocParameterTag(tag) && tag.Name() == parent { + return tag + } + return nil + } + binExp := parent.Parent + if IsBinaryExpression(binExp) && GetAssignmentDeclarationKind(binExp.AsBinaryExpression()) != JSDeclarationKindNone { + // (binExp.left as BindableStaticNameExpression).symbol || binExp.symbol + leftHasSymbol := false + if binExp.AsBinaryExpression().Left != nil && binExp.AsBinaryExpression().Left.Symbol() != nil { + leftHasSymbol = true + } + if leftHasSymbol || binExp.Symbol() != nil { + if GetNameOfDeclaration(binExp.AsNode()) == name { + return binExp.AsNode() + } + } + } + case KindPrivateIdentifier: + if IsDeclaration(parent) && parent.Name() == name { + return parent + } + } + return nil +} + +func declarationIsWriteAccess(decl *Node) bool { + if decl == nil { + return false + } + // Consider anything in an ambient declaration to be a write access since it may be coming from JS. + if decl.Flags&NodeFlagsAmbient != 0 { + return true + } + + switch decl.Kind { + case KindBinaryExpression, + KindBindingElement, + KindClassDeclaration, + KindClassExpression, + KindDefaultKeyword, + KindEnumDeclaration, + KindEnumMember, + KindExportSpecifier, + KindImportClause, // default import + KindImportEqualsDeclaration, + KindImportSpecifier, + KindInterfaceDeclaration, + KindJSDocCallbackTag, + KindJSDocTypedefTag, + KindJsxAttribute, + KindModuleDeclaration, + KindNamespaceExportDeclaration, + KindNamespaceImport, + KindNamespaceExport, + KindParameter, + KindShorthandPropertyAssignment, + KindTypeAliasDeclaration, + KindTypeParameter: + return true + + case KindPropertyAssignment: + // In `({ x: y } = 0);`, `x` is not a write access. + return !IsArrayLiteralOrObjectLiteralDestructuringPattern(decl.Parent) + + case KindFunctionDeclaration, KindFunctionExpression, KindConstructor, KindMethodDeclaration, KindGetAccessor, KindSetAccessor: + // functions considered write if they provide a value (have a body) + switch decl.Kind { + case KindFunctionDeclaration: + return decl.AsFunctionDeclaration().Body != nil + case KindFunctionExpression: + return decl.AsFunctionExpression().Body != nil + case KindConstructor: + // constructor node stores body on the parent? treat same as others + return decl.AsConstructorDeclaration().Body != nil + case KindMethodDeclaration: + return decl.AsMethodDeclaration().Body != nil + case KindGetAccessor: + return decl.AsGetAccessorDeclaration().Body != nil + case KindSetAccessor: + return decl.AsSetAccessorDeclaration().Body != nil + } + return false + + case KindVariableDeclaration, KindPropertyDeclaration: + // variable/property write if initializer present or is in catch clause + var hasInit bool + switch decl.Kind { + case KindVariableDeclaration: + hasInit = decl.AsVariableDeclaration().Initializer != nil + case KindPropertyDeclaration: + hasInit = decl.AsPropertyDeclaration().Initializer != nil + } + return hasInit || IsCatchClause(decl.Parent) + + case KindMethodSignature, KindPropertySignature, KindJSDocPropertyTag, KindJSDocParameterTag: + return false + + default: + // preserve TS behavior: crash on unexpected kinds + panic("Unhandled case in declarationIsWriteAccess") + } +} + +func IsArrayLiteralOrObjectLiteralDestructuringPattern(node *Node) bool { + if !(IsArrayLiteralExpression(node) || IsObjectLiteralExpression(node)) { + return false + } + parent := node.Parent + // [a,b,c] from: + // [a, b, c] = someExpression; + if IsBinaryExpression(parent) && parent.AsBinaryExpression().Left == node && parent.AsBinaryExpression().OperatorToken.Kind == KindEqualsToken { + return true + } + // [a, b, c] from: + // for([a, b, c] of expression) + if IsForOfStatement(parent) && parent.Initializer() == node { + return true + } + // {x, a: {a, b, c} } = someExpression + if IsPropertyAssignment(parent) { + return IsArrayLiteralOrObjectLiteralDestructuringPattern(parent.Parent) + } + // [a, b, c] of + // [x, [a, b, c] ] = someExpression + return IsArrayLiteralOrObjectLiteralDestructuringPattern(parent) +} + +func accessKind(node *Node) AccessKind { + parent := node.Parent + switch parent.Kind { + case KindParenthesizedExpression: + return accessKind(parent) + case KindPrefixUnaryExpression: + operator := parent.AsPrefixUnaryExpression().Operator + if operator == KindPlusPlusToken || operator == KindMinusMinusToken { + return AccessKindReadWrite + } + return AccessKindRead + case KindPostfixUnaryExpression: + operator := parent.AsPostfixUnaryExpression().Operator + if operator == KindPlusPlusToken || operator == KindMinusMinusToken { + return AccessKindReadWrite + } + return AccessKindRead + case KindBinaryExpression: + if parent.AsBinaryExpression().Left == node { + operator := parent.AsBinaryExpression().OperatorToken + if IsAssignmentOperator(operator.Kind) { + if operator.Kind == KindEqualsToken { + return AccessKindWrite + } + return AccessKindReadWrite + } + } + return AccessKindRead + case KindPropertyAccessExpression: + if parent.AsPropertyAccessExpression().Name() != node { + return AccessKindRead + } + return accessKind(parent) + case KindPropertyAssignment: + parentAccess := accessKind(parent.Parent) + // In `({ x: varname }) = { x: 1 }`, the left `x` is a read, the right `x` is a write. + if node == parent.AsPropertyAssignment().Name() { + return reverseAccessKind(parentAccess) + } + return parentAccess + case KindShorthandPropertyAssignment: + // Assume it's the local variable being accessed, since we don't check public properties for --noUnusedLocals. + if node == parent.AsShorthandPropertyAssignment().ObjectAssignmentInitializer { + return AccessKindRead + } + return accessKind(parent.Parent) + case KindArrayLiteralExpression: + return accessKind(parent) + case KindForInStatement, KindForOfStatement: + if node == parent.AsForInOrOfStatement().Initializer { + return AccessKindWrite + } + return AccessKindRead + } + return AccessKindRead +} + +func reverseAccessKind(a AccessKind) AccessKind { + switch a { + case AccessKindRead: + return AccessKindWrite + case AccessKindWrite: + return AccessKindRead + case AccessKindReadWrite: + return AccessKindReadWrite + } + panic("Unhandled case in reverseAccessKind") +} + +type AccessKind int32 + +const ( + AccessKindRead AccessKind = iota // Only reads from a variable + AccessKindWrite // Only writes to a variable without ever reading it. E.g.: `x=1;`. + AccessKindReadWrite // Reads from and writes to a variable. E.g.: `f(x++);`, `x/=1`. +) + +// DeclarationBase + +type DeclarationBase struct { + Symbol *Symbol // Symbol declared by node (initialized by binding) +} + +func (node *DeclarationBase) DeclarationData() *DeclarationBase { return node } + +func IsDeclarationNode(node *Node) bool { + return node.DeclarationData() != nil +} + +// ExportableBase + +type ExportableBase struct { + LocalSymbol *Symbol // Local symbol declared by node (initialized by binding only for exported nodes) +} + +func (node *ExportableBase) ExportableData() *ExportableBase { return node } + +// ModifiersBase + +type ModifiersBase struct { + modifiers *ModifierList +} + +func (node *ModifiersBase) Modifiers() *ModifierList { return node.modifiers } + +// LocalsContainerBase + +type LocalsContainerBase struct { + Locals SymbolTable // Locals associated with node (initialized by binding) + NextContainer *Node // Next container in declaration order (initialized by binding) +} + +func (node *LocalsContainerBase) LocalsContainerData() *LocalsContainerBase { return node } + +func IsLocalsContainer(node *Node) bool { + return node.LocalsContainerData() != nil +} + +// FunctionLikeBase + +type FunctionLikeBase struct { + LocalsContainerBase + TypeParameters *NodeList // NodeList[*TypeParameterDeclarationNode]. Optional + Parameters *NodeList // NodeList[*ParameterDeclarationNode] + Type *TypeNode // Optional + FullSignature *TypeNode // Type that applies to the whole function; should not be set if Type is set or if Parameters have types set. +} + +func (node *FunctionLikeBase) LocalsContainerData() *LocalsContainerBase { + return &node.LocalsContainerBase +} +func (node *FunctionLikeBase) FunctionLikeData() *FunctionLikeBase { return node } + +// BodyBase + +type BodyBase struct { + AsteriskToken *TokenNode + Body *BlockOrExpression // Optional, can be Expression only in arrow functions + EndFlowNode *FlowNode +} + +func (node *BodyBase) BodyData() *BodyBase { return node } + +// FunctionLikeWithBodyBase + +type FunctionLikeWithBodyBase struct { + FunctionLikeBase + BodyBase +} + +func (node *FunctionLikeWithBodyBase) LocalsContainerData() *LocalsContainerBase { + return &node.LocalsContainerBase +} + +func (node *FunctionLikeWithBodyBase) FunctionLikeData() *FunctionLikeBase { + return &node.FunctionLikeBase +} +func (node *FunctionLikeWithBodyBase) BodyData() *BodyBase { return &node.BodyBase } + +// FlowNodeBase + +type FlowNodeBase struct { + FlowNode *FlowNode +} + +func (node *FlowNodeBase) FlowNodeData() *FlowNodeBase { return node } + +// if you provide nil for file, this code will walk to the root of the tree to find the file +func (node *Node) JSDoc(file *SourceFile) []*Node { + if node.Flags&NodeFlagsHasJSDoc == 0 { + return nil + } + if file == nil { + file = GetSourceFileOfNode(node) + if file == nil { + return nil + } + } + if jsdocs, ok := file.jsdocCache[node]; ok { + return jsdocs + } + return nil +} + +// compositeNodeBase + +// A composite node is a node that contains a complex subtree. This struct is intended to be +// embedded in a node that requires caching for its subtree facts. +type compositeNodeBase struct { + facts atomic.Uint32 // caches the SubtreeFacts for this node and its subtree +} + +func (node *compositeNodeBase) subtreeFactsWorker(self nodeData) SubtreeFacts { + // computeSubtreeFacts() is expected to be idempotent, so races will only impact time, not correctness. + facts := SubtreeFacts(node.facts.Load()) + if facts&SubtreeFactsComputed == 0 { + facts |= self.computeSubtreeFacts() | SubtreeFactsComputed + node.facts.Store(uint32(facts)) + } + return facts &^ SubtreeFactsComputed +} + +func (node *compositeNodeBase) computeSubtreeFacts() SubtreeFacts { + // This method must be implemented by the concrete node type. + panic("not implemented") +} + +// typeSyntaxBase + +// A "type-syntax" node is a node whose subtree may only consist of TypeScript syntax. This struct is intended to be +// embedded in a node that only ever returns `SubtreeContainsTypeScript` for its subtree facts. +type typeSyntaxBase struct{} + +func (node *typeSyntaxBase) computeSubtreeFacts() SubtreeFacts { return SubtreeContainsTypeScript } +func (node *typeSyntaxBase) propagateSubtreeFacts() SubtreeFacts { return SubtreeContainsTypeScript } + +// Token + +type Token struct { + NodeBase +} + +func (f *NodeFactory) NewToken(kind Kind) *Node { + return f.newNode(kind, f.tokenPool.New()) +} + +func (node *Token) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewToken(node.Kind), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *Token) computeSubtreeFacts() SubtreeFacts { + switch node.Kind { + case KindUsingKeyword: + return SubtreeContainsUsing + case KindPublicKeyword, + KindPrivateKeyword, + KindProtectedKeyword, + KindReadonlyKeyword, + KindAbstractKeyword, + KindDeclareKeyword, + KindConstKeyword, + KindAnyKeyword, + KindNumberKeyword, + KindBigIntKeyword, + KindNeverKeyword, + KindObjectKeyword, + KindInKeyword, + KindOutKeyword, + KindOverrideKeyword, + KindStringKeyword, + KindBooleanKeyword, + KindSymbolKeyword, + KindVoidKeyword, + KindUnknownKeyword, + KindUndefinedKeyword, // `undefined` is an Identifier in the expression case. + KindExportKeyword: // `export` is TypeScript syntax in a namespace + return SubtreeContainsTypeScript + case KindAccessorKeyword: + return SubtreeContainsClassFields + case KindAsteriskAsteriskToken, KindAsteriskAsteriskEqualsToken: + return SubtreeContainsExponentiationOperator + case KindQuestionQuestionToken: + return SubtreeContainsNullishCoalescing + case KindQuestionDotToken: + return SubtreeContainsOptionalChaining + case KindQuestionQuestionEqualsToken, KindBarBarEqualsToken, KindAmpersandAmpersandEqualsToken: + return SubtreeContainsLogicalAssignments + } + return SubtreeFactsNone +} + +// Identifier + +type Identifier struct { + ExpressionBase + FlowNodeBase + Text string +} + +func (f *NodeFactory) NewIdentifier(text string) *Node { + data := f.identifierPool.New() + data.Text = text + f.textCount++ + return f.newNode(KindIdentifier, data) +} + +func (node *Identifier) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewIdentifier(node.Text), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *Identifier) SubtreeFacts() SubtreeFacts { + return SubtreeContainsIdentifier +} + +func IsIdentifier(node *Node) bool { + return node.Kind == KindIdentifier +} + +// PrivateIdentifier + +type PrivateIdentifier struct { + ExpressionBase + Text string +} + +func (f *NodeFactory) NewPrivateIdentifier(text string) *Node { + data := &PrivateIdentifier{} + data.Text = text + f.textCount++ + return f.newNode(KindPrivateIdentifier, data) +} + +func (node *PrivateIdentifier) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewPrivateIdentifier(node.Text), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *PrivateIdentifier) computeSubtreeFacts() SubtreeFacts { + return SubtreeContainsClassFields +} + +func IsPrivateIdentifier(node *Node) bool { + return node.Kind == KindPrivateIdentifier +} + +// QualifiedName + +type QualifiedName struct { + NodeBase + FlowNodeBase + compositeNodeBase + Left *EntityName // EntityName + Right *IdentifierNode // IdentifierNode +} + +func (f *NodeFactory) NewQualifiedName(left *EntityName, right *IdentifierNode) *Node { + data := &QualifiedName{} + data.Left = left + data.Right = right + return f.newNode(KindQualifiedName, data) +} + +func (f *NodeFactory) UpdateQualifiedName(node *QualifiedName, left *EntityName, right *IdentifierNode) *Node { + if left != node.Left || right != node.Right { + return updateNode(f.NewQualifiedName(left, right), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *QualifiedName) ForEachChild(v Visitor) bool { + return visit(v, node.Left) || visit(v, node.Right) +} + +func (node *QualifiedName) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateQualifiedName(node, v.visitNode(node.Left), v.visitNode(node.Right)) +} + +func (node *QualifiedName) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewQualifiedName(node.Left, node.Right), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsQualifiedName(node *Node) bool { + return node.Kind == KindQualifiedName +} + +func (node *QualifiedName) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Left) | + propagateSubtreeFacts(node.Right) +} + +// TypeParameterDeclaration + +type TypeParameterDeclaration struct { + NodeBase + DeclarationBase + ModifiersBase + typeSyntaxBase + name *IdentifierNode // IdentifierNode + Constraint *TypeNode // TypeNode. Optional + Expression *Expression // Expression. Optional, for error recovery purposes + DefaultType *TypeNode // TypeNode. Optional +} + +func (f *NodeFactory) NewTypeParameterDeclaration(modifiers *ModifierList, name *IdentifierNode, constraint *TypeNode, defaultType *TypeNode) *Node { + data := f.typeParameterDeclarationPool.New() + data.modifiers = modifiers + data.name = name + data.Constraint = constraint + data.DefaultType = defaultType + return f.newNode(KindTypeParameter, data) +} + +func (f *NodeFactory) UpdateTypeParameterDeclaration(node *TypeParameterDeclaration, modifiers *ModifierList, name *IdentifierNode, constraint *TypeNode, defaultType *TypeNode) *Node { + if modifiers != node.modifiers || name != node.name || constraint != node.Constraint || defaultType != node.DefaultType { + return updateNode(f.NewTypeParameterDeclaration(modifiers, name, constraint, defaultType), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *TypeParameterDeclaration) ForEachChild(v Visitor) bool { + return visitModifiers(v, node.modifiers) || visit(v, node.name) || visit(v, node.Constraint) || visit(v, node.Expression) || visit(v, node.DefaultType) +} + +func (node *TypeParameterDeclaration) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateTypeParameterDeclaration(node, v.visitModifiers(node.modifiers), v.visitNode(node.name), v.visitNode(node.Constraint), v.visitNode(node.DefaultType)) +} + +func (node *TypeParameterDeclaration) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewTypeParameterDeclaration(node.Modifiers(), node.Name(), node.Constraint, node.DefaultType), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *TypeParameterDeclaration) Name() *DeclarationName { + return node.name +} + +func IsTypeParameterDeclaration(node *Node) bool { + return node.Kind == KindTypeParameter +} + +// ComputedPropertyName + +type ComputedPropertyName struct { + NodeBase + compositeNodeBase + Expression *Expression // Expression +} + +func (f *NodeFactory) NewComputedPropertyName(expression *Expression) *Node { + data := &ComputedPropertyName{} + data.Expression = expression + return f.newNode(KindComputedPropertyName, data) +} + +func (f *NodeFactory) UpdateComputedPropertyName(node *ComputedPropertyName, expression *Expression) *Node { + if expression != node.Expression { + return updateNode(f.NewComputedPropertyName(expression), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ComputedPropertyName) ForEachChild(v Visitor) bool { + return visit(v, node.Expression) +} + +func (node *ComputedPropertyName) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateComputedPropertyName(node, v.visitNode(node.Expression)) +} + +func (node *ComputedPropertyName) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewComputedPropertyName(node.Expression), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *ComputedPropertyName) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) +} + +func IsComputedPropertyName(node *Node) bool { + return node.Kind == KindComputedPropertyName +} + +// Modifier + +func (f *NodeFactory) NewModifier(kind Kind) *Node { + return f.NewToken(kind) +} + +// Decorator + +type Decorator struct { + NodeBase + compositeNodeBase + Expression *LeftHandSideExpression // LeftHandSideExpression +} + +func (f *NodeFactory) NewDecorator(expression *LeftHandSideExpression) *Node { + data := &Decorator{} + data.Expression = expression + return f.newNode(KindDecorator, data) +} + +func (f *NodeFactory) UpdateDecorator(node *Decorator, expression *Expression) *Node { + if expression != node.Expression { + return updateNode(f.NewDecorator(expression), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *Decorator) ForEachChild(v Visitor) bool { + return visit(v, node.Expression) +} + +func (node *Decorator) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateDecorator(node, v.visitNode(node.Expression)) +} + +func (node *Decorator) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewDecorator(node.Expression), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *Decorator) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) | + SubtreeContainsTypeScript | // Decorator metadata + SubtreeContainsDecorators // legacy or ES decorators +} + +func IsDecorator(node *Node) bool { + return node.Kind == KindDecorator +} + +// StatementBase + +type StatementBase struct { + NodeBase + FlowNodeBase +} + +// EmptyStatement + +type EmptyStatement struct { + StatementBase +} + +func (f *NodeFactory) NewEmptyStatement() *Node { + return f.newNode(KindEmptyStatement, &EmptyStatement{}) +} + +func (node *EmptyStatement) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewEmptyStatement(), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsEmptyStatement(node *Node) bool { + return node.Kind == KindEmptyStatement +} + +// IfStatement + +type IfStatement struct { + StatementBase + compositeNodeBase + Expression *Expression // Expression + ThenStatement *Statement // Statement + ElseStatement *Statement // Statement. Optional +} + +func (f *NodeFactory) NewIfStatement(expression *Expression, thenStatement *Statement, elseStatement *Statement) *Node { + data := f.ifStatementPool.New() + data.Expression = expression + data.ThenStatement = thenStatement + data.ElseStatement = elseStatement + return f.newNode(KindIfStatement, data) +} + +func (f *NodeFactory) UpdateIfStatement(node *IfStatement, expression *Expression, thenStatement *Statement, elseStatement *Statement) *Node { + if expression != node.Expression || thenStatement != node.ThenStatement || elseStatement != node.ElseStatement { + return updateNode(f.NewIfStatement(expression, thenStatement, elseStatement), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *IfStatement) ForEachChild(v Visitor) bool { + return visit(v, node.Expression) || visit(v, node.ThenStatement) || visit(v, node.ElseStatement) +} + +func (node *IfStatement) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateIfStatement(node, v.visitNode(node.Expression), v.visitEmbeddedStatement(node.ThenStatement), v.visitEmbeddedStatement(node.ElseStatement)) +} + +func (node *IfStatement) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewIfStatement(node.Expression, node.ThenStatement, node.ElseStatement), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *IfStatement) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) | + propagateSubtreeFacts(node.ThenStatement) | + propagateSubtreeFacts(node.ElseStatement) +} + +func IsIfStatement(node *Node) bool { + return node.Kind == KindIfStatement +} + +// DoStatement + +type DoStatement struct { + StatementBase + compositeNodeBase + Statement *Statement // Statement + Expression *Expression // Expression +} + +func (f *NodeFactory) NewDoStatement(statement *Statement, expression *Expression) *Node { + data := &DoStatement{} + data.Statement = statement + data.Expression = expression + return f.newNode(KindDoStatement, data) +} + +func (f *NodeFactory) UpdateDoStatement(node *DoStatement, statement *Statement, expression *Expression) *Node { + if statement != node.Statement || expression != node.Expression { + return updateNode(f.NewDoStatement(statement, expression), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *DoStatement) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateDoStatement(node, v.visitIterationBody(node.Statement), v.visitNode(node.Expression)) +} + +func (node *DoStatement) ForEachChild(v Visitor) bool { + return visit(v, node.Statement) || visit(v, node.Expression) +} + +func (node *DoStatement) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewDoStatement(node.Statement, node.Expression), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *DoStatement) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Statement) | + propagateSubtreeFacts(node.Expression) +} + +// WhileStatement + +type WhileStatement struct { + StatementBase + compositeNodeBase + Expression *Expression // Expression + Statement *Statement // Statement +} + +func (f *NodeFactory) NewWhileStatement(expression *Expression, statement *Statement) *Node { + data := &WhileStatement{} + data.Expression = expression + data.Statement = statement + return f.newNode(KindWhileStatement, data) +} + +func (f *NodeFactory) UpdateWhileStatement(node *WhileStatement, expression *Expression, statement *Statement) *Node { + if expression != node.Expression || statement != node.Statement { + return updateNode(f.NewWhileStatement(expression, statement), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *WhileStatement) ForEachChild(v Visitor) bool { + return visit(v, node.Expression) || visit(v, node.Statement) +} + +func (node *WhileStatement) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateWhileStatement(node, v.visitNode(node.Expression), v.visitIterationBody(node.Statement)) +} + +func (node *WhileStatement) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewWhileStatement(node.Expression, node.Statement), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *WhileStatement) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) | propagateSubtreeFacts(node.Statement) +} + +// ForStatement + +type ForStatement struct { + StatementBase + LocalsContainerBase + compositeNodeBase + Initializer *ForInitializer // ForInitializer. Optional + Condition *Expression // Expression. Optional + Incrementor *Expression // Expression. Optional + Statement *Statement // Statement +} + +func (f *NodeFactory) NewForStatement(initializer *ForInitializer, condition *Expression, incrementor *Expression, statement *Statement) *Node { + data := &ForStatement{} + data.Initializer = initializer + data.Condition = condition + data.Incrementor = incrementor + data.Statement = statement + return f.newNode(KindForStatement, data) +} + +func (f *NodeFactory) UpdateForStatement(node *ForStatement, initializer *ForInitializer, condition *Expression, incrementor *Expression, statement *Statement) *Node { + if initializer != node.Initializer || condition != node.Condition || incrementor != node.Incrementor || statement != node.Statement { + return updateNode(f.NewForStatement(initializer, condition, incrementor, statement), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ForStatement) ForEachChild(v Visitor) bool { + return visit(v, node.Initializer) || visit(v, node.Condition) || visit(v, node.Incrementor) || visit(v, node.Statement) +} + +func (node *ForStatement) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateForStatement(node, v.visitNode(node.Initializer), v.visitNode(node.Condition), v.visitNode(node.Incrementor), v.visitIterationBody(node.Statement)) +} + +func (node *ForStatement) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewForStatement(node.Initializer, node.Expression(), node.Incrementor, node.Statement), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *ForStatement) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Initializer) | + propagateSubtreeFacts(node.Condition) | + propagateSubtreeFacts(node.Incrementor) | + propagateSubtreeFacts(node.Statement) +} + +func IsForStatement(node *Node) bool { + return node.Kind == KindForStatement +} + +// ForInOrOfStatement + +type ForInOrOfStatement struct { + StatementBase + LocalsContainerBase + compositeNodeBase + AwaitModifier *TokenNode // TokenNode. Optional + Initializer *ForInitializer // ForInitializer + Expression *Expression // Expression + Statement *Statement // Statement +} + +func (f *NodeFactory) NewForInOrOfStatement(kind Kind, awaitModifier *TokenNode, initializer *ForInitializer, expression *Expression, statement *Statement) *Node { + data := &ForInOrOfStatement{} + data.AwaitModifier = awaitModifier + data.Initializer = initializer + data.Expression = expression + data.Statement = statement + return f.newNode(kind, data) +} + +func (f *NodeFactory) UpdateForInOrOfStatement(node *ForInOrOfStatement, awaitModifier *TokenNode, initializer *ForInitializer, expression *Expression, statement *Statement) *Node { + if awaitModifier != node.AwaitModifier || initializer != node.Initializer || expression != node.Expression || statement != node.Statement { + return updateNode(f.NewForInOrOfStatement(node.AsNode().Kind, awaitModifier, initializer, expression, statement), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ForInOrOfStatement) ForEachChild(v Visitor) bool { + return visit(v, node.AwaitModifier) || visit(v, node.Initializer) || visit(v, node.Expression) || visit(v, node.Statement) +} + +func (node *ForInOrOfStatement) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateForInOrOfStatement(node, v.visitToken(node.AwaitModifier), v.visitNode(node.Initializer), v.visitNode(node.Expression), v.visitIterationBody(node.Statement)) +} + +func (node *ForInOrOfStatement) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewForInOrOfStatement(node.Kind, node.AwaitModifier, node.Initializer, node.Expression, node.Statement), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *ForInOrOfStatement) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Initializer) | + propagateSubtreeFacts(node.Expression) | + propagateSubtreeFacts(node.Statement) | + core.IfElse(node.AwaitModifier != nil, SubtreeContainsForAwaitOrAsyncGenerator, SubtreeFactsNone) +} + +func IsForInStatement(node *Node) bool { + return node.Kind == KindForInStatement +} + +func IsForOfStatement(node *Node) bool { + return node.Kind == KindForOfStatement +} + +func IsForInOrOfStatement(node *Node) bool { + return IsForInStatement(node) || IsForOfStatement(node) +} + +// BreakStatement + +type BreakStatement struct { + StatementBase + Label *IdentifierNode // IdentifierNode. Optional +} + +func (f *NodeFactory) NewBreakStatement(label *IdentifierNode) *Node { + data := &BreakStatement{} + data.Label = label + return f.newNode(KindBreakStatement, data) +} + +func (f *NodeFactory) UpdateBreakStatement(node *BreakStatement, label *IdentifierNode) *Node { + if label != node.Label { + return updateNode(f.NewBreakStatement(label), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *BreakStatement) ForEachChild(v Visitor) bool { + return visit(v, node.Label) +} + +func (node *BreakStatement) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateBreakStatement(node, v.visitNode(node.Label)) +} + +func (node *BreakStatement) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewBreakStatement(node.Label), node.AsNode(), f.AsNodeFactory().hooks) +} + +// ContinueStatement + +type ContinueStatement struct { + StatementBase + Label *IdentifierNode // IdentifierNode. Optional +} + +func (f *NodeFactory) NewContinueStatement(label *IdentifierNode) *Node { + data := &ContinueStatement{} + data.Label = label + return f.newNode(KindContinueStatement, data) +} + +func (f *NodeFactory) UpdateContinueStatement(node *ContinueStatement, label *IdentifierNode) *Node { + if label != node.Label { + return updateNode(f.NewContinueStatement(label), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ContinueStatement) ForEachChild(v Visitor) bool { + return visit(v, node.Label) +} + +func (node *ContinueStatement) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateContinueStatement(node, v.visitNode(node.Label)) +} + +func (node *ContinueStatement) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewContinueStatement(node.Label), node.AsNode(), f.AsNodeFactory().hooks) +} + +// ReturnStatement + +type ReturnStatement struct { + StatementBase + compositeNodeBase + Expression *Expression // Expression. Optional +} + +func (f *NodeFactory) NewReturnStatement(expression *Expression) *Node { + data := f.returnStatementPool.New() + data.Expression = expression + return f.newNode(KindReturnStatement, data) +} + +func (f *NodeFactory) UpdateReturnStatement(node *ReturnStatement, expression *Expression) *Node { + if expression != node.Expression { + return updateNode(f.NewReturnStatement(expression), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ReturnStatement) ForEachChild(v Visitor) bool { + return visit(v, node.Expression) +} + +func (node *ReturnStatement) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateReturnStatement(node, v.visitNode(node.Expression)) +} + +func (node *ReturnStatement) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewReturnStatement(node.Expression), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *ReturnStatement) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) +} + +func IsReturnStatement(node *Node) bool { + return node.Kind == KindReturnStatement +} + +// WithStatement + +type WithStatement struct { + StatementBase + compositeNodeBase + Expression *Expression // Expression + Statement *Statement // Statement +} + +func (f *NodeFactory) NewWithStatement(expression *Expression, statement *Statement) *Node { + data := &WithStatement{} + data.Expression = expression + data.Statement = statement + return f.newNode(KindWithStatement, data) +} + +func (f *NodeFactory) UpdateWithStatement(node *WithStatement, expression *Expression, statement *Statement) *Node { + if expression != node.Expression || statement != node.Statement { + return updateNode(f.NewWithStatement(expression, statement), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *WithStatement) ForEachChild(v Visitor) bool { + return visit(v, node.Expression) || visit(v, node.Statement) +} + +func (node *WithStatement) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateWithStatement(node, v.visitNode(node.Expression), v.visitEmbeddedStatement(node.Statement)) +} + +func (node *WithStatement) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewWithStatement(node.Expression, node.Statement), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *WithStatement) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) | propagateSubtreeFacts(node.Statement) +} + +// SwitchStatement + +type SwitchStatement struct { + StatementBase + compositeNodeBase + Expression *Expression // Expression + CaseBlock *CaseBlockNode // CaseBlockNode +} + +func (f *NodeFactory) NewSwitchStatement(expression *Expression, caseBlock *CaseBlockNode) *Node { + data := &SwitchStatement{} + data.Expression = expression + data.CaseBlock = caseBlock + return f.newNode(KindSwitchStatement, data) +} + +func (f *NodeFactory) UpdateSwitchStatement(node *SwitchStatement, expression *Expression, caseBlock *CaseBlockNode) *Node { + if expression != node.Expression || caseBlock != node.CaseBlock { + return updateNode(f.NewSwitchStatement(expression, caseBlock), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *SwitchStatement) ForEachChild(v Visitor) bool { + return visit(v, node.Expression) || visit(v, node.CaseBlock) +} + +func (node *SwitchStatement) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateSwitchStatement(node, v.visitNode(node.Expression), v.visitNode(node.CaseBlock)) +} + +func (node *SwitchStatement) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewSwitchStatement(node.Expression, node.CaseBlock), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *SwitchStatement) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) | + propagateSubtreeFacts(node.CaseBlock) +} + +func IsSwitchStatement(node *Node) bool { + return node.Kind == KindSwitchStatement +} + +// CaseBlock + +type CaseBlock struct { + NodeBase + LocalsContainerBase + compositeNodeBase + Clauses *NodeList // NodeList[*CaseOrDefaultClauseNode] +} + +func (f *NodeFactory) NewCaseBlock(clauses *NodeList) *Node { + data := &CaseBlock{} + data.Clauses = clauses + return f.newNode(KindCaseBlock, data) +} + +func (f *NodeFactory) UpdateCaseBlock(node *CaseBlock, clauses *CaseClausesList) *Node { + if clauses != node.Clauses { + return updateNode(f.NewCaseBlock(clauses), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *CaseBlock) ForEachChild(v Visitor) bool { + return visitNodeList(v, node.Clauses) +} + +func (node *CaseBlock) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateCaseBlock(node, v.visitNodes(node.Clauses)) +} + +func (node *CaseBlock) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewCaseBlock(node.Clauses), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *CaseBlock) computeSubtreeFacts() SubtreeFacts { + return propagateNodeListSubtreeFacts(node.Clauses, propagateSubtreeFacts) +} + +// CaseOrDefaultClause + +type CaseOrDefaultClause struct { + NodeBase + compositeNodeBase + Expression *Expression // Expression. nil in default clause + Statements *NodeList // NodeList[*Statement] + FallthroughFlowNode *FlowNode +} + +func (f *NodeFactory) NewCaseOrDefaultClause(kind Kind, expression *Expression, statements *NodeList) *Node { + data := &CaseOrDefaultClause{} + data.Expression = expression + data.Statements = statements + return f.newNode(kind, data) +} + +func (f *NodeFactory) UpdateCaseOrDefaultClause(node *CaseOrDefaultClause, expression *Expression, statements *StatementList) *Node { + if expression != node.Expression || statements != node.Statements { + return updateNode(f.NewCaseOrDefaultClause(node.Kind, expression, statements), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *CaseOrDefaultClause) ForEachChild(v Visitor) bool { + return visit(v, node.Expression) || visitNodeList(v, node.Statements) +} + +func (node *CaseOrDefaultClause) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateCaseOrDefaultClause(node, v.visitNode(node.Expression), v.visitNodes(node.Statements)) +} + +func (node *CaseOrDefaultClause) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewCaseOrDefaultClause(node.Kind, node.Expression, node.Statements), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *CaseOrDefaultClause) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) | propagateNodeListSubtreeFacts(node.Statements, propagateSubtreeFacts) +} + +func IsCaseClause(node *Node) bool { + return node.Kind == KindCaseClause +} + +func IsDefaultClause(node *Node) bool { + return node.Kind == KindDefaultClause +} + +// ThrowStatement + +type ThrowStatement struct { + StatementBase + compositeNodeBase + Expression *Expression // Expression +} + +func (f *NodeFactory) NewThrowStatement(expression *Expression) *Node { + data := &ThrowStatement{} + data.Expression = expression + return f.newNode(KindThrowStatement, data) +} + +func (f *NodeFactory) UpdateThrowStatement(node *ThrowStatement, expression *Expression) *Node { + if expression != node.Expression { + return updateNode(f.NewThrowStatement(expression), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ThrowStatement) ForEachChild(v Visitor) bool { + return visit(v, node.Expression) +} + +func (node *ThrowStatement) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateThrowStatement(node, v.visitNode(node.Expression)) +} + +func (node *ThrowStatement) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewThrowStatement(node.Expression), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *ThrowStatement) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) +} + +func IsThrowStatement(node *Node) bool { + return node.Kind == KindThrowStatement +} + +// TryStatement + +type TryStatement struct { + StatementBase + compositeNodeBase + TryBlock *BlockNode // BlockNode + CatchClause *CatchClauseNode // CatchClauseNode. Optional + FinallyBlock *BlockNode // BlockNode. Optional +} + +func (f *NodeFactory) NewTryStatement(tryBlock *BlockNode, catchClause *CatchClauseNode, finallyBlock *BlockNode) *Node { + data := &TryStatement{} + data.TryBlock = tryBlock + data.CatchClause = catchClause + data.FinallyBlock = finallyBlock + return f.newNode(KindTryStatement, data) +} + +func (f *NodeFactory) UpdateTryStatement(node *TryStatement, tryBlock *BlockNode, catchClause *CatchClauseNode, finallyBlock *BlockNode) *Node { + if tryBlock != node.TryBlock || catchClause != node.CatchClause || finallyBlock != node.FinallyBlock { + return updateNode(f.NewTryStatement(tryBlock, catchClause, finallyBlock), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *TryStatement) ForEachChild(v Visitor) bool { + return visit(v, node.TryBlock) || visit(v, node.CatchClause) || visit(v, node.FinallyBlock) +} + +func (node *TryStatement) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateTryStatement(node, v.visitNode(node.TryBlock), v.visitNode(node.CatchClause), v.visitNode(node.FinallyBlock)) +} + +func (node *TryStatement) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewTryStatement(node.TryBlock, node.CatchClause, node.FinallyBlock), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *TryStatement) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.TryBlock) | + propagateSubtreeFacts(node.CatchClause) | + propagateSubtreeFacts(node.FinallyBlock) +} + +func IsTryStatement(node *Node) bool { + return node.Kind == KindTryStatement +} + +// CatchClause + +type CatchClause struct { + NodeBase + LocalsContainerBase + compositeNodeBase + VariableDeclaration *VariableDeclarationNode // VariableDeclarationNode. Optional + Block *BlockNode // BlockNode +} + +func (f *NodeFactory) NewCatchClause(variableDeclaration *VariableDeclarationNode, block *BlockNode) *Node { + data := &CatchClause{} + data.VariableDeclaration = variableDeclaration + data.Block = block + return f.newNode(KindCatchClause, data) +} + +func (f *NodeFactory) UpdateCatchClause(node *CatchClause, variableDeclaration *VariableDeclarationNode, block *BlockNode) *Node { + if variableDeclaration != node.VariableDeclaration || block != node.Block { + return updateNode(f.NewCatchClause(variableDeclaration, block), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *CatchClause) ForEachChild(v Visitor) bool { + return visit(v, node.VariableDeclaration) || visit(v, node.Block) +} + +func (node *CatchClause) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateCatchClause(node, v.visitNode(node.VariableDeclaration), v.visitNode(node.Block)) +} + +func (node *CatchClause) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewCatchClause(node.VariableDeclaration, node.Block), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *CatchClause) computeSubtreeFacts() SubtreeFacts { + res := propagateSubtreeFacts(node.VariableDeclaration) | + propagateSubtreeFacts(node.Block) + if node.VariableDeclaration == nil { + res |= SubtreeContainsMissingCatchClauseVariable + } + return res +} + +func (node *CatchClause) propagateSubtreeFacts() SubtreeFacts { + return node.SubtreeFacts() & ^SubtreeExclusionsCatchClause +} + +func IsCatchClause(node *Node) bool { + return node.Kind == KindCatchClause +} + +// DebuggerStatement + +type DebuggerStatement struct { + StatementBase +} + +func (f *NodeFactory) NewDebuggerStatement() *Node { + return f.newNode(KindDebuggerStatement, &DebuggerStatement{}) +} + +func (node *DebuggerStatement) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewDebuggerStatement(), node.AsNode(), f.AsNodeFactory().hooks) +} + +// LabeledStatement + +type LabeledStatement struct { + StatementBase + Label *IdentifierNode // IdentifierNode + Statement *Statement // Statement +} + +func (f *NodeFactory) NewLabeledStatement(label *IdentifierNode, statement *Statement) *Node { + data := &LabeledStatement{} + data.Label = label + data.Statement = statement + return f.newNode(KindLabeledStatement, data) +} + +func (f *NodeFactory) UpdateLabeledStatement(node *LabeledStatement, label *IdentifierNode, statement *Statement) *Node { + if label != node.Label || statement != node.Statement { + return updateNode(f.NewLabeledStatement(label, statement), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *LabeledStatement) ForEachChild(v Visitor) bool { + return visit(v, node.Label) || visit(v, node.Statement) +} + +func (node *LabeledStatement) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateLabeledStatement(node, v.visitNode(node.Label), v.visitEmbeddedStatement(node.Statement)) +} + +func (node *LabeledStatement) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewLabeledStatement(node.Label, node.Statement), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *LabeledStatement) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Statement) +} + +func IsLabeledStatement(node *Node) bool { + return node.Kind == KindLabeledStatement +} + +// ExpressionStatement + +type ExpressionStatement struct { + StatementBase + Expression *Expression // Expression +} + +func (f *NodeFactory) NewExpressionStatement(expression *Expression) *Node { + data := f.expressionStatementPool.New() + data.Expression = expression + return f.newNode(KindExpressionStatement, data) +} + +func (f *NodeFactory) UpdateExpressionStatement(node *ExpressionStatement, expression *Expression) *Node { + if expression != node.Expression { + return updateNode(f.NewExpressionStatement(expression), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ExpressionStatement) ForEachChild(v Visitor) bool { + return visit(v, node.Expression) +} + +func (node *ExpressionStatement) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateExpressionStatement(node, v.visitNode(node.Expression)) +} + +func (node *ExpressionStatement) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewExpressionStatement(node.Expression), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *ExpressionStatement) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) +} + +func IsExpressionStatement(node *Node) bool { + return node.Kind == KindExpressionStatement +} + +// Block + +type Block struct { + StatementBase + LocalsContainerBase + compositeNodeBase + Statements *NodeList // NodeList[*Statement] + Multiline bool +} + +func (f *NodeFactory) NewBlock(statements *NodeList, multiline bool) *Node { + data := f.blockPool.New() + data.Statements = statements + data.Multiline = multiline + return f.newNode(KindBlock, data) +} + +func (f *NodeFactory) UpdateBlock(node *Block, statements *StatementList) *Node { + if statements != node.Statements { + return updateNode(f.NewBlock(statements, node.Multiline), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *Block) ForEachChild(v Visitor) bool { + return visitNodeList(v, node.Statements) +} + +func (node *Block) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateBlock(node, v.visitNodes(node.Statements)) +} + +func (node *Block) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewBlock(node.Statements, node.Multiline), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *Block) computeSubtreeFacts() SubtreeFacts { + return propagateNodeListSubtreeFacts(node.Statements, propagateSubtreeFacts) +} + +func IsBlock(node *Node) bool { + return node.Kind == KindBlock +} + +// VariableStatement + +type VariableStatement struct { + StatementBase + ModifiersBase + compositeNodeBase + DeclarationList *VariableDeclarationListNode // VariableDeclarationListNode +} + +func (f *NodeFactory) NewVariableStatement(modifiers *ModifierList, declarationList *VariableDeclarationListNode) *Node { + data := f.variableStatementPool.New() + data.modifiers = modifiers + data.DeclarationList = declarationList + return f.newNode(KindVariableStatement, data) +} + +func (f *NodeFactory) UpdateVariableStatement(node *VariableStatement, modifiers *ModifierList, declarationList *VariableDeclarationListNode) *Node { + if modifiers != node.modifiers || declarationList != node.DeclarationList { + return updateNode(f.NewVariableStatement(modifiers, declarationList), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *VariableStatement) ForEachChild(v Visitor) bool { + return visitModifiers(v, node.modifiers) || visit(v, node.DeclarationList) +} + +func (node *VariableStatement) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateVariableStatement(node, v.visitModifiers(node.modifiers), v.visitNode(node.DeclarationList)) +} + +func (node *VariableStatement) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewVariableStatement(node.Modifiers(), node.DeclarationList), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *VariableStatement) computeSubtreeFacts() SubtreeFacts { + if node.modifiers != nil && node.modifiers.ModifierFlags&ModifierFlagsAmbient != 0 { + return SubtreeContainsTypeScript + } else { + return propagateModifierListSubtreeFacts(node.modifiers) | + propagateSubtreeFacts(node.DeclarationList) + } +} + +func IsVariableStatement(node *Node) bool { + return node.Kind == KindVariableStatement +} + +// VariableDeclaration + +type VariableDeclaration struct { + NodeBase + DeclarationBase + ExportableBase + compositeNodeBase + name *BindingName // BindingName + ExclamationToken *TokenNode // TokenNode. Optional + Type *TypeNode // TypeNode. Optional + Initializer *Expression // Expression. Optional +} + +func (f *NodeFactory) NewVariableDeclaration(name *BindingName, exclamationToken *TokenNode, typeNode *TypeNode, initializer *Expression) *Node { + data := f.variableDeclarationPool.New() + data.name = name + data.ExclamationToken = exclamationToken + data.Type = typeNode + data.Initializer = initializer + return f.newNode(KindVariableDeclaration, data) +} + +func (f *NodeFactory) UpdateVariableDeclaration(node *VariableDeclaration, name *BindingName, exclamationToken *TokenNode, typeNode *TypeNode, initializer *Expression) *Node { + if name != node.name || exclamationToken != node.ExclamationToken || typeNode != node.Type || initializer != node.Initializer { + return updateNode(f.NewVariableDeclaration(name, exclamationToken, typeNode, initializer), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *VariableDeclaration) ForEachChild(v Visitor) bool { + return visit(v, node.name) || visit(v, node.ExclamationToken) || visit(v, node.Type) || visit(v, node.Initializer) +} + +func (node *VariableDeclaration) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateVariableDeclaration(node, v.visitNode(node.name), v.visitToken(node.ExclamationToken), v.visitNode(node.Type), v.visitNode(node.Initializer)) +} + +func (node *VariableDeclaration) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewVariableDeclaration(node.Name(), node.ExclamationToken, node.Type, node.Initializer), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *VariableDeclaration) Name() *DeclarationName { + return node.name +} + +func (node *VariableDeclaration) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.name) | + propagateEraseableSyntaxSubtreeFacts(node.ExclamationToken) | + propagateEraseableSyntaxSubtreeFacts(node.Type) | + propagateSubtreeFacts(node.Initializer) +} + +func IsVariableDeclaration(node *Node) bool { + return node.Kind == KindVariableDeclaration +} + +// VariableDeclarationList + +type VariableDeclarationList struct { + NodeBase + compositeNodeBase + Declarations *NodeList // NodeList[*VariableDeclarationNode] +} + +func (f *NodeFactory) NewVariableDeclarationList(flags NodeFlags, declarations *NodeList) *Node { + data := f.variableDeclarationListPool.New() + data.Declarations = declarations + node := f.newNode(KindVariableDeclarationList, data) + node.Flags = flags + return node +} + +func (f *NodeFactory) UpdateVariableDeclarationList(node *VariableDeclarationList, declarations *VariableDeclarationNodeList) *Node { + if declarations != node.Declarations { + return updateNode(f.NewVariableDeclarationList(node.Flags, declarations), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *VariableDeclarationList) ForEachChild(v Visitor) bool { + return visitNodeList(v, node.Declarations) +} + +func (node *VariableDeclarationList) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateVariableDeclarationList(node, v.visitNodes(node.Declarations)) +} + +func (node *VariableDeclarationList) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewVariableDeclarationList(node.Flags, node.Declarations), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *VariableDeclarationList) computeSubtreeFacts() SubtreeFacts { + return propagateNodeListSubtreeFacts(node.Declarations, propagateSubtreeFacts) | + core.IfElse(node.Flags&NodeFlagsUsing != 0, SubtreeContainsUsing, SubtreeFactsNone) +} + +func (node *VariableDeclarationList) propagateSubtreeFacts() SubtreeFacts { + return node.SubtreeFacts() & ^SubtreeExclusionsVariableDeclarationList +} + +func IsVariableDeclarationList(node *Node) bool { + return node.Kind == KindVariableDeclarationList +} + +// BindingPattern (SyntaxBindObjectBindingPattern | KindArrayBindingPattern) + +type BindingPattern struct { + NodeBase + compositeNodeBase + Elements *NodeList // NodeList[*BindingElementNode] +} + +func (f *NodeFactory) NewBindingPattern(kind Kind, elements *NodeList) *Node { + data := &BindingPattern{} + data.Elements = elements + return f.newNode(kind, data) +} + +func (f *NodeFactory) UpdateBindingPattern(node *BindingPattern, elements *BindingElementList) *Node { + if elements != node.Elements { + return updateNode(f.NewBindingPattern(node.Kind, elements), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *BindingPattern) ForEachChild(v Visitor) bool { + return visitNodeList(v, node.Elements) +} + +func (node *BindingPattern) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateBindingPattern(node, v.visitNodes(node.Elements)) +} + +func (node *BindingPattern) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewBindingPattern(node.Kind, node.Elements), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *BindingPattern) computeSubtreeFacts() SubtreeFacts { + switch node.Kind { + case KindObjectBindingPattern: + return propagateNodeListSubtreeFacts(node.Elements, propagateObjectBindingElementSubtreeFacts) + case KindArrayBindingPattern: + return propagateNodeListSubtreeFacts(node.Elements, propagateBindingElementSubtreeFacts) + default: + return SubtreeFactsNone + } +} + +func (node *BindingPattern) propagateSubtreeFacts() SubtreeFacts { + return node.SubtreeFacts() & ^SubtreeExclusionsBindingPattern +} + +func IsObjectBindingPattern(node *Node) bool { + return node.Kind == KindObjectBindingPattern +} + +func IsArrayBindingPattern(node *Node) bool { + return node.Kind == KindArrayBindingPattern +} + +func IsBindingPattern(node *Node) bool { + return node.Kind == KindArrayBindingPattern || node.Kind == KindObjectBindingPattern +} + +// ParameterDeclaration + +type ParameterDeclaration struct { + NodeBase + DeclarationBase + ModifiersBase + compositeNodeBase + DotDotDotToken *TokenNode // TokenNode. Present on rest parameter + name *BindingName // BindingName. Declared parameter name + QuestionToken *TokenNode // TokenNode. Present on optional parameter + Type *TypeNode // TypeNode. Optional + Initializer *Expression // Expression. Optional +} + +func (f *NodeFactory) NewParameterDeclaration(modifiers *ModifierList, dotDotDotToken *TokenNode, name *BindingName, questionToken *TokenNode, typeNode *TypeNode, initializer *Expression) *Node { + data := f.parameterDeclarationPool.New() + data.modifiers = modifiers + data.DotDotDotToken = dotDotDotToken + data.name = name + data.QuestionToken = questionToken + data.Type = typeNode + data.Initializer = initializer + return f.newNode(KindParameter, data) +} + +func (f *NodeFactory) UpdateParameterDeclaration(node *ParameterDeclaration, modifiers *ModifierList, dotDotDotToken *TokenNode, name *BindingName, questionToken *TokenNode, typeNode *TypeNode, initializer *Expression) *Node { + if modifiers != node.modifiers || dotDotDotToken != node.DotDotDotToken || name != node.name || questionToken != node.QuestionToken || typeNode != node.Type || initializer != node.Initializer { + return updateNode(f.NewParameterDeclaration(modifiers, dotDotDotToken, name, questionToken, typeNode, initializer), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ParameterDeclaration) ForEachChild(v Visitor) bool { + return visitModifiers(v, node.modifiers) || visit(v, node.DotDotDotToken) || visit(v, node.name) || + visit(v, node.QuestionToken) || visit(v, node.Type) || visit(v, node.Initializer) +} + +func (node *ParameterDeclaration) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateParameterDeclaration(node, v.visitModifiers(node.modifiers), v.visitToken(node.DotDotDotToken), v.visitNode(node.name), v.visitToken(node.QuestionToken), v.visitNode(node.Type), v.visitNode(node.Initializer)) +} + +func (node *ParameterDeclaration) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewParameterDeclaration(node.Modifiers(), node.DotDotDotToken, node.Name(), node.QuestionToken, node.Type, node.Initializer), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *ParameterDeclaration) computeSubtreeFacts() SubtreeFacts { + if node.name != nil && IsThisIdentifier(node.name) { + return SubtreeContainsTypeScript + } else { + return propagateModifierListSubtreeFacts(node.modifiers) | + propagateSubtreeFacts(node.name) | + propagateEraseableSyntaxSubtreeFacts(node.QuestionToken) | + propagateEraseableSyntaxSubtreeFacts(node.Type) | + propagateSubtreeFacts(node.Initializer) + } +} + +func (node *ParameterDeclaration) propagateSubtreeFacts() SubtreeFacts { + return node.SubtreeFacts() & ^SubtreeExclusionsParameter +} + +func (node *ParameterDeclaration) Name() *DeclarationName { + return node.name +} + +func IsParameter(node *Node) bool { + return node.Kind == KindParameter +} + +// BindingElement + +type BindingElement struct { + NodeBase + DeclarationBase + ExportableBase + FlowNodeBase + compositeNodeBase + DotDotDotToken *TokenNode // TokenNode. Present on rest element (in object binding pattern) + PropertyName *PropertyName // PropertyName. Optional binding property name in object binding pattern + name *BindingName // BindingName. Optional (nil for missing element) + Initializer *Expression // Expression. Optional +} + +func (f *NodeFactory) NewBindingElement(dotDotDotToken *TokenNode, propertyName *PropertyName, name *BindingName, initializer *Expression) *Node { + data := &BindingElement{} + data.DotDotDotToken = dotDotDotToken + data.PropertyName = propertyName + data.name = name + data.Initializer = initializer + return f.newNode(KindBindingElement, data) +} + +func (f *NodeFactory) UpdateBindingElement(node *BindingElement, dotDotDotToken *TokenNode, propertyName *PropertyName, name *BindingName, initializer *Expression) *Node { + if dotDotDotToken != node.DotDotDotToken || propertyName != node.PropertyName || name != node.name || initializer != node.Initializer { + return updateNode(f.NewBindingElement(dotDotDotToken, propertyName, name, initializer), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *BindingElement) ForEachChild(v Visitor) bool { + return visit(v, node.DotDotDotToken) || visit(v, node.PropertyName) || visit(v, node.name) || visit(v, node.Initializer) +} + +func (node *BindingElement) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateBindingElement(node, v.visitToken(node.DotDotDotToken), v.visitNode(node.PropertyName), v.visitNode(node.name), v.visitNode(node.Initializer)) +} + +func (node *BindingElement) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewBindingElement(node.DotDotDotToken, node.PropertyName, node.Name(), node.Initializer), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *BindingElement) Name() *DeclarationName { + return node.name +} + +func (node *BindingElement) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.PropertyName) | + propagateSubtreeFacts(node.name) | + propagateSubtreeFacts(node.Initializer) | + core.IfElse(node.DotDotDotToken != nil, SubtreeContainsRestOrSpread, SubtreeFactsNone) +} + +func IsBindingElement(node *Node) bool { + return node.Kind == KindBindingElement +} + +// MissingDeclaration + +type MissingDeclaration struct { + StatementBase + DeclarationBase + ModifiersBase +} + +func (f *NodeFactory) NewMissingDeclaration(modifiers *ModifierList) *Node { + data := &MissingDeclaration{} + data.modifiers = modifiers + return f.newNode(KindMissingDeclaration, data) +} + +func (f *NodeFactory) UpdateMissingDeclaration(node *MissingDeclaration, modifiers *ModifierList) *Node { + if modifiers != node.modifiers { + return updateNode(f.NewMissingDeclaration(modifiers), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *MissingDeclaration) ForEachChild(v Visitor) bool { + return visitModifiers(v, node.modifiers) +} + +func (node *MissingDeclaration) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateMissingDeclaration(node, v.visitModifiers(node.modifiers)) +} + +func (node *MissingDeclaration) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewMissingDeclaration(node.Modifiers()), node.AsNode(), f.AsNodeFactory().hooks) +} + +// FunctionDeclaration + +type FunctionDeclaration struct { + StatementBase + DeclarationBase + ExportableBase + ModifiersBase + FunctionLikeWithBodyBase + compositeNodeBase + name *IdentifierNode // IdentifierNode + ReturnFlowNode *FlowNode +} + +func (f *NodeFactory) NewFunctionDeclaration(modifiers *ModifierList, asteriskToken *TokenNode, name *IdentifierNode, typeParameters *NodeList, parameters *NodeList, returnType *TypeNode, fullSignature *TypeNode, body *BlockNode) *Node { + data := f.functionDeclarationPool.New() + data.modifiers = modifiers + data.AsteriskToken = asteriskToken + data.name = name + data.TypeParameters = typeParameters + data.Parameters = parameters + data.Type = returnType + data.FullSignature = fullSignature + data.Body = body + return f.newNode(KindFunctionDeclaration, data) +} + +func (f *NodeFactory) UpdateFunctionDeclaration(node *FunctionDeclaration, modifiers *ModifierList, asteriskToken *TokenNode, name *IdentifierNode, typeParameters *TypeParameterList, parameters *ParameterList, returnType *TypeNode, fullSignature *TypeNode, body *BlockNode) *Node { + if modifiers != node.modifiers || asteriskToken != node.AsteriskToken || name != node.name || typeParameters != node.TypeParameters || parameters != node.Parameters || returnType != node.Type || fullSignature != node.FullSignature || body != node.Body { + return updateNode(f.NewFunctionDeclaration(modifiers, asteriskToken, name, typeParameters, parameters, returnType, fullSignature, body), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *FunctionDeclaration) ForEachChild(v Visitor) bool { + return visitModifiers(v, node.modifiers) || visit(v, node.AsteriskToken) || visit(v, node.name) || visitNodeList(v, node.TypeParameters) || + visitNodeList(v, node.Parameters) || visit(v, node.Type) || visit(v, node.FullSignature) || visit(v, node.Body) +} + +func (node *FunctionDeclaration) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateFunctionDeclaration(node, v.visitModifiers(node.modifiers), v.visitToken(node.AsteriskToken), v.visitNode(node.name), v.visitNodes(node.TypeParameters), v.visitParameters(node.Parameters), v.visitNode(node.Type), v.visitNode(node.FullSignature), v.visitFunctionBody(node.Body)) +} + +func (node *FunctionDeclaration) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewFunctionDeclaration(node.Modifiers(), node.AsteriskToken, node.Name(), node.TypeParameters, node.Parameters, node.Type, node.FullSignature, node.Body), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *FunctionDeclaration) Name() *DeclarationName { + return node.name +} + +func (node *FunctionDeclaration) computeSubtreeFacts() SubtreeFacts { + if node.Body == nil || node.ModifierFlags()&ModifierFlagsAmbient != 0 { + return SubtreeContainsTypeScript + } else { + isAsync := node.ModifierFlags()&ModifierFlagsAsync != 0 + isGenerator := node.AsteriskToken != nil + return propagateModifierListSubtreeFacts(node.modifiers) | + propagateSubtreeFacts(node.AsteriskToken) | + propagateSubtreeFacts(node.name) | + propagateEraseableSyntaxListSubtreeFacts(node.TypeParameters) | + propagateNodeListSubtreeFacts(node.Parameters, propagateSubtreeFacts) | + propagateEraseableSyntaxSubtreeFacts(node.Type) | + propagateEraseableSyntaxSubtreeFacts(node.FullSignature) | + propagateSubtreeFacts(node.Body) | + core.IfElse(isAsync && isGenerator, SubtreeContainsForAwaitOrAsyncGenerator, SubtreeFactsNone) | + core.IfElse(isAsync && !isGenerator, SubtreeContainsAnyAwait, SubtreeFactsNone) + } +} + +func (node *FunctionDeclaration) propagateSubtreeFacts() SubtreeFacts { + return node.SubtreeFacts() & ^SubtreeExclusionsFunction +} + +func IsFunctionDeclaration(node *Node) bool { + return node.Kind == KindFunctionDeclaration +} + +// ClassLikeDeclarationBase + +type ClassLikeBase struct { + DeclarationBase + ExportableBase + ModifiersBase + LocalsContainerBase + compositeNodeBase + name *IdentifierNode // IdentifierNode + TypeParameters *NodeList // NodeList[*TypeParameterDeclarationNode]. Optional + HeritageClauses *NodeList // NodeList[*HeritageClauseNode]. Optional + Members *NodeList // NodeList[*ClassElement] +} + +func (node *ClassLikeBase) ForEachChild(v Visitor) bool { + return visitModifiers(v, node.modifiers) || visit(v, node.name) || visitNodeList(v, node.TypeParameters) || + visitNodeList(v, node.HeritageClauses) || visitNodeList(v, node.Members) +} + +func (node *ClassLikeBase) Name() *DeclarationName { return node.name } +func (node *ClassLikeBase) ClassLikeData() *ClassLikeBase { return node } + +func (node *ClassLikeBase) computeSubtreeFacts() SubtreeFacts { + if node.modifiers != nil && node.modifiers.ModifierFlags&ModifierFlagsAmbient != 0 { + return SubtreeContainsTypeScript + } else { + return propagateModifierListSubtreeFacts(node.modifiers) | + propagateSubtreeFacts(node.name) | + propagateEraseableSyntaxListSubtreeFacts(node.TypeParameters) | + propagateNodeListSubtreeFacts(node.HeritageClauses, propagateSubtreeFacts) | + propagateNodeListSubtreeFacts(node.Members, propagateSubtreeFacts) + } +} + +// ClassDeclaration + +type ClassDeclaration struct { + StatementBase + ClassLikeBase +} + +func (f *NodeFactory) NewClassDeclaration(modifiers *ModifierList, name *IdentifierNode, typeParameters *NodeList, heritageClauses *NodeList, members *NodeList) *Node { + data := &ClassDeclaration{} + data.modifiers = modifiers + data.name = name + data.TypeParameters = typeParameters + data.HeritageClauses = heritageClauses + data.Members = members + return f.newNode(KindClassDeclaration, data) +} + +func (f *NodeFactory) UpdateClassDeclaration(node *ClassDeclaration, modifiers *ModifierList, name *IdentifierNode, typeParameters *TypeParameterList, heritageClauses *HeritageClauseList, members *ClassElementList) *Node { + if modifiers != node.modifiers || name != node.name || typeParameters != node.TypeParameters || heritageClauses != node.HeritageClauses || members != node.Members { + return updateNode(f.NewClassDeclaration(modifiers, name, typeParameters, heritageClauses, members), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ClassDeclaration) VisitEachChild(v *NodeVisitor) *Node { + modifiers := v.visitModifiers(node.modifiers) + name := v.visitNode(node.name) + typeParameters := v.visitNodes(node.TypeParameters) + heritageClauses := v.visitNodes(node.HeritageClauses) + if heritageClauses != nil && len(heritageClauses.Nodes) == 0 { + heritageClauses = nil + } + members := v.visitNodes(node.Members) + return v.Factory.UpdateClassDeclaration(node, modifiers, name, typeParameters, heritageClauses, members) +} + +func (node *ClassDeclaration) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewClassDeclaration(node.Modifiers(), node.Name(), node.TypeParameters, node.HeritageClauses, node.Members), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *ClassDeclaration) propagateSubtreeFacts() SubtreeFacts { + return node.SubtreeFacts() & ^SubtreeExclusionsClass +} + +func IsClassDeclaration(node *Node) bool { + return node.Kind == KindClassDeclaration +} + +// ClassExpression + +type ClassExpression struct { + ExpressionBase + ClassLikeBase +} + +func (f *NodeFactory) NewClassExpression(modifiers *ModifierList, name *IdentifierNode, typeParameters *NodeList, heritageClauses *NodeList, members *NodeList) *Node { + data := &ClassExpression{} + data.modifiers = modifiers + data.name = name + data.TypeParameters = typeParameters + data.HeritageClauses = heritageClauses + data.Members = members + return f.newNode(KindClassExpression, data) +} + +func (f *NodeFactory) UpdateClassExpression(node *ClassExpression, modifiers *ModifierList, name *IdentifierNode, typeParameters *TypeParameterList, heritageClauses *HeritageClauseList, members *ClassElementList) *Node { + if modifiers != node.modifiers || name != node.name || typeParameters != node.TypeParameters || heritageClauses != node.HeritageClauses || members != node.Members { + return updateNode(f.NewClassExpression(modifiers, name, typeParameters, heritageClauses, members), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ClassExpression) VisitEachChild(v *NodeVisitor) *Node { + modifiers := v.visitModifiers(node.modifiers) + name := v.visitNode(node.name) + typeParameters := v.visitNodes(node.TypeParameters) + heritageClauses := v.visitNodes(node.HeritageClauses) + if heritageClauses != nil && len(heritageClauses.Nodes) == 0 { + heritageClauses = nil + } + members := v.visitNodes(node.Members) + return v.Factory.UpdateClassExpression(node, modifiers, name, typeParameters, heritageClauses, members) +} + +func (node *ClassExpression) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewClassExpression(node.Modifiers(), node.Name(), node.TypeParameters, node.HeritageClauses, node.Members), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *ClassExpression) propagateSubtreeFacts() SubtreeFacts { + return node.SubtreeFacts() & ^SubtreeExclusionsClass +} + +func IsClassExpression(node *Node) bool { + return node.Kind == KindClassExpression +} + +// HeritageClause + +type HeritageClause struct { + NodeBase + compositeNodeBase + Token Kind + Types *NodeList // NodeList[*ExpressionWithTypeArgumentsNode] +} + +func (f *NodeFactory) NewHeritageClause(token Kind, types *NodeList) *Node { + data := f.heritageClausePool.New() + data.Token = token + data.Types = types + return f.newNode(KindHeritageClause, data) +} + +func (f *NodeFactory) UpdateHeritageClause(node *HeritageClause, types *ExpressionWithTypeArgumentsList) *Node { + if types != node.Types { + return updateNode(f.NewHeritageClause(node.Token, types), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *HeritageClause) ForEachChild(v Visitor) bool { + return visitNodeList(v, node.Types) +} + +func (node *HeritageClause) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateHeritageClause(node, v.visitNodes(node.Types)) +} + +func (node *HeritageClause) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewHeritageClause(node.Kind, node.Types), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *HeritageClause) computeSubtreeFacts() SubtreeFacts { + switch node.Token { + case KindExtendsKeyword: + return propagateNodeListSubtreeFacts(node.Types, propagateSubtreeFacts) + case KindImplementsKeyword: + return SubtreeContainsTypeScript + default: + return SubtreeFactsNone + } +} + +func IsHeritageClause(node *Node) bool { + return node.Kind == KindHeritageClause +} + +// InterfaceDeclaration + +type InterfaceDeclaration struct { + StatementBase + DeclarationBase + ExportableBase + ModifiersBase + typeSyntaxBase + name *IdentifierNode + TypeParameters *NodeList // NodeList[*TypeParameterDeclarationNode]. Optional + HeritageClauses *NodeList // NodeList[*HeritageClauseNode]. Optional + Members *NodeList // NodeList[*TypeElement] +} + +func (f *NodeFactory) NewInterfaceDeclaration(modifiers *ModifierList, name *IdentifierNode, typeParameters *NodeList, heritageClauses *NodeList, members *NodeList) *Node { + data := f.interfaceDeclarationPool.New() + data.modifiers = modifiers + data.name = name + data.TypeParameters = typeParameters + data.HeritageClauses = heritageClauses + data.Members = members + return f.newNode(KindInterfaceDeclaration, data) +} + +func (f *NodeFactory) UpdateInterfaceDeclaration(node *InterfaceDeclaration, modifiers *ModifierList, name *IdentifierNode, typeParameters *TypeParameterList, heritageClauses *HeritageClauseList, members *TypeElementList) *Node { + if modifiers != node.modifiers || name != node.name || typeParameters != node.TypeParameters || heritageClauses != node.HeritageClauses || members != node.Members { + return updateNode(f.NewInterfaceDeclaration(modifiers, name, typeParameters, heritageClauses, members), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *InterfaceDeclaration) ForEachChild(v Visitor) bool { + return visitModifiers(v, node.modifiers) || visit(v, node.name) || visitNodeList(v, node.TypeParameters) || + visitNodeList(v, node.HeritageClauses) || visitNodeList(v, node.Members) +} + +func (node *InterfaceDeclaration) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateInterfaceDeclaration(node, v.visitModifiers(node.modifiers), v.visitNode(node.name), v.visitNodes(node.TypeParameters), v.visitNodes(node.HeritageClauses), v.visitNodes(node.Members)) +} + +func (node *InterfaceDeclaration) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewInterfaceDeclaration(node.Modifiers(), node.Name(), node.TypeParameters, node.HeritageClauses, node.Members), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *InterfaceDeclaration) Name() *DeclarationName { return node.name } + +func IsInterfaceDeclaration(node *Node) bool { + return node.Kind == KindInterfaceDeclaration +} + +// TypeAliasDeclaration + +type TypeAliasDeclaration struct { + StatementBase + DeclarationBase + ExportableBase + ModifiersBase + LocalsContainerBase + typeSyntaxBase + name *IdentifierNode // IdentifierNode + TypeParameters *NodeList // NodeList[*TypeParameterDeclarationNode]. Optional + Type *TypeNode // TypeNode +} + +func (f *NodeFactory) newTypeAliasOrJSTypeAliasDeclaration(kind Kind, modifiers *ModifierList, name *IdentifierNode, typeParameters *NodeList, typeNode *TypeNode) *Node { + data := f.typeAliasDeclarationPool.New() + data.modifiers = modifiers + data.name = name + data.TypeParameters = typeParameters + data.Type = typeNode + return f.newNode(kind, data) +} + +func (f *NodeFactory) NewTypeAliasDeclaration(modifiers *ModifierList, name *IdentifierNode, typeParameters *NodeList, typeNode *TypeNode) *Node { + return f.newTypeAliasOrJSTypeAliasDeclaration(KindTypeAliasDeclaration, modifiers, name, typeParameters, typeNode) +} + +func (f *NodeFactory) UpdateTypeAliasDeclaration(node *TypeAliasDeclaration, modifiers *ModifierList, name *IdentifierNode, typeParameters *TypeParameterList, typeNode *TypeNode) *Node { + if modifiers != node.modifiers || name != node.name || typeParameters != node.TypeParameters || typeNode != node.Type { + return updateNode(f.newTypeAliasOrJSTypeAliasDeclaration(node.Kind, modifiers, name, typeParameters, typeNode), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *TypeAliasDeclaration) ForEachChild(v Visitor) bool { + return visitModifiers(v, node.modifiers) || visit(v, node.name) || visitNodeList(v, node.TypeParameters) || visit(v, node.Type) +} + +func (node *TypeAliasDeclaration) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateTypeAliasDeclaration(node, v.visitModifiers(node.modifiers), v.visitNode(node.name), v.visitNodes(node.TypeParameters), v.visitNode(node.Type)) +} + +func (node *TypeAliasDeclaration) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().newTypeAliasOrJSTypeAliasDeclaration(node.Kind, node.Modifiers(), node.Name(), node.TypeParameters, node.Type), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *TypeAliasDeclaration) Name() *DeclarationName { return node.name } + +func IsTypeAliasDeclaration(node *Node) bool { + return node.Kind == KindTypeAliasDeclaration +} + +func IsTypeOrJSTypeAliasDeclaration(node *Node) bool { + return node.Kind == KindTypeAliasDeclaration || node.Kind == KindJSTypeAliasDeclaration +} + +func (f *NodeFactory) NewJSTypeAliasDeclaration(modifiers *ModifierList, name *IdentifierNode, typeParameters *NodeList, typeNode *TypeNode) *Node { + return f.newTypeAliasOrJSTypeAliasDeclaration(KindJSTypeAliasDeclaration, modifiers, name, typeParameters, typeNode) +} + +func IsJSTypeAliasDeclaration(node *Node) bool { + return node.Kind == KindJSTypeAliasDeclaration +} + +// EnumMember + +type EnumMember struct { + NodeBase + NamedMemberBase + compositeNodeBase + Initializer *Expression // Expression. Optional +} + +func (f *NodeFactory) NewEnumMember(name *PropertyName, initializer *Expression) *Node { + data := &EnumMember{} + data.name = name + data.Initializer = initializer + return f.newNode(KindEnumMember, data) +} + +func (f *NodeFactory) UpdateEnumMember(node *EnumMember, name *PropertyName, initializer *Expression) *Node { + if name != node.name || initializer != node.Initializer { + return updateNode(f.NewEnumMember(name, initializer), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *EnumMember) ForEachChild(v Visitor) bool { + return visit(v, node.name) || visit(v, node.Initializer) +} + +func (node *EnumMember) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateEnumMember(node, v.visitNode(node.name), v.visitNode(node.Initializer)) +} + +func (node *EnumMember) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewEnumMember(node.Name(), node.Initializer), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *EnumMember) Name() *DeclarationName { + return node.name +} + +func (node *EnumMember) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.name) | + propagateSubtreeFacts(node.Initializer) | + SubtreeContainsTypeScript +} + +func IsEnumMember(node *Node) bool { + return node.Kind == KindEnumMember +} + +// EnumDeclaration + +type EnumDeclaration struct { + StatementBase + DeclarationBase + ExportableBase + ModifiersBase + compositeNodeBase + name *IdentifierNode // IdentifierNode + Members *NodeList // NodeList[*EnumMemberNode] +} + +func (f *NodeFactory) NewEnumDeclaration(modifiers *ModifierList, name *IdentifierNode, members *NodeList) *Node { + data := &EnumDeclaration{} + data.modifiers = modifiers + data.name = name + data.Members = members + return f.newNode(KindEnumDeclaration, data) +} + +func (f *NodeFactory) UpdateEnumDeclaration(node *EnumDeclaration, modifiers *ModifierList, name *IdentifierNode, members *EnumMemberList) *Node { + if modifiers != node.modifiers || name != node.name || members != node.Members { + return updateNode(f.NewEnumDeclaration(modifiers, name, members), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *EnumDeclaration) ForEachChild(v Visitor) bool { + return visitModifiers(v, node.modifiers) || visit(v, node.name) || visitNodeList(v, node.Members) +} + +func (node *EnumDeclaration) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateEnumDeclaration(node, v.visitModifiers(node.modifiers), v.visitNode(node.name), v.visitNodes(node.Members)) +} + +func (node *EnumDeclaration) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewEnumDeclaration(node.Modifiers(), node.Name(), node.Members), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *EnumDeclaration) Name() *DeclarationName { + return node.name +} + +func (node *EnumDeclaration) computeSubtreeFacts() SubtreeFacts { + if node.modifiers != nil && node.modifiers.ModifierFlags&ModifierFlagsAmbient != 0 { + return SubtreeContainsTypeScript + } else { + return propagateModifierListSubtreeFacts(node.modifiers) | + propagateSubtreeFacts(node.name) | + propagateNodeListSubtreeFacts(node.Members, propagateSubtreeFacts) | + SubtreeContainsTypeScript + } +} + +func IsEnumDeclaration(node *Node) bool { + return node.Kind == KindEnumDeclaration +} + +// ModuleBlock + +type ModuleBlock struct { + StatementBase + compositeNodeBase + Statements *NodeList // NodeList[*Statement] +} + +func (f *NodeFactory) NewModuleBlock(statements *NodeList) *Node { + data := &ModuleBlock{} + data.Statements = statements + return f.newNode(KindModuleBlock, data) +} + +func (f *NodeFactory) UpdateModuleBlock(node *ModuleBlock, statements *StatementList) *Node { + if statements != node.Statements { + return updateNode(f.NewModuleBlock(statements), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ModuleBlock) ForEachChild(v Visitor) bool { + return visitNodeList(v, node.Statements) +} + +func (node *ModuleBlock) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateModuleBlock(node, v.visitNodes(node.Statements)) +} + +func (node *ModuleBlock) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewModuleBlock(node.Statements), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *ModuleBlock) computeSubtreeFacts() SubtreeFacts { + return propagateNodeListSubtreeFacts(node.Statements, propagateSubtreeFacts) +} + +func IsModuleBlock(node *Node) bool { + return node.Kind == KindModuleBlock +} + +// ModuleDeclaration + +type ModuleDeclaration struct { + StatementBase + DeclarationBase + ExportableBase + ModifiersBase + LocalsContainerBase + BodyBase + compositeNodeBase + name *ModuleName // ModuleName + Keyword Kind // KindModuleKeyword, KindNamespaceKeyword, KindGlobalKeyword (global augmentation) +} + +func (f *NodeFactory) NewModuleDeclaration(modifiers *ModifierList, keyword Kind, name *ModuleName, body *ModuleBody) *Node { + data := &ModuleDeclaration{} + data.modifiers = modifiers + data.Keyword = keyword + data.name = name + data.Body = body + node := f.newNode(KindModuleDeclaration, data) + return node +} + +func (f *NodeFactory) UpdateModuleDeclaration(node *ModuleDeclaration, modifiers *ModifierList, keyword Kind, name *ModuleName, body *ModuleBody) *Node { + if modifiers != node.modifiers || keyword != node.Keyword || name != node.name || body != node.Body { + return updateNode(f.NewModuleDeclaration(modifiers, keyword, name, body), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ModuleDeclaration) ForEachChild(v Visitor) bool { + return visitModifiers(v, node.modifiers) || visit(v, node.name) || visit(v, node.Body) +} + +func (node *ModuleDeclaration) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateModuleDeclaration(node, v.visitModifiers(node.modifiers), node.Keyword, v.visitNode(node.name), v.visitNode(node.Body)) +} + +func (node *ModuleDeclaration) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewModuleDeclaration(node.Modifiers(), node.Keyword, node.Name(), node.Body), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *ModuleDeclaration) Name() *DeclarationName { + return node.name +} + +func (node *ModuleDeclaration) computeSubtreeFacts() SubtreeFacts { + if node.ModifierFlags()&ModifierFlagsAmbient != 0 { + return SubtreeContainsTypeScript + } else { + return propagateModifierListSubtreeFacts(node.modifiers) | + propagateSubtreeFacts(node.name) | + propagateSubtreeFacts(node.Body) | + SubtreeContainsTypeScript + } +} + +func (node *ModuleDeclaration) propagateSubtreeFacts() SubtreeFacts { + return node.SubtreeFacts() & ^SubtreeExclusionsModule +} + +func IsModuleDeclaration(node *Node) bool { + return node.Kind == KindModuleDeclaration +} + +// NotEmittedStatement + +// Represents a statement that is elided as part of a transformation to emit comments on a +// not-emitted node. +type NotEmittedStatement struct { + StatementBase +} + +func (f *NodeFactory) NewNotEmittedStatement() *Node { + data := &NotEmittedStatement{} + return newNode(KindNotEmittedStatement, data, f.hooks) +} + +func (node *NotEmittedStatement) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewNotEmittedStatement(), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsNotEmittedStatement(node *Node) bool { + return node.Kind == KindNotEmittedStatement +} + +// NotEmittedTypeElement + +// Represents a type element that is elided as part of a transformation to emit comments on a +// not-emitted node. +type NotEmittedTypeElement struct { + NodeBase + TypeElementBase +} + +func (f *NodeFactory) NewNotEmittedTypeElement() *Node { + data := &NotEmittedTypeElement{} + return newNode(KindNotEmittedTypeElement, data, f.hooks) +} + +func (node *NotEmittedTypeElement) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewNotEmittedTypeElement(), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsNotEmittedTypeElement(node *Node) bool { + return node.Kind == KindNotEmittedTypeElement +} + +// SyntheticReferenceExpression +// Used by optional chaining transform to shuffle a `this` arg expression between steps of a chain. +// While this does implement the full expected interface of a node, and is used in place of a node in transforms, +// it generally shouldn't be treated or visited like a normal node. + +type SyntheticReferenceExpression struct { + ExpressionBase + Expression *Expression + ThisArg *Expression +} + +func (f *NodeFactory) NewSyntheticReferenceExpression(expr *Expression, thisArg *Expression) *Node { + data := &SyntheticReferenceExpression{Expression: expr, ThisArg: thisArg} + return newNode(KindSyntheticReferenceExpression, data, f.hooks) +} + +func (f *NodeFactory) UpdateSyntheticReferenceExpression(node *SyntheticReferenceExpression, expr *Expression, thisArg *Expression) *Node { + if expr != node.Expression || thisArg != node.ThisArg { + return updateNode(f.NewSyntheticReferenceExpression(expr, thisArg), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *SyntheticReferenceExpression) ForEachChild(v Visitor) bool { + return visit(v, node.Expression) +} + +func (node *SyntheticReferenceExpression) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateSyntheticReferenceExpression(node, v.visitNode(node.Expression), node.ThisArg) +} + +func (node *SyntheticReferenceExpression) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewSyntheticReferenceExpression(node.Expression, node.ThisArg), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *SyntheticReferenceExpression) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) +} + +func (node *SyntheticReferenceExpression) propagateSubtreeFacts() SubtreeFacts { + return node.SubtreeFacts() +} + +func IsSyntheticReferenceExpression(node *Node) bool { + return node.Kind == KindSyntheticReferenceExpression +} + +// ImportEqualsDeclaration + +type ImportEqualsDeclaration struct { + StatementBase + DeclarationBase + ExportableBase + ModifiersBase + compositeNodeBase + IsTypeOnly bool + name *IdentifierNode // IdentifierNode + // 'EntityName' for an internal module reference, 'ExternalModuleReference' for an external + // module reference. + ModuleReference *ModuleReference // ModuleReference +} + +func (f *NodeFactory) NewImportEqualsDeclaration(modifiers *ModifierList, isTypeOnly bool, name *IdentifierNode, moduleReference *ModuleReference) *Node { + data := &ImportEqualsDeclaration{} + data.modifiers = modifiers + data.IsTypeOnly = isTypeOnly + data.name = name + data.ModuleReference = moduleReference + return f.newNode(KindImportEqualsDeclaration, data) +} + +func (f *NodeFactory) UpdateImportEqualsDeclaration(node *ImportEqualsDeclaration, modifiers *ModifierList, isTypeOnly bool, name *IdentifierNode, moduleReference *ModuleReference) *Node { + if modifiers != node.modifiers || isTypeOnly != node.IsTypeOnly || name != node.name || moduleReference != node.ModuleReference { + return updateNode(f.NewImportEqualsDeclaration(modifiers, isTypeOnly, name, moduleReference), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ImportEqualsDeclaration) ForEachChild(v Visitor) bool { + return visitModifiers(v, node.modifiers) || visit(v, node.name) || visit(v, node.ModuleReference) +} + +func (node *ImportEqualsDeclaration) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateImportEqualsDeclaration(node, v.visitModifiers(node.modifiers), node.IsTypeOnly, v.visitNode(node.name), v.visitNode(node.ModuleReference)) +} + +func (node *ImportEqualsDeclaration) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewImportEqualsDeclaration(node.Modifiers(), node.IsTypeOnly, node.Name(), node.ModuleReference), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *ImportEqualsDeclaration) Name() *DeclarationName { + return node.name +} + +func (node *ImportEqualsDeclaration) computeSubtreeFacts() SubtreeFacts { + if node.IsTypeOnly || !IsExternalModuleReference(node.ModuleReference) { + return SubtreeContainsTypeScript + } else { + return propagateModifierListSubtreeFacts(node.modifiers) | + propagateSubtreeFacts(node.name) | + propagateSubtreeFacts(node.ModuleReference) + } +} + +func IsImportEqualsDeclaration(node *Node) bool { + return node.Kind == KindImportEqualsDeclaration +} + +// ImportDeclaration + +type ImportDeclaration struct { + StatementBase + ModifiersBase + compositeNodeBase + ImportClause *ImportClauseNode // ImportClauseNode. Optional + ModuleSpecifier *Expression // Expression + Attributes *ImportAttributesNode // ImportAttributesNode. Optional +} + +func (f *NodeFactory) newImportOrJSImportDeclaration(kind Kind, modifiers *ModifierList, importClause *ImportClauseNode, moduleSpecifier *Expression, attributes *ImportAttributesNode) *Node { + data := &ImportDeclaration{} + data.modifiers = modifiers + data.ImportClause = importClause + data.ModuleSpecifier = moduleSpecifier + data.Attributes = attributes + return f.newNode(kind, data) +} + +func (f *NodeFactory) NewImportDeclaration(modifiers *ModifierList, importClause *ImportClauseNode, moduleSpecifier *Expression, attributes *ImportAttributesNode) *Node { + return f.newImportOrJSImportDeclaration(KindImportDeclaration, modifiers, importClause, moduleSpecifier, attributes) +} + +func (f *NodeFactory) NewJSImportDeclaration(modifiers *ModifierList, importClause *ImportClauseNode, moduleSpecifier *Expression, attributes *ImportAttributesNode) *Node { + return f.newImportOrJSImportDeclaration(KindJSImportDeclaration, modifiers, importClause, moduleSpecifier, attributes) +} + +func (f *NodeFactory) UpdateImportDeclaration(node *ImportDeclaration, modifiers *ModifierList, importClause *ImportClauseNode, moduleSpecifier *Expression, attributes *ImportAttributesNode) *Node { + if modifiers != node.modifiers || importClause != node.ImportClause || moduleSpecifier != node.ModuleSpecifier || attributes != node.Attributes { + return updateNode(f.newImportOrJSImportDeclaration(node.Kind, modifiers, importClause, moduleSpecifier, attributes), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ImportDeclaration) ForEachChild(v Visitor) bool { + return visitModifiers(v, node.modifiers) || visit(v, node.ImportClause) || visit(v, node.ModuleSpecifier) || visit(v, node.Attributes) +} + +func (node *ImportDeclaration) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateImportDeclaration(node, v.visitModifiers(node.modifiers), v.visitNode(node.ImportClause), v.visitNode(node.ModuleSpecifier), v.visitNode(node.Attributes)) +} + +func (node *ImportDeclaration) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().newImportOrJSImportDeclaration(node.Kind, node.Modifiers(), node.ImportClause, node.ModuleSpecifier, node.Attributes), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *ImportDeclaration) computeSubtreeFacts() SubtreeFacts { + return propagateModifierListSubtreeFacts(node.modifiers) | + propagateSubtreeFacts(node.ImportClause) | + propagateSubtreeFacts(node.ModuleSpecifier) | + propagateSubtreeFacts(node.Attributes) +} + +func IsImportDeclaration(node *Node) bool { + return node.Kind == KindImportDeclaration +} + +func IsImportDeclarationOrJSImportDeclaration(node *Node) bool { + return node.Kind == KindImportDeclaration || node.Kind == KindJSImportDeclaration +} + +// ImportSpecifier + +type ImportSpecifier struct { + NodeBase + DeclarationBase + ExportableBase + compositeNodeBase + IsTypeOnly bool + PropertyName *ModuleExportName // ModuleExportName. Optional + name *IdentifierNode // IdentifierNode +} + +func (f *NodeFactory) NewImportSpecifier(isTypeOnly bool, propertyName *ModuleExportName, name *IdentifierNode) *Node { + data := f.importSpecifierPool.New() + data.IsTypeOnly = isTypeOnly + data.PropertyName = propertyName + data.name = name + return f.newNode(KindImportSpecifier, data) +} + +func (f *NodeFactory) UpdateImportSpecifier(node *ImportSpecifier, isTypeOnly bool, propertyName *ModuleExportName, name *IdentifierNode) *Node { + if isTypeOnly != node.IsTypeOnly || propertyName != node.PropertyName || name != node.name { + return updateNode(f.NewImportSpecifier(isTypeOnly, propertyName, name), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ImportSpecifier) ForEachChild(v Visitor) bool { + return visit(v, node.PropertyName) || visit(v, node.name) +} + +func (node *ImportSpecifier) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateImportSpecifier(node, node.IsTypeOnly, v.visitNode(node.PropertyName), v.visitNode(node.name)) +} + +func (node *ImportSpecifier) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewImportSpecifier(node.IsTypeOnly, node.PropertyName, node.Name()), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *ImportSpecifier) Name() *DeclarationName { + return node.name +} + +func (node *ImportSpecifier) computeSubtreeFacts() SubtreeFacts { + if node.IsTypeOnly { + return SubtreeContainsTypeScript + } else { + return propagateSubtreeFacts(node.PropertyName) | + propagateSubtreeFacts(node.name) + } +} + +func IsImportSpecifier(node *Node) bool { + return node.Kind == KindImportSpecifier +} + +// ExternalModuleReference + +type ExternalModuleReference struct { + NodeBase + Expression *Expression // Expression +} + +func (f *NodeFactory) NewExternalModuleReference(expression *Expression) *Node { + data := &ExternalModuleReference{} + data.Expression = expression + return f.newNode(KindExternalModuleReference, data) +} + +func (f *NodeFactory) UpdateExternalModuleReference(node *ExternalModuleReference, expression *Expression) *Node { + if expression != node.Expression { + return updateNode(f.NewExternalModuleReference(expression), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ExternalModuleReference) ForEachChild(v Visitor) bool { + return visit(v, node.Expression) +} + +func (node *ExternalModuleReference) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateExternalModuleReference(node, v.visitNode(node.Expression)) +} + +func (node *ExternalModuleReference) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewExternalModuleReference(node.Expression), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *ExternalModuleReference) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) +} + +func IsExternalModuleReference(node *Node) bool { + return node.Kind == KindExternalModuleReference +} + +// ImportClause + +type ImportClause struct { + NodeBase + DeclarationBase + ExportableBase + compositeNodeBase + PhaseModifier Kind // KindTypeKeyword | KindDeferKeyword + NamedBindings *NamedImportBindings // NamedImportBindings. Optional, named bindings + name *IdentifierNode // IdentifierNode. Optional, default binding +} + +func (f *NodeFactory) NewImportClause(phaseModifier Kind, name *IdentifierNode, namedBindings *NamedImportBindings) *Node { + data := &ImportClause{} + data.PhaseModifier = phaseModifier + data.name = name + data.NamedBindings = namedBindings + return f.newNode(KindImportClause, data) +} + +func (f *NodeFactory) UpdateImportClause(node *ImportClause, phaseModifier Kind, name *IdentifierNode, namedBindings *NamedImportBindings) *Node { + if phaseModifier != node.PhaseModifier || name != node.name || namedBindings != node.NamedBindings { + return updateNode(f.NewImportClause(phaseModifier, name, namedBindings), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ImportClause) ForEachChild(v Visitor) bool { + return visit(v, node.name) || visit(v, node.NamedBindings) +} + +func (node *ImportClause) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateImportClause(node, node.PhaseModifier, v.visitNode(node.name), v.visitNode(node.NamedBindings)) +} + +func (node *ImportClause) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewImportClause(node.PhaseModifier, node.Name(), node.NamedBindings), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *ImportClause) Name() *DeclarationName { + return node.name +} + +func (node *ImportClause) computeSubtreeFacts() SubtreeFacts { + if node.PhaseModifier == KindTypeKeyword { + return SubtreeContainsTypeScript + } else { + return propagateSubtreeFacts(node.name) | + propagateSubtreeFacts(node.NamedBindings) + } +} + +func IsImportClause(node *Node) bool { + return node.Kind == KindImportClause +} + +// NamespaceImport + +type NamespaceImport struct { + NodeBase + DeclarationBase + ExportableBase + name *IdentifierNode // IdentifierNode +} + +func (f *NodeFactory) NewNamespaceImport(name *IdentifierNode) *Node { + data := &NamespaceImport{} + data.name = name + return f.newNode(KindNamespaceImport, data) +} + +func (f *NodeFactory) UpdateNamespaceImport(node *NamespaceImport, name *IdentifierNode) *Node { + if name != node.name { + return updateNode(f.NewNamespaceImport(name), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *NamespaceImport) ForEachChild(v Visitor) bool { + return visit(v, node.name) +} + +func (node *NamespaceImport) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateNamespaceImport(node, v.visitNode(node.name)) +} + +func (node *NamespaceImport) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewNamespaceImport(node.Name()), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *NamespaceImport) Name() *DeclarationName { + return node.name +} + +func (node *NamespaceImport) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.name) +} + +func IsNamespaceImport(node *Node) bool { + return node.Kind == KindNamespaceImport +} + +// NamedImports + +type NamedImports struct { + NodeBase + compositeNodeBase + Elements *ImportSpecifierList // NodeList[*ImportSpecifierNode] +} + +func (f *NodeFactory) NewNamedImports(elements *ImportSpecifierList) *Node { + data := &NamedImports{} + data.Elements = elements + return f.newNode(KindNamedImports, data) +} + +func (f *NodeFactory) UpdateNamedImports(node *NamedImports, elements *ImportSpecifierList) *Node { + if elements != node.Elements { + return updateNode(f.NewNamedImports(elements), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *NamedImports) ForEachChild(v Visitor) bool { + return visitNodeList(v, node.Elements) +} + +func (node *NamedImports) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateNamedImports(node, v.visitNodes(node.Elements)) +} + +func (node *NamedImports) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewNamedImports(node.Elements), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *NamedImports) computeSubtreeFacts() SubtreeFacts { + return propagateNodeListSubtreeFacts(node.Elements, propagateSubtreeFacts) +} + +func IsNamedImports(node *Node) bool { + return node.Kind == KindNamedImports +} + +// ExportAssignment + +// This is either an `export =` or an `export default` declaration. +// Unless `isExportEquals` is set, this node was parsed as an `export default`. +// If Kind is KindJSExportAssignment, it is a synthetic declaration for `module.exports =`. +type ExportAssignment struct { + StatementBase + DeclarationBase + ModifiersBase + compositeNodeBase + IsExportEquals bool + Type *TypeNode // TypeNode. Only set by JSDoc @type tags. + Expression *Expression // Expression +} + +func (f *NodeFactory) newExportOrJSExportAssignment(kind Kind, modifiers *ModifierList, isExportEquals bool, typeNode *TypeNode, expression *Expression) *Node { + data := &ExportAssignment{} + data.modifiers = modifiers + data.IsExportEquals = isExportEquals + data.Type = typeNode + data.Expression = expression + return f.newNode(kind, data) +} + +func (f *NodeFactory) NewExportAssignment(modifiers *ModifierList, isExportEquals bool, typeNode *TypeNode, expression *Expression) *Node { + return f.newExportOrJSExportAssignment(KindExportAssignment, modifiers, isExportEquals, typeNode, expression) +} + +func (f *NodeFactory) NewJSExportAssignment(t *TypeNode, expression *Expression) *Node { + return f.newExportOrJSExportAssignment(KindJSExportAssignment, nil /*modifiers*/, true, t, expression) +} + +func (f *NodeFactory) UpdateExportAssignment(node *ExportAssignment, modifiers *ModifierList, typeNode *TypeNode, expression *Expression) *Node { + if modifiers != node.modifiers || typeNode != node.Type || expression != node.Expression { + return updateNode(f.newExportOrJSExportAssignment(node.Kind, modifiers, node.IsExportEquals, typeNode, expression), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ExportAssignment) ForEachChild(v Visitor) bool { + return visitModifiers(v, node.modifiers) || visit(v, node.Type) || visit(v, node.Expression) +} + +func (node *ExportAssignment) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateExportAssignment(node, v.visitModifiers(node.modifiers), v.visitNode(node.Type), v.visitNode(node.Expression)) +} + +func (node *ExportAssignment) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().newExportOrJSExportAssignment(node.Kind, node.Modifiers(), node.IsExportEquals, node.Type, node.Expression), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *ExportAssignment) computeSubtreeFacts() SubtreeFacts { + return propagateModifierListSubtreeFacts(node.modifiers) | propagateSubtreeFacts(node.Type) | propagateSubtreeFacts(node.Expression) +} + +func IsExportAssignment(node *Node) bool { + return node.Kind == KindExportAssignment +} + +func IsJSExportAssignment(node *Node) bool { + return node.Kind == KindJSExportAssignment +} + +func IsAnyExportAssignment(node *Node) bool { + return node.Kind == KindExportAssignment || node.Kind == KindJSExportAssignment +} + +// CommonJSExport + +type CommonJSExport struct { + StatementBase + DeclarationBase + ExportableBase + ModifiersBase + name *IdentifierNode + Type *TypeNode + Initializer *Expression +} + +func (f *NodeFactory) NewCommonJSExport(modifiers *ModifierList, name *IdentifierNode, typeNode *TypeNode, initializer *Expression) *Node { + data := &CommonJSExport{} + data.modifiers = modifiers + data.name = name + data.Type = typeNode + data.Initializer = initializer + return newNode(KindCommonJSExport, data, f.hooks) +} + +func (f *NodeFactory) UpdateCommonJSExport(node *CommonJSExport, modifiers *ModifierList, name *IdentifierNode, typeNode *TypeNode, initializer *Expression) *Node { + if modifiers != node.modifiers || initializer != node.Initializer || name != node.name || typeNode != node.Type { + return updateNode(f.NewCommonJSExport(node.modifiers, name, typeNode, initializer), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *CommonJSExport) ForEachChild(v Visitor) bool { + return visitModifiers(v, node.modifiers) || visit(v, node.name) || visit(v, node.Type) || visit(v, node.Initializer) +} + +func (node *CommonJSExport) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateCommonJSExport(node, v.visitModifiers(node.modifiers), v.visitNode(node.name), v.visitNode(node.Type), v.visitNode(node.Initializer)) +} + +func (node *CommonJSExport) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewCommonJSExport(node.Modifiers(), node.name, node.Type, node.Initializer), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsCommonJSExport(node *Node) bool { + return node.Kind == KindCommonJSExport +} + +func (node *CommonJSExport) Name() *DeclarationName { + return node.name +} + +// NamespaceExportDeclaration + +type NamespaceExportDeclaration struct { + StatementBase + DeclarationBase + ModifiersBase + typeSyntaxBase + name *IdentifierNode // IdentifierNode +} + +func (f *NodeFactory) NewNamespaceExportDeclaration(modifiers *ModifierList, name *IdentifierNode) *Node { + data := &NamespaceExportDeclaration{} + data.modifiers = modifiers + data.name = name + return f.newNode(KindNamespaceExportDeclaration, data) +} + +func (f *NodeFactory) UpdateNamespaceExportDeclaration(node *NamespaceExportDeclaration, modifiers *ModifierList, name *IdentifierNode) *Node { + if modifiers != node.modifiers || name != node.name { + return updateNode(f.NewNamespaceExportDeclaration(modifiers, name), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *NamespaceExportDeclaration) ForEachChild(v Visitor) bool { + return visitModifiers(v, node.modifiers) || visit(v, node.name) +} + +func (node *NamespaceExportDeclaration) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateNamespaceExportDeclaration(node, v.visitModifiers(node.modifiers), v.visitNode(node.name)) +} + +func (node *NamespaceExportDeclaration) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewNamespaceExportDeclaration(node.Modifiers(), node.Name()), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *NamespaceExportDeclaration) Name() *DeclarationName { + return node.name +} + +func IsNamespaceExportDeclaration(node *Node) bool { + return node.Kind == KindNamespaceExportDeclaration +} + +// ExportDeclaration + +type ExportDeclaration struct { + StatementBase + DeclarationBase + ModifiersBase + compositeNodeBase + IsTypeOnly bool + ExportClause *NamedExportBindings // NamedExportBindings. Optional + ModuleSpecifier *Expression // Expression. Optional + Attributes *ImportAttributesNode // ImportAttributesNode. Optional +} + +func (f *NodeFactory) NewExportDeclaration(modifiers *ModifierList, isTypeOnly bool, exportClause *NamedExportBindings, moduleSpecifier *Expression, attributes *ImportAttributesNode) *Node { + data := &ExportDeclaration{} + data.modifiers = modifiers + data.IsTypeOnly = isTypeOnly + data.ExportClause = exportClause + data.ModuleSpecifier = moduleSpecifier + data.Attributes = attributes + return f.newNode(KindExportDeclaration, data) +} + +func (f *NodeFactory) UpdateExportDeclaration(node *ExportDeclaration, modifiers *ModifierList, isTypeOnly bool, exportClause *NamedExportBindings, moduleSpecifier *Expression, attributes *ImportAttributesNode) *Node { + if modifiers != node.modifiers || exportClause != node.ExportClause || moduleSpecifier != node.ModuleSpecifier || attributes != node.Attributes { + return updateNode(f.NewExportDeclaration(modifiers, isTypeOnly, exportClause, moduleSpecifier, attributes), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ExportDeclaration) ForEachChild(v Visitor) bool { + return visitModifiers(v, node.modifiers) || visit(v, node.ExportClause) || visit(v, node.ModuleSpecifier) || visit(v, node.Attributes) +} + +func (node *ExportDeclaration) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateExportDeclaration(node, v.visitModifiers(node.modifiers), node.IsTypeOnly, v.visitNode(node.ExportClause), v.visitNode(node.ModuleSpecifier), v.visitNode(node.Attributes)) +} + +func (node *ExportDeclaration) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewExportDeclaration(node.Modifiers(), node.IsTypeOnly, node.ExportClause, node.ModuleSpecifier, node.Attributes), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *ExportDeclaration) computeSubtreeFacts() SubtreeFacts { + return propagateModifierListSubtreeFacts(node.modifiers) | + propagateSubtreeFacts(node.ExportClause) | + propagateSubtreeFacts(node.ModuleSpecifier) | + propagateSubtreeFacts(node.Attributes) | + core.IfElse(node.IsTypeOnly, SubtreeContainsTypeScript, SubtreeFactsNone) +} + +func IsExportDeclaration(node *Node) bool { + return node.Kind == KindExportDeclaration +} + +// NamespaceExport + +type NamespaceExport struct { + NodeBase + DeclarationBase + name *ModuleExportName // ModuleExportName +} + +func (f *NodeFactory) NewNamespaceExport(name *ModuleExportName) *Node { + data := &NamespaceExport{} + data.name = name + return f.newNode(KindNamespaceExport, data) +} + +func (f *NodeFactory) UpdateNamespaceExport(node *NamespaceExport, name *ModuleExportName) *Node { + if name != node.name { + return updateNode(f.NewNamespaceExport(name), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *NamespaceExport) ForEachChild(v Visitor) bool { + return visit(v, node.name) +} + +func (node *NamespaceExport) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateNamespaceExport(node, v.visitNode(node.name)) +} + +func (node *NamespaceExport) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewNamespaceExport(node.Name()), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *NamespaceExport) Name() *DeclarationName { + return node.name +} + +func (node *NamespaceExport) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.name) +} + +func IsNamespaceExport(node *Node) bool { + return node.Kind == KindNamespaceExport +} + +// NamedExports + +type NamedExports struct { + NodeBase + compositeNodeBase + Elements *ExportSpecifierList // NodeList[*ExportSpecifierNode] +} + +func (f *NodeFactory) NewNamedExports(elements *NodeList) *Node { + data := &NamedExports{} + data.Elements = elements + return f.newNode(KindNamedExports, data) +} + +func (f *NodeFactory) UpdateNamedExports(node *NamedExports, elements *ExportSpecifierList) *Node { + if elements != node.Elements { + return updateNode(f.NewNamedExports(elements), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *NamedExports) ForEachChild(v Visitor) bool { + return visitNodeList(v, node.Elements) +} + +func (node *NamedExports) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateNamedExports(node, v.visitNodes(node.Elements)) +} + +func (node *NamedExports) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewNamedExports(node.Elements), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *NamedExports) computeSubtreeFacts() SubtreeFacts { + return propagateNodeListSubtreeFacts(node.Elements, propagateSubtreeFacts) +} + +func IsNamedExports(node *Node) bool { + return node.Kind == KindNamedExports +} + +// ExportSpecifier + +type ExportSpecifier struct { + NodeBase + DeclarationBase + ExportableBase + compositeNodeBase + IsTypeOnly bool + PropertyName *ModuleExportName // ModuleExportName. Optional, name preceding 'as' keyword + name *ModuleExportName // ModuleExportName +} + +func (f *NodeFactory) NewExportSpecifier(isTypeOnly bool, propertyName *ModuleExportName, name *ModuleExportName) *Node { + data := &ExportSpecifier{} + data.IsTypeOnly = isTypeOnly + data.PropertyName = propertyName + data.name = name + return f.newNode(KindExportSpecifier, data) +} + +func (f *NodeFactory) UpdateExportSpecifier(node *ExportSpecifier, isTypeOnly bool, propertyName *ModuleExportName, name *ModuleExportName) *Node { + if isTypeOnly != node.IsTypeOnly || propertyName != node.PropertyName || name != node.name { + return updateNode(f.NewExportSpecifier(isTypeOnly, propertyName, name), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ExportSpecifier) ForEachChild(v Visitor) bool { + return visit(v, node.PropertyName) || visit(v, node.name) +} + +func (node *ExportSpecifier) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateExportSpecifier(node, node.IsTypeOnly, v.visitNode(node.PropertyName), v.visitNode(node.name)) +} + +func (node *ExportSpecifier) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewExportSpecifier(node.IsTypeOnly, node.PropertyName, node.Name()), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *ExportSpecifier) Name() *DeclarationName { + return node.name +} + +func (node *ExportSpecifier) computeSubtreeFacts() SubtreeFacts { + if node.IsTypeOnly { + return SubtreeContainsTypeScript + } else { + return propagateSubtreeFacts(node.PropertyName) | + propagateSubtreeFacts(node.name) + } +} + +func IsExportSpecifier(node *Node) bool { + return node.Kind == KindExportSpecifier +} + +// TypeElementBase + +type TypeElementBase struct{} + +// ClassElementBase + +type ClassElementBase struct{} + +// NamedMemberBase + +type NamedMemberBase struct { + DeclarationBase + ModifiersBase + name *PropertyName // PropertyName + PostfixToken *TokenNode // TokenNode. Optional +} + +func (node *NamedMemberBase) DeclarationData() *DeclarationBase { return &node.DeclarationBase } +func (node *NamedMemberBase) Modifiers() *ModifierList { return node.modifiers } +func (node *NamedMemberBase) setModifiers(modifiers *ModifierList) { node.modifiers = modifiers } +func (node *NamedMemberBase) Name() *DeclarationName { return node.name } + +// CallSignatureDeclaration + +type CallSignatureDeclaration struct { + NodeBase + DeclarationBase + FunctionLikeBase + TypeElementBase + typeSyntaxBase +} + +func (f *NodeFactory) NewCallSignatureDeclaration(typeParameters *NodeList, parameters *NodeList, returnType *TypeNode) *Node { + data := &CallSignatureDeclaration{} + data.TypeParameters = typeParameters + data.Parameters = parameters + data.Type = returnType + return f.newNode(KindCallSignature, data) +} + +func (f *NodeFactory) UpdateCallSignatureDeclaration(node *CallSignatureDeclaration, typeParameters *TypeParameterList, parameters *ParameterList, returnType *TypeNode) *Node { + if typeParameters != node.TypeParameters || parameters != node.Parameters || returnType != node.Type { + return updateNode(f.NewCallSignatureDeclaration(typeParameters, parameters, returnType), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *CallSignatureDeclaration) ForEachChild(v Visitor) bool { + return visitNodeList(v, node.TypeParameters) || visitNodeList(v, node.Parameters) || visit(v, node.Type) +} + +func (node *CallSignatureDeclaration) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateCallSignatureDeclaration(node, v.visitNodes(node.TypeParameters), v.visitNodes(node.Parameters), v.visitNode(node.Type)) +} + +func (node *CallSignatureDeclaration) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewCallSignatureDeclaration(node.TypeParameters, node.Parameters, node.Type), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsCallSignatureDeclaration(node *Node) bool { + return node.Kind == KindCallSignature +} + +// ConstructSignatureDeclaration + +type ConstructSignatureDeclaration struct { + NodeBase + DeclarationBase + FunctionLikeBase + TypeElementBase + typeSyntaxBase +} + +func (f *NodeFactory) NewConstructSignatureDeclaration(typeParameters *NodeList, parameters *NodeList, returnType *TypeNode) *Node { + data := f.constructSignatureDeclarationPool.New() + data.TypeParameters = typeParameters + data.Parameters = parameters + data.Type = returnType + return f.newNode(KindConstructSignature, data) +} + +func (f *NodeFactory) UpdateConstructSignatureDeclaration(node *ConstructSignatureDeclaration, typeParameters *TypeParameterList, parameters *ParameterList, returnType *TypeNode) *Node { + if typeParameters != node.TypeParameters || parameters != node.Parameters || returnType != node.Type { + return updateNode(f.NewConstructSignatureDeclaration(typeParameters, parameters, returnType), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ConstructSignatureDeclaration) ForEachChild(v Visitor) bool { + return visitNodeList(v, node.TypeParameters) || visitNodeList(v, node.Parameters) || visit(v, node.Type) +} + +func (node *ConstructSignatureDeclaration) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateConstructSignatureDeclaration(node, v.visitNodes(node.TypeParameters), v.visitNodes(node.Parameters), v.visitNode(node.Type)) +} + +func (node *ConstructSignatureDeclaration) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewConstructSignatureDeclaration(node.TypeParameters, node.Parameters, node.Type), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsConstructSignatureDeclaration(node *Node) bool { + return node.Kind == KindConstructSignature +} + +// ConstructorDeclaration + +type ConstructorDeclaration struct { + NodeBase + DeclarationBase + ModifiersBase + FunctionLikeWithBodyBase + ClassElementBase + compositeNodeBase + ReturnFlowNode *FlowNode +} + +func (f *NodeFactory) NewConstructorDeclaration(modifiers *ModifierList, typeParameters *NodeList, parameters *NodeList, returnType *TypeNode, fullSignature *TypeNode, body *BlockNode) *Node { + data := &ConstructorDeclaration{} + data.modifiers = modifiers + data.TypeParameters = typeParameters + data.Parameters = parameters + data.Type = returnType + data.FullSignature = fullSignature + data.Body = body + return f.newNode(KindConstructor, data) +} + +func (f *NodeFactory) UpdateConstructorDeclaration(node *ConstructorDeclaration, modifiers *ModifierList, typeParameters *TypeParameterList, parameters *ParameterList, returnType *TypeNode, fullSignature *TypeNode, body *BlockNode) *Node { + if modifiers != node.modifiers || typeParameters != node.TypeParameters || parameters != node.Parameters || returnType != node.Type || fullSignature != node.FullSignature || body != node.Body { + return updateNode(f.NewConstructorDeclaration(modifiers, typeParameters, parameters, returnType, fullSignature, body), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ConstructorDeclaration) ForEachChild(v Visitor) bool { + return visitModifiers(v, node.modifiers) || visitNodeList(v, node.TypeParameters) || visitNodeList(v, node.Parameters) || visit(v, node.Type) || visit(v, node.FullSignature) || visit(v, node.Body) +} + +func (node *ConstructorDeclaration) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateConstructorDeclaration(node, v.visitModifiers(node.modifiers), v.visitNodes(node.TypeParameters), v.visitParameters(node.Parameters), v.visitNode(node.Type), v.visitNode(node.FullSignature), v.visitFunctionBody(node.Body)) +} + +func (node *ConstructorDeclaration) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewConstructorDeclaration(node.Modifiers(), node.TypeParameters, node.Parameters, node.Type, node.FullSignature, node.Body), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *ConstructorDeclaration) computeSubtreeFacts() SubtreeFacts { + if node.Body == nil { + return SubtreeContainsTypeScript + } else { + return propagateModifierListSubtreeFacts(node.modifiers) | + propagateEraseableSyntaxListSubtreeFacts(node.TypeParameters) | + propagateNodeListSubtreeFacts(node.Parameters, propagateSubtreeFacts) | + propagateEraseableSyntaxSubtreeFacts(node.Type) | + propagateEraseableSyntaxSubtreeFacts(node.FullSignature) | + propagateSubtreeFacts(node.Body) + } +} + +func (node *ConstructorDeclaration) propagateSubtreeFacts() SubtreeFacts { + return node.SubtreeFacts() & ^SubtreeExclusionsConstructor +} + +func IsConstructorDeclaration(node *Node) bool { + return node.Kind == KindConstructor +} + +// AccessorDeclarationBase + +type AccessorDeclarationBase struct { + NodeBase + NamedMemberBase + FunctionLikeWithBodyBase + FlowNodeBase + TypeElementBase + ClassElementBase + ObjectLiteralElementBase + compositeNodeBase +} + +func (node *AccessorDeclarationBase) ForEachChild(v Visitor) bool { + return visitModifiers(v, node.modifiers) || visit(v, node.name) || visitNodeList(v, node.TypeParameters) || visitNodeList(v, node.Parameters) || + visit(v, node.Type) || visit(v, node.FullSignature) || visit(v, node.Body) +} + +func (node *AccessorDeclarationBase) IsAccessorDeclaration() {} + +func (node *AccessorDeclarationBase) computeSubtreeFacts() SubtreeFacts { + if node.Body == nil { + return SubtreeContainsTypeScript + } else { + return propagateModifierListSubtreeFacts(node.modifiers) | + propagateSubtreeFacts(node.name) | + propagateEraseableSyntaxListSubtreeFacts(node.TypeParameters) | + propagateNodeListSubtreeFacts(node.Parameters, propagateSubtreeFacts) | + propagateEraseableSyntaxSubtreeFacts(node.Type) | + propagateEraseableSyntaxSubtreeFacts(node.FullSignature) | + propagateSubtreeFacts(node.Body) + } +} + +func (node *AccessorDeclarationBase) propagateSubtreeFacts() SubtreeFacts { + return node.SubtreeFacts() & ^SubtreeExclusionsAccessor | + propagateSubtreeFacts(node.name) +} + +// GetAccessorDeclaration + +type GetAccessorDeclaration struct { + AccessorDeclarationBase +} + +func (f *NodeFactory) NewGetAccessorDeclaration(modifiers *ModifierList, name *PropertyName, typeParameters *NodeList, parameters *NodeList, returnType *TypeNode, fullSignature *TypeNode, body *BlockNode) *Node { + data := &GetAccessorDeclaration{} + data.modifiers = modifiers + data.name = name + data.TypeParameters = typeParameters + data.Parameters = parameters + data.Type = returnType + data.FullSignature = fullSignature + data.Body = body + return f.newNode(KindGetAccessor, data) +} + +func (f *NodeFactory) UpdateGetAccessorDeclaration(node *GetAccessorDeclaration, modifiers *ModifierList, name *PropertyName, typeParameters *TypeParameterList, parameters *ParameterList, returnType *TypeNode, fullSignature *TypeNode, body *BlockNode) *Node { + if modifiers != node.modifiers || name != node.name || typeParameters != node.TypeParameters || parameters != node.Parameters || returnType != node.Type || fullSignature != node.FullSignature || body != node.Body { + return updateNode(f.NewGetAccessorDeclaration(modifiers, name, typeParameters, parameters, returnType, fullSignature, body), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *GetAccessorDeclaration) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateGetAccessorDeclaration(node, v.visitModifiers(node.modifiers), v.visitNode(node.name), v.visitNodes(node.TypeParameters), v.visitParameters(node.Parameters), v.visitNode(node.Type), v.visitNode(node.FullSignature), v.visitFunctionBody(node.Body)) +} + +func (node *GetAccessorDeclaration) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewGetAccessorDeclaration(node.modifiers, node.Name(), node.TypeParameters, node.Parameters, node.Type, node.FullSignature, node.Body), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsGetAccessorDeclaration(node *Node) bool { + return node.Kind == KindGetAccessor +} + +// SetAccessorDeclaration + +type SetAccessorDeclaration struct { + AccessorDeclarationBase +} + +func (f *NodeFactory) NewSetAccessorDeclaration(modifiers *ModifierList, name *PropertyName, typeParameters *NodeList, parameters *NodeList, returnType *TypeNode, fullSignature *TypeNode, body *BlockNode) *Node { + data := &SetAccessorDeclaration{} + data.modifiers = modifiers + data.name = name + data.TypeParameters = typeParameters + data.Parameters = parameters + data.Type = returnType + data.FullSignature = fullSignature + data.Body = body + return f.newNode(KindSetAccessor, data) +} + +func (f *NodeFactory) UpdateSetAccessorDeclaration(node *SetAccessorDeclaration, modifiers *ModifierList, name *PropertyName, typeParameters *TypeParameterList, parameters *ParameterList, returnType *TypeNode, fullSignature *TypeNode, body *BlockNode) *Node { + if modifiers != node.modifiers || name != node.name || typeParameters != node.TypeParameters || parameters != node.Parameters || returnType != node.Type || fullSignature != node.FullSignature || body != node.Body { + return updateNode(f.NewSetAccessorDeclaration(modifiers, name, typeParameters, parameters, returnType, fullSignature, body), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *SetAccessorDeclaration) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateSetAccessorDeclaration(node, v.visitModifiers(node.modifiers), v.visitNode(node.name), v.visitNodes(node.TypeParameters), v.visitParameters(node.Parameters), v.visitNode(node.Type), v.visitNode(node.FullSignature), v.visitFunctionBody(node.Body)) +} + +func (node *SetAccessorDeclaration) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewSetAccessorDeclaration(node.Modifiers(), node.Name(), node.TypeParameters, node.Parameters, node.Type, node.FullSignature, node.Body), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsSetAccessorDeclaration(node *Node) bool { + return node.Kind == KindSetAccessor +} + +// IndexSignatureDeclaration + +type IndexSignatureDeclaration struct { + NodeBase + DeclarationBase + ModifiersBase + FunctionLikeBase + TypeElementBase + ClassElementBase + typeSyntaxBase +} + +func (f *NodeFactory) NewIndexSignatureDeclaration(modifiers *ModifierList, parameters *NodeList, returnType *TypeNode) *Node { + data := &IndexSignatureDeclaration{} + data.modifiers = modifiers + data.Parameters = parameters + data.Type = returnType + return f.newNode(KindIndexSignature, data) +} + +func (f *NodeFactory) UpdateIndexSignatureDeclaration(node *IndexSignatureDeclaration, modifiers *ModifierList, parameters *ParameterList, returnType *TypeNode) *Node { + if modifiers != node.modifiers || parameters != node.Parameters || returnType != node.Type { + return updateNode(f.NewIndexSignatureDeclaration(modifiers, parameters, returnType), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *IndexSignatureDeclaration) ForEachChild(v Visitor) bool { + return visitModifiers(v, node.modifiers) || visitNodeList(v, node.Parameters) || visit(v, node.Type) +} + +func (node *IndexSignatureDeclaration) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateIndexSignatureDeclaration(node, v.visitModifiers(node.modifiers), v.visitNodes(node.Parameters), v.visitNode(node.Type)) +} + +func (node *IndexSignatureDeclaration) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewIndexSignatureDeclaration(node.Modifiers(), node.Parameters, node.Type), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsIndexSignatureDeclaration(node *Node) bool { + return node.Kind == KindIndexSignature +} + +// MethodSignatureDeclaration + +type MethodSignatureDeclaration struct { + NodeBase + NamedMemberBase + FunctionLikeBase + TypeElementBase + typeSyntaxBase +} + +func (f *NodeFactory) NewMethodSignatureDeclaration(modifiers *ModifierList, name *PropertyName, postfixToken *TokenNode, typeParameters *NodeList, parameters *NodeList, returnType *TypeNode) *Node { + data := f.methodSignatureDeclarationPool.New() + data.modifiers = modifiers + data.name = name + data.PostfixToken = postfixToken + data.TypeParameters = typeParameters + data.Parameters = parameters + data.Type = returnType + return f.newNode(KindMethodSignature, data) +} + +func (f *NodeFactory) UpdateMethodSignatureDeclaration(node *MethodSignatureDeclaration, modifiers *ModifierList, name *PropertyName, postfixToken *TokenNode, typeParameters *TypeParameterList, parameters *ParameterList, returnType *TypeNode) *Node { + if modifiers != node.modifiers || name != node.name || postfixToken != node.PostfixToken || typeParameters != node.TypeParameters || parameters != node.Parameters || returnType != node.Type { + return updateNode(f.NewMethodSignatureDeclaration(modifiers, name, postfixToken, typeParameters, parameters, returnType), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *MethodSignatureDeclaration) ForEachChild(v Visitor) bool { + return visitModifiers(v, node.modifiers) || visit(v, node.name) || visit(v, node.PostfixToken) || visitNodeList(v, node.TypeParameters) || + visitNodeList(v, node.Parameters) || visit(v, node.Type) +} + +func (node *MethodSignatureDeclaration) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateMethodSignatureDeclaration(node, v.visitModifiers(node.modifiers), v.visitNode(node.name), v.visitToken(node.PostfixToken), v.visitNodes(node.TypeParameters), v.visitNodes(node.Parameters), v.visitNode(node.Type)) +} + +func (node *MethodSignatureDeclaration) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewMethodSignatureDeclaration(node.Modifiers(), node.Name(), node.PostfixToken, node.TypeParameters, node.Parameters, node.Type), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsMethodSignatureDeclaration(node *Node) bool { + return node.Kind == KindMethodSignature +} + +// MethodSignatureDeclaration + +type MethodDeclaration struct { + NodeBase + NamedMemberBase + FunctionLikeWithBodyBase + FlowNodeBase + ClassElementBase + ObjectLiteralElementBase + compositeNodeBase +} + +func (f *NodeFactory) NewMethodDeclaration(modifiers *ModifierList, asteriskToken *TokenNode, name *PropertyName, postfixToken *TokenNode, typeParameters *NodeList, parameters *NodeList, returnType *TypeNode, fullSignature *TypeNode, body *BlockNode) *Node { + data := &MethodDeclaration{} + data.modifiers = modifiers + data.AsteriskToken = asteriskToken + data.name = name + data.PostfixToken = postfixToken + data.TypeParameters = typeParameters + data.Parameters = parameters + data.Type = returnType + data.FullSignature = fullSignature + data.Body = body + return f.newNode(KindMethodDeclaration, data) +} + +func (f *NodeFactory) UpdateMethodDeclaration(node *MethodDeclaration, modifiers *ModifierList, asteriskToken *TokenNode, name *PropertyName, postfixToken *TokenNode, typeParameters *TypeParameterList, parameters *ParameterList, returnType *TypeNode, fullSignature *TypeNode, body *BlockNode) *Node { + if modifiers != node.modifiers || asteriskToken != node.AsteriskToken || name != node.name || postfixToken != node.PostfixToken || typeParameters != node.TypeParameters || parameters != node.Parameters || returnType != node.Type || fullSignature != node.FullSignature || body != node.Body { + return updateNode(f.NewMethodDeclaration(modifiers, asteriskToken, name, postfixToken, typeParameters, parameters, returnType, fullSignature, body), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *MethodDeclaration) ForEachChild(v Visitor) bool { + return visitModifiers(v, node.modifiers) || visit(v, node.AsteriskToken) || visit(v, node.name) || visit(v, node.PostfixToken) || + visitNodeList(v, node.TypeParameters) || visitNodeList(v, node.Parameters) || visit(v, node.Type) || visit(v, node.FullSignature) || visit(v, node.Body) +} + +func (node *MethodDeclaration) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateMethodDeclaration(node, v.visitModifiers(node.modifiers), v.visitToken(node.AsteriskToken), v.visitNode(node.name), v.visitToken(node.PostfixToken), v.visitNodes(node.TypeParameters), v.visitParameters(node.Parameters), v.visitNode(node.Type), v.visitNode(node.FullSignature), v.visitFunctionBody(node.Body)) +} + +func (node *MethodDeclaration) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewMethodDeclaration(node.Modifiers(), node.AsteriskToken, node.Name(), node.PostfixToken, node.TypeParameters, node.Parameters, node.Type, node.FullSignature, node.Body), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *MethodDeclaration) computeSubtreeFacts() SubtreeFacts { + if node.Body == nil { + return SubtreeContainsTypeScript + } else { + isAsync := node.modifiers != nil && node.modifiers.ModifierFlags&ModifierFlagsAsync != 0 + isGenerator := node.AsteriskToken != nil + return propagateModifierListSubtreeFacts(node.modifiers) | + propagateSubtreeFacts(node.AsteriskToken) | + propagateSubtreeFacts(node.name) | + propagateEraseableSyntaxSubtreeFacts(node.PostfixToken) | + propagateEraseableSyntaxListSubtreeFacts(node.TypeParameters) | + propagateNodeListSubtreeFacts(node.Parameters, propagateSubtreeFacts) | + propagateSubtreeFacts(node.Body) | + propagateEraseableSyntaxSubtreeFacts(node.Type) | + propagateEraseableSyntaxSubtreeFacts(node.FullSignature) | + core.IfElse(isAsync && isGenerator, SubtreeContainsForAwaitOrAsyncGenerator, SubtreeFactsNone) | + core.IfElse(isAsync && !isGenerator, SubtreeContainsAnyAwait, SubtreeFactsNone) + } +} + +func (node *MethodDeclaration) propagateSubtreeFacts() SubtreeFacts { + return node.SubtreeFacts() & ^SubtreeExclusionsMethod | + propagateSubtreeFacts(node.name) +} + +func IsMethodDeclaration(node *Node) bool { + return node.Kind == KindMethodDeclaration +} + +// PropertySignatureDeclaration + +type PropertySignatureDeclaration struct { + NodeBase + NamedMemberBase + TypeElementBase + typeSyntaxBase + Type *TypeNode // TypeNode + Initializer *Expression // Expression. For error reporting purposes +} + +func (f *NodeFactory) NewPropertySignatureDeclaration(modifiers *ModifierList, name *PropertyName, postfixToken *TokenNode, typeNode *TypeNode, initializer *Expression) *Node { + data := f.propertySignatureDeclarationPool.New() + data.modifiers = modifiers + data.name = name + data.PostfixToken = postfixToken + data.Type = typeNode + data.Initializer = initializer + return f.newNode(KindPropertySignature, data) +} + +func (f *NodeFactory) UpdatePropertySignatureDeclaration(node *PropertySignatureDeclaration, modifiers *ModifierList, name *PropertyName, postfixToken *TokenNode, typeNode *TypeNode, initializer *Expression) *Node { + if modifiers != node.modifiers || name != node.name || postfixToken != node.PostfixToken || typeNode != node.Type || initializer != node.Initializer { + return updateNode(f.NewPropertySignatureDeclaration(modifiers, name, postfixToken, typeNode, initializer), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *PropertySignatureDeclaration) ForEachChild(v Visitor) bool { + return visitModifiers(v, node.modifiers) || visit(v, node.name) || visit(v, node.PostfixToken) || visit(v, node.Type) || visit(v, node.Initializer) +} + +func (node *PropertySignatureDeclaration) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdatePropertySignatureDeclaration(node, v.visitModifiers(node.modifiers), v.visitNode(node.name), v.visitToken(node.PostfixToken), v.visitNode(node.Type), v.visitNode(node.Initializer)) +} + +func (node *PropertySignatureDeclaration) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewPropertySignatureDeclaration(node.Modifiers(), node.Name(), node.PostfixToken, node.Type, node.Initializer), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsPropertySignatureDeclaration(node *Node) bool { + return node.Kind == KindPropertySignature +} + +// PropertyDeclaration + +type PropertyDeclaration struct { + NodeBase + NamedMemberBase + ClassElementBase + compositeNodeBase + Type *TypeNode // TypeNode. Optional + Initializer *Expression // Expression. Optional +} + +func (f *NodeFactory) NewPropertyDeclaration(modifiers *ModifierList, name *PropertyName, postfixToken *TokenNode, typeNode *TypeNode, initializer *Expression) *Node { + data := &PropertyDeclaration{} + data.modifiers = modifiers + data.name = name + data.PostfixToken = postfixToken + data.Type = typeNode + data.Initializer = initializer + return f.newNode(KindPropertyDeclaration, data) +} + +func (f *NodeFactory) UpdatePropertyDeclaration(node *PropertyDeclaration, modifiers *ModifierList, name *PropertyName, postfixToken *TokenNode, typeNode *TypeNode, initializer *Expression) *Node { + if modifiers != node.modifiers || name != node.name || postfixToken != node.PostfixToken || typeNode != node.Type || initializer != node.Initializer { + return updateNode(f.NewPropertyDeclaration(modifiers, name, postfixToken, typeNode, initializer), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *PropertyDeclaration) ForEachChild(v Visitor) bool { + return visitModifiers(v, node.modifiers) || visit(v, node.name) || visit(v, node.PostfixToken) || visit(v, node.Type) || visit(v, node.Initializer) +} + +func (node *PropertyDeclaration) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdatePropertyDeclaration(node, v.visitModifiers(node.modifiers), v.visitNode(node.name), v.visitToken(node.PostfixToken), v.visitNode(node.Type), v.visitNode(node.Initializer)) +} + +func (node *PropertyDeclaration) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewPropertyDeclaration(node.Modifiers(), node.Name(), node.PostfixToken, node.Type, node.Initializer), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *PropertyDeclaration) computeSubtreeFacts() SubtreeFacts { + return propagateModifierListSubtreeFacts(node.modifiers) | + propagateSubtreeFacts(node.name) | + propagateEraseableSyntaxSubtreeFacts(node.PostfixToken) | + propagateEraseableSyntaxSubtreeFacts(node.Type) | + propagateSubtreeFacts(node.Initializer) | + SubtreeContainsClassFields +} + +func (node *PropertyDeclaration) propagateSubtreeFacts() SubtreeFacts { + return node.SubtreeFacts() & ^SubtreeExclusionsProperty | + propagateSubtreeFacts(node.name) +} + +func IsPropertyDeclaration(node *Node) bool { + return node.Kind == KindPropertyDeclaration +} + +// SemicolonClassElement + +type SemicolonClassElement struct { + NodeBase + DeclarationBase + ClassElementBase +} + +func (f *NodeFactory) NewSemicolonClassElement() *Node { + return f.newNode(KindSemicolonClassElement, &SemicolonClassElement{}) +} + +func (node *SemicolonClassElement) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewSemicolonClassElement(), node.AsNode(), f.AsNodeFactory().hooks) +} + +// ClassStaticBlockDeclaration + +type ClassStaticBlockDeclaration struct { + NodeBase + DeclarationBase + ModifiersBase + LocalsContainerBase + ClassElementBase + compositeNodeBase + Body *BlockNode // BlockNode + ReturnFlowNode *FlowNode +} + +func (f *NodeFactory) NewClassStaticBlockDeclaration(modifiers *ModifierList, body *BlockNode) *Node { + data := &ClassStaticBlockDeclaration{} + data.modifiers = modifiers + data.Body = body + return f.newNode(KindClassStaticBlockDeclaration, data) +} + +func (f *NodeFactory) UpdateClassStaticBlockDeclaration(node *ClassStaticBlockDeclaration, modifiers *ModifierList, body *BlockNode) *Node { + if modifiers != node.modifiers || body != node.Body { + return updateNode(f.NewClassStaticBlockDeclaration(modifiers, body), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ClassStaticBlockDeclaration) ForEachChild(v Visitor) bool { + return visitModifiers(v, node.modifiers) || visit(v, node.Body) +} + +func (node *ClassStaticBlockDeclaration) VisitEachChild(v *NodeVisitor) *Node { + // A `static {}` Block does not have parameters, but we must still ensure we enter the lexical scope + modifiers := v.visitModifiers(node.modifiers) + body := v.visitNode(node.Body) + return v.Factory.UpdateClassStaticBlockDeclaration(node, modifiers, body) +} + +func (node *ClassStaticBlockDeclaration) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewClassStaticBlockDeclaration(node.Modifiers(), node.Body), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *ClassStaticBlockDeclaration) computeSubtreeFacts() SubtreeFacts { + return propagateModifierListSubtreeFacts(node.modifiers) | + propagateSubtreeFacts(node.Body) | + SubtreeContainsClassFields +} + +func IsClassStaticBlockDeclaration(node *Node) bool { + return node.Kind == KindClassStaticBlockDeclaration +} + +// ExpressionBase + +type ExpressionBase struct { + NodeBase +} + +// OmittedExpression + +type OmittedExpression struct { + ExpressionBase +} + +func (f *NodeFactory) NewOmittedExpression() *Node { + return f.newNode(KindOmittedExpression, &OmittedExpression{}) +} + +func (node *OmittedExpression) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewOmittedExpression(), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsOmittedExpression(node *Node) bool { + return node.Kind == KindOmittedExpression +} + +// KeywordExpression + +type KeywordExpression struct { + ExpressionBase + FlowNodeBase // For 'this' and 'super' expressions +} + +func (f *NodeFactory) NewKeywordExpression(kind Kind) *Node { + return f.newNode(kind, f.keywordExpressionPool.New()) +} + +func (node *KeywordExpression) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewKeywordExpression(node.Kind), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *KeywordExpression) computeSubtreeFacts() SubtreeFacts { + switch node.Kind { + case KindThisKeyword: + return SubtreeContainsLexicalThis + case KindSuperKeyword: + return SubtreeContainsLexicalSuper + } + return SubtreeFactsNone +} + +// LiteralLikeBase + +type LiteralLikeBase struct { + Text string + TokenFlags TokenFlags +} + +func (node *LiteralLikeBase) LiteralLikeData() *LiteralLikeBase { return node } + +// StringLiteral + +type StringLiteral struct { + ExpressionBase + LiteralLikeBase +} + +func (f *NodeFactory) NewStringLiteral(text string) *Node { + data := f.stringLiteralPool.New() + data.Text = text + f.textCount++ + return f.newNode(KindStringLiteral, data) +} + +func (node *StringLiteral) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewStringLiteral(node.Text), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsStringLiteral(node *Node) bool { + return node.Kind == KindStringLiteral +} + +// NumericLiteral + +type NumericLiteral struct { + ExpressionBase + LiteralLikeBase +} + +func (f *NodeFactory) NewNumericLiteral(text string) *Node { + data := f.numericLiteralPool.New() + data.Text = text + f.textCount++ + return f.newNode(KindNumericLiteral, data) +} + +func (node *NumericLiteral) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewNumericLiteral(node.Text), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsNumericLiteral(node *Node) bool { + return node.Kind == KindNumericLiteral +} + +// BigIntLiteral + +type BigIntLiteral struct { + ExpressionBase + LiteralLikeBase +} + +func (f *NodeFactory) NewBigIntLiteral(text string) *Node { + data := &BigIntLiteral{} + data.Text = text + f.textCount++ + return f.newNode(KindBigIntLiteral, data) +} + +func (node *BigIntLiteral) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewBigIntLiteral(node.Text), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *BigIntLiteral) computeSubtreeFacts() SubtreeFacts { + return SubtreeFactsNone // `bigint` is not downleveled in any way +} + +func IsBigIntLiteral(node *Node) bool { + return node.Kind == KindBigIntLiteral +} + +// RegularExpressionLiteral + +type RegularExpressionLiteral struct { + ExpressionBase + LiteralLikeBase +} + +func (f *NodeFactory) NewRegularExpressionLiteral(text string) *Node { + data := &RegularExpressionLiteral{} + data.Text = text + f.textCount++ + return f.newNode(KindRegularExpressionLiteral, data) +} + +func (node *RegularExpressionLiteral) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewRegularExpressionLiteral(node.Text), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsRegularExpressionLiteral(node *Node) bool { + return node.Kind == KindRegularExpressionLiteral +} + +// NoSubstitutionTemplateLiteral + +type NoSubstitutionTemplateLiteral struct { + ExpressionBase + TemplateLiteralLikeBase +} + +func (f *NodeFactory) NewNoSubstitutionTemplateLiteral(text string) *Node { + data := &NoSubstitutionTemplateLiteral{} + data.Text = text + f.textCount++ + return f.newNode(KindNoSubstitutionTemplateLiteral, data) +} + +func (node *NoSubstitutionTemplateLiteral) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewNoSubstitutionTemplateLiteral(node.Text), node.AsNode(), f.AsNodeFactory().hooks) +} + +// BinaryExpression + +type BinaryExpression struct { + ExpressionBase + DeclarationBase + ModifiersBase + compositeNodeBase + Left *Expression // Expression + Type *TypeNode // TypeNode. Only set by JSDoc @type tags. + OperatorToken *TokenNode // TokenNode + Right *Expression // Expression +} + +func (f *NodeFactory) NewBinaryExpression(modifiers *ModifierList, left *Expression, typeNode *TypeNode, operatorToken *TokenNode, right *Expression) *Node { + if operatorToken == nil { + panic("operatorToken is required") + } + data := f.binaryExpressionPool.New() + data.modifiers = modifiers + data.Left = left + data.Type = typeNode + data.OperatorToken = operatorToken + data.Right = right + return f.newNode(KindBinaryExpression, data) +} + +func (f *NodeFactory) UpdateBinaryExpression(node *BinaryExpression, modifiers *ModifierList, left *Expression, typeNode *TypeNode, operatorToken *TokenNode, right *Expression) *Node { + if left != node.Left || typeNode != node.Type || operatorToken != node.OperatorToken || right != node.Right { + return updateNode(f.NewBinaryExpression(modifiers, left, typeNode, operatorToken, right), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *BinaryExpression) ForEachChild(v Visitor) bool { + return visitModifiers(v, node.modifiers) || visit(v, node.Left) || visit(v, node.Type) || visit(v, node.OperatorToken) || visit(v, node.Right) +} + +func (node *BinaryExpression) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateBinaryExpression(node, v.visitModifiers(node.modifiers), v.visitNode(node.Left), v.visitNode(node.Type), v.visitToken(node.OperatorToken), v.visitNode(node.Right)) +} + +func (node *BinaryExpression) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewBinaryExpression(node.modifiers, node.Left, node.Type, node.OperatorToken, node.Right), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *BinaryExpression) computeSubtreeFacts() SubtreeFacts { + return propagateModifierListSubtreeFacts(node.modifiers) | + propagateSubtreeFacts(node.Left) | + propagateSubtreeFacts(node.Type) | + propagateSubtreeFacts(node.OperatorToken) | + propagateSubtreeFacts(node.Right) | + core.IfElse(node.OperatorToken.Kind == KindInKeyword && IsPrivateIdentifier(node.Left), SubtreeContainsClassFields, SubtreeFactsNone) +} + +func (node *BinaryExpression) setModifiers(modifiers *ModifierList) { node.modifiers = modifiers } + +func IsBinaryExpression(node *Node) bool { + return node.Kind == KindBinaryExpression +} + +// PrefixUnaryExpression + +type PrefixUnaryExpression struct { + ExpressionBase + Operator Kind + Operand *Expression // Expression +} + +func (f *NodeFactory) NewPrefixUnaryExpression(operator Kind, operand *Expression) *Node { + data := f.prefixUnaryExpressionPool.New() + data.Operator = operator + data.Operand = operand + return f.newNode(KindPrefixUnaryExpression, data) +} + +func (f *NodeFactory) UpdatePrefixUnaryExpression(node *PrefixUnaryExpression, operand *Expression) *Node { + if operand != node.Operand { + return updateNode(f.NewPrefixUnaryExpression(node.Operator, operand), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *PrefixUnaryExpression) ForEachChild(v Visitor) bool { + return visit(v, node.Operand) +} + +func (node *PrefixUnaryExpression) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdatePrefixUnaryExpression(node, v.visitNode(node.Operand)) +} + +func (node *PrefixUnaryExpression) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewPrefixUnaryExpression(node.Operator, node.Operand), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *PrefixUnaryExpression) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Operand) +} + +func IsPrefixUnaryExpression(node *Node) bool { + return node.Kind == KindPrefixUnaryExpression +} + +// PostfixUnaryExpression + +type PostfixUnaryExpression struct { + ExpressionBase + Operand *Expression // Expression + Operator Kind +} + +func (f *NodeFactory) NewPostfixUnaryExpression(operand *Expression, operator Kind) *Node { + data := &PostfixUnaryExpression{} + data.Operand = operand + data.Operator = operator + return f.newNode(KindPostfixUnaryExpression, data) +} + +func (f *NodeFactory) UpdatePostfixUnaryExpression(node *PostfixUnaryExpression, operand *Expression) *Node { + if operand != node.Operand { + return updateNode(f.NewPostfixUnaryExpression(operand, node.Operator), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *PostfixUnaryExpression) ForEachChild(v Visitor) bool { + return visit(v, node.Operand) +} + +func (node *PostfixUnaryExpression) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdatePostfixUnaryExpression(node, v.visitNode(node.Operand)) +} + +func (node *PostfixUnaryExpression) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewPostfixUnaryExpression(node.Operand, node.Operator), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *PostfixUnaryExpression) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Operand) +} + +// YieldExpression + +type YieldExpression struct { + ExpressionBase + AsteriskToken *TokenNode // TokenNode + Expression *Expression // Expression. Optional +} + +func (f *NodeFactory) NewYieldExpression(asteriskToken *TokenNode, expression *Expression) *Node { + data := &YieldExpression{} + data.AsteriskToken = asteriskToken + data.Expression = expression + return f.newNode(KindYieldExpression, data) +} + +func (f *NodeFactory) UpdateYieldExpression(node *YieldExpression, asteriskToken *TokenNode, expression *Expression) *Node { + if asteriskToken != node.AsteriskToken || expression != node.Expression { + return updateNode(f.NewYieldExpression(asteriskToken, expression), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *YieldExpression) ForEachChild(v Visitor) bool { + return visit(v, node.AsteriskToken) || visit(v, node.Expression) +} + +func (node *YieldExpression) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateYieldExpression(node, v.visitToken(node.AsteriskToken), v.visitNode(node.Expression)) +} + +func (node *YieldExpression) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewYieldExpression(node.AsteriskToken, node.Expression), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *YieldExpression) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) | SubtreeContainsForAwaitOrAsyncGenerator +} + +func IsYieldExpression(node *Node) bool { + return node.Kind == KindYieldExpression +} + +// ArrowFunction + +type ArrowFunction struct { + ExpressionBase + DeclarationBase + ModifiersBase + FunctionLikeWithBodyBase + FlowNodeBase + compositeNodeBase + EqualsGreaterThanToken *TokenNode // TokenNode +} + +func (f *NodeFactory) NewArrowFunction(modifiers *ModifierList, typeParameters *NodeList, parameters *NodeList, returnType *TypeNode, fullSignature *TypeNode, equalsGreaterThanToken *TokenNode, body *BlockOrExpression) *Node { + data := &ArrowFunction{} + data.modifiers = modifiers + data.TypeParameters = typeParameters + data.Parameters = parameters + data.Type = returnType + data.FullSignature = fullSignature + data.EqualsGreaterThanToken = equalsGreaterThanToken + data.Body = body + return f.newNode(KindArrowFunction, data) +} + +func (f *NodeFactory) UpdateArrowFunction(node *ArrowFunction, modifiers *ModifierList, typeParameters *TypeParameterList, parameters *ParameterList, returnType *TypeNode, fullSignature *TypeNode, equalsGreaterThanToken *TokenNode, body *BlockOrExpression) *Node { + if modifiers != node.modifiers || typeParameters != node.TypeParameters || parameters != node.Parameters || returnType != node.Type || fullSignature != node.FullSignature || equalsGreaterThanToken != node.EqualsGreaterThanToken || body != node.Body { + return updateNode(f.NewArrowFunction(modifiers, typeParameters, parameters, returnType, fullSignature, equalsGreaterThanToken, body), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ArrowFunction) ForEachChild(v Visitor) bool { + return visitModifiers(v, node.modifiers) || visitNodeList(v, node.TypeParameters) || visitNodeList(v, node.Parameters) || + visit(v, node.Type) || visit(v, node.FullSignature) || visit(v, node.EqualsGreaterThanToken) || visit(v, node.Body) +} + +func (node *ArrowFunction) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateArrowFunction(node, v.visitModifiers(node.modifiers), v.visitNodes(node.TypeParameters), v.visitParameters(node.Parameters), v.visitNode(node.Type), v.visitNode(node.FullSignature), v.visitToken(node.EqualsGreaterThanToken), v.visitFunctionBody(node.Body)) +} + +func (node *ArrowFunction) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewArrowFunction(node.Modifiers(), node.TypeParameters, node.Parameters, node.Type, node.FullSignature, node.EqualsGreaterThanToken, node.Body), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *ArrowFunction) Name() *DeclarationName { + return nil +} + +func (node *ArrowFunction) computeSubtreeFacts() SubtreeFacts { + return propagateModifierListSubtreeFacts(node.modifiers) | + propagateEraseableSyntaxListSubtreeFacts(node.TypeParameters) | + propagateNodeListSubtreeFacts(node.Parameters, propagateSubtreeFacts) | + propagateEraseableSyntaxSubtreeFacts(node.Type) | + propagateEraseableSyntaxSubtreeFacts(node.FullSignature) | + propagateSubtreeFacts(node.Body) | + core.IfElse(node.ModifierFlags()&ModifierFlagsAsync != 0, SubtreeContainsAnyAwait, SubtreeFactsNone) +} + +func (node *ArrowFunction) propagateSubtreeFacts() SubtreeFacts { + return node.SubtreeFacts() & ^SubtreeExclusionsArrowFunction +} + +func IsArrowFunction(node *Node) bool { + return node.Kind == KindArrowFunction +} + +// FunctionExpression + +type FunctionExpression struct { + ExpressionBase + DeclarationBase + ModifiersBase + FunctionLikeWithBodyBase + FlowNodeBase + compositeNodeBase + name *IdentifierNode // IdentifierNode. Optional + ReturnFlowNode *FlowNode +} + +func (f *NodeFactory) NewFunctionExpression(modifiers *ModifierList, asteriskToken *TokenNode, name *IdentifierNode, typeParameters *NodeList, parameters *NodeList, returnType *TypeNode, fullSignature *TypeNode, body *BlockNode) *Node { + data := &FunctionExpression{} + data.modifiers = modifiers + data.AsteriskToken = asteriskToken + data.name = name + data.TypeParameters = typeParameters + data.Parameters = parameters + data.Type = returnType + data.FullSignature = fullSignature + data.Body = body + return f.newNode(KindFunctionExpression, data) +} + +func (f *NodeFactory) UpdateFunctionExpression(node *FunctionExpression, modifiers *ModifierList, asteriskToken *TokenNode, name *IdentifierNode, typeParameters *TypeParameterList, parameters *ParameterList, returnType *TypeNode, fullSignature *TypeNode, body *BlockNode) *Node { + if modifiers != node.modifiers || asteriskToken != node.AsteriskToken || name != node.name || typeParameters != node.TypeParameters || parameters != node.Parameters || returnType != node.Type || fullSignature != node.FullSignature || body != node.Body { + return updateNode(f.NewFunctionExpression(modifiers, asteriskToken, name, typeParameters, parameters, returnType, fullSignature, body), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *FunctionExpression) ForEachChild(v Visitor) bool { + return visitModifiers(v, node.modifiers) || visit(v, node.AsteriskToken) || visit(v, node.name) || visitNodeList(v, node.TypeParameters) || + visitNodeList(v, node.Parameters) || visit(v, node.Type) || visit(v, node.FullSignature) || visit(v, node.Body) +} + +func (node *FunctionExpression) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateFunctionExpression(node, v.visitModifiers(node.modifiers), v.visitToken(node.AsteriskToken), v.visitNode(node.name), v.visitNodes(node.TypeParameters), v.visitParameters(node.Parameters), v.visitNode(node.Type), v.visitNode(node.FullSignature), v.visitFunctionBody(node.Body)) +} + +func (node *FunctionExpression) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewFunctionExpression(node.Modifiers(), node.AsteriskToken, node.Name(), node.TypeParameters, node.Parameters, node.Type, node.FullSignature, node.Body), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *FunctionExpression) Name() *DeclarationName { + return node.name +} + +func (node *FunctionExpression) computeSubtreeFacts() SubtreeFacts { + isAsync := node.modifiers != nil && node.modifiers.ModifierFlags&ModifierFlagsAsync != 0 + isGenerator := node.AsteriskToken != nil + return propagateModifierListSubtreeFacts(node.modifiers) | + propagateSubtreeFacts(node.AsteriskToken) | + propagateSubtreeFacts(node.name) | + propagateEraseableSyntaxListSubtreeFacts(node.TypeParameters) | + propagateNodeListSubtreeFacts(node.Parameters, propagateSubtreeFacts) | + propagateEraseableSyntaxSubtreeFacts(node.Type) | + propagateEraseableSyntaxSubtreeFacts(node.FullSignature) | + propagateSubtreeFacts(node.Body) | + core.IfElse(isAsync && isGenerator, SubtreeContainsForAwaitOrAsyncGenerator, SubtreeFactsNone) | + core.IfElse(isAsync && !isGenerator, SubtreeContainsAnyAwait, SubtreeFactsNone) +} + +func (node *FunctionExpression) propagateSubtreeFacts() SubtreeFacts { + return node.SubtreeFacts() & ^SubtreeExclusionsFunction +} + +func IsFunctionExpression(node *Node) bool { + return node.Kind == KindFunctionExpression +} + +// AsExpression + +type AsExpression struct { + ExpressionBase + Expression *Expression // Expression + Type *TypeNode // TypeNode +} + +func (f *NodeFactory) NewAsExpression(expression *Expression, typeNode *TypeNode) *Node { + data := &AsExpression{} + data.Expression = expression + data.Type = typeNode + return f.newNode(KindAsExpression, data) +} + +func (f *NodeFactory) UpdateAsExpression(node *AsExpression, expression *Expression, typeNode *TypeNode) *Node { + if expression != node.Expression || typeNode != node.Type { + return updateNode(f.NewAsExpression(expression, typeNode), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *AsExpression) ForEachChild(v Visitor) bool { + return visit(v, node.Expression) || visit(v, node.Type) +} + +func (node *AsExpression) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateAsExpression(node, v.visitNode(node.Expression), v.visitNode(node.Type)) +} + +func (node *AsExpression) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewAsExpression(node.Expression, node.Type), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *AsExpression) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) | SubtreeContainsTypeScript +} + +func (node *AsExpression) propagateSubtreeFacts() SubtreeFacts { + return node.SubtreeFacts() & ^SubtreeExclusionsOuterExpression +} + +// SatisfiesExpression + +type SatisfiesExpression struct { + ExpressionBase + Expression *Expression // Expression + Type *TypeNode // TypeNode +} + +func (f *NodeFactory) NewSatisfiesExpression(expression *Expression, typeNode *TypeNode) *Node { + data := &SatisfiesExpression{} + data.Expression = expression + data.Type = typeNode + return f.newNode(KindSatisfiesExpression, data) +} + +func (f *NodeFactory) UpdateSatisfiesExpression(node *SatisfiesExpression, expression *Expression, typeNode *TypeNode) *Node { + if expression != node.Expression || typeNode != node.Type { + return updateNode(f.NewSatisfiesExpression(expression, typeNode), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *SatisfiesExpression) ForEachChild(v Visitor) bool { + return visit(v, node.Expression) || visit(v, node.Type) +} + +func (node *SatisfiesExpression) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateSatisfiesExpression(node, v.visitNode(node.Expression), v.visitNode(node.Type)) +} + +func (node *SatisfiesExpression) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewSatisfiesExpression(node.Expression, node.Type), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *SatisfiesExpression) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) | SubtreeContainsTypeScript +} + +func (node *SatisfiesExpression) propagateSubtreeFacts() SubtreeFacts { + return node.SubtreeFacts() & ^SubtreeExclusionsOuterExpression +} + +func IsSatisfiesExpression(node *Node) bool { + return node.Kind == KindSatisfiesExpression +} + +// ConditionalExpression + +type ConditionalExpression struct { + ExpressionBase + compositeNodeBase + Condition *Expression + QuestionToken *TokenNode + WhenTrue *Expression + ColonToken *TokenNode + WhenFalse *Expression +} + +func (f *NodeFactory) NewConditionalExpression(condition *Expression, questionToken *TokenNode, whenTrue *Expression, colonToken *TokenNode, whenFalse *Expression) *Node { + data := f.conditionalExpressionPool.New() + data.Condition = condition + data.QuestionToken = questionToken + data.WhenTrue = whenTrue + data.ColonToken = colonToken + data.WhenFalse = whenFalse + return f.newNode(KindConditionalExpression, data) +} + +func (f *NodeFactory) UpdateConditionalExpression(node *ConditionalExpression, condition *Expression, questionToken *TokenNode, whenTrue *Expression, colonToken *TokenNode, whenFalse *Expression) *Node { + if condition != node.Condition || questionToken != node.QuestionToken || whenTrue != node.WhenTrue || colonToken != node.ColonToken || whenFalse != node.WhenFalse { + return updateNode(f.NewConditionalExpression(condition, questionToken, whenTrue, colonToken, whenFalse), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ConditionalExpression) ForEachChild(v Visitor) bool { + return visit(v, node.Condition) || visit(v, node.QuestionToken) || visit(v, node.WhenTrue) || + visit(v, node.ColonToken) || visit(v, node.WhenFalse) +} + +func (node *ConditionalExpression) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateConditionalExpression(node, v.visitNode(node.Condition), v.visitToken(node.QuestionToken), v.visitNode(node.WhenTrue), v.visitToken(node.ColonToken), v.visitNode(node.WhenFalse)) +} + +func (node *ConditionalExpression) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewConditionalExpression(node.Condition, node.QuestionToken, node.WhenTrue, node.ColonToken, node.WhenFalse), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *ConditionalExpression) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Condition) | + propagateSubtreeFacts(node.WhenTrue) | + propagateSubtreeFacts(node.WhenFalse) +} + +func IsConditionalExpression(node *Node) bool { + return node.Kind == KindConditionalExpression +} + +// PropertyAccessExpression + +type PropertyAccessExpression struct { + ExpressionBase + FlowNodeBase + compositeNodeBase + Expression *Expression // Expression + QuestionDotToken *TokenNode // TokenNode + name *MemberName // MemberName +} + +func (f *NodeFactory) NewPropertyAccessExpression(expression *Expression, questionDotToken *TokenNode, name *MemberName, flags NodeFlags) *Node { + data := f.propertyAccessExpressionPool.New() + data.Expression = expression + data.QuestionDotToken = questionDotToken + data.name = name + node := f.newNode(KindPropertyAccessExpression, data) + node.Flags |= flags & NodeFlagsOptionalChain + return node +} + +func (f *NodeFactory) UpdatePropertyAccessExpression(node *PropertyAccessExpression, expression *Expression, questionDotToken *TokenNode, name *MemberName) *Node { + if expression != node.Expression || questionDotToken != node.QuestionDotToken || name != node.name { + return updateNode(f.NewPropertyAccessExpression(expression, questionDotToken, name, node.Flags), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *PropertyAccessExpression) ForEachChild(v Visitor) bool { + return visit(v, node.Expression) || visit(v, node.QuestionDotToken) || visit(v, node.name) +} + +func (node *PropertyAccessExpression) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdatePropertyAccessExpression(node, v.visitNode(node.Expression), v.visitToken(node.QuestionDotToken), v.visitNode(node.name)) +} + +func (node *PropertyAccessExpression) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewPropertyAccessExpression(node.Expression, node.QuestionDotToken, node.Name(), node.Flags), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *PropertyAccessExpression) Name() *DeclarationName { return node.name } + +func (node *PropertyAccessExpression) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) | + propagateSubtreeFacts(node.QuestionDotToken) | + propagateSubtreeFacts(node.name) +} + +func (node *PropertyAccessExpression) propagateSubtreeFacts() SubtreeFacts { + return node.SubtreeFacts() & ^SubtreeExclusionsPropertyAccess +} + +func IsPropertyAccessExpression(node *Node) bool { + return node.Kind == KindPropertyAccessExpression +} + +// ElementAccessExpression + +type ElementAccessExpression struct { + ExpressionBase + FlowNodeBase + compositeNodeBase + Expression *Expression // Expression + QuestionDotToken *TokenNode // TokenNode + ArgumentExpression *Expression // Expression +} + +func (f *NodeFactory) NewElementAccessExpression(expression *Expression, questionDotToken *TokenNode, argumentExpression *Expression, flags NodeFlags) *Node { + data := f.elementAccessExpressionPool.New() + data.Expression = expression + data.QuestionDotToken = questionDotToken + data.ArgumentExpression = argumentExpression + node := f.newNode(KindElementAccessExpression, data) + node.Flags |= flags & NodeFlagsOptionalChain + return node +} + +func (f *NodeFactory) UpdateElementAccessExpression(node *ElementAccessExpression, expression *Expression, questionDotToken *TokenNode, argumentExpression *Expression) *Node { + if expression != node.Expression || questionDotToken != node.QuestionDotToken || argumentExpression != node.ArgumentExpression { + return updateNode(f.NewElementAccessExpression(expression, questionDotToken, argumentExpression, node.Flags), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ElementAccessExpression) ForEachChild(v Visitor) bool { + return visit(v, node.Expression) || visit(v, node.QuestionDotToken) || visit(v, node.ArgumentExpression) +} + +func (node *ElementAccessExpression) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateElementAccessExpression(node, v.visitNode(node.Expression), v.visitToken(node.QuestionDotToken), v.visitNode(node.ArgumentExpression)) +} + +func (node *ElementAccessExpression) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewElementAccessExpression(node.Expression, node.QuestionDotToken, node.ArgumentExpression, node.Flags), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *ElementAccessExpression) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) | + propagateSubtreeFacts(node.QuestionDotToken) | + propagateSubtreeFacts(node.ArgumentExpression) +} + +func (node *ElementAccessExpression) propagateSubtreeFacts() SubtreeFacts { + return node.SubtreeFacts() & ^SubtreeExclusionsElementAccess +} + +func IsElementAccessExpression(node *Node) bool { + return node.Kind == KindElementAccessExpression +} + +// CallExpression + +type CallExpression struct { + ExpressionBase + compositeNodeBase + Expression *Expression // Expression + QuestionDotToken *TokenNode // TokenNode + TypeArguments *NodeList // NodeList[*TypeNode]. Optional + Arguments *NodeList // NodeList[*Expression] +} + +func (f *NodeFactory) NewCallExpression(expression *Expression, questionDotToken *TokenNode, typeArguments *NodeList, arguments *NodeList, flags NodeFlags) *Node { + data := f.callExpressionPool.New() + data.Expression = expression + data.QuestionDotToken = questionDotToken + data.TypeArguments = typeArguments + data.Arguments = arguments + node := f.newNode(KindCallExpression, data) + node.Flags |= flags & NodeFlagsOptionalChain + return node +} + +func (f *NodeFactory) UpdateCallExpression(node *CallExpression, expression *Expression, questionDotToken *TokenNode, typeArguments *TypeArgumentList, arguments *ArgumentList) *Node { + if expression != node.Expression || questionDotToken != node.QuestionDotToken || typeArguments != node.TypeArguments || arguments != node.Arguments { + return updateNode(f.NewCallExpression(expression, questionDotToken, typeArguments, arguments, node.Flags), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *CallExpression) ForEachChild(v Visitor) bool { + return visit(v, node.Expression) || visit(v, node.QuestionDotToken) || visitNodeList(v, node.TypeArguments) || visitNodeList(v, node.Arguments) +} + +func (node *CallExpression) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateCallExpression(node, v.visitNode(node.Expression), v.visitToken(node.QuestionDotToken), v.visitNodes(node.TypeArguments), v.visitNodes(node.Arguments)) +} + +func (node *CallExpression) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewCallExpression(node.Expression, node.QuestionDotToken, node.TypeArguments, node.Arguments, node.Flags), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *CallExpression) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) | + propagateSubtreeFacts(node.QuestionDotToken) | + propagateEraseableSyntaxListSubtreeFacts(node.TypeArguments) | + propagateNodeListSubtreeFacts(node.Arguments, propagateSubtreeFacts) | + core.IfElse(node.Expression.Kind == KindImportKeyword, SubtreeContainsDynamicImport, SubtreeFactsNone) +} + +func (node *CallExpression) propagateSubtreeFacts() SubtreeFacts { + return node.SubtreeFacts() & ^SubtreeExclusionsCall +} + +func IsCallExpression(node *Node) bool { + return node.Kind == KindCallExpression +} + +// NewExpression + +type NewExpression struct { + ExpressionBase + compositeNodeBase + Expression *Expression // Expression + TypeArguments *NodeList // NodeList[*TypeNode]. Optional + Arguments *NodeList // NodeList[*Expression]. Optional +} + +func (f *NodeFactory) NewNewExpression(expression *Expression, typeArguments *NodeList, arguments *NodeList) *Node { + data := &NewExpression{} + data.Expression = expression + data.TypeArguments = typeArguments + data.Arguments = arguments + return f.newNode(KindNewExpression, data) +} + +func (f *NodeFactory) UpdateNewExpression(node *NewExpression, expression *Expression, typeArguments *TypeArgumentList, arguments *ArgumentList) *Node { + if expression != node.Expression || typeArguments != node.TypeArguments || arguments != node.Arguments { + return updateNode(f.NewNewExpression(expression, typeArguments, arguments), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *NewExpression) ForEachChild(v Visitor) bool { + return visit(v, node.Expression) || visitNodeList(v, node.TypeArguments) || visitNodeList(v, node.Arguments) +} + +func (node *NewExpression) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateNewExpression(node, v.visitNode(node.Expression), v.visitNodes(node.TypeArguments), v.visitNodes(node.Arguments)) +} + +func (node *NewExpression) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewNewExpression(node.Expression, node.TypeArguments, node.Arguments), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *NewExpression) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) | + propagateEraseableSyntaxListSubtreeFacts(node.TypeArguments) | + propagateNodeListSubtreeFacts(node.Arguments, propagateSubtreeFacts) +} + +func (node *NewExpression) propagateSubtreeFacts() SubtreeFacts { + return node.SubtreeFacts() & ^SubtreeExclusionsNew +} + +func IsNewExpression(node *Node) bool { + return node.Kind == KindNewExpression +} + +// MetaProperty + +type MetaProperty struct { + ExpressionBase + FlowNodeBase + compositeNodeBase + KeywordToken Kind // NewKeyword | ImportKeyword + name *IdentifierNode // IdentifierNode +} + +func (f *NodeFactory) NewMetaProperty(keywordToken Kind, name *IdentifierNode) *Node { + data := &MetaProperty{} + data.KeywordToken = keywordToken + data.name = name + return f.newNode(KindMetaProperty, data) +} + +func (f *NodeFactory) UpdateMetaProperty(node *MetaProperty, name *IdentifierNode) *Node { + if name != node.name { + return updateNode(f.NewMetaProperty(node.KeywordToken, name), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *MetaProperty) ForEachChild(v Visitor) bool { + return visit(v, node.name) +} + +func (node *MetaProperty) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateMetaProperty(node, v.visitNode(node.name)) +} + +func (node *MetaProperty) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewMetaProperty(node.Kind, node.Name()), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *MetaProperty) Name() *DeclarationName { + return node.name +} + +func (node *MetaProperty) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.name) // `import.meta` is not downleveled in any way +} + +func IsMetaProperty(node *Node) bool { + return node.Kind == KindMetaProperty +} + +// NonNullExpression + +type NonNullExpression struct { + ExpressionBase + Expression *Expression // Expression +} + +func (f *NodeFactory) NewNonNullExpression(expression *Expression, flags NodeFlags) *Node { + data := &NonNullExpression{} + data.Expression = expression + data.Flags |= flags & NodeFlagsOptionalChain + return f.newNode(KindNonNullExpression, data) +} + +func (f *NodeFactory) UpdateNonNullExpression(node *NonNullExpression, expression *Expression) *Node { + if expression != node.Expression { + return updateNode(f.NewNonNullExpression(expression, node.AsNode().Flags), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *NonNullExpression) ForEachChild(v Visitor) bool { + return visit(v, node.Expression) +} + +func (node *NonNullExpression) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateNonNullExpression(node, v.visitNode(node.Expression)) +} + +func (node *NonNullExpression) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewNonNullExpression(node.Expression, node.Flags), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *NonNullExpression) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) | SubtreeContainsTypeScript +} + +func IsNonNullExpression(node *Node) bool { + return node.Kind == KindNonNullExpression +} + +// SpreadElement + +type SpreadElement struct { + ExpressionBase + Expression *Expression // Expression +} + +func (f *NodeFactory) NewSpreadElement(expression *Expression) *Node { + data := &SpreadElement{} + data.Expression = expression + return f.newNode(KindSpreadElement, data) +} + +func (f *NodeFactory) UpdateSpreadElement(node *SpreadElement, expression *Expression) *Node { + if expression != node.Expression { + return updateNode(f.NewSpreadElement(expression), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *SpreadElement) ForEachChild(v Visitor) bool { + return visit(v, node.Expression) +} + +func (node *SpreadElement) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateSpreadElement(node, v.visitNode(node.Expression)) +} + +func (node *SpreadElement) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewSpreadElement(node.Expression), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *SpreadElement) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) | SubtreeContainsRestOrSpread +} + +func IsSpreadElement(node *Node) bool { + return node.Kind == KindSpreadElement +} + +// TemplateExpression + +type TemplateExpression struct { + ExpressionBase + compositeNodeBase + Head *TemplateHeadNode // TemplateHeadNode + TemplateSpans *NodeList // NodeList[*TemplateSpanNode] +} + +func (f *NodeFactory) NewTemplateExpression(head *TemplateHeadNode, templateSpans *NodeList) *Node { + data := &TemplateExpression{} + data.Head = head + data.TemplateSpans = templateSpans + return f.newNode(KindTemplateExpression, data) +} + +func (f *NodeFactory) UpdateTemplateExpression(node *TemplateExpression, head *TemplateHeadNode, templateSpans *TemplateSpanList) *Node { + if head != node.Head || templateSpans != node.TemplateSpans { + return updateNode(f.NewTemplateExpression(head, templateSpans), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *TemplateExpression) ForEachChild(v Visitor) bool { + return visit(v, node.Head) || visitNodeList(v, node.TemplateSpans) +} + +func (node *TemplateExpression) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateTemplateExpression(node, v.visitNode(node.Head), v.visitNodes(node.TemplateSpans)) +} + +func (node *TemplateExpression) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewTemplateExpression(node.Head, node.TemplateSpans), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *TemplateExpression) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Head) | + propagateNodeListSubtreeFacts(node.TemplateSpans, propagateSubtreeFacts) +} + +func IsTemplateExpression(node *Node) bool { + return node.Kind == KindTemplateExpression +} + +// TemplateLiteralTypeSpan + +type TemplateSpan struct { + NodeBase + Expression *Expression // Expression + Literal *TemplateMiddleOrTail // TemplateMiddleOrTail +} + +func (f *NodeFactory) NewTemplateSpan(expression *Expression, literal *TemplateMiddleOrTail) *Node { + data := &TemplateSpan{} + data.Expression = expression + data.Literal = literal + return f.newNode(KindTemplateSpan, data) +} + +func (f *NodeFactory) UpdateTemplateSpan(node *TemplateSpan, expression *Expression, literal *TemplateMiddleOrTail) *Node { + if expression != node.Expression || literal != node.Literal { + return updateNode(f.NewTemplateSpan(expression, literal), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *TemplateSpan) ForEachChild(v Visitor) bool { + return visit(v, node.Expression) || visit(v, node.Literal) +} + +func (node *TemplateSpan) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateTemplateSpan(node, v.visitNode(node.Expression), v.visitNode(node.Literal)) +} + +func (node *TemplateSpan) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewTemplateSpan(node.Expression, node.Literal), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *TemplateSpan) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) +} + +func IsTemplateSpan(node *Node) bool { + return node.Kind == KindTemplateSpan +} + +// TaggedTemplateExpression + +type TaggedTemplateExpression struct { + ExpressionBase + compositeNodeBase + Tag *Expression // Expression + QuestionDotToken *TokenNode // TokenNode. For error reporting purposes only + TypeArguments *NodeList // NodeList[*TypeNode]. Optional + Template *TemplateLiteral // TemplateLiteral +} + +func (f *NodeFactory) NewTaggedTemplateExpression(tag *Expression, questionDotToken *TokenNode, typeArguments *NodeList, template *TemplateLiteral, flags NodeFlags) *Node { + data := &TaggedTemplateExpression{} + data.Tag = tag + data.QuestionDotToken = questionDotToken + data.TypeArguments = typeArguments + data.Template = template + node := f.newNode(KindTaggedTemplateExpression, data) + node.Flags |= flags & NodeFlagsOptionalChain + return node +} + +func (f *NodeFactory) UpdateTaggedTemplateExpression(node *TaggedTemplateExpression, tag *Expression, questionDotToken *TokenNode, typeArguments *TypeArgumentList, template *TemplateLiteral) *Node { + if tag != node.Tag || questionDotToken != node.QuestionDotToken || typeArguments != node.TypeArguments || template != node.Template { + return updateNode(f.NewTaggedTemplateExpression(tag, questionDotToken, typeArguments, template, node.Flags), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *TaggedTemplateExpression) ForEachChild(v Visitor) bool { + return visit(v, node.Tag) || visit(v, node.QuestionDotToken) || visitNodeList(v, node.TypeArguments) || visit(v, node.Template) +} + +func (node *TaggedTemplateExpression) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateTaggedTemplateExpression(node, v.visitNode(node.Tag), v.visitToken(node.QuestionDotToken), v.visitNodes(node.TypeArguments), v.visitNode(node.Template)) +} + +func (node *TaggedTemplateExpression) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewTaggedTemplateExpression(node.Tag, node.QuestionDotToken, node.TypeArguments, node.Template, node.Flags), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *TaggedTemplateExpression) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Tag) | + propagateSubtreeFacts(node.QuestionDotToken) | + propagateEraseableSyntaxListSubtreeFacts(node.TypeArguments) | + propagateSubtreeFacts(node.Template) +} + +func IsTaggedTemplateExpression(node *Node) bool { + return node.Kind == KindTaggedTemplateExpression +} + +// ParenthesizedExpression + +type ParenthesizedExpression struct { + ExpressionBase + Expression *Expression // Expression +} + +func (f *NodeFactory) NewParenthesizedExpression(expression *Expression) *Node { + data := f.parenthesizedExpressionPool.New() + data.Expression = expression + return f.newNode(KindParenthesizedExpression, data) +} + +func (f *NodeFactory) UpdateParenthesizedExpression(node *ParenthesizedExpression, expression *Expression) *Node { + if expression != node.Expression { + return updateNode(f.NewParenthesizedExpression(expression), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ParenthesizedExpression) ForEachChild(v Visitor) bool { + return visit(v, node.Expression) +} + +func (node *ParenthesizedExpression) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateParenthesizedExpression(node, v.visitNode(node.Expression)) +} + +func (node *ParenthesizedExpression) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewParenthesizedExpression(node.Expression), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *ParenthesizedExpression) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) +} + +func (node *ParenthesizedExpression) propagateSubtreeFacts() SubtreeFacts { + return node.SubtreeFacts() & ^SubtreeExclusionsOuterExpression +} + +func IsParenthesizedExpression(node *Node) bool { + return node.Kind == KindParenthesizedExpression +} + +// ArrayLiteralExpression + +type ArrayLiteralExpression struct { + ExpressionBase + compositeNodeBase + Elements *NodeList // NodeList[*Expression] + MultiLine bool +} + +func (f *NodeFactory) NewArrayLiteralExpression(elements *NodeList, multiLine bool) *Node { + data := &ArrayLiteralExpression{} + data.Elements = elements + data.MultiLine = multiLine + return f.newNode(KindArrayLiteralExpression, data) +} + +func (f *NodeFactory) UpdateArrayLiteralExpression(node *ArrayLiteralExpression, elements *ElementList) *Node { + if elements != node.Elements { + return updateNode(f.NewArrayLiteralExpression(elements, node.MultiLine), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ArrayLiteralExpression) ForEachChild(v Visitor) bool { + return visitNodeList(v, node.Elements) +} + +func (node *ArrayLiteralExpression) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateArrayLiteralExpression(node, v.visitNodes(node.Elements)) +} + +func (node *ArrayLiteralExpression) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewArrayLiteralExpression(node.Elements, node.MultiLine), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *ArrayLiteralExpression) computeSubtreeFacts() SubtreeFacts { + return propagateNodeListSubtreeFacts(node.Elements, propagateSubtreeFacts) +} + +func (node *ArrayLiteralExpression) propagateSubtreeFacts() SubtreeFacts { + return node.SubtreeFacts() & ^SubtreeExclusionsArrayLiteral +} + +func IsArrayLiteralExpression(node *Node) bool { + return node.Kind == KindArrayLiteralExpression +} + +// ObjectLiteralExpression + +type ObjectLiteralExpression struct { + ExpressionBase + DeclarationBase + compositeNodeBase + Properties *NodeList // NodeList[*ObjectLiteralElement] + MultiLine bool +} + +func (f *NodeFactory) NewObjectLiteralExpression(properties *NodeList, multiLine bool) *Node { + data := &ObjectLiteralExpression{} + data.Properties = properties + data.MultiLine = multiLine + return f.newNode(KindObjectLiteralExpression, data) +} + +func (f *NodeFactory) UpdateObjectLiteralExpression(node *ObjectLiteralExpression, properties *PropertyDefinitionList) *Node { + if properties != node.Properties { + return updateNode(f.NewObjectLiteralExpression(properties, node.MultiLine), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ObjectLiteralExpression) ForEachChild(v Visitor) bool { + return visitNodeList(v, node.Properties) +} + +func (node *ObjectLiteralExpression) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateObjectLiteralExpression(node, v.visitNodes(node.Properties)) +} + +func (node *ObjectLiteralExpression) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewObjectLiteralExpression(node.Properties, node.MultiLine), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *ObjectLiteralExpression) computeSubtreeFacts() SubtreeFacts { + return propagateNodeListSubtreeFacts(node.Properties, propagateSubtreeFacts) +} + +func (node *ObjectLiteralExpression) propagateSubtreeFacts() SubtreeFacts { + return node.SubtreeFacts() & ^SubtreeExclusionsObjectLiteral +} + +func IsObjectLiteralExpression(node *Node) bool { + return node.Kind == KindObjectLiteralExpression +} + +// ObjectLiteralElementBase + +type ObjectLiteralElementBase struct{} + +// SpreadAssignment + +type SpreadAssignment struct { + NodeBase + DeclarationBase + ObjectLiteralElementBase + Expression *Expression // Expression +} + +func (f *NodeFactory) NewSpreadAssignment(expression *Expression) *Node { + data := &SpreadAssignment{} + data.Expression = expression + return f.newNode(KindSpreadAssignment, data) +} + +func (f *NodeFactory) UpdateSpreadAssignment(node *SpreadAssignment, expression *Expression) *Node { + if expression != node.Expression { + return updateNode(f.NewSpreadAssignment(expression), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *SpreadAssignment) ForEachChild(v Visitor) bool { + return visit(v, node.Expression) +} + +func (node *SpreadAssignment) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateSpreadAssignment(node, v.visitNode(node.Expression)) +} + +func (node *SpreadAssignment) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewSpreadAssignment(node.Expression), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *SpreadAssignment) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) | SubtreeContainsESObjectRestOrSpread | SubtreeContainsObjectRestOrSpread +} + +func IsSpreadAssignment(node *Node) bool { + return node.Kind == KindSpreadAssignment +} + +// PropertyAssignment + +type PropertyAssignment struct { + NodeBase + NamedMemberBase + ObjectLiteralElementBase + compositeNodeBase + Type *TypeNode // TypeNode. Only set by JSDoc @type tags. + Initializer *Expression // Expression +} + +func (f *NodeFactory) NewPropertyAssignment(modifiers *ModifierList, name *PropertyName, postfixToken *TokenNode, typeNode *TypeNode, initializer *Expression) *Node { + data := f.propertyAssignmentPool.New() + data.modifiers = modifiers + data.name = name + data.PostfixToken = postfixToken + data.Type = typeNode + data.Initializer = initializer + return f.newNode(KindPropertyAssignment, data) +} + +func (f *NodeFactory) UpdatePropertyAssignment(node *PropertyAssignment, modifiers *ModifierList, name *PropertyName, postfixToken *TokenNode, typeNode *TypeNode, initializer *Expression) *Node { + if modifiers != node.modifiers || name != node.name || postfixToken != node.PostfixToken || typeNode != node.Type || initializer != node.Initializer { + return updateNode(f.NewPropertyAssignment(modifiers, name, postfixToken, typeNode, initializer), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *PropertyAssignment) ForEachChild(v Visitor) bool { + return visitModifiers(v, node.modifiers) || visit(v, node.name) || visit(v, node.PostfixToken) || visit(v, node.Type) || visit(v, node.Initializer) +} + +func (node *PropertyAssignment) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdatePropertyAssignment(node, v.visitModifiers(node.modifiers), v.visitNode(node.name), v.visitToken(node.PostfixToken), v.visitNode(node.Type), v.visitNode(node.Initializer)) +} + +func (node *PropertyAssignment) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewPropertyAssignment(node.Modifiers(), node.Name(), node.PostfixToken, node.Type, node.Initializer), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *PropertyAssignment) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.name) | + propagateSubtreeFacts(node.Type) | + propagateSubtreeFacts(node.Initializer) +} + +func IsPropertyAssignment(node *Node) bool { + return node.Kind == KindPropertyAssignment +} + +// ShorthandPropertyAssignment + +type ShorthandPropertyAssignment struct { + NodeBase + NamedMemberBase + ObjectLiteralElementBase + compositeNodeBase + Type *TypeNode // TypeNode. Only set by JSDoc @type tags. + EqualsToken *TokenNode + ObjectAssignmentInitializer *Expression // Optional +} + +func (f *NodeFactory) NewShorthandPropertyAssignment(modifiers *ModifierList, name *PropertyName, postfixToken *TokenNode, typeNode *TypeNode, equalsToken *TokenNode, objectAssignmentInitializer *Expression) *Node { + data := &ShorthandPropertyAssignment{} + data.modifiers = modifiers + data.name = name + data.PostfixToken = postfixToken + data.Type = typeNode + data.EqualsToken = equalsToken + data.ObjectAssignmentInitializer = objectAssignmentInitializer + return f.newNode(KindShorthandPropertyAssignment, data) +} + +func (f *NodeFactory) UpdateShorthandPropertyAssignment(node *ShorthandPropertyAssignment, modifiers *ModifierList, name *PropertyName, postfixToken *TokenNode, typeNode *TypeNode, equalsToken *TokenNode, objectAssignmentInitializer *Expression) *Node { + if modifiers != node.modifiers || name != node.name || typeNode != node.Type || postfixToken != node.PostfixToken || objectAssignmentInitializer != node.ObjectAssignmentInitializer { + return updateNode(f.NewShorthandPropertyAssignment(modifiers, name, postfixToken, typeNode, equalsToken, objectAssignmentInitializer), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ShorthandPropertyAssignment) ForEachChild(v Visitor) bool { + return visitModifiers(v, node.modifiers) || visit(v, node.name) || visit(v, node.Type) || visit(v, node.PostfixToken) || visit(v, node.EqualsToken) || visit(v, node.ObjectAssignmentInitializer) +} + +func (node *ShorthandPropertyAssignment) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateShorthandPropertyAssignment(node, v.visitModifiers(node.modifiers), v.visitNode(node.name), v.visitToken(node.PostfixToken), v.visitNode(node.Type), v.visitToken(node.EqualsToken), v.visitNode(node.ObjectAssignmentInitializer)) +} + +func (node *ShorthandPropertyAssignment) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewShorthandPropertyAssignment(node.Modifiers(), node.Name(), node.PostfixToken, node.Type, node.EqualsToken, node.ObjectAssignmentInitializer), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *ShorthandPropertyAssignment) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.name) | // we do not use propagateSubtreeFacts here because this is an IdentifierReference + propagateSubtreeFacts(node.Type) | + propagateSubtreeFacts(node.ObjectAssignmentInitializer) | + SubtreeContainsTypeScript // may require rewriting in a TypeScript namespace +} + +func IsShorthandPropertyAssignment(node *Node) bool { + return node.Kind == KindShorthandPropertyAssignment +} + +// DeleteExpression + +type DeleteExpression struct { + ExpressionBase + Expression *Expression // Expression +} + +func (f *NodeFactory) NewDeleteExpression(expression *Expression) *Node { + data := &DeleteExpression{} + data.Expression = expression + return f.newNode(KindDeleteExpression, data) +} + +func (f *NodeFactory) UpdateDeleteExpression(node *DeleteExpression, expression *Expression) *Node { + if expression != node.Expression { + return updateNode(f.NewDeleteExpression(expression), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *DeleteExpression) ForEachChild(v Visitor) bool { + return visit(v, node.Expression) +} + +func (node *DeleteExpression) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateDeleteExpression(node, v.visitNode(node.Expression)) +} + +func (node *DeleteExpression) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewDeleteExpression(node.Expression), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *DeleteExpression) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) +} + +// TypeOfExpression + +type TypeOfExpression struct { + ExpressionBase + Expression *Expression // Expression +} + +func (f *NodeFactory) NewTypeOfExpression(expression *Expression) *Node { + data := &TypeOfExpression{} + data.Expression = expression + return f.newNode(KindTypeOfExpression, data) +} + +func (f *NodeFactory) UpdateTypeOfExpression(node *TypeOfExpression, expression *Expression) *Node { + if expression != node.Expression { + return updateNode(f.NewTypeOfExpression(expression), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *TypeOfExpression) ForEachChild(v Visitor) bool { + return visit(v, node.Expression) +} + +func (node *TypeOfExpression) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateTypeOfExpression(node, v.visitNode(node.Expression)) +} + +func (node *TypeOfExpression) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewTypeOfExpression(node.Expression), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *TypeOfExpression) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) +} + +func IsTypeOfExpression(node *Node) bool { + return node.Kind == KindTypeOfExpression +} + +// VoidExpression + +type VoidExpression struct { + ExpressionBase + Expression *Expression // Expression +} + +func (f *NodeFactory) NewVoidExpression(expression *Expression) *Node { + data := &VoidExpression{} + data.Expression = expression + return f.newNode(KindVoidExpression, data) +} + +func (f *NodeFactory) UpdateVoidExpression(node *VoidExpression, expression *Expression) *Node { + if expression != node.Expression { + return updateNode(f.NewVoidExpression(expression), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *VoidExpression) ForEachChild(v Visitor) bool { + return visit(v, node.Expression) +} + +func (node *VoidExpression) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateVoidExpression(node, v.visitNode(node.Expression)) +} + +func (node *VoidExpression) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewVoidExpression(node.Expression), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *VoidExpression) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) +} + +// AwaitExpression + +type AwaitExpression struct { + ExpressionBase + Expression *Expression // Expression +} + +func (f *NodeFactory) NewAwaitExpression(expression *Expression) *Node { + data := &AwaitExpression{} + data.Expression = expression + return f.newNode(KindAwaitExpression, data) +} + +func (f *NodeFactory) UpdateAwaitExpression(node *AwaitExpression, expression *Expression) *Node { + if expression != node.Expression { + return updateNode(f.NewAwaitExpression(expression), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *AwaitExpression) ForEachChild(v Visitor) bool { + return visit(v, node.Expression) +} + +func (node *AwaitExpression) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateAwaitExpression(node, v.visitNode(node.Expression)) +} + +func (node *AwaitExpression) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewAwaitExpression(node.Expression), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *AwaitExpression) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) | SubtreeContainsAwait +} + +func IsAwaitExpression(node *Node) bool { + return node.Kind == KindAwaitExpression +} + +// TypeAssertion + +type TypeAssertion struct { + ExpressionBase + Type *TypeNode // TypeNode + Expression *Expression // Expression +} + +func (f *NodeFactory) NewTypeAssertion(typeNode *TypeNode, expression *Expression) *Node { + data := &TypeAssertion{} + data.Type = typeNode + data.Expression = expression + return f.newNode(KindTypeAssertionExpression, data) +} + +func (f *NodeFactory) UpdateTypeAssertion(node *TypeAssertion, typeNode *TypeNode, expression *Expression) *Node { + if typeNode != node.Type || expression != node.Expression { + return updateNode(f.NewTypeAssertion(typeNode, expression), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *TypeAssertion) ForEachChild(v Visitor) bool { + return visit(v, node.Type) || visit(v, node.Expression) +} + +func (node *TypeAssertion) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateTypeAssertion(node, v.visitNode(node.Type), v.visitNode(node.Expression)) +} + +func (node *TypeAssertion) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewTypeAssertion(node.Type, node.Expression), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *TypeAssertion) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) | SubtreeContainsTypeScript +} + +func (node *TypeAssertion) propagateSubtreeFacts() SubtreeFacts { + return node.SubtreeFacts() & ^SubtreeExclusionsOuterExpression +} + +// TypeNodeBase + +type TypeNodeBase struct { + NodeBase + typeSyntaxBase +} + +// KeywordTypeNode + +type KeywordTypeNode struct { + TypeNodeBase +} + +func (f *NodeFactory) NewKeywordTypeNode(kind Kind) *Node { + return f.newNode(kind, f.keywordTypeNodePool.New()) +} + +func (node *KeywordTypeNode) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewKeywordTypeNode(node.Kind), node.AsNode(), f.AsNodeFactory().hooks) +} + +// UnionOrIntersectionTypeBase + +type UnionOrIntersectionTypeNodeBase struct { + TypeNodeBase + Types *NodeList // NodeList[*TypeNode] +} + +func (node *UnionOrIntersectionTypeNodeBase) ForEachChild(v Visitor) bool { + return visitNodeList(v, node.Types) +} + +// UnionTypeNode + +type UnionTypeNode struct { + UnionOrIntersectionTypeNodeBase +} + +func (f *NodeFactory) UpdateUnionTypeNode(node *UnionTypeNode, types *TypeList) *Node { + if types != node.Types { + return updateNode(f.NewUnionTypeNode(types), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (f *NodeFactory) NewUnionTypeNode(types *NodeList) *Node { + data := f.unionTypeNodePool.New() + data.Types = types + return f.newNode(KindUnionType, data) +} + +func (node *UnionTypeNode) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateUnionTypeNode(node, v.visitNodes(node.Types)) +} + +func (node *UnionTypeNode) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewUnionTypeNode(node.Types), node.AsNode(), f.AsNodeFactory().hooks) +} + +// IntersectionTypeNode + +type IntersectionTypeNode struct { + UnionOrIntersectionTypeNodeBase +} + +func (f *NodeFactory) UpdateIntersectionTypeNode(node *IntersectionTypeNode, types *TypeList) *Node { + if types != node.Types { + return updateNode(f.NewIntersectionTypeNode(types), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (f *NodeFactory) NewIntersectionTypeNode(types *NodeList) *Node { + data := f.intersectionTypeNodePool.New() + data.Types = types + return f.newNode(KindIntersectionType, data) +} + +func (node *IntersectionTypeNode) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateIntersectionTypeNode(node, v.visitNodes(node.Types)) +} + +func (node *IntersectionTypeNode) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewIntersectionTypeNode(node.Types), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsIntersectionTypeNode(node *Node) bool { + return node.Kind == KindIntersectionType +} + +// ConditionalTypeNode + +type ConditionalTypeNode struct { + TypeNodeBase + LocalsContainerBase + CheckType *TypeNode // TypeNode + ExtendsType *TypeNode // TypeNode + TrueType *TypeNode // TypeNode + FalseType *TypeNode // TypeNode +} + +func (f *NodeFactory) NewConditionalTypeNode(checkType *TypeNode, extendsType *TypeNode, trueType *TypeNode, falseType *TypeNode) *Node { + data := &ConditionalTypeNode{} + data.CheckType = checkType + data.ExtendsType = extendsType + data.TrueType = trueType + data.FalseType = falseType + return f.newNode(KindConditionalType, data) +} + +func (f *NodeFactory) UpdateConditionalTypeNode(node *ConditionalTypeNode, checkType *TypeNode, extendsType *TypeNode, trueType *TypeNode, falseType *TypeNode) *Node { + if checkType != node.CheckType || extendsType != node.ExtendsType || trueType != node.TrueType || falseType != node.FalseType { + return updateNode(f.NewConditionalTypeNode(checkType, extendsType, trueType, falseType), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ConditionalTypeNode) ForEachChild(v Visitor) bool { + return visit(v, node.CheckType) || visit(v, node.ExtendsType) || visit(v, node.TrueType) || visit(v, node.FalseType) +} + +func (node *ConditionalTypeNode) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateConditionalTypeNode(node, v.visitNode(node.CheckType), v.visitNode(node.ExtendsType), v.visitNode(node.TrueType), v.visitNode(node.FalseType)) +} + +func (node *ConditionalTypeNode) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewConditionalTypeNode(node.CheckType, node.ExtendsType, node.TrueType, node.FalseType), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsConditionalTypeNode(node *Node) bool { + return node.Kind == KindConditionalType +} + +// TypeOperatorNode + +type TypeOperatorNode struct { + TypeNodeBase + Operator Kind // KindKeyOfKeyword | KindUniqueKeyword | KindReadonlyKeyword + Type *TypeNode // TypeNode +} + +func (f *NodeFactory) NewTypeOperatorNode(operator Kind, typeNode *TypeNode) *Node { + data := f.typeOperatorNodePool.New() + data.Operator = operator + data.Type = typeNode + return f.newNode(KindTypeOperator, data) +} + +func (f *NodeFactory) UpdateTypeOperatorNode(node *TypeOperatorNode, typeNode *TypeNode) *Node { + if typeNode != node.Type { + return updateNode(f.NewTypeOperatorNode(node.Operator, typeNode), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *TypeOperatorNode) ForEachChild(v Visitor) bool { + return visit(v, node.Type) +} + +func (node *TypeOperatorNode) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateTypeOperatorNode(node, v.visitNode(node.Type)) +} + +func (node *TypeOperatorNode) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewTypeOperatorNode(node.Operator, node.Type), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsTypeOperatorNode(node *Node) bool { + return node.Kind == KindTypeOperator +} + +// InferTypeNode + +type InferTypeNode struct { + TypeNodeBase + TypeParameter *TypeParameterDeclarationNode // TypeParameterDeclarationNode +} + +func (f *NodeFactory) NewInferTypeNode(typeParameter *TypeParameterDeclarationNode) *Node { + data := &InferTypeNode{} + data.TypeParameter = typeParameter + return f.newNode(KindInferType, data) +} + +func (f *NodeFactory) UpdateInferTypeNode(node *InferTypeNode, typeParameter *TypeNode) *Node { + if typeParameter != node.TypeParameter { + return updateNode(f.NewInferTypeNode(typeParameter), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *InferTypeNode) ForEachChild(v Visitor) bool { + return visit(v, node.TypeParameter) +} + +func (node *InferTypeNode) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateInferTypeNode(node, v.visitNode(node.TypeParameter)) +} + +func (node *InferTypeNode) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewInferTypeNode(node.TypeParameter), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsInferTypeNode(node *Node) bool { + return node.Kind == KindInferType +} + +// ArrayTypeNode + +type ArrayTypeNode struct { + TypeNodeBase + ElementType *TypeNode // TypeNode +} + +func (f *NodeFactory) NewArrayTypeNode(elementType *TypeNode) *Node { + data := f.arrayTypeNodePool.New() + data.ElementType = elementType + return f.newNode(KindArrayType, data) +} + +func (f *NodeFactory) UpdateArrayTypeNode(node *ArrayTypeNode, elementType *TypeNode) *Node { + if elementType != node.ElementType { + return updateNode(f.NewArrayTypeNode(elementType), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ArrayTypeNode) ForEachChild(v Visitor) bool { + return visit(v, node.ElementType) +} + +func (node *ArrayTypeNode) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateArrayTypeNode(node, v.visitNode(node.ElementType)) +} + +func (node *ArrayTypeNode) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewArrayTypeNode(node.ElementType), node.AsNode(), f.AsNodeFactory().hooks) +} + +// IndexedAccessTypeNode + +type IndexedAccessTypeNode struct { + TypeNodeBase + ObjectType *TypeNode // TypeNode + IndexType *TypeNode // TypeNode +} + +func (f *NodeFactory) NewIndexedAccessTypeNode(objectType *TypeNode, indexType *TypeNode) *Node { + data := f.indexedAccessTypeNodePool.New() + data.ObjectType = objectType + data.IndexType = indexType + return f.newNode(KindIndexedAccessType, data) +} + +func (f *NodeFactory) UpdateIndexedAccessTypeNode(node *IndexedAccessTypeNode, objectType *TypeNode, indexType *TypeNode) *Node { + if objectType != node.ObjectType || indexType != node.IndexType { + return updateNode(f.NewIndexedAccessTypeNode(objectType, indexType), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *IndexedAccessTypeNode) ForEachChild(v Visitor) bool { + return visit(v, node.ObjectType) || visit(v, node.IndexType) +} + +func (node *IndexedAccessTypeNode) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateIndexedAccessTypeNode(node, v.visitNode(node.ObjectType), v.visitNode(node.IndexType)) +} + +func (node *IndexedAccessTypeNode) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewIndexedAccessTypeNode(node.ObjectType, node.IndexType), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsIndexedAccessTypeNode(node *Node) bool { + return node.Kind == KindIndexedAccessType +} + +// TypeReferenceNode + +type TypeReferenceNode struct { + TypeNodeBase + TypeName *EntityName // EntityName + TypeArguments *NodeList // NodeList[*TypeNode]. Optional +} + +func (f *NodeFactory) NewTypeReferenceNode(typeName *EntityName, typeArguments *NodeList) *Node { + data := f.typeReferenceNodePool.New() + data.TypeName = typeName + data.TypeArguments = typeArguments + return f.newNode(KindTypeReference, data) +} + +func (f *NodeFactory) UpdateTypeReferenceNode(node *TypeReferenceNode, typeName *EntityName, typeArguments *TypeArgumentList) *Node { + if typeName != node.TypeName || typeArguments != node.TypeArguments { + return updateNode(f.NewTypeReferenceNode(typeName, typeArguments), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *TypeReferenceNode) ForEachChild(v Visitor) bool { + return visit(v, node.TypeName) || visitNodeList(v, node.TypeArguments) +} + +func (node *TypeReferenceNode) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateTypeReferenceNode(node, v.visitNode(node.TypeName), v.visitNodes(node.TypeArguments)) +} + +func (node *TypeReferenceNode) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewTypeReferenceNode(node.TypeName, node.TypeArguments), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsTypeReferenceNode(node *Node) bool { + return node.Kind == KindTypeReference +} + +// ExpressionWithTypeArguments + +type ExpressionWithTypeArguments struct { + ExpressionBase + compositeNodeBase + Expression *Expression // Expression + TypeArguments *NodeList // NodeList[*TypeNode]. Optional +} + +func (f *NodeFactory) NewExpressionWithTypeArguments(expression *Expression, typeArguments *NodeList) *Node { + data := f.expressionWithTypeArgumentsPool.New() + data.Expression = expression + data.TypeArguments = typeArguments + return f.newNode(KindExpressionWithTypeArguments, data) +} + +func (f *NodeFactory) UpdateExpressionWithTypeArguments(node *ExpressionWithTypeArguments, expression *Expression, typeArguments *TypeArgumentList) *Node { + if expression != node.Expression || typeArguments != node.TypeArguments { + return updateNode(f.NewExpressionWithTypeArguments(expression, typeArguments), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ExpressionWithTypeArguments) ForEachChild(v Visitor) bool { + return visit(v, node.Expression) || visitNodeList(v, node.TypeArguments) +} + +func (node *ExpressionWithTypeArguments) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateExpressionWithTypeArguments(node, v.visitNode(node.Expression), v.visitNodes(node.TypeArguments)) +} + +func (node *ExpressionWithTypeArguments) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewExpressionWithTypeArguments(node.Expression, node.TypeArguments), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *ExpressionWithTypeArguments) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) | + propagateEraseableSyntaxListSubtreeFacts(node.TypeArguments) +} + +func IsExpressionWithTypeArguments(node *Node) bool { + return node.Kind == KindExpressionWithTypeArguments +} + +// LiteralTypeNode + +type LiteralTypeNode struct { + TypeNodeBase + Literal *Node // KeywordExpression | LiteralExpression | PrefixUnaryExpression +} + +func (f *NodeFactory) NewLiteralTypeNode(literal *Node) *Node { + data := f.literalTypeNodePool.New() + data.Literal = literal + return f.newNode(KindLiteralType, data) +} + +func (f *NodeFactory) UpdateLiteralTypeNode(node *LiteralTypeNode, literal *Node) *Node { + if literal != node.Literal { + return updateNode(f.NewLiteralTypeNode(literal), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *LiteralTypeNode) ForEachChild(v Visitor) bool { + return visit(v, node.Literal) +} + +func (node *LiteralTypeNode) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateLiteralTypeNode(node, v.visitNode(node.Literal)) +} + +func (node *LiteralTypeNode) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewLiteralTypeNode(node.Literal), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsLiteralTypeNode(node *Node) bool { + return node.Kind == KindLiteralType +} + +// ThisTypeNode + +type ThisTypeNode struct { + TypeNodeBase +} + +func (f *NodeFactory) NewThisTypeNode() *Node { + return f.newNode(KindThisType, &ThisTypeNode{}) +} + +func (node *ThisTypeNode) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewThisTypeNode(), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsThisTypeNode(node *Node) bool { + return node.Kind == KindThisType +} + +// TypePredicateNode + +type TypePredicateNode struct { + TypeNodeBase + AssertsModifier *TokenNode // TokenNode. Optional + ParameterName *TypePredicateParameterName // TypePredicateParameterName (Identifier | ThisTypeNode) + Type *TypeNode // TypeNode. Optional +} + +func (f *NodeFactory) NewTypePredicateNode(assertsModifier *TokenNode, parameterName *TypePredicateParameterName, typeNode *TypeNode) *Node { + data := &TypePredicateNode{} + data.AssertsModifier = assertsModifier + data.ParameterName = parameterName + data.Type = typeNode + return f.newNode(KindTypePredicate, data) +} + +func (f *NodeFactory) UpdateTypePredicateNode(node *TypePredicateNode, assertsModifier *TokenNode, parameterName *TypePredicateParameterName, typeNode *TypeNode) *Node { + if assertsModifier != node.AssertsModifier || parameterName != node.ParameterName || typeNode != node.Type { + return updateNode(f.NewTypePredicateNode(assertsModifier, parameterName, typeNode), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *TypePredicateNode) ForEachChild(v Visitor) bool { + return visit(v, node.AssertsModifier) || visit(v, node.ParameterName) || visit(v, node.Type) +} + +func (node *TypePredicateNode) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateTypePredicateNode(node, v.visitNode(node.AssertsModifier), v.visitNode(node.ParameterName), v.visitNode(node.Type)) +} + +func (node *TypePredicateNode) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewTypePredicateNode(node.AssertsModifier, node.ParameterName, node.Type), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsTypePredicateNode(node *Node) bool { + return node.Kind == KindTypePredicate +} + +// ImportTypeNode + +type ImportTypeNode struct { + TypeNodeBase + IsTypeOf bool + Argument *TypeNode // TypeNode + Attributes *ImportAttributesNode // ImportAttributesNode. Optional + Qualifier *EntityName // EntityName. Optional + TypeArguments *NodeList // NodeList[*TypeNode]. Optional +} + +func (f *NodeFactory) NewImportTypeNode(isTypeOf bool, argument *TypeNode, attributes *ImportAttributesNode, qualifier *EntityName, typeArguments *NodeList) *Node { + data := &ImportTypeNode{} + data.IsTypeOf = isTypeOf + data.Argument = argument + data.Attributes = attributes + data.Qualifier = qualifier + data.TypeArguments = typeArguments + return f.newNode(KindImportType, data) +} + +func (f *NodeFactory) UpdateImportTypeNode(node *ImportTypeNode, isTypeOf bool, argument *TypeNode, attributes *ImportAttributesNode, qualifier *EntityName, typeArguments *TypeArgumentList) *Node { + if isTypeOf != node.IsTypeOf || argument != node.Argument || attributes != node.Attributes || qualifier != node.Qualifier || typeArguments != node.TypeArguments { + return updateNode(f.NewImportTypeNode(isTypeOf, argument, attributes, qualifier, typeArguments), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ImportTypeNode) ForEachChild(v Visitor) bool { + return visit(v, node.Argument) || visit(v, node.Attributes) || visit(v, node.Qualifier) || visitNodeList(v, node.TypeArguments) +} + +func (node *ImportTypeNode) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateImportTypeNode(node, node.IsTypeOf, v.visitNode(node.Argument), v.visitNode(node.Attributes), v.visitNode(node.Qualifier), v.visitNodes(node.TypeArguments)) +} + +func (node *ImportTypeNode) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewImportTypeNode(node.IsTypeOf, node.Argument, node.Attributes, node.Qualifier, node.TypeArguments), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsImportTypeNode(node *Node) bool { + return node.Kind == KindImportType +} + +// ImportAttribute + +type ImportAttribute struct { + NodeBase + compositeNodeBase + name *ImportAttributeName // ImportAttributeName + Value *Expression // Expression +} + +func (f *NodeFactory) NewImportAttribute(name *ImportAttributeName, value *Expression) *Node { + data := &ImportAttribute{} + data.name = name + data.Value = value + return f.newNode(KindImportAttribute, data) +} + +func (f *NodeFactory) UpdateImportAttribute(node *ImportAttribute, name *ImportAttributeName, value *Expression) *Node { + if name != node.name || value != node.Value { + return updateNode(f.NewImportAttribute(name, value), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ImportAttribute) ForEachChild(v Visitor) bool { + return visit(v, node.name) || visit(v, node.Value) +} + +func (node *ImportAttribute) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateImportAttribute(node, v.visitNode(node.name), v.visitNode(node.Value)) +} + +func (node *ImportAttribute) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewImportAttribute(node.Name(), node.Value), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *ImportAttribute) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.name) | + propagateSubtreeFacts(node.Value) +} + +func (node *ImportAttribute) Name() *ImportAttributeName { + return node.name +} + +// ImportAttributes + +type ImportAttributes struct { + NodeBase + compositeNodeBase + Token Kind + Attributes *NodeList // NodeList[*ImportAttributeNode] + MultiLine bool +} + +func (f *NodeFactory) NewImportAttributes(token Kind, attributes *NodeList, multiLine bool) *Node { + data := &ImportAttributes{} + data.Token = token + data.Attributes = attributes + data.MultiLine = multiLine + return f.newNode(KindImportAttributes, data) +} + +func (f *NodeFactory) UpdateImportAttributes(node *ImportAttributes, attributes *ImportAttributeList) *Node { + if attributes != node.Attributes { + return updateNode(f.NewImportAttributes(node.Token, attributes, node.MultiLine), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ImportAttributes) ForEachChild(v Visitor) bool { + return visitNodeList(v, node.Attributes) +} + +func (node *ImportAttributes) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateImportAttributes(node, v.visitNodes(node.Attributes)) +} + +func (node *ImportAttributes) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewImportAttributes(node.Token, node.Attributes, node.MultiLine), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *ImportAttributes) computeSubtreeFacts() SubtreeFacts { + return propagateNodeListSubtreeFacts(node.Attributes, propagateSubtreeFacts) +} + +func IsImportAttributes(node *Node) bool { + return node.Kind == KindImportAttributes +} + +func (node *ImportAttributesNode) GetResolutionModeOverride( /* !!! grammarErrorOnNode?: (node: Node, diagnostic: DiagnosticMessage) => void*/ ) (core.ResolutionMode, bool) { + if node == nil { + return core.ResolutionModeNone, false + } + + attributes := node.AsImportAttributes().Attributes + + if len(attributes.Nodes) != 1 { + // !!! + // grammarErrorOnNode?.( + // node, + // node.token === SyntaxKind.WithKeyword + // ? Diagnostics.Type_import_attributes_should_have_exactly_one_key_resolution_mode_with_value_import_or_require + // : Diagnostics.Type_import_assertions_should_have_exactly_one_key_resolution_mode_with_value_import_or_require, + // ); + return core.ResolutionModeNone, false + } + + elem := attributes.Nodes[0].AsImportAttribute() + if !IsStringLiteralLike(elem.Name()) { + return core.ResolutionModeNone, false + } + if elem.Name().Text() != "resolution-mode" { + // !!! + // grammarErrorOnNode?.( + // elem.name, + // node.token === SyntaxKind.WithKeyword + // ? Diagnostics.resolution_mode_is_the_only_valid_key_for_type_import_attributes + // : Diagnostics.resolution_mode_is_the_only_valid_key_for_type_import_assertions, + // ); + return core.ResolutionModeNone, false + } + if !IsStringLiteralLike(elem.Value) { + return core.ResolutionModeNone, false + } + if elem.Value.Text() != "import" && elem.Value.Text() != "require" { + // !!! + // grammarErrorOnNode?.(elem.value, Diagnostics.resolution_mode_should_be_either_require_or_import); + return core.ResolutionModeNone, false + } + if elem.Value.Text() == "import" { + return core.ResolutionModeESM, true + } else { + return core.ModuleKindCommonJS, true + } +} + +// TypeQueryNode + +type TypeQueryNode struct { + TypeNodeBase + ExprName *EntityName // EntityName + TypeArguments *NodeList // NodeList[*TypeNode]. Optional +} + +func (f *NodeFactory) NewTypeQueryNode(exprName *EntityName, typeArguments *NodeList) *Node { + data := &TypeQueryNode{} + data.ExprName = exprName + data.TypeArguments = typeArguments + return f.newNode(KindTypeQuery, data) +} + +func (f *NodeFactory) UpdateTypeQueryNode(node *TypeQueryNode, exprName *EntityName, typeArguments *TypeArgumentList) *Node { + if exprName != node.ExprName || typeArguments != node.TypeArguments { + return updateNode(f.NewTypeQueryNode(exprName, typeArguments), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *TypeQueryNode) ForEachChild(v Visitor) bool { + return visit(v, node.ExprName) || visitNodeList(v, node.TypeArguments) +} + +func (node *TypeQueryNode) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateTypeQueryNode(node, v.visitNode(node.ExprName), v.visitNodes(node.TypeArguments)) +} + +func (node *TypeQueryNode) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewTypeQueryNode(node.ExprName, node.TypeArguments), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsTypeQueryNode(node *Node) bool { + return node.Kind == KindTypeQuery +} + +// MappedTypeNode + +type MappedTypeNode struct { + TypeNodeBase + DeclarationBase + LocalsContainerBase + ReadonlyToken *TokenNode // TokenNode. Optional + TypeParameter *TypeParameterDeclarationNode // TypeParameterDeclarationNode + NameType *TypeNode // TypeNode. Optional + QuestionToken *TokenNode // TokenNode. Optional + Type *TypeNode // TypeNode. Optional (error if missing) + Members *NodeList // NodeList[*TypeElement]. Used only to produce grammar errors +} + +func (f *NodeFactory) NewMappedTypeNode(readonlyToken *TokenNode, typeParameter *TypeParameterDeclarationNode, nameType *TypeNode, questionToken *TokenNode, typeNode *TypeNode, members *NodeList) *Node { + data := &MappedTypeNode{} + data.ReadonlyToken = readonlyToken + data.TypeParameter = typeParameter + data.NameType = nameType + data.QuestionToken = questionToken + data.Type = typeNode + data.Members = members + return f.newNode(KindMappedType, data) +} + +func (f *NodeFactory) UpdateMappedTypeNode(node *MappedTypeNode, readonlyToken *TokenNode, typeParameter *TypeParameterDeclarationNode, nameType *TypeNode, questionToken *TokenNode, typeNode *TypeNode, members *TypeElementList) *Node { + if readonlyToken != node.ReadonlyToken || typeParameter != node.TypeParameter || nameType != node.NameType || questionToken != node.QuestionToken || typeNode != node.Type || members != node.Members { + return updateNode(f.NewMappedTypeNode(readonlyToken, typeParameter, nameType, questionToken, typeNode, members), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *MappedTypeNode) ForEachChild(v Visitor) bool { + return visit(v, node.ReadonlyToken) || visit(v, node.TypeParameter) || visit(v, node.NameType) || + visit(v, node.QuestionToken) || visit(v, node.Type) || visitNodeList(v, node.Members) +} + +func (node *MappedTypeNode) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateMappedTypeNode(node, v.visitToken(node.ReadonlyToken), v.visitNode(node.TypeParameter), v.visitNode(node.NameType), v.visitToken(node.QuestionToken), v.visitNode(node.Type), v.visitNodes(node.Members)) +} + +func (node *MappedTypeNode) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewMappedTypeNode(node.ReadonlyToken, node.TypeParameter, node.NameType, node.QuestionToken, node.Type, node.Members), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsMappedTypeNode(node *Node) bool { + return node.Kind == KindMappedType +} + +// TypeLiteralNode + +type TypeLiteralNode struct { + TypeNodeBase + DeclarationBase + Members *NodeList // NodeList[*TypeElement] +} + +func (f *NodeFactory) NewTypeLiteralNode(members *NodeList) *Node { + data := f.typeLiteralNodePool.New() + data.Members = members + return f.newNode(KindTypeLiteral, data) +} + +func (f *NodeFactory) UpdateTypeLiteralNode(node *TypeLiteralNode, members *TypeElementList) *Node { + if members != node.Members { + return updateNode(f.NewTypeLiteralNode(members), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *TypeLiteralNode) ForEachChild(v Visitor) bool { + return visitNodeList(v, node.Members) +} + +func (node *TypeLiteralNode) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateTypeLiteralNode(node, v.visitNodes(node.Members)) +} + +func (node *TypeLiteralNode) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewTypeLiteralNode(node.Members), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsTypeLiteralNode(node *Node) bool { + return node.Kind == KindTypeLiteral +} + +// TupleTypeNode + +type TupleTypeNode struct { + TypeNodeBase + Elements *NodeList // NodeList[*TypeNode] +} + +func (f *NodeFactory) NewTupleTypeNode(elements *NodeList) *Node { + data := &TupleTypeNode{} + data.Elements = elements + return f.newNode(KindTupleType, data) +} + +func (f *NodeFactory) UpdateTupleTypeNode(node *TupleTypeNode, elements *TypeList) *Node { + if elements != node.Elements { + return updateNode(f.NewTupleTypeNode(elements), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *TupleTypeNode) ForEachChild(v Visitor) bool { + return visitNodeList(v, node.Elements) +} + +func (node *TupleTypeNode) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateTupleTypeNode(node, v.visitNodes(node.Elements)) +} + +func (node *TupleTypeNode) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewTupleTypeNode(node.Elements), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsTupleTypeNode(node *Node) bool { + return node.Kind == KindTupleType +} + +// NamedTupleTypeMember + +type NamedTupleMember struct { + TypeNodeBase + DeclarationBase + DotDotDotToken *TokenNode // TokenNode + name *IdentifierNode // IdentifierNode + QuestionToken *TokenNode // TokenNode + Type *TypeNode // TypeNode +} + +func (f *NodeFactory) NewNamedTupleMember(dotDotDotToken *TokenNode, name *IdentifierNode, questionToken *TokenNode, typeNode *TypeNode) *Node { + data := &NamedTupleMember{} + data.DotDotDotToken = dotDotDotToken + data.name = name + data.QuestionToken = questionToken + data.Type = typeNode + return f.newNode(KindNamedTupleMember, data) +} + +func (f *NodeFactory) UpdateNamedTupleMember(node *NamedTupleMember, dotDotDotToken *TokenNode, name *IdentifierNode, questionToken *TokenNode, typeNode *TypeNode) *Node { + if dotDotDotToken != node.DotDotDotToken || name != node.name || questionToken != node.QuestionToken || typeNode != node.Type { + return updateNode(f.NewNamedTupleMember(dotDotDotToken, name, questionToken, typeNode), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *NamedTupleMember) ForEachChild(v Visitor) bool { + return visit(v, node.DotDotDotToken) || visit(v, node.name) || visit(v, node.QuestionToken) || visit(v, node.Type) +} + +func (node *NamedTupleMember) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateNamedTupleMember(node, v.visitToken(node.DotDotDotToken), v.visitNode(node.name), v.visitToken(node.QuestionToken), v.visitNode(node.Type)) +} + +func (node *NamedTupleMember) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewNamedTupleMember(node.DotDotDotToken, node.Name(), node.QuestionToken, node.Type), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *NamedTupleMember) Name() *DeclarationName { + return node.name +} + +func IsNamedTupleMember(node *Node) bool { + return node.Kind == KindNamedTupleMember +} + +// OptionalTypeNode + +type OptionalTypeNode struct { + TypeNodeBase + Type *TypeNode // TypeNode +} + +func (f *NodeFactory) NewOptionalTypeNode(typeNode *TypeNode) *Node { + data := &OptionalTypeNode{} + data.Type = typeNode + return f.newNode(KindOptionalType, data) +} + +func (f *NodeFactory) UpdateOptionalTypeNode(node *OptionalTypeNode, typeNode *TypeNode) *Node { + if typeNode != node.Type { + return updateNode(f.NewOptionalTypeNode(typeNode), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *OptionalTypeNode) ForEachChild(v Visitor) bool { + return visit(v, node.Type) +} + +func (node *OptionalTypeNode) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateOptionalTypeNode(node, v.visitNode(node.Type)) +} + +func (node *OptionalTypeNode) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewOptionalTypeNode(node.Type), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsOptionalTypeNode(node *Node) bool { + return node.Kind == KindOptionalType +} + +// RestTypeNode + +type RestTypeNode struct { + TypeNodeBase + Type *TypeNode // TypeNode +} + +func (f *NodeFactory) NewRestTypeNode(typeNode *TypeNode) *Node { + data := &RestTypeNode{} + data.Type = typeNode + return f.newNode(KindRestType, data) +} + +func (f *NodeFactory) UpdateRestTypeNode(node *RestTypeNode, typeNode *TypeNode) *Node { + if typeNode != node.Type { + return updateNode(f.NewRestTypeNode(typeNode), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *RestTypeNode) ForEachChild(v Visitor) bool { + return visit(v, node.Type) +} + +func (node *RestTypeNode) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateRestTypeNode(node, v.visitNode(node.Type)) +} + +func (node *RestTypeNode) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewRestTypeNode(node.Type), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsRestTypeNode(node *Node) bool { + return node.Kind == KindRestType +} + +// ParenthesizedTypeNode + +type ParenthesizedTypeNode struct { + TypeNodeBase + Type *TypeNode // TypeNode +} + +func (f *NodeFactory) NewParenthesizedTypeNode(typeNode *TypeNode) *Node { + data := f.parenthesizedTypeNodePool.New() + data.Type = typeNode + return f.newNode(KindParenthesizedType, data) +} + +func (f *NodeFactory) UpdateParenthesizedTypeNode(node *ParenthesizedTypeNode, typeNode *TypeNode) *Node { + if typeNode != node.Type { + return updateNode(f.NewParenthesizedTypeNode(typeNode), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ParenthesizedTypeNode) ForEachChild(v Visitor) bool { + return visit(v, node.Type) +} + +func (node *ParenthesizedTypeNode) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateParenthesizedTypeNode(node, v.visitNode(node.Type)) +} + +func (node *ParenthesizedTypeNode) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewParenthesizedTypeNode(node.Type), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsParenthesizedTypeNode(node *Node) bool { + return node.Kind == KindParenthesizedType +} + +// FunctionOrConstructorTypeNodeBase + +type FunctionOrConstructorTypeNodeBase struct { + TypeNodeBase + DeclarationBase + ModifiersBase + FunctionLikeBase +} + +func (node *FunctionOrConstructorTypeNodeBase) ForEachChild(v Visitor) bool { + return visitModifiers(v, node.modifiers) || visitNodeList(v, node.TypeParameters) || visitNodeList(v, node.Parameters) || visit(v, node.Type) +} + +// FunctionTypeNode + +type FunctionTypeNode struct { + FunctionOrConstructorTypeNodeBase +} + +func (f *NodeFactory) NewFunctionTypeNode(typeParameters *NodeList, parameters *NodeList, returnType *TypeNode) *Node { + data := f.functionTypeNodePool.New() + data.TypeParameters = typeParameters + data.Parameters = parameters + data.Type = returnType + return f.newNode(KindFunctionType, data) +} + +func (f *NodeFactory) UpdateFunctionTypeNode(node *FunctionTypeNode, typeParameters *TypeParameterList, parameters *ParameterList, returnType *TypeNode) *Node { + if typeParameters != node.TypeParameters || parameters != node.Parameters || returnType != node.Type { + return updateNode(f.NewFunctionTypeNode(typeParameters, parameters, returnType), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *FunctionTypeNode) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateFunctionTypeNode(node, v.visitNodes(node.TypeParameters), v.visitNodes(node.Parameters), v.visitNode(node.Type)) +} + +func (node *FunctionTypeNode) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewFunctionTypeNode(node.TypeParameters, node.Parameters, node.Type), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsFunctionTypeNode(node *Node) bool { + return node.Kind == KindFunctionType +} + +// ConstructorTypeNode + +type ConstructorTypeNode struct { + FunctionOrConstructorTypeNodeBase +} + +func (f *NodeFactory) NewConstructorTypeNode(modifiers *ModifierList, typeParameters *NodeList, parameters *NodeList, returnType *TypeNode) *Node { + data := &ConstructorTypeNode{} + data.modifiers = modifiers + data.TypeParameters = typeParameters + data.Parameters = parameters + data.Type = returnType + return f.newNode(KindConstructorType, data) +} + +func (f *NodeFactory) UpdateConstructorTypeNode(node *ConstructorTypeNode, modifiers *ModifierList, typeParameters *TypeParameterList, parameters *ParameterList, returnType *TypeNode) *Node { + if modifiers != node.modifiers || typeParameters != node.TypeParameters || parameters != node.Parameters || returnType != node.Type { + return updateNode(f.NewConstructorTypeNode(modifiers, typeParameters, parameters, returnType), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *ConstructorTypeNode) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateConstructorTypeNode(node, v.visitModifiers(node.modifiers), v.visitNodes(node.TypeParameters), v.visitNodes(node.Parameters), v.visitNode(node.Type)) +} + +func (node *ConstructorTypeNode) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewConstructorTypeNode(node.Modifiers(), node.TypeParameters, node.Parameters, node.Type), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsConstructorTypeNode(node *Node) bool { + return node.Kind == KindConstructorType +} + +// TemplateLiteralLikeBase + +type TemplateLiteralLikeBase struct { + LiteralLikeBase + RawText string + TemplateFlags TokenFlags +} + +func (node *TemplateLiteralLikeBase) LiteralLikeData() *LiteralLikeBase { return &node.LiteralLikeBase } +func (node *TemplateLiteralLikeBase) TemplateLiteralLikeData() *TemplateLiteralLikeBase { return node } + +// TemplateHead + +type TemplateHead struct { + NodeBase + TemplateLiteralLikeBase +} + +func (f *NodeFactory) NewTemplateHead(text string, rawText string, templateFlags TokenFlags) *Node { + data := &TemplateHead{} + data.Text = text + data.RawText = rawText + data.TemplateFlags = templateFlags + f.textCount++ + return f.newNode(KindTemplateHead, data) +} + +func (node *TemplateHead) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewTemplateHead(node.Text, node.RawText, node.TemplateFlags), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsTemplateHead(node *Node) bool { + return node.Kind == KindTemplateHead +} + +// TemplateMiddle + +type TemplateMiddle struct { + NodeBase + TemplateLiteralLikeBase +} + +func (f *NodeFactory) NewTemplateMiddle(text string, rawText string, templateFlags TokenFlags) *Node { + data := &TemplateMiddle{} + data.Text = text + data.RawText = rawText + data.TemplateFlags = templateFlags + f.textCount++ + return f.newNode(KindTemplateMiddle, data) +} + +func (node *TemplateMiddle) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewTemplateMiddle(node.Text, node.RawText, node.TemplateFlags), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsTemplateMiddle(node *Node) bool { + return node.Kind == KindTemplateMiddle +} + +// TemplateTail + +type TemplateTail struct { + NodeBase + TemplateLiteralLikeBase +} + +func (f *NodeFactory) NewTemplateTail(text string, rawText string, templateFlags TokenFlags) *Node { + data := &TemplateTail{} + data.Text = text + data.RawText = rawText + data.TemplateFlags = templateFlags + f.textCount++ + return f.newNode(KindTemplateTail, data) +} + +func (node *TemplateTail) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewTemplateTail(node.Text, node.RawText, node.TemplateFlags), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsTemplateTail(node *Node) bool { + return node.Kind == KindTemplateTail +} + +// TemplateLiteralTypeNode + +type TemplateLiteralTypeNode struct { + TypeNodeBase + Head *TemplateHeadNode // TemplateHeadNode + TemplateSpans *NodeList // NodeList[*TemplateLiteralTypeSpanNode] +} + +func (f *NodeFactory) NewTemplateLiteralTypeNode(head *TemplateHeadNode, templateSpans *NodeList) *Node { + data := &TemplateLiteralTypeNode{} + data.Head = head + data.TemplateSpans = templateSpans + return f.newNode(KindTemplateLiteralType, data) +} + +func (f *NodeFactory) UpdateTemplateLiteralTypeNode(node *TemplateLiteralTypeNode, head *TemplateHeadNode, templateSpans *TemplateLiteralTypeSpanList) *Node { + if head != node.Head || templateSpans != node.TemplateSpans { + return updateNode(f.NewTemplateLiteralTypeNode(head, templateSpans), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *TemplateLiteralTypeNode) ForEachChild(v Visitor) bool { + return visit(v, node.Head) || visitNodeList(v, node.TemplateSpans) +} + +func (node *TemplateLiteralTypeNode) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateTemplateLiteralTypeNode(node, v.visitNode(node.Head), v.visitNodes(node.TemplateSpans)) +} + +func (node *TemplateLiteralTypeNode) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewTemplateLiteralTypeNode(node.Head, node.TemplateSpans), node.AsNode(), f.AsNodeFactory().hooks) +} + +// TemplateLiteralTypeSpan + +type TemplateLiteralTypeSpan struct { + NodeBase + typeSyntaxBase + Type *TypeNode // TypeNode + Literal *TemplateMiddleOrTail // TemplateMiddleOrTail +} + +func (f *NodeFactory) NewTemplateLiteralTypeSpan(typeNode *TypeNode, literal *TemplateMiddleOrTail) *Node { + data := &TemplateLiteralTypeSpan{} + data.Type = typeNode + data.Literal = literal + return f.newNode(KindTemplateLiteralTypeSpan, data) +} + +func (f *NodeFactory) UpdateTemplateLiteralTypeSpan(node *TemplateLiteralTypeSpan, typeNode *TypeNode, literal *TemplateMiddleOrTail) *Node { + if typeNode != node.Type || literal != node.Literal { + return updateNode(f.NewTemplateLiteralTypeSpan(typeNode, literal), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *TemplateLiteralTypeSpan) ForEachChild(v Visitor) bool { + return visit(v, node.Type) || visit(v, node.Literal) +} + +func (node *TemplateLiteralTypeSpan) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateTemplateLiteralTypeSpan(node, v.visitNode(node.Type), v.visitNode(node.Literal)) +} + +func (node *TemplateLiteralTypeSpan) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewTemplateLiteralTypeSpan(node.Type, node.Literal), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsTemplateLiteralTypeSpan(node *Node) bool { + return node.Kind == KindTemplateLiteralTypeSpan +} + +// SyntheticExpression + +type SyntheticExpression struct { + ExpressionBase + Type any + IsSpread bool + TupleNameSource *Node +} + +func (f *NodeFactory) NewSyntheticExpression(t any, isSpread bool, tupleNameSource *Node) *Node { + data := &SyntheticExpression{} + data.Type = t + data.IsSpread = isSpread + data.TupleNameSource = tupleNameSource + return f.newNode(KindSyntheticExpression, data) +} + +func (node *SyntheticExpression) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewSyntheticExpression(node.Type, node.IsSpread, node.TupleNameSource), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsSyntheticExpression(node *Node) bool { + return node.Kind == KindSyntheticExpression +} + +// PartiallyEmittedExpression + +type PartiallyEmittedExpression struct { + ExpressionBase + Expression *Expression // Expression +} + +func (f *NodeFactory) NewPartiallyEmittedExpression(expression *Expression) *Node { + data := &PartiallyEmittedExpression{} + data.Expression = expression + return newNode(KindPartiallyEmittedExpression, data, f.hooks) +} + +func (f *NodeFactory) UpdatePartiallyEmittedExpression(node *PartiallyEmittedExpression, expression *Expression) *Node { + if expression != node.Expression { + return updateNode(f.NewPartiallyEmittedExpression(expression), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *PartiallyEmittedExpression) ForEachChild(v Visitor) bool { + return visit(v, node.Expression) +} + +func (node *PartiallyEmittedExpression) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdatePartiallyEmittedExpression(node, v.visitNode(node.Expression)) +} + +func (node *PartiallyEmittedExpression) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewPartiallyEmittedExpression(node.Expression), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *PartiallyEmittedExpression) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) +} + +func (node *PartiallyEmittedExpression) propagateSubtreeFacts() SubtreeFacts { + return node.SubtreeFacts() & ^SubtreeExclusionsOuterExpression +} + +func IsPartiallyEmittedExpression(node *Node) bool { + return node.Kind == KindPartiallyEmittedExpression +} + +/// A JSX expression of the form ... + +type JsxElement struct { + ExpressionBase + compositeNodeBase + OpeningElement *JsxOpeningElementNode // JsxOpeningElementNode + Children *NodeList // NodeList[*JsxChild] + ClosingElement *JsxClosingElementNode // JsxClosingElementNode +} + +func (f *NodeFactory) NewJsxElement(openingElement *JsxOpeningElementNode, children *NodeList, closingElement *JsxClosingElementNode) *Node { + data := &JsxElement{} + data.OpeningElement = openingElement + data.Children = children + data.ClosingElement = closingElement + return f.newNode(KindJsxElement, data) +} + +func (f *NodeFactory) UpdateJsxElement(node *JsxElement, openingElement *JsxOpeningElementNode, children *JsxChildList, closingElement *JsxClosingElementNode) *Node { + if openingElement != node.OpeningElement || children != node.Children || closingElement != node.ClosingElement { + return updateNode(f.NewJsxElement(openingElement, children, closingElement), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JsxElement) ForEachChild(v Visitor) bool { + return visit(v, node.OpeningElement) || visitNodeList(v, node.Children) || visit(v, node.ClosingElement) +} + +func (node *JsxElement) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJsxElement(node, v.visitNode(node.OpeningElement), v.visitNodes(node.Children), v.visitNode(node.ClosingElement)) +} + +func (node *JsxElement) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJsxElement(node.OpeningElement, node.Children, node.ClosingElement), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *JsxElement) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.OpeningElement) | + propagateNodeListSubtreeFacts(node.Children, propagateSubtreeFacts) | + propagateSubtreeFacts(node.ClosingElement) | + SubtreeContainsJsx +} + +func IsJsxElement(node *Node) bool { + return node.Kind == KindJsxElement +} + +// JsxAttributes +type JsxAttributes struct { + ExpressionBase + DeclarationBase + compositeNodeBase + Properties *NodeList // NodeList[*JsxAttributeLike] +} + +func (f *NodeFactory) NewJsxAttributes(properties *NodeList) *Node { + data := &JsxAttributes{} + data.Properties = properties + return f.newNode(KindJsxAttributes, data) +} + +func (f *NodeFactory) UpdateJsxAttributes(node *JsxAttributes, properties *JsxAttributeList) *Node { + if properties != node.Properties { + return updateNode(f.NewJsxAttributes(properties), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JsxAttributes) ForEachChild(v Visitor) bool { + return visitNodeList(v, node.Properties) +} + +func (node *JsxAttributes) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJsxAttributes(node, v.visitNodes(node.Properties)) +} + +func (node *JsxAttributes) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJsxAttributes(node.Properties), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *JsxAttributes) computeSubtreeFacts() SubtreeFacts { + return propagateNodeListSubtreeFacts(node.Properties, propagateSubtreeFacts) | + SubtreeContainsJsx +} + +func IsJsxAttributes(node *Node) bool { + return node.Kind == KindJsxAttributes +} + +// JsxNamespacedName + +type JsxNamespacedName struct { + ExpressionBase + compositeNodeBase + name *IdentifierNode // IdentifierNode + Namespace *IdentifierNode // IdentifierNode +} + +func (f *NodeFactory) NewJsxNamespacedName(namespace *IdentifierNode, name *IdentifierNode) *Node { + data := &JsxNamespacedName{} + data.Namespace = namespace + data.name = name + return f.newNode(KindJsxNamespacedName, data) +} + +func (f *NodeFactory) UpdateJsxNamespacedName(node *JsxNamespacedName, name *IdentifierNode, namespace *IdentifierNode) *Node { + if name != node.name || namespace != node.Namespace { + return updateNode(f.NewJsxNamespacedName(name, namespace), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JsxNamespacedName) ForEachChild(v Visitor) bool { + return visit(v, node.Namespace) || visit(v, node.name) +} + +func (node *JsxNamespacedName) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJsxNamespacedName(node, v.visitNode(node.name), v.visitNode(node.Namespace)) +} + +func (node *JsxNamespacedName) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJsxNamespacedName(node.Name(), node.Namespace), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *JsxNamespacedName) Name() *DeclarationName { + return node.name +} + +func (node *JsxNamespacedName) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Namespace) | + propagateSubtreeFacts(node.name) | + SubtreeContainsJsx +} + +func IsJsxNamespacedName(node *Node) bool { + return node.Kind == KindJsxNamespacedName +} + +/// The opening element of a ... JsxElement + +type JsxOpeningElement struct { + ExpressionBase + compositeNodeBase + TagName *JsxTagNameExpression // JsxTagNameExpression (Identifier | KeywordExpression | JsxTagNamePropertyAccess | JsxNamespacedName) + TypeArguments *NodeList // NodeList[*TypeNode]. Optional + Attributes *JsxAttributesNode // JsxAttributesNode +} + +func (f *NodeFactory) NewJsxOpeningElement(tagName *JsxTagNameExpression, typeArguments *NodeList, attributes *JsxAttributesNode) *Node { + data := &JsxOpeningElement{} + data.TagName = tagName + data.TypeArguments = typeArguments + data.Attributes = attributes + return f.newNode(KindJsxOpeningElement, data) +} + +func (f *NodeFactory) UpdateJsxOpeningElement(node *JsxOpeningElement, tagName *JsxTagNameExpression, typeArguments *TypeArgumentList, attributes *JsxAttributesNode) *Node { + if tagName != node.TagName || typeArguments != node.TypeArguments || attributes != node.Attributes { + return updateNode(f.NewJsxOpeningElement(tagName, typeArguments, attributes), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JsxOpeningElement) ForEachChild(v Visitor) bool { + return visit(v, node.TagName) || visitNodeList(v, node.TypeArguments) || visit(v, node.Attributes) +} + +func (node *JsxOpeningElement) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJsxOpeningElement(node, v.visitNode(node.TagName), v.visitNodes(node.TypeArguments), v.visitNode(node.Attributes)) +} + +func (node *JsxOpeningElement) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJsxOpeningElement(node.TagName, node.TypeArguments, node.Attributes), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *JsxOpeningElement) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.TagName) | + propagateEraseableSyntaxListSubtreeFacts(node.TypeArguments) | + propagateSubtreeFacts(node.Attributes) | + SubtreeContainsJsx +} + +func IsJsxOpeningElement(node *Node) bool { + return node.Kind == KindJsxOpeningElement +} + +/// A JSX expression of the form + +type JsxSelfClosingElement struct { + ExpressionBase + compositeNodeBase + TagName *JsxTagNameExpression // JsxTagNameExpression (IdentifierReference | KeywordExpression | JsxTagNamePropertyAccess | JsxNamespacedName) + TypeArguments *NodeList // NodeList[*TypeNode]. Optional + Attributes *JsxAttributesNode // JsxAttributesNode +} + +func (f *NodeFactory) NewJsxSelfClosingElement(tagName *JsxTagNameExpression, typeArguments *NodeList, attributes *JsxAttributesNode) *Node { + data := &JsxSelfClosingElement{} + data.TagName = tagName + data.TypeArguments = typeArguments + data.Attributes = attributes + return f.newNode(KindJsxSelfClosingElement, data) +} + +func (f *NodeFactory) UpdateJsxSelfClosingElement(node *JsxSelfClosingElement, tagName *JsxTagNameExpression, typeArguments *TypeArgumentList, attributes *JsxAttributesNode) *Node { + if tagName != node.TagName || typeArguments != node.TypeArguments || attributes != node.Attributes { + return updateNode(f.NewJsxSelfClosingElement(tagName, typeArguments, attributes), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JsxSelfClosingElement) ForEachChild(v Visitor) bool { + return visit(v, node.TagName) || visitNodeList(v, node.TypeArguments) || visit(v, node.Attributes) +} + +func (node *JsxSelfClosingElement) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJsxSelfClosingElement(node, v.visitNode(node.TagName), v.visitNodes(node.TypeArguments), v.visitNode(node.Attributes)) +} + +func (node *JsxSelfClosingElement) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJsxSelfClosingElement(node.TagName, node.TypeArguments, node.Attributes), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *JsxSelfClosingElement) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.TagName) | + propagateEraseableSyntaxListSubtreeFacts(node.TypeArguments) | + propagateSubtreeFacts(node.Attributes) | + SubtreeContainsJsx +} + +func IsJsxSelfClosingElement(node *Node) bool { + return node.Kind == KindJsxSelfClosingElement +} + +/// A JSX expression of the form <>... + +type JsxFragment struct { + ExpressionBase + compositeNodeBase + OpeningFragment *JsxOpeningFragmentNode // JsxOpeningFragmentNode + Children *NodeList // NodeList[*JsxChild] + ClosingFragment *JsxClosingFragmentNode // JsxClosingFragmentNode +} + +func (f *NodeFactory) NewJsxFragment(openingFragment *JsxOpeningFragmentNode, children *NodeList, closingFragment *JsxClosingFragmentNode) *Node { + data := &JsxFragment{} + data.OpeningFragment = openingFragment + data.Children = children + data.ClosingFragment = closingFragment + return f.newNode(KindJsxFragment, data) +} + +func (f *NodeFactory) UpdateJsxFragment(node *JsxFragment, openingFragment *JsxOpeningFragmentNode, children *JsxChildList, closingFragment *JsxClosingFragmentNode) *Node { + if openingFragment != node.OpeningFragment || children != node.Children || closingFragment != node.ClosingFragment { + return updateNode(f.NewJsxFragment(openingFragment, children, closingFragment), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JsxFragment) ForEachChild(v Visitor) bool { + return visit(v, node.OpeningFragment) || visitNodeList(v, node.Children) || visit(v, node.ClosingFragment) +} + +func (node *JsxFragment) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJsxFragment(node, v.visitNode(node.OpeningFragment), v.visitNodes(node.Children), v.visitNode(node.ClosingFragment)) +} + +func (node *JsxFragment) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJsxFragment(node.OpeningFragment, node.Children, node.ClosingFragment), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *JsxFragment) computeSubtreeFacts() SubtreeFacts { + return propagateNodeListSubtreeFacts(node.Children, propagateSubtreeFacts) | + SubtreeContainsJsx +} + +func IsJsxFragment(node *Node) bool { + return node.Kind == KindJsxFragment +} + +/// The opening element of a <>... JsxFragment + +type JsxOpeningFragment struct { + ExpressionBase +} + +func (f *NodeFactory) NewJsxOpeningFragment() *Node { + return f.newNode(KindJsxOpeningFragment, &JsxOpeningFragment{}) +} + +func (node *JsxOpeningFragment) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJsxOpeningFragment(), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *JsxOpeningFragment) computeSubtreeFacts() SubtreeFacts { + return SubtreeContainsJsx +} + +func IsJsxOpeningFragment(node *Node) bool { + return node.Kind == KindJsxOpeningFragment +} + +/// The closing element of a <>... JsxFragment + +type JsxClosingFragment struct { + ExpressionBase +} + +func (f *NodeFactory) NewJsxClosingFragment() *Node { + return f.newNode(KindJsxClosingFragment, &JsxClosingFragment{}) +} + +func (node *JsxClosingFragment) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJsxClosingFragment(), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *JsxClosingFragment) computeSubtreeFacts() SubtreeFacts { + return SubtreeContainsJsx +} + +// JsxAttribute + +type JsxAttribute struct { + NodeBase + DeclarationBase + compositeNodeBase + name *JsxAttributeName // JsxAttributeName + Initializer *JsxAttributeValue // JsxAttributeValue. Optional, is sugar for +} + +func (f *NodeFactory) NewJsxAttribute(name *JsxAttributeName, initializer *JsxAttributeValue) *Node { + data := &JsxAttribute{} + data.name = name + data.Initializer = initializer + return f.newNode(KindJsxAttribute, data) +} + +func (f *NodeFactory) UpdateJsxAttribute(node *JsxAttribute, name *JsxAttributeName, initializer *JsxAttributeValue) *Node { + if name != node.name || initializer != node.Initializer { + return updateNode(f.NewJsxAttribute(name, initializer), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JsxAttribute) ForEachChild(v Visitor) bool { + return visit(v, node.name) || visit(v, node.Initializer) +} + +func (node *JsxAttribute) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJsxAttribute(node, v.visitNode(node.name), v.visitNode(node.Initializer)) +} + +func (node *JsxAttribute) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJsxAttribute(node.Name(), node.Initializer), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *JsxAttribute) Name() *JsxAttributeName { + return node.name +} + +func (node *JsxAttribute) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.name) | + propagateSubtreeFacts(node.Initializer) | + SubtreeContainsJsx +} + +func IsJsxAttribute(node *Node) bool { + return node.Kind == KindJsxAttribute +} + +// JsxSpreadAttribute + +type JsxSpreadAttribute struct { + NodeBase + Expression *Expression // Expression +} + +func (f *NodeFactory) NewJsxSpreadAttribute(expression *Expression) *Node { + data := &JsxSpreadAttribute{} + data.Expression = expression + return f.newNode(KindJsxSpreadAttribute, data) +} + +func (f *NodeFactory) UpdateJsxSpreadAttribute(node *JsxSpreadAttribute, expression *Expression) *Node { + if expression != node.Expression { + return updateNode(f.NewJsxSpreadAttribute(expression), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JsxSpreadAttribute) ForEachChild(v Visitor) bool { + return visit(v, node.Expression) +} + +func (node *JsxSpreadAttribute) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJsxSpreadAttribute(node, v.visitNode(node.Expression)) +} + +func (node *JsxSpreadAttribute) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJsxSpreadAttribute(node.Expression), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *JsxSpreadAttribute) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) | SubtreeContainsJsx +} + +func IsJsxSpreadAttribute(node *Node) bool { + return node.Kind == KindJsxSpreadAttribute +} + +// JsxClosingElement + +type JsxClosingElement struct { + NodeBase + TagName *JsxTagNameExpression // JsxTagNameExpression +} + +func (f *NodeFactory) NewJsxClosingElement(tagName *JsxTagNameExpression) *Node { + data := &JsxClosingElement{} + data.TagName = tagName + return f.newNode(KindJsxClosingElement, data) +} + +func (f *NodeFactory) UpdateJsxClosingElement(node *JsxClosingElement, tagName *JsxTagNameExpression) *Node { + if tagName != node.TagName { + return updateNode(f.NewJsxClosingElement(tagName), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JsxClosingElement) ForEachChild(v Visitor) bool { + return visit(v, node.TagName) +} + +func (node *JsxClosingElement) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJsxClosingElement(node, v.visitNode(node.TagName)) +} + +func (node *JsxClosingElement) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJsxClosingElement(node.TagName), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *JsxClosingElement) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.TagName) | SubtreeContainsJsx +} + +func IsJsxClosingElement(node *Node) bool { + return node.Kind == KindJsxClosingElement +} + +// JsxExpression + +type JsxExpression struct { + ExpressionBase + DotDotDotToken *TokenNode // TokenNode. Optional + Expression *Expression // Expression +} + +func (f *NodeFactory) NewJsxExpression(dotDotDotToken *TokenNode, expression *Expression) *Node { + data := &JsxExpression{} + data.DotDotDotToken = dotDotDotToken + data.Expression = expression + return f.newNode(KindJsxExpression, data) +} + +func (f *NodeFactory) UpdateJsxExpression(node *JsxExpression, dotDotDotToken *TokenNode, expression *Expression) *Node { + if dotDotDotToken != node.DotDotDotToken || expression != node.Expression { + return updateNode(f.NewJsxExpression(dotDotDotToken, expression), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JsxExpression) ForEachChild(v Visitor) bool { + return visit(v, node.DotDotDotToken) || visit(v, node.Expression) +} + +func (node *JsxExpression) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJsxExpression(node, v.visitToken(node.DotDotDotToken), v.visitNode(node.Expression)) +} + +func (node *JsxExpression) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJsxExpression(node.DotDotDotToken, node.Expression), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *JsxExpression) computeSubtreeFacts() SubtreeFacts { + return propagateSubtreeFacts(node.Expression) | SubtreeContainsJsx +} + +func IsJsxExpression(node *Node) bool { + return node.Kind == KindJsxExpression +} + +// JsxText + +type JsxText struct { + ExpressionBase + LiteralLikeBase + ContainsOnlyTriviaWhiteSpaces bool +} + +func (f *NodeFactory) NewJsxText(text string, containsOnlyTriviaWhiteSpace bool) *Node { + data := &JsxText{} + data.Text = text + data.ContainsOnlyTriviaWhiteSpaces = containsOnlyTriviaWhiteSpace + f.textCount++ + return f.newNode(KindJsxText, data) +} + +func (node *JsxText) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJsxText(node.Text, node.ContainsOnlyTriviaWhiteSpaces), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *JsxText) computeSubtreeFacts() SubtreeFacts { + return SubtreeContainsJsx +} + +func IsJsxText(node *Node) bool { + return node.Kind == KindJsxText +} + +// SyntaxList + +type SyntaxList struct { + NodeBase + Children []*Node +} + +func (f *NodeFactory) NewSyntaxList(children []*Node) *Node { + data := &SyntaxList{} + data.Children = children + return f.newNode(KindSyntaxList, data) +} + +func (node *SyntaxList) ForEachChild(v Visitor) bool { + return visitNodes(v, node.Children) +} + +func (node *SyntaxList) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewSyntaxList(node.Children), node.AsNode(), f.AsNodeFactory().hooks) +} + +/// JSDoc /// + +type JSDoc struct { + NodeBase + Comment *NodeList // NodeList[*JSDocCommentBase] + Tags *NodeList // NodeList[*JSDocTagBase] +} + +func (f *NodeFactory) NewJSDoc(comment *NodeList, tags *NodeList) *Node { + data := f.jsdocPool.New() + data.Comment = comment + data.Tags = tags + return f.newNode(KindJSDoc, data) +} + +func (f *NodeFactory) UpdateJSDoc(node *JSDoc, comment *NodeList, tags *NodeList) *Node { + if comment != node.Comment || tags != node.Tags { + return updateNode(f.NewJSDoc(comment, tags), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDoc) ForEachChild(v Visitor) bool { + return visitNodeList(v, node.Comment) || visitNodeList(v, node.Tags) +} + +func (node *JSDoc) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJSDoc(node, v.visitNodes(node.Comment), v.visitNodes(node.Tags)) +} + +func (node *JSDoc) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDoc(node.Comment, node.Tags), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *Node) IsJSDoc() bool { + return node.Kind == KindJSDoc +} + +type JSDocTagBase struct { + NodeBase + TagName *IdentifierNode + Comment *NodeList +} + +type JSDocCommentBase struct { + NodeBase + text []string +} + +// JSDoc comments +type JSDocText struct { + JSDocCommentBase +} + +func (f *NodeFactory) NewJSDocText(text []string) *Node { + data := f.jsdocTextPool.New() + data.text = text + f.textCount++ + return f.newNode(KindJSDocText, data) +} + +func (node *JSDocText) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocText(node.text), node.AsNode(), f.AsNodeFactory().hooks) +} + +type JSDocLink struct { + JSDocCommentBase + name *Node // optional (should only be EntityName) +} + +func (f *NodeFactory) NewJSDocLink(name *Node, text []string) *Node { + data := &JSDocLink{} + data.name = name + data.text = text + f.textCount++ + return f.newNode(KindJSDocLink, data) +} + +func (f *NodeFactory) UpdateJSDocLink(node *JSDocLink, name *Node, text []string) *Node { + if name != node.name || !core.Same(text, node.text) { + return updateNode(f.NewJSDocLink(name, text), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDocLink) ForEachChild(v Visitor) bool { + return visit(v, node.name) +} + +func (node *JSDocLink) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJSDocLink(node, v.visitNode(node.name), node.text) +} + +func (node *JSDocLink) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocLink(node.Name(), node.text), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *JSDocLink) Name() *DeclarationName { + return node.name +} + +type JSDocLinkPlain struct { + JSDocCommentBase + name *Node // optional (should only be EntityName) +} + +func (f *NodeFactory) NewJSDocLinkPlain(name *Node, text []string) *Node { + data := &JSDocLinkPlain{} + data.name = name + data.text = text + f.textCount++ + return f.newNode(KindJSDocLinkPlain, data) +} + +func (f *NodeFactory) UpdateJSDocLinkPlain(node *JSDocLinkPlain, name *Node, text []string) *Node { + if name != node.name || !core.Same(text, node.text) { + return updateNode(f.NewJSDocLinkPlain(name, text), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDocLinkPlain) ForEachChild(v Visitor) bool { + return visit(v, node.name) +} + +func (node *JSDocLinkPlain) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJSDocLinkPlain(node, v.visitNode(node.name), node.text) +} + +func (node *JSDocLinkPlain) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocLinkPlain(node.Name(), node.text), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *JSDocLinkPlain) Name() *DeclarationName { + return node.name +} + +type JSDocLinkCode struct { + JSDocCommentBase + name *Node // optional (should only be EntityName) +} + +func (f *NodeFactory) NewJSDocLinkCode(name *Node, text []string) *Node { + data := &JSDocLinkCode{} + data.name = name + data.text = text + f.textCount++ + return f.newNode(KindJSDocLinkCode, data) +} + +func (f *NodeFactory) UpdateJSDocLinkCode(node *JSDocLinkCode, name *Node, text []string) *Node { + if name != node.name || !core.Same(text, node.text) { + return updateNode(f.NewJSDocLinkCode(name, text), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDocLinkCode) ForEachChild(v Visitor) bool { + return visit(v, node.name) +} + +func (node *JSDocLinkCode) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJSDocLinkCode(node, v.visitNode(node.name), node.text) +} + +func (node *JSDocLinkCode) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocLinkCode(node.Name(), node.text), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *JSDocLinkCode) Name() *DeclarationName { + return node.name +} + +// JSDocTypeExpression + +type JSDocTypeExpression struct { + TypeNodeBase + Type *TypeNode +} + +func (f *NodeFactory) NewJSDocTypeExpression(typeNode *TypeNode) *Node { + data := &JSDocTypeExpression{} + data.Type = typeNode + return f.newNode(KindJSDocTypeExpression, data) +} + +func (f *NodeFactory) UpdateJSDocTypeExpression(node *JSDocTypeExpression, typeNode *TypeNode) *Node { + if typeNode != node.Type { + return updateNode(f.NewJSDocTypeExpression(typeNode), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDocTypeExpression) ForEachChild(v Visitor) bool { + return visit(v, node.Type) +} + +func (node *JSDocTypeExpression) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJSDocTypeExpression(node, v.visitNode(node.Type)) +} + +func (node *JSDocTypeExpression) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocTypeExpression(node.Type), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsJSDocTypeExpression(node *Node) bool { + return node.Kind == KindJSDocTypeExpression +} + +// JSDocNonNullableType + +type JSDocNonNullableType struct { + TypeNodeBase + Type *TypeNode // TypeNode +} + +func (f *NodeFactory) NewJSDocNonNullableType(typeNode *TypeNode) *Node { + data := &JSDocNonNullableType{} + data.Type = typeNode + return f.newNode(KindJSDocNonNullableType, data) +} + +func (f *NodeFactory) UpdateJSDocNonNullableType(node *JSDocNonNullableType, typeNode *TypeNode) *Node { + if typeNode != node.Type { + return updateNode(f.NewJSDocNonNullableType(typeNode), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDocNonNullableType) ForEachChild(v Visitor) bool { + return visit(v, node.Type) +} + +func (node *JSDocNonNullableType) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJSDocNonNullableType(node, v.visitNode(node.Type)) +} + +func (node *JSDocNonNullableType) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocNonNullableType(node.Type), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsJSDocNonNullableType(node *Node) bool { + return node.Kind == KindJSDocNonNullableType +} + +// JSDocNullableType + +type JSDocNullableType struct { + TypeNodeBase + Type *TypeNode // TypeNode +} + +func (f *NodeFactory) NewJSDocNullableType(typeNode *TypeNode) *Node { + data := &JSDocNullableType{} + data.Type = typeNode + return f.newNode(KindJSDocNullableType, data) +} + +func (f *NodeFactory) UpdateJSDocNullableType(node *JSDocNullableType, typeNode *TypeNode) *Node { + if typeNode != node.Type { + return updateNode(f.NewJSDocNullableType(typeNode), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDocNullableType) ForEachChild(v Visitor) bool { + return visit(v, node.Type) +} + +func (node *JSDocNullableType) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJSDocNullableType(node, v.visitNode(node.Type)) +} + +func (node *JSDocNullableType) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocNullableType(node.Type), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsJSDocNullableType(node *Node) bool { + return node.Kind == KindJSDocNullableType +} + +// JSDocAllType + +type JSDocAllType struct { + TypeNodeBase +} + +func (f *NodeFactory) NewJSDocAllType() *Node { + data := &JSDocAllType{} + return f.newNode(KindJSDocAllType, data) +} + +func (node *JSDocAllType) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocAllType(), node.AsNode(), f.AsNodeFactory().hooks) +} + +// JSDocVariadicType + +type JSDocVariadicType struct { + TypeNodeBase + Type *TypeNode +} + +func (f *NodeFactory) NewJSDocVariadicType(typeNode *TypeNode) *Node { + data := &JSDocVariadicType{} + data.Type = typeNode + return f.newNode(KindJSDocVariadicType, data) +} + +func (f *NodeFactory) UpdateJSDocVariadicType(node *JSDocVariadicType, typeNode *TypeNode) *Node { + if typeNode != node.Type { + return updateNode(f.NewJSDocVariadicType(typeNode), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDocVariadicType) ForEachChild(v Visitor) bool { + return visit(v, node.Type) +} + +func (node *JSDocVariadicType) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJSDocVariadicType(node, v.visitNode(node.Type)) +} + +func (node *JSDocVariadicType) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocVariadicType(node.Type), node.AsNode(), f.AsNodeFactory().hooks) +} + +// JSDocOptionalType + +type JSDocOptionalType struct { + TypeNodeBase + Type *TypeNode +} + +func (f *NodeFactory) NewJSDocOptionalType(typeNode *TypeNode) *Node { + data := &JSDocOptionalType{} + data.Type = typeNode + return f.newNode(KindJSDocOptionalType, data) +} + +func (f *NodeFactory) UpdateJSDocOptionalType(node *JSDocOptionalType, typeNode *TypeNode) *Node { + if typeNode != node.Type { + return updateNode(f.NewJSDocOptionalType(typeNode), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDocOptionalType) ForEachChild(v Visitor) bool { + return visit(v, node.Type) +} + +func (node *JSDocOptionalType) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJSDocOptionalType(node, v.visitNode(node.Type)) +} + +func (node *JSDocOptionalType) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocOptionalType(node.Type), node.AsNode(), f.AsNodeFactory().hooks) +} + +// JSDocTypeTag + +type JSDocTypeTag struct { + JSDocTagBase + TypeExpression *TypeNode +} + +func (f *NodeFactory) NewJSDocTypeTag(tagName *IdentifierNode, typeExpression *Node, comment *NodeList) *Node { + data := &JSDocTypeTag{} + data.TagName = tagName + data.TypeExpression = typeExpression + data.Comment = comment + return f.newNode(KindJSDocTypeTag, data) +} + +func (f *NodeFactory) UpdateJSDocTypeTag(node *JSDocTypeTag, tagName *IdentifierNode, typeExpression *TypeNode, comment *NodeList) *Node { + if tagName != node.TagName || typeExpression != node.TypeExpression || comment != node.Comment { + return updateNode(f.NewJSDocTypeTag(tagName, typeExpression, comment), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDocTypeTag) ForEachChild(v Visitor) bool { + return visit(v, node.TagName) || visit(v, node.TypeExpression) || visitNodeList(v, node.Comment) +} + +func (node *JSDocTypeTag) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJSDocTypeTag(node, v.visitNode(node.TagName), v.visitNode(node.TypeExpression), v.visitNodes(node.Comment)) +} + +func (node *JSDocTypeTag) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocTypeTag(node.TagName, node.TypeExpression, node.Comment), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsJSDocTypeTag(node *Node) bool { + return node.Kind == KindJSDocTypeTag +} + +// JSDocUnknownTag +type JSDocUnknownTag struct { + JSDocTagBase +} + +func (f *NodeFactory) NewJSDocUnknownTag(tagName *IdentifierNode, comment *NodeList) *Node { + data := f.jsdocUnknownTagPool.New() + data.TagName = tagName + data.Comment = comment + return f.newNode(KindJSDocTag, data) +} + +func (f *NodeFactory) UpdateJSDocUnknownTag(node *JSDocUnknownTag, tagName *IdentifierNode, comment *NodeList) *Node { + if tagName != node.TagName || comment != node.Comment { + return updateNode(f.NewJSDocUnknownTag(tagName, comment), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDocUnknownTag) ForEachChild(v Visitor) bool { + return visit(v, node.TagName) || visitNodeList(v, node.Comment) +} + +func (node *JSDocUnknownTag) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJSDocUnknownTag(node, v.visitNode(node.TagName), v.visitNodes(node.Comment)) +} + +func (node *JSDocUnknownTag) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocUnknownTag(node.TagName, node.Comment), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsJSDocUnknownTag(node *Node) bool { + return node.Kind == KindJSDocTag +} + +// JSDocTemplateTag +type JSDocTemplateTag struct { + JSDocTagBase + Constraint *Node + TypeParameters *TypeParameterList +} + +func (f *NodeFactory) NewJSDocTemplateTag(tagName *IdentifierNode, constraint *Node, typeParameters *TypeParameterList, comment *NodeList) *Node { + data := &JSDocTemplateTag{} + data.TagName = tagName + data.Constraint = constraint + data.TypeParameters = typeParameters + data.Comment = comment + return f.newNode(KindJSDocTemplateTag, data) +} + +func (f *NodeFactory) UpdateJSDocTemplateTag(node *JSDocTemplateTag, tagName *IdentifierNode, constraint *Node, typeParameters *TypeParameterList, comment *NodeList) *Node { + if tagName != node.TagName || constraint != node.Constraint || typeParameters != node.TypeParameters || comment != node.Comment { + return updateNode(f.NewJSDocTemplateTag(tagName, constraint, typeParameters, comment), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDocTemplateTag) ForEachChild(v Visitor) bool { + return visit(v, node.TagName) || visit(v, node.Constraint) || visitNodeList(v, node.TypeParameters) || visitNodeList(v, node.Comment) +} + +func (node *JSDocTemplateTag) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJSDocTemplateTag(node, v.visitNode(node.TagName), v.visitNode(node.Constraint), v.visitNodes(node.TypeParameters), v.visitNodes(node.Comment)) +} + +func (node *JSDocTemplateTag) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocTemplateTag(node.TagName, node.Constraint, node.TypeParameters, node.Comment), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsJSDocTemplateTag(n *Node) bool { + return n.Kind == KindJSDocTemplateTag +} + +// JSDocParameterOrPropertyTag +type JSDocParameterOrPropertyTag struct { + JSDocTagBase + name *EntityName + IsBracketed bool + TypeExpression *TypeNode + IsNameFirst bool +} + +type ( + JSDocParameterTag = JSDocParameterOrPropertyTag + JSDocPropertyTag = JSDocParameterOrPropertyTag +) + +func (f *NodeFactory) newJSDocParameterOrPropertyTag(kind Kind, tagName *IdentifierNode, name *EntityName, isBracketed bool, typeExpression *TypeNode, isNameFirst bool, comment *NodeList) *Node { + data := f.jsdocParameterOrPropertyTagPool.New() + data.TagName = tagName + data.name = name + data.IsBracketed = isBracketed + data.TypeExpression = typeExpression + data.IsNameFirst = isNameFirst + data.Comment = comment + return f.newNode(kind, data) +} + +func (f *NodeFactory) NewJSDocParameterTag(tagName *IdentifierNode, name *EntityName, isBracketed bool, typeExpression *TypeNode, isNameFirst bool, comment *NodeList) *Node { + return f.newJSDocParameterOrPropertyTag(KindJSDocParameterTag, tagName, name, isBracketed, typeExpression, isNameFirst, comment) +} + +func (f *NodeFactory) NewJSDocPropertyTag(tagName *IdentifierNode, name *EntityName, isBracketed bool, typeExpression *TypeNode, isNameFirst bool, comment *NodeList) *Node { + return f.newJSDocParameterOrPropertyTag(KindJSDocPropertyTag, tagName, name, isBracketed, typeExpression, isNameFirst, comment) +} + +func (f *NodeFactory) UpdateJSDocParameterOrPropertyTag(kind Kind, node *JSDocParameterOrPropertyTag, tagName *IdentifierNode, name *EntityName, isBracketed bool, typeExpression *TypeNode, isNameFirst bool, comment *NodeList) *Node { + if tagName != node.TagName || name != node.name || isBracketed != node.IsBracketed || typeExpression != node.TypeExpression || isNameFirst != node.IsNameFirst || comment != node.Comment { + return updateNode(f.newJSDocParameterOrPropertyTag(kind, tagName, name, isBracketed, typeExpression, isNameFirst, comment), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDocParameterOrPropertyTag) ForEachChild(v Visitor) bool { + if node.IsNameFirst { + return visit(v, node.TagName) || visit(v, node.name) || visit(v, node.TypeExpression) || visitNodeList(v, node.Comment) + } else { + return visit(v, node.TagName) || visit(v, node.TypeExpression) || visit(v, node.name) || visitNodeList(v, node.Comment) + } +} + +func (node *JSDocParameterOrPropertyTag) VisitEachChild(v *NodeVisitor) *Node { + tagName := v.visitNode(node.TagName) + var name, typeExpression *Node + if node.IsNameFirst { + name, typeExpression = v.visitNode(node.name), v.visitNode(node.TypeExpression) + } else { + typeExpression, name = v.visitNode(node.TypeExpression), v.visitNode(node.name) + } + return v.Factory.UpdateJSDocParameterOrPropertyTag(node.Kind, node, tagName, name, node.IsBracketed, typeExpression, node.IsNameFirst, v.visitNodes(node.Comment)) +} + +func (node *JSDocParameterOrPropertyTag) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().newJSDocParameterOrPropertyTag(node.Kind, node.TagName, node.Name(), node.IsBracketed, node.TypeExpression, node.IsNameFirst, node.Comment), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *JSDocParameterOrPropertyTag) Name() *EntityName { return node.name } + +func IsJSDocParameterTag(node *Node) bool { + return node.Kind == KindJSDocParameterTag +} + +func IsJSDocPropertyTag(node *Node) bool { + return node.Kind == KindJSDocPropertyTag +} + +// JSDocReturnTag +type JSDocReturnTag struct { + JSDocTagBase + TypeExpression *TypeNode +} + +func (f *NodeFactory) NewJSDocReturnTag(tagName *IdentifierNode, typeExpression *TypeNode, comment *NodeList) *Node { + data := &JSDocReturnTag{} + data.TagName = tagName + data.TypeExpression = typeExpression + data.Comment = comment + return f.newNode(KindJSDocReturnTag, data) +} + +func (f *NodeFactory) UpdateJSDocReturnTag(node *JSDocReturnTag, tagName *IdentifierNode, typeExpression *TypeNode, comment *NodeList) *Node { + if tagName != node.TagName || typeExpression != node.TypeExpression || comment != node.Comment { + return updateNode(f.NewJSDocReturnTag(tagName, typeExpression, comment), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDocReturnTag) ForEachChild(v Visitor) bool { + return visit(v, node.TagName) || visit(v, node.TypeExpression) || visitNodeList(v, node.Comment) +} + +func (node *JSDocReturnTag) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJSDocReturnTag(node, v.visitNode(node.TagName), v.visitNode(node.TypeExpression), v.visitNodes(node.Comment)) +} + +func (node *JSDocReturnTag) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocReturnTag(node.TagName, node.TypeExpression, node.Comment), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsJSDocReturnTag(node *Node) bool { + return node.Kind == KindJSDocReturnTag +} + +// JSDocPublicTag +type JSDocPublicTag struct { + JSDocTagBase +} + +func (f *NodeFactory) NewJSDocPublicTag(tagName *IdentifierNode, comment *NodeList) *Node { + data := &JSDocPublicTag{} + data.TagName = tagName + data.Comment = comment + return f.newNode(KindJSDocPublicTag, data) +} + +func (f *NodeFactory) UpdateJSDocPublicTag(node *JSDocPublicTag, tagName *IdentifierNode, comment *NodeList) *Node { + if tagName != node.TagName || comment != node.Comment { + return updateNode(f.NewJSDocPublicTag(tagName, comment), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDocPublicTag) ForEachChild(v Visitor) bool { + return visit(v, node.TagName) || visitNodeList(v, node.Comment) +} + +func (node *JSDocPublicTag) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJSDocPublicTag(node, v.visitNode(node.TagName), v.visitNodes(node.Comment)) +} + +func (node *JSDocPublicTag) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocPublicTag(node.TagName, node.Comment), node.AsNode(), f.AsNodeFactory().hooks) +} + +// JSDocPrivateTag +type JSDocPrivateTag struct { + JSDocTagBase +} + +func (f *NodeFactory) NewJSDocPrivateTag(tagName *IdentifierNode, comment *NodeList) *Node { + data := &JSDocPrivateTag{} + data.TagName = tagName + data.Comment = comment + return f.newNode(KindJSDocPrivateTag, data) +} + +func (f *NodeFactory) UpdateJSDocPrivateTag(node *JSDocPrivateTag, tagName *IdentifierNode, comment *NodeList) *Node { + if tagName != node.TagName || comment != node.Comment { + return updateNode(f.NewJSDocPrivateTag(tagName, comment), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDocPrivateTag) ForEachChild(v Visitor) bool { + return visit(v, node.TagName) || visitNodeList(v, node.Comment) +} + +func (node *JSDocPrivateTag) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJSDocPrivateTag(node, v.visitNode(node.TagName), v.visitNodes(node.Comment)) +} + +func (node *JSDocPrivateTag) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocPrivateTag(node.TagName, node.Comment), node.AsNode(), f.AsNodeFactory().hooks) +} + +// JSDocProtectedTag +type JSDocProtectedTag struct { + JSDocTagBase +} + +func (f *NodeFactory) NewJSDocProtectedTag(tagName *IdentifierNode, comment *NodeList) *Node { + data := &JSDocProtectedTag{} + data.TagName = tagName + data.Comment = comment + return f.newNode(KindJSDocProtectedTag, data) +} + +func (f *NodeFactory) UpdateJSDocProtectedTag(node *JSDocProtectedTag, tagName *IdentifierNode, comment *NodeList) *Node { + if tagName != node.TagName || comment != node.Comment { + return updateNode(f.NewJSDocProtectedTag(tagName, comment), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDocProtectedTag) ForEachChild(v Visitor) bool { + return visit(v, node.TagName) || visitNodeList(v, node.Comment) +} + +func (node *JSDocProtectedTag) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJSDocProtectedTag(node, v.visitNode(node.TagName), v.visitNodes(node.Comment)) +} + +func (node *JSDocProtectedTag) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocProtectedTag(node.TagName, node.Comment), node.AsNode(), f.AsNodeFactory().hooks) +} + +// JSDocReadonlyTag +type JSDocReadonlyTag struct { + JSDocTagBase +} + +func (f *NodeFactory) NewJSDocReadonlyTag(tagName *IdentifierNode, comment *NodeList) *Node { + data := &JSDocReadonlyTag{} + data.TagName = tagName + data.Comment = comment + return f.newNode(KindJSDocReadonlyTag, data) +} + +func (f *NodeFactory) UpdateJSDocReadonlyTag(node *JSDocReadonlyTag, tagName *IdentifierNode, comment *NodeList) *Node { + if tagName != node.TagName || comment != node.Comment { + return updateNode(f.NewJSDocReadonlyTag(tagName, comment), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDocReadonlyTag) ForEachChild(v Visitor) bool { + return visit(v, node.TagName) || visitNodeList(v, node.Comment) +} + +func (node *JSDocReadonlyTag) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJSDocReadonlyTag(node, v.visitNode(node.TagName), v.visitNodes(node.Comment)) +} + +func (node *JSDocReadonlyTag) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocReadonlyTag(node.TagName, node.Comment), node.AsNode(), f.AsNodeFactory().hooks) +} + +// JSDocOverrideTag +type JSDocOverrideTag struct { + JSDocTagBase +} + +func (f *NodeFactory) NewJSDocOverrideTag(tagName *IdentifierNode, comment *NodeList) *Node { + data := &JSDocOverrideTag{} + data.TagName = tagName + data.Comment = comment + return f.newNode(KindJSDocOverrideTag, data) +} + +func (f *NodeFactory) UpdateJSDocOverrideTag(node *JSDocOverrideTag, tagName *IdentifierNode, comment *NodeList) *Node { + if tagName != node.TagName || comment != node.Comment { + return updateNode(f.NewJSDocOverrideTag(tagName, comment), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDocOverrideTag) ForEachChild(v Visitor) bool { + return visit(v, node.TagName) || visitNodeList(v, node.Comment) +} + +func (node *JSDocOverrideTag) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJSDocOverrideTag(node, v.visitNode(node.TagName), v.visitNodes(node.Comment)) +} + +func (node *JSDocOverrideTag) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocOverrideTag(node.TagName, node.Comment), node.AsNode(), f.AsNodeFactory().hooks) +} + +// JSDocDeprecatedTag +type JSDocDeprecatedTag struct { + JSDocTagBase +} + +func (f *NodeFactory) NewJSDocDeprecatedTag(tagName *IdentifierNode, comment *NodeList) *Node { + data := f.jsdocDeprecatedTagPool.New() + data.TagName = tagName + data.Comment = comment + return f.newNode(KindJSDocDeprecatedTag, data) +} + +func (f *NodeFactory) UpdateJSDocDeprecatedTag(node *JSDocDeprecatedTag, tagName *IdentifierNode, comment *NodeList) *Node { + if tagName != node.TagName || comment != node.Comment { + return updateNode(f.NewJSDocDeprecatedTag(tagName, comment), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDocDeprecatedTag) ForEachChild(v Visitor) bool { + return visit(v, node.TagName) || visitNodeList(v, node.Comment) +} + +func (node *JSDocDeprecatedTag) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJSDocDeprecatedTag(node, v.visitNode(node.TagName), v.visitNodes(node.Comment)) +} + +func (node *JSDocDeprecatedTag) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocDeprecatedTag(node.TagName, node.Comment), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsJSDocDeprecatedTag(node *Node) bool { + return node.Kind == KindJSDocDeprecatedTag +} + +// JSDocSeeTag +type JSDocSeeTag struct { + JSDocTagBase + NameExpression *TypeNode +} + +func (f *NodeFactory) NewJSDocSeeTag(tagName *IdentifierNode, nameExpression *TypeNode, comment *NodeList) *Node { + data := &JSDocSeeTag{} + data.TagName = tagName + data.NameExpression = nameExpression + data.Comment = comment + return f.newNode(KindJSDocSeeTag, data) +} + +func (f *NodeFactory) UpdateJSDocSeeTag(node *JSDocSeeTag, tagName *IdentifierNode, nameExpression *TypeNode, comment *NodeList) *Node { + if tagName != node.TagName || nameExpression != node.NameExpression || comment != node.Comment { + return updateNode(f.NewJSDocSeeTag(tagName, nameExpression, comment), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDocSeeTag) ForEachChild(v Visitor) bool { + return visit(v, node.TagName) || visit(v, node.NameExpression) || visitNodeList(v, node.Comment) +} + +func (node *JSDocSeeTag) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJSDocSeeTag(node, v.visitNode(node.TagName), v.visitNode(node.NameExpression), v.visitNodes(node.Comment)) +} + +func (node *JSDocSeeTag) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocSeeTag(node.TagName, node.NameExpression, node.Comment), node.AsNode(), f.AsNodeFactory().hooks) +} + +// JSDocImplementsTag +type JSDocImplementsTag struct { + JSDocTagBase + ClassName *Expression +} + +func (f *NodeFactory) NewJSDocImplementsTag(tagName *IdentifierNode, className *Expression, comment *NodeList) *Node { + data := &JSDocImplementsTag{} + data.TagName = tagName + data.ClassName = className + data.Comment = comment + return f.newNode(KindJSDocImplementsTag, data) +} + +func (f *NodeFactory) UpdateJSDocImplementsTag(node *JSDocImplementsTag, tagName *IdentifierNode, className *Expression, comment *NodeList) *Node { + if tagName != node.TagName || className != node.ClassName || comment != node.Comment { + return updateNode(f.NewJSDocImplementsTag(tagName, className, comment), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDocImplementsTag) ForEachChild(v Visitor) bool { + return visit(v, node.TagName) || visit(v, node.ClassName) || visitNodeList(v, node.Comment) +} + +func (node *JSDocImplementsTag) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJSDocImplementsTag(node, v.visitNode(node.TagName), v.visitNode(node.ClassName), v.visitNodes(node.Comment)) +} + +func (node *JSDocImplementsTag) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocImplementsTag(node.TagName, node.ClassName, node.Comment), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsJSDocImplementsTag(node *Node) bool { + return node.Kind == KindJSDocImplementsTag +} + +// JSDocAugmentsTag +type JSDocAugmentsTag struct { + JSDocTagBase + ClassName *Expression +} + +func (f *NodeFactory) NewJSDocAugmentsTag(tagName *IdentifierNode, className *Expression, comment *NodeList) *Node { + data := &JSDocAugmentsTag{} + data.TagName = tagName + data.ClassName = className + data.Comment = comment + return f.newNode(KindJSDocAugmentsTag, data) +} + +func (f *NodeFactory) UpdateJSDocAugmentsTag(node *JSDocAugmentsTag, tagName *IdentifierNode, className *Expression, comment *NodeList) *Node { + if tagName != node.TagName || className != node.ClassName || comment != node.Comment { + return updateNode(f.NewJSDocAugmentsTag(tagName, className, comment), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDocAugmentsTag) ForEachChild(v Visitor) bool { + return visit(v, node.TagName) || visit(v, node.ClassName) || visitNodeList(v, node.Comment) +} + +func (node *JSDocAugmentsTag) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJSDocAugmentsTag(node, v.visitNode(node.TagName), v.visitNode(node.ClassName), v.visitNodes(node.Comment)) +} + +func (node *JSDocAugmentsTag) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocAugmentsTag(node.TagName, node.ClassName, node.Comment), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsJSDocAugmentsTag(node *Node) bool { + return node.Kind == KindJSDocAugmentsTag +} + +// JSDocSatisfiesTag +type JSDocSatisfiesTag struct { + JSDocTagBase + TypeExpression *TypeNode +} + +func (f *NodeFactory) NewJSDocSatisfiesTag(tagName *IdentifierNode, typeExpression *TypeNode, comment *NodeList) *Node { + data := &JSDocSatisfiesTag{} + data.TagName = tagName + data.TypeExpression = typeExpression + data.Comment = comment + return f.newNode(KindJSDocSatisfiesTag, data) +} + +func (f *NodeFactory) UpdateJSDocSatisfiesTag(node *JSDocSatisfiesTag, tagName *IdentifierNode, typeExpression *TypeNode, comment *NodeList) *Node { + if tagName != node.TagName || typeExpression != node.TypeExpression || comment != node.Comment { + return updateNode(f.NewJSDocSatisfiesTag(tagName, typeExpression, comment), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDocSatisfiesTag) ForEachChild(v Visitor) bool { + return visit(v, node.TagName) || visit(v, node.TypeExpression) || visitNodeList(v, node.Comment) +} + +func (node *JSDocSatisfiesTag) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJSDocSatisfiesTag(node, v.visitNode(node.TagName), v.visitNode(node.TypeExpression), v.visitNodes(node.Comment)) +} + +func (node *JSDocSatisfiesTag) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocSatisfiesTag(node.TagName, node.TypeExpression, node.Comment), node.AsNode(), f.AsNodeFactory().hooks) +} + +// JSDocThisTag +type JSDocThisTag struct { + JSDocTagBase + TypeExpression *TypeNode +} + +func (f *NodeFactory) NewJSDocThisTag(tagName *IdentifierNode, typeExpression *TypeNode, comment *NodeList) *Node { + data := &JSDocThisTag{} + data.TagName = tagName + data.TypeExpression = typeExpression + data.Comment = comment + return f.newNode(KindJSDocThisTag, data) +} + +func (f *NodeFactory) UpdateJSDocThisTag(node *JSDocThisTag, tagName *IdentifierNode, typeExpression *TypeNode, comment *NodeList) *Node { + if tagName != node.TagName || typeExpression != node.TypeExpression || comment != node.Comment { + return updateNode(f.NewJSDocThisTag(tagName, typeExpression, comment), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDocThisTag) ForEachChild(v Visitor) bool { + return visit(v, node.TagName) || visit(v, node.TypeExpression) || visitNodeList(v, node.Comment) +} + +func (node *JSDocThisTag) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJSDocThisTag(node, v.visitNode(node.TagName), v.visitNode(node.TypeExpression), v.visitNodes(node.Comment)) +} + +func (node *JSDocThisTag) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocThisTag(node.TagName, node.TypeExpression, node.Comment), node.AsNode(), f.AsNodeFactory().hooks) +} + +// JSDocImportTag +type JSDocImportTag struct { + JSDocTagBase + ImportClause *Declaration + ModuleSpecifier *Expression + Attributes *Node +} + +func (f *NodeFactory) NewJSDocImportTag(tagName *IdentifierNode, importClause *Declaration, moduleSpecifier *Node, attributes *Node, comment *NodeList) *Node { + data := &JSDocImportTag{} + data.TagName = tagName + data.ImportClause = importClause + data.ModuleSpecifier = moduleSpecifier + data.Attributes = attributes + data.Comment = comment + return f.newNode(KindJSDocImportTag, data) +} + +func (f *NodeFactory) UpdateJSDocImportTag(node *JSDocImportTag, tagName *IdentifierNode, importClause *Declaration, moduleSpecifier *Node, attributes *Node, comment *NodeList) *Node { + if tagName != node.TagName || importClause != node.ImportClause || moduleSpecifier != node.ModuleSpecifier || attributes != node.Attributes || comment != node.Comment { + return updateNode(f.NewJSDocImportTag(tagName, importClause, moduleSpecifier, attributes, comment), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDocImportTag) ForEachChild(v Visitor) bool { + return visit(v, node.TagName) || visit(v, node.ImportClause) || visit(v, node.ModuleSpecifier) || visit(v, node.Attributes) || visitNodeList(v, node.Comment) +} + +func (node *JSDocImportTag) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJSDocImportTag(node, v.visitNode(node.TagName), v.visitNode(node.ImportClause), v.visitNode(node.ModuleSpecifier), v.visitNode(node.Attributes), v.visitNodes(node.Comment)) +} + +func (node *JSDocImportTag) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocImportTag(node.TagName, node.ImportClause, node.ModuleSpecifier, node.Attributes, node.Comment), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsJSDocImportTag(node *Node) bool { + return node.Kind == KindJSDocImportTag +} + +// JSDocCallbackTag +type JSDocCallbackTag struct { + JSDocTagBase + FullName *Node + TypeExpression *TypeNode +} + +func (f *NodeFactory) NewJSDocCallbackTag(tagName *IdentifierNode, typeExpression *TypeNode, fullName *Node, comment *NodeList) *Node { + data := &JSDocCallbackTag{} + data.TagName = tagName + data.FullName = fullName + data.TypeExpression = typeExpression + data.Comment = comment + return f.newNode(KindJSDocCallbackTag, data) +} + +func (f *NodeFactory) UpdateJSDocCallbackTag(node *JSDocCallbackTag, tagName *IdentifierNode, typeExpression *TypeNode, fullName *Node, comment *NodeList) *Node { + if tagName != node.TagName || typeExpression != node.TypeExpression || fullName != node.FullName || comment != node.Comment { + return updateNode(f.NewJSDocCallbackTag(tagName, typeExpression, fullName, comment), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDocCallbackTag) ForEachChild(v Visitor) bool { + return visit(v, node.TagName) || visit(v, node.FullName) || visit(v, node.TypeExpression) || visitNodeList(v, node.Comment) +} + +func (node *JSDocCallbackTag) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJSDocCallbackTag(node, v.visitNode(node.TagName), v.visitNode(node.TypeExpression), v.visitNode(node.FullName), v.visitNodes(node.Comment)) +} + +func (node *JSDocCallbackTag) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocCallbackTag(node.TagName, node.TypeExpression, node.FullName, node.Comment), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *JSDocCallbackTag) Name() *DeclarationName { return node.FullName } + +func IsJSDocCallbackTag(node *Node) bool { + return node.Kind == KindJSDocCallbackTag +} + +// JSDocOverloadTag +type JSDocOverloadTag struct { + JSDocTagBase + TypeExpression *TypeNode +} + +func (f *NodeFactory) NewJSDocOverloadTag(tagName *IdentifierNode, typeExpression *TypeNode, comment *NodeList) *Node { + data := &JSDocOverloadTag{} + data.TagName = tagName + data.TypeExpression = typeExpression + data.Comment = comment + return f.newNode(KindJSDocOverloadTag, data) +} + +func (f *NodeFactory) UpdateJSDocOverloadTag(node *JSDocOverloadTag, tagName *IdentifierNode, typeExpression *TypeNode, comment *NodeList) *Node { + if tagName != node.TagName || typeExpression != node.TypeExpression || comment != node.Comment { + return updateNode(f.NewJSDocOverloadTag(tagName, typeExpression, comment), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDocOverloadTag) ForEachChild(v Visitor) bool { + return visit(v, node.TagName) || visit(v, node.TypeExpression) || visitNodeList(v, node.Comment) +} + +func (node *JSDocOverloadTag) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJSDocOverloadTag(node, v.visitNode(node.TagName), v.visitNode(node.TypeExpression), v.visitNodes(node.Comment)) +} + +func (node *JSDocOverloadTag) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocOverloadTag(node.TagName, node.TypeExpression, node.Comment), node.AsNode(), f.AsNodeFactory().hooks) +} + +// JSDocTypedefTag +type JSDocTypedefTag struct { + JSDocTagBase + TypeExpression *Node + name *IdentifierNode +} + +func (f *NodeFactory) NewJSDocTypedefTag(tagName *IdentifierNode, typeExpression *Node, name *IdentifierNode, comment *NodeList) *Node { + data := &JSDocTypedefTag{} + data.TagName = tagName + data.TypeExpression = typeExpression + data.name = name + data.Comment = comment + return f.newNode(KindJSDocTypedefTag, data) +} + +func (f *NodeFactory) UpdateJSDocTypedefTag(node *JSDocTypedefTag, tagName *IdentifierNode, typeExpression *Node, fullName *IdentifierNode, comment *NodeList) *Node { + if tagName != node.TagName || typeExpression != node.TypeExpression || fullName != node.name || comment != node.Comment { + return updateNode(f.NewJSDocTypedefTag(tagName, typeExpression, fullName, comment), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDocTypedefTag) ForEachChild(v Visitor) bool { + if node.TypeExpression != nil && node.TypeExpression.Kind == KindJSDocTypeLiteral { + return visit(v, node.TagName) || visit(v, node.name) || visit(v, node.TypeExpression) || visitNodeList(v, node.Comment) + } + return visit(v, node.TagName) || visit(v, node.TypeExpression) || visit(v, node.name) || visitNodeList(v, node.Comment) +} + +func (node *JSDocTypedefTag) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJSDocTypedefTag(node, v.visitNode(node.TagName), v.visitNode(node.TypeExpression), v.visitNode(node.name), v.visitNodes(node.Comment)) +} + +func (node *JSDocTypedefTag) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocTypedefTag(node.TagName, node.TypeExpression, node.name, node.Comment), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *JSDocTypedefTag) Name() *DeclarationName { return node.name } + +func IsJSDocTypedefTag(node *Node) bool { + return node.Kind == KindJSDocTypedefTag +} + +// JSDocTypeLiteral +type JSDocTypeLiteral struct { + TypeNodeBase + DeclarationBase + JSDocPropertyTags []*Node + IsArrayType bool +} + +func (f *NodeFactory) NewJSDocTypeLiteral(jsdocPropertyTags []*Node, isArrayType bool) *Node { + data := &JSDocTypeLiteral{} + data.JSDocPropertyTags = jsdocPropertyTags + data.IsArrayType = isArrayType + return f.newNode(KindJSDocTypeLiteral, data) +} + +func (f *NodeFactory) UpdateJSDocTypeLiteral(node *JSDocTypeLiteral, jsdocPropertyTags []*Node, isArrayType bool) *Node { + if !core.Same(jsdocPropertyTags, node.JSDocPropertyTags) || isArrayType != node.IsArrayType { + return updateNode(f.NewJSDocTypeLiteral(jsdocPropertyTags, isArrayType), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDocTypeLiteral) ForEachChild(v Visitor) bool { + return visitNodes(v, node.JSDocPropertyTags) +} + +func (node *JSDocTypeLiteral) VisitEachChild(v *NodeVisitor) *Node { + jsdocPropertyTags := core.SameMap(node.JSDocPropertyTags, func(n *Node) *Node { return v.visitNode(n) }) + return v.Factory.UpdateJSDocTypeLiteral(node, jsdocPropertyTags, node.IsArrayType) +} + +func (node *JSDocTypeLiteral) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocTypeLiteral(node.JSDocPropertyTags, node.IsArrayType), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsJSDocTypeLiteral(node *Node) bool { + return node.Kind == KindJSDocTypeLiteral +} + +// JSDocSignature +type JSDocSignature struct { + TypeNodeBase + FunctionLikeBase +} + +func (f *NodeFactory) NewJSDocSignature(typeParameters *NodeList, parameters *NodeList, typeNode *JSDocTag) *Node { + data := &JSDocSignature{} + data.TypeParameters = typeParameters + data.Parameters = parameters + data.Type = typeNode + return f.newNode(KindJSDocSignature, data) +} + +func (f *NodeFactory) UpdateJSDocSignature(node *JSDocSignature, typeParameters *NodeList, parameters *NodeList, typeNode *JSDocTag) *Node { + if typeParameters != node.TypeParameters || parameters != node.Parameters || typeNode != node.Type { + return updateNode(f.NewJSDocSignature(typeParameters, parameters, typeNode), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDocSignature) ForEachChild(v Visitor) bool { + return visitNodeList(v, node.TypeParameters) || visitNodeList(v, node.Parameters) || visit(v, node.Type) +} + +func (node *JSDocSignature) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJSDocSignature(node, v.visitNodes(node.TypeParameters), v.visitNodes(node.Parameters), v.visitNode(node.Type)) +} + +func (node *JSDocSignature) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocSignature(node.TypeParameters, node.Parameters, node.Type), node.AsNode(), f.AsNodeFactory().hooks) +} + +func IsJSDocSignature(node *Node) bool { + return node.Kind == KindJSDocSignature +} + +// JSDocNameReference +type JSDocNameReference struct { + TypeNodeBase + name *EntityName +} + +func (f *NodeFactory) NewJSDocNameReference(name *EntityName) *Node { + data := &JSDocNameReference{} + data.name = name + return f.newNode(KindJSDocNameReference, data) +} + +func (f *NodeFactory) UpdateJSDocNameReference(node *JSDocNameReference, name *EntityName) *Node { + if name != node.name { + return updateNode(f.NewJSDocNameReference(name), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *JSDocNameReference) ForEachChild(v Visitor) bool { + return visit(v, node.name) +} + +func (node *JSDocNameReference) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateJSDocNameReference(node, v.visitNode(node.name)) +} + +func (node *JSDocNameReference) Clone(f NodeFactoryCoercible) *Node { + return cloneNode(f.AsNodeFactory().NewJSDocNameReference(node.Name()), node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *JSDocNameReference) Name() *EntityName { return node.name } + +func IsJSDocNameReference(node *Node) bool { + return node.Kind == KindJSDocNameReference +} + +// PatternAmbientModule + +type PatternAmbientModule struct { + Pattern core.Pattern + Symbol *Symbol +} + +type CommentDirectiveKind int32 + +const ( + CommentDirectiveKindUnknown CommentDirectiveKind = iota + CommentDirectiveKindExpectError + CommentDirectiveKindIgnore +) + +type CommentDirective struct { + Loc core.TextRange + Kind CommentDirectiveKind +} + +// SourceFile + +type SourceFileMetaData struct { + PackageJsonType string + PackageJsonDirectory string + ImpliedNodeFormat core.ResolutionMode +} + +type CheckJsDirective struct { + Enabled bool + Range CommentRange +} + +type HasFileName interface { + FileName() string + Path() tspath.Path +} + +type SourceFile struct { + NodeBase + DeclarationBase + LocalsContainerBase + compositeNodeBase + + // Fields set by NewSourceFile + fileName string // For debugging convenience + parseOptions SourceFileParseOptions + text string + Statements *NodeList // NodeList[*Statement] + EndOfFileToken *TokenNode // TokenNode[*EndOfFileToken] + + // Fields set by parser + diagnostics []*Diagnostic + jsDiagnostics []*Diagnostic + jsdocDiagnostics []*Diagnostic + LanguageVariant core.LanguageVariant + ScriptKind core.ScriptKind + IsDeclarationFile bool + UsesUriStyleNodeCoreModules core.Tristate + Identifiers map[string]string + IdentifierCount int + imports []*LiteralLikeNode // []LiteralLikeNode + ModuleAugmentations []*ModuleName // []ModuleName + AmbientModuleNames []string + CommentDirectives []CommentDirective + jsdocCache map[*Node][]*Node + Pragmas []Pragma + ReferencedFiles []*FileReference + TypeReferenceDirectives []*FileReference + LibReferenceDirectives []*FileReference + CheckJsDirective *CheckJsDirective + NodeCount int + TextCount int + CommonJSModuleIndicator *Node + ExternalModuleIndicator *Node + + // Fields set by binder + + isBound atomic.Bool + bindOnce sync.Once + bindDiagnostics []*Diagnostic + BindSuggestionDiagnostics []*Diagnostic + EndFlowNode *FlowNode + SymbolCount int + ClassifiableNames collections.Set[string] + PatternAmbientModules []*PatternAmbientModule + + // Fields set by ECMALineMap + + ecmaLineMapMu sync.RWMutex + ecmaLineMap []core.TextPos + + // Fields set by language service + + tokenCacheMu sync.Mutex + tokenCache map[core.TextRange]*Node + declarationMapMu sync.Mutex + declarationMap map[string][]*Node +} + +func (f *NodeFactory) NewSourceFile(opts SourceFileParseOptions, text string, statements *NodeList, endOfFileToken *TokenNode) *Node { + if tspath.GetEncodedRootLength(opts.FileName) == 0 || opts.FileName != tspath.NormalizePath(opts.FileName) { + panic(fmt.Sprintf("fileName should be normalized and absolute: %q", opts.FileName)) + } + data := &SourceFile{} + data.fileName = opts.FileName + data.parseOptions = opts + data.text = text + data.Statements = statements + data.EndOfFileToken = endOfFileToken + return f.newNode(KindSourceFile, data) +} + +func (node *SourceFile) ParseOptions() SourceFileParseOptions { + return node.parseOptions +} + +func (node *SourceFile) Text() string { + return node.text +} + +func (node *SourceFile) FileName() string { + return node.parseOptions.FileName +} + +func (node *SourceFile) Path() tspath.Path { + return node.parseOptions.Path +} + +func (node *SourceFile) Imports() []*LiteralLikeNode { + return node.imports +} + +func (node *SourceFile) Diagnostics() []*Diagnostic { + return node.diagnostics +} + +func (node *SourceFile) SetDiagnostics(diags []*Diagnostic) { + node.diagnostics = diags +} + +func (node *SourceFile) JSDiagnostics() []*Diagnostic { + return node.jsDiagnostics +} + +func (node *SourceFile) SetJSDiagnostics(diags []*Diagnostic) { + node.jsDiagnostics = diags +} + +func (node *SourceFile) JSDocDiagnostics() []*Diagnostic { + return node.jsdocDiagnostics +} + +func (node *SourceFile) SetJSDocDiagnostics(diags []*Diagnostic) { + node.jsdocDiagnostics = diags +} + +func (node *SourceFile) JSDocCache() map[*Node][]*Node { + return node.jsdocCache +} + +func (node *SourceFile) SetJSDocCache(cache map[*Node][]*Node) { + node.jsdocCache = cache +} + +func (node *SourceFile) BindDiagnostics() []*Diagnostic { + return node.bindDiagnostics +} + +func (node *SourceFile) SetBindDiagnostics(diags []*Diagnostic) { + node.bindDiagnostics = diags +} + +func (node *SourceFile) ForEachChild(v Visitor) bool { + return visitNodeList(v, node.Statements) || visit(v, node.EndOfFileToken) +} + +func (node *SourceFile) VisitEachChild(v *NodeVisitor) *Node { + return v.Factory.UpdateSourceFile(node, v.visitTopLevelStatements(node.Statements), v.visitToken(node.EndOfFileToken)) +} + +func (node *SourceFile) IsJS() bool { + return IsSourceFileJS(node) +} + +func (node *SourceFile) copyFrom(other *SourceFile) { + // Do not copy fields set by NewSourceFile (Text, FileName, Path, or Statements) + node.LanguageVariant = other.LanguageVariant + node.ScriptKind = other.ScriptKind + node.IsDeclarationFile = other.IsDeclarationFile + node.UsesUriStyleNodeCoreModules = other.UsesUriStyleNodeCoreModules + node.Identifiers = other.Identifiers + node.imports = other.imports + node.ModuleAugmentations = other.ModuleAugmentations + node.AmbientModuleNames = other.AmbientModuleNames + node.CommentDirectives = other.CommentDirectives + node.Pragmas = other.Pragmas + node.ReferencedFiles = other.ReferencedFiles + node.TypeReferenceDirectives = other.TypeReferenceDirectives + node.LibReferenceDirectives = other.LibReferenceDirectives + node.CommonJSModuleIndicator = other.CommonJSModuleIndicator + node.ExternalModuleIndicator = other.ExternalModuleIndicator + node.Flags |= other.Flags +} + +func (node *SourceFile) Clone(f NodeFactoryCoercible) *Node { + updated := f.AsNodeFactory().NewSourceFile(node.parseOptions, node.text, node.Statements, node.EndOfFileToken) + newFile := updated.AsSourceFile() + newFile.copyFrom(node) + return cloneNode(updated, node.AsNode(), f.AsNodeFactory().hooks) +} + +func (node *SourceFile) computeSubtreeFacts() SubtreeFacts { + return propagateNodeListSubtreeFacts(node.Statements, propagateSubtreeFacts) +} + +func (f *NodeFactory) UpdateSourceFile(node *SourceFile, statements *StatementList, endOfFileToken *TokenNode) *Node { + if statements != node.Statements || endOfFileToken != node.EndOfFileToken { + updated := f.NewSourceFile(node.parseOptions, node.text, statements, endOfFileToken).AsSourceFile() + updated.copyFrom(node) + return updateNode(updated.AsNode(), node.AsNode(), f.hooks) + } + return node.AsNode() +} + +func (node *SourceFile) ECMALineMap() []core.TextPos { + node.ecmaLineMapMu.RLock() + lineMap := node.ecmaLineMap + node.ecmaLineMapMu.RUnlock() + if lineMap == nil { + node.ecmaLineMapMu.Lock() + defer node.ecmaLineMapMu.Unlock() + lineMap = node.ecmaLineMap + if lineMap == nil { + lineMap = core.ComputeECMALineStarts(node.Text()) + node.ecmaLineMap = lineMap + } + } + return lineMap +} + +func (node *SourceFile) IsBound() bool { + return node.isBound.Load() +} + +func (node *SourceFile) BindOnce(bind func()) { + node.bindOnce.Do(func() { + bind() + node.isBound.Store(true) + }) +} + +func (node *SourceFile) GetOrCreateToken( + kind Kind, + pos int, + end int, + parent *Node, +) *TokenNode { + node.tokenCacheMu.Lock() + defer node.tokenCacheMu.Unlock() + + loc := core.NewTextRange(pos, end) + if node.tokenCache == nil { + node.tokenCache = make(map[core.TextRange]*Node) + } else if token, ok := node.tokenCache[loc]; ok { + if token.Kind != kind { + panic(fmt.Sprintf("Token cache mismatch: %v != %v", token.Kind, kind)) + } + if token.Parent != parent { + panic(fmt.Sprintf("Token cache mismatch: parent. Expected parent of kind %v, got %v", token.Parent.Kind, parent.Kind)) + } + return token + } + + token := newNode(kind, &Token{}, NodeFactoryHooks{}) + token.Loc = loc + token.Parent = parent + node.tokenCache[loc] = token + return token +} + +func IsSourceFile(node *Node) bool { + return node.Kind == KindSourceFile +} + +func (node *SourceFile) GetDeclarationMap() map[string][]*Node { + node.declarationMapMu.Lock() + defer node.declarationMapMu.Unlock() + if node.declarationMap == nil { + node.declarationMap = node.computeDeclarationMap() + } + return node.declarationMap +} + +func (node *SourceFile) computeDeclarationMap() map[string][]*Node { + result := make(map[string][]*Node) + + addDeclaration := func(declaration *Node) { + name := getDeclarationName(declaration) + if name != "" { + result[name] = append(result[name], declaration) + } + } + + var visit func(*Node) bool + visit = func(node *Node) bool { + switch node.Kind { + case KindFunctionDeclaration, KindFunctionExpression, KindMethodDeclaration, KindMethodSignature: + declarationName := getDeclarationName(node) + if declarationName != "" { + declarations := result[declarationName] + var lastDeclaration *Node + if len(declarations) != 0 { + lastDeclaration = declarations[len(declarations)-1] + } + // Check whether this declaration belongs to an "overload group". + if lastDeclaration != nil && node.Parent == lastDeclaration.Parent && node.Symbol() == lastDeclaration.Symbol() { + // Overwrite the last declaration if it was an overload and this one is an implementation. + if node.Body() != nil && lastDeclaration.Body() == nil { + declarations[len(declarations)-1] = node + } + } else { + result[declarationName] = append(result[declarationName], node) + } + } + node.ForEachChild(visit) + case KindClassDeclaration, KindClassExpression, KindInterfaceDeclaration, KindTypeAliasDeclaration, KindEnumDeclaration, KindModuleDeclaration, + KindImportEqualsDeclaration, KindImportClause, KindNamespaceImport, KindGetAccessor, KindSetAccessor, KindTypeLiteral: + addDeclaration(node) + node.ForEachChild(visit) + case KindImportSpecifier, KindExportSpecifier: + if node.PropertyName() != nil { + addDeclaration(node) + } + case KindParameter: + // Only consider parameter properties + if !HasSyntacticModifier(node, ModifierFlagsParameterPropertyModifier) { + break + } + fallthrough + case KindVariableDeclaration, KindBindingElement: + name := node.Name() + if name != nil { + if IsBindingPattern(name) { + node.Name().ForEachChild(visit) + } else { + if node.Initializer() != nil { + visit(node.Initializer()) + } + addDeclaration(node) + } + } + case KindEnumMember, KindPropertyDeclaration, KindPropertySignature: + addDeclaration(node) + case KindExportDeclaration: + // Handle named exports case e.g.: + // export {a, b as B} from "mod"; + exportClause := node.AsExportDeclaration().ExportClause + if exportClause != nil { + if IsNamedExports(exportClause) { + for _, element := range exportClause.AsNamedExports().Elements.Nodes { + visit(element) + } + } else { + visit(exportClause.AsNamespaceExport().Name()) + } + } + case KindImportDeclaration: + importClause := node.AsImportDeclaration().ImportClause + if importClause != nil { + // Handle default import case e.g.: + // import d from "mod"; + if importClause.Name() != nil { + addDeclaration(importClause.Name()) + } + // Handle named bindings in imports e.g.: + // import * as NS from "mod"; + // import {a, b as B} from "mod"; + namedBindings := importClause.AsImportClause().NamedBindings + if namedBindings != nil { + if namedBindings.Kind == KindNamespaceImport { + addDeclaration(namedBindings) + } else { + for _, element := range namedBindings.AsNamedImports().Elements.Nodes { + visit(element) + } + } + } + } + default: + node.ForEachChild(visit) + } + return false + } + node.ForEachChild(visit) + return result +} + +func getDeclarationName(declaration *Node) string { + name := GetNonAssignedNameOfDeclaration(declaration) + if name != nil { + if IsComputedPropertyName(name) { + if IsStringOrNumericLiteralLike(name.Expression()) { + return name.Expression().Text() + } + if IsPropertyAccessExpression(name.Expression()) { + return name.Expression().Name().Text() + } + } else if IsPropertyName(name) { + return name.Text() + } + } + return "" +} + +type SourceFileLike interface { + Text() string + ECMALineMap() []core.TextPos +} + +type CommentRange struct { + core.TextRange + Kind Kind + HasTrailingNewLine bool +} + +func (f *NodeFactory) NewCommentRange(kind Kind, pos int, end int, hasTrailingNewLine bool) CommentRange { + return CommentRange{ + TextRange: core.NewTextRange(pos, end), + Kind: kind, + HasTrailingNewLine: hasTrailingNewLine, + } +} + +type FileReference struct { + core.TextRange + FileName string + ResolutionMode core.ResolutionMode + Preserve bool +} + +type PragmaArgument struct { + core.TextRange + Name string + Value string +} + +type Pragma struct { + CommentRange + Name string + Args map[string]PragmaArgument +} + +type PragmaKindFlags = uint8 + +const ( + PragmaKindTripleSlashXML PragmaKindFlags = 1 << iota + PragmaKindSingleLine + PragmaKindMultiLine + PragmaKindFlagsNone PragmaKindFlags = 0 + PragmaKindAll = PragmaKindTripleSlashXML | PragmaKindSingleLine | PragmaKindMultiLine + PragmaKindDefault = PragmaKindAll +) + +type PragmaArgumentSpecification struct { + Name string + Optional bool + CaptureSpan bool +} +type PragmaSpecification struct { + Args []PragmaArgumentSpecification + Kind PragmaKindFlags +} + +func (spec *PragmaSpecification) IsTripleSlash() bool { + return (spec.Kind & PragmaKindTripleSlashXML) > 0 +} diff --git a/kitcom/internal/tsgo/ast/checkflags.go b/kitcom/internal/tsgo/ast/checkflags.go new file mode 100644 index 0000000..5c86398 --- /dev/null +++ b/kitcom/internal/tsgo/ast/checkflags.go @@ -0,0 +1,35 @@ +package ast + +// CheckFlags + +type CheckFlags uint32 + +const ( + CheckFlagsNone CheckFlags = 0 + CheckFlagsInstantiated CheckFlags = 1 << 0 // Instantiated symbol + CheckFlagsSyntheticProperty CheckFlags = 1 << 1 // Property in union or intersection type + CheckFlagsSyntheticMethod CheckFlags = 1 << 2 // Method in union or intersection type + CheckFlagsReadonly CheckFlags = 1 << 3 // Readonly transient symbol + CheckFlagsReadPartial CheckFlags = 1 << 4 // Synthetic property present in some but not all constituents + CheckFlagsWritePartial CheckFlags = 1 << 5 // Synthetic property present in some but only satisfied by an index signature in others + CheckFlagsHasNonUniformType CheckFlags = 1 << 6 // Synthetic property with non-uniform type in constituents + CheckFlagsHasLiteralType CheckFlags = 1 << 7 // Synthetic property with at least one literal type in constituents + CheckFlagsContainsPublic CheckFlags = 1 << 8 // Synthetic property with public constituent(s) + CheckFlagsContainsProtected CheckFlags = 1 << 9 // Synthetic property with protected constituent(s) + CheckFlagsContainsPrivate CheckFlags = 1 << 10 // Synthetic property with private constituent(s) + CheckFlagsContainsStatic CheckFlags = 1 << 11 // Synthetic property with static constituent(s) + CheckFlagsLate CheckFlags = 1 << 12 // Late-bound symbol for a computed property with a dynamic name + CheckFlagsReverseMapped CheckFlags = 1 << 13 // Property of reverse-inferred homomorphic mapped type + CheckFlagsOptionalParameter CheckFlags = 1 << 14 // Optional parameter + CheckFlagsRestParameter CheckFlags = 1 << 15 // Rest parameter + CheckFlagsDeferredType CheckFlags = 1 << 16 // Calculation of the type of this symbol is deferred due to processing costs, should be fetched with `getTypeOfSymbolWithDeferredType` + CheckFlagsHasNeverType CheckFlags = 1 << 17 // Synthetic property with at least one never type in constituents + CheckFlagsMapped CheckFlags = 1 << 18 // Property of mapped type + CheckFlagsStripOptional CheckFlags = 1 << 19 // Strip optionality in mapped property + CheckFlagsUnresolved CheckFlags = 1 << 20 // Unresolved type alias symbol + CheckFlagsIsDiscriminantComputed CheckFlags = 1 << 21 // IsDiscriminant flags has been computed + CheckFlagsIsDiscriminant CheckFlags = 1 << 22 // Discriminant property + CheckFlagsSynthetic = CheckFlagsSyntheticProperty | CheckFlagsSyntheticMethod + CheckFlagsNonUniformAndLiteral = CheckFlagsHasNonUniformType | CheckFlagsHasLiteralType + CheckFlagsPartial = CheckFlagsReadPartial | CheckFlagsWritePartial +) diff --git a/kitcom/internal/tsgo/ast/deepclone.go b/kitcom/internal/tsgo/ast/deepclone.go new file mode 100644 index 0000000..f7f0890 --- /dev/null +++ b/kitcom/internal/tsgo/ast/deepclone.go @@ -0,0 +1,86 @@ +package ast + +import "efprojects.com/kitten-ipc/kitcom/internal/tsgo/core" + +// Ideally, this would get cached on the node factory so there's only ever one set of closures made per factory +func getDeepCloneVisitor(f *NodeFactory, syntheticLocation bool) *NodeVisitor { + var visitor *NodeVisitor + visitor = NewNodeVisitor( + func(node *Node) *Node { + visited := visitor.VisitEachChild(node) + if visited != node { + if syntheticLocation { + visited.Loc = core.NewTextRange(-1, -1) + } + return visited + } + c := node.Clone(f) // forcibly clone leaf nodes, which will then cascade new nodes/arrays upwards via `update` calls + // In strada, `factory.cloneNode` was dynamic and did _not_ clone positions for any "special cases", meanwhile + // Node.Clone in corsa reliably uses `Update` calls for all nodes and so copies locations by default. + // Deep clones are done to copy a node across files, so here, we explicitly make the location range synthetic on all cloned nodes + if syntheticLocation { + c.Loc = core.NewTextRange(-1, -1) + } + return c + }, + f, + NodeVisitorHooks{ + VisitNodes: func(nodes *NodeList, v *NodeVisitor) *NodeList { + if nodes == nil { + return nil + } + visited := v.VisitNodes(nodes) + var newList *NodeList + if visited != nodes { + newList = visited + } else { + newList = nodes.Clone(v.Factory) + } + if syntheticLocation { + newList.Loc = core.NewTextRange(-1, -1) + if nodes.HasTrailingComma() { + newList.Nodes[len(newList.Nodes)-1].Loc = core.NewTextRange(-2, -2) + } + } + return newList + }, + VisitModifiers: func(nodes *ModifierList, v *NodeVisitor) *ModifierList { + if nodes == nil { + return nil + } + visited := v.VisitModifiers(nodes) + var newList *ModifierList + if visited != nodes { + newList = visited + } else { + newList = nodes.Clone(v.Factory) + } + if syntheticLocation { + newList.Loc = core.NewTextRange(-1, -1) + if nodes.HasTrailingComma() { + newList.Nodes[len(newList.Nodes)-1].Loc = core.NewTextRange(-2, -2) + } + } + return newList + }, + }, + ) + return visitor +} + +func (f *NodeFactory) DeepCloneNode(node *Node) *Node { + return getDeepCloneVisitor(f, true /*syntheticLocation*/).VisitNode(node) +} + +func (f *NodeFactory) DeepCloneReparse(node *Node) *Node { + if node != nil { + node = getDeepCloneVisitor(f, false /*syntheticLocation*/).VisitNode(node) + SetParentInChildren(node) + node.Flags |= NodeFlagsReparsed + } + return node +} + +func (f *NodeFactory) DeepCloneReparseModifiers(modifiers *ModifierList) *ModifierList { + return getDeepCloneVisitor(f, false /*syntheticLocation*/).VisitModifiers(modifiers) +} diff --git a/kitcom/internal/tsgo/ast/diagnostic.go b/kitcom/internal/tsgo/ast/diagnostic.go new file mode 100644 index 0000000..de3009b --- /dev/null +++ b/kitcom/internal/tsgo/ast/diagnostic.go @@ -0,0 +1,272 @@ +package ast + +import ( + "maps" + "slices" + "strings" + + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/core" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/diagnostics" +) + +// Diagnostic + +type Diagnostic struct { + file *SourceFile + loc core.TextRange + code int32 + category diagnostics.Category + message string + messageChain []*Diagnostic + relatedInformation []*Diagnostic + reportsUnnecessary bool + reportsDeprecated bool + skippedOnNoEmit bool +} + +func (d *Diagnostic) File() *SourceFile { return d.file } +func (d *Diagnostic) Pos() int { return d.loc.Pos() } +func (d *Diagnostic) End() int { return d.loc.End() } +func (d *Diagnostic) Len() int { return d.loc.Len() } +func (d *Diagnostic) Loc() core.TextRange { return d.loc } +func (d *Diagnostic) Code() int32 { return d.code } +func (d *Diagnostic) Category() diagnostics.Category { return d.category } +func (d *Diagnostic) Message() string { return d.message } +func (d *Diagnostic) MessageChain() []*Diagnostic { return d.messageChain } +func (d *Diagnostic) RelatedInformation() []*Diagnostic { return d.relatedInformation } +func (d *Diagnostic) ReportsUnnecessary() bool { return d.reportsUnnecessary } +func (d *Diagnostic) ReportsDeprecated() bool { return d.reportsDeprecated } +func (d *Diagnostic) SkippedOnNoEmit() bool { return d.skippedOnNoEmit } + +func (d *Diagnostic) SetFile(file *SourceFile) { d.file = file } +func (d *Diagnostic) SetLocation(loc core.TextRange) { d.loc = loc } +func (d *Diagnostic) SetCategory(category diagnostics.Category) { d.category = category } +func (d *Diagnostic) SetSkippedOnNoEmit() { d.skippedOnNoEmit = true } + +func (d *Diagnostic) SetMessageChain(messageChain []*Diagnostic) *Diagnostic { + d.messageChain = messageChain + return d +} + +func (d *Diagnostic) AddMessageChain(messageChain *Diagnostic) *Diagnostic { + if messageChain != nil { + d.messageChain = append(d.messageChain, messageChain) + } + return d +} + +func (d *Diagnostic) SetRelatedInfo(relatedInformation []*Diagnostic) *Diagnostic { + d.relatedInformation = relatedInformation + return d +} + +func (d *Diagnostic) AddRelatedInfo(relatedInformation *Diagnostic) *Diagnostic { + if relatedInformation != nil { + d.relatedInformation = append(d.relatedInformation, relatedInformation) + } + return d +} + +func (d *Diagnostic) Clone() *Diagnostic { + result := *d + return &result +} + +func NewDiagnosticWith( + file *SourceFile, + loc core.TextRange, + code int32, + category diagnostics.Category, + message string, + messageChain []*Diagnostic, + relatedInformation []*Diagnostic, + reportsUnnecessary bool, + reportsDeprecated bool, + skippedOnNoEmit bool, +) *Diagnostic { + return &Diagnostic{ + file: file, + loc: loc, + code: code, + category: category, + message: message, + messageChain: messageChain, + relatedInformation: relatedInformation, + reportsUnnecessary: reportsUnnecessary, + reportsDeprecated: reportsDeprecated, + skippedOnNoEmit: skippedOnNoEmit, + } +} + +func NewDiagnostic(file *SourceFile, loc core.TextRange, message *diagnostics.Message, args ...any) *Diagnostic { + return &Diagnostic{ + file: file, + loc: loc, + code: message.Code(), + category: message.Category(), + message: message.Format(args...), + reportsUnnecessary: message.ReportsUnnecessary(), + reportsDeprecated: message.ReportsDeprecated(), + } +} + +func NewDiagnosticChain(chain *Diagnostic, message *diagnostics.Message, args ...any) *Diagnostic { + if chain != nil { + return NewDiagnostic(chain.file, chain.loc, message, args...).AddMessageChain(chain).SetRelatedInfo(chain.relatedInformation) + } + return NewDiagnostic(nil, core.TextRange{}, message, args...) +} + +func NewCompilerDiagnostic(message *diagnostics.Message, args ...any) *Diagnostic { + return NewDiagnostic(nil, core.UndefinedTextRange(), message, args...) +} + +type DiagnosticsCollection struct { + fileDiagnostics map[string][]*Diagnostic + nonFileDiagnostics []*Diagnostic +} + +func (c *DiagnosticsCollection) Add(diagnostic *Diagnostic) { + if diagnostic.File() != nil { + fileName := diagnostic.File().FileName() + if c.fileDiagnostics == nil { + c.fileDiagnostics = make(map[string][]*Diagnostic) + } + c.fileDiagnostics[fileName] = core.InsertSorted(c.fileDiagnostics[fileName], diagnostic, CompareDiagnostics) + } else { + c.nonFileDiagnostics = core.InsertSorted(c.nonFileDiagnostics, diagnostic, CompareDiagnostics) + } +} + +func (c *DiagnosticsCollection) Lookup(diagnostic *Diagnostic) *Diagnostic { + var diagnostics []*Diagnostic + if diagnostic.File() != nil { + diagnostics = c.fileDiagnostics[diagnostic.File().FileName()] + } else { + diagnostics = c.nonFileDiagnostics + } + if i, ok := slices.BinarySearchFunc(diagnostics, diagnostic, CompareDiagnostics); ok { + return diagnostics[i] + } + return nil +} + +func (c *DiagnosticsCollection) GetGlobalDiagnostics() []*Diagnostic { + return c.nonFileDiagnostics +} + +func (c *DiagnosticsCollection) GetDiagnosticsForFile(fileName string) []*Diagnostic { + return c.fileDiagnostics[fileName] +} + +func (c *DiagnosticsCollection) GetDiagnostics() []*Diagnostic { + fileNames := slices.Collect(maps.Keys(c.fileDiagnostics)) + slices.Sort(fileNames) + diagnostics := slices.Clip(c.nonFileDiagnostics) + for _, fileName := range fileNames { + diagnostics = append(diagnostics, c.fileDiagnostics[fileName]...) + } + return diagnostics +} + +func getDiagnosticPath(d *Diagnostic) string { + if d.File() != nil { + return d.File().FileName() + } + return "" +} + +func EqualDiagnostics(d1, d2 *Diagnostic) bool { + return EqualDiagnosticsNoRelatedInfo(d1, d2) && + slices.EqualFunc(d1.RelatedInformation(), d2.RelatedInformation(), EqualDiagnostics) +} + +func EqualDiagnosticsNoRelatedInfo(d1, d2 *Diagnostic) bool { + return getDiagnosticPath(d1) == getDiagnosticPath(d2) && + d1.Loc() == d2.Loc() && + d1.Code() == d2.Code() && + d1.Message() == d2.Message() && + slices.EqualFunc(d1.MessageChain(), d2.MessageChain(), equalMessageChain) +} + +func equalMessageChain(c1, c2 *Diagnostic) bool { + return c1.Code() == c2.Code() && + c1.Message() == c2.Message() && + slices.EqualFunc(c1.MessageChain(), c2.MessageChain(), equalMessageChain) +} + +func compareMessageChainSize(c1, c2 []*Diagnostic) int { + c := len(c2) - len(c1) + if c != 0 { + return c + } + for i := range c1 { + c = compareMessageChainSize(c1[i].MessageChain(), c2[i].MessageChain()) + if c != 0 { + return c + } + } + return 0 +} + +func compareMessageChainContent(c1, c2 []*Diagnostic) int { + for i := range c1 { + c := strings.Compare(c1[i].Message(), c2[i].Message()) + if c != 0 { + return c + } + if c1[i].MessageChain() != nil { + c = compareMessageChainContent(c1[i].MessageChain(), c2[i].MessageChain()) + if c != 0 { + return c + } + } + } + return 0 +} + +func compareRelatedInfo(r1, r2 []*Diagnostic) int { + c := len(r2) - len(r1) + if c != 0 { + return c + } + for i := range r1 { + c = CompareDiagnostics(r1[i], r2[i]) + if c != 0 { + return c + } + } + return 0 +} + +func CompareDiagnostics(d1, d2 *Diagnostic) int { + c := strings.Compare(getDiagnosticPath(d1), getDiagnosticPath(d2)) + if c != 0 { + return c + } + c = d1.Loc().Pos() - d2.Loc().Pos() + if c != 0 { + return c + } + c = d1.Loc().End() - d2.Loc().End() + if c != 0 { + return c + } + c = int(d1.Code()) - int(d2.Code()) + if c != 0 { + return c + } + c = strings.Compare(d1.Message(), d2.Message()) + if c != 0 { + return c + } + c = compareMessageChainSize(d1.MessageChain(), d2.MessageChain()) + if c != 0 { + return c + } + c = compareMessageChainContent(d1.MessageChain(), d2.MessageChain()) + if c != 0 { + return c + } + return compareRelatedInfo(d1.RelatedInformation(), d2.RelatedInformation()) +} diff --git a/kitcom/internal/tsgo/ast/flow.go b/kitcom/internal/tsgo/ast/flow.go new file mode 100644 index 0000000..274a92f --- /dev/null +++ b/kitcom/internal/tsgo/ast/flow.go @@ -0,0 +1,75 @@ +package ast + +// FlowFlags + +type FlowFlags uint32 + +const ( + FlowFlagsUnreachable FlowFlags = 1 << 0 // Unreachable code + FlowFlagsStart FlowFlags = 1 << 1 // Start of flow graph + FlowFlagsBranchLabel FlowFlags = 1 << 2 // Non-looping junction + FlowFlagsLoopLabel FlowFlags = 1 << 3 // Looping junction + FlowFlagsAssignment FlowFlags = 1 << 4 // Assignment + FlowFlagsTrueCondition FlowFlags = 1 << 5 // Condition known to be true + FlowFlagsFalseCondition FlowFlags = 1 << 6 // Condition known to be false + FlowFlagsSwitchClause FlowFlags = 1 << 7 // Switch statement clause + FlowFlagsArrayMutation FlowFlags = 1 << 8 // Potential array mutation + FlowFlagsCall FlowFlags = 1 << 9 // Potential assertion call + FlowFlagsReduceLabel FlowFlags = 1 << 10 // Temporarily reduce antecedents of label + FlowFlagsReferenced FlowFlags = 1 << 11 // Referenced as antecedent once + FlowFlagsShared FlowFlags = 1 << 12 // Referenced as antecedent more than once + FlowFlagsLabel = FlowFlagsBranchLabel | FlowFlagsLoopLabel + FlowFlagsCondition = FlowFlagsTrueCondition | FlowFlagsFalseCondition +) + +// FlowNode + +type FlowNode struct { + Flags FlowFlags + Node *Node // Associated AST node + Antecedent *FlowNode // Antecedent for all but FlowLabel + Antecedents *FlowList // Linked list of antecedents for FlowLabel +} + +type FlowList struct { + Flow *FlowNode + Next *FlowList +} + +type FlowLabel = FlowNode + +// FlowSwitchClauseData (synthetic AST node for FlowFlagsSwitchClause) + +type FlowSwitchClauseData struct { + NodeBase + SwitchStatement *Node + ClauseStart int32 // Start index of case/default clause range + ClauseEnd int32 // End index of case/default clause range +} + +func NewFlowSwitchClauseData(switchStatement *Node, clauseStart int, clauseEnd int) *Node { + node := &FlowSwitchClauseData{} + node.SwitchStatement = switchStatement + node.ClauseStart = int32(clauseStart) + node.ClauseEnd = int32(clauseEnd) + return newNode(KindUnknown, node, NodeFactoryHooks{}) +} + +func (node *FlowSwitchClauseData) IsEmpty() bool { + return node.ClauseStart == node.ClauseEnd +} + +// FlowReduceLabelData (synthetic AST node for FlowFlagsReduceLabel) + +type FlowReduceLabelData struct { + NodeBase + Target *FlowLabel // Target label + Antecedents *FlowList // Temporary antecedent list +} + +func NewFlowReduceLabelData(target *FlowLabel, antecedents *FlowList) *Node { + node := &FlowReduceLabelData{} + node.Target = target + node.Antecedents = antecedents + return newNode(KindUnknown, node, NodeFactoryHooks{}) +} diff --git a/kitcom/internal/tsgo/ast/ids.go b/kitcom/internal/tsgo/ast/ids.go new file mode 100644 index 0000000..63e415d --- /dev/null +++ b/kitcom/internal/tsgo/ast/ids.go @@ -0,0 +1,6 @@ +package ast + +type ( + NodeId uint64 + SymbolId uint64 +) diff --git a/kitcom/internal/tsgo/ast/kind.go b/kitcom/internal/tsgo/ast/kind.go new file mode 100644 index 0000000..57cdaf6 --- /dev/null +++ b/kitcom/internal/tsgo/ast/kind.go @@ -0,0 +1,430 @@ +package ast + +//go:generate go tool golang.org/x/tools/cmd/stringer -type=Kind -output=kind_stringer_generated.go +//go:generate go tool mvdan.cc/gofumpt -w kind_stringer_generated.go + +type Kind int16 + +const ( + KindUnknown Kind = iota + KindEndOfFile + KindSingleLineCommentTrivia + KindMultiLineCommentTrivia + KindNewLineTrivia + KindWhitespaceTrivia + KindConflictMarkerTrivia + KindNonTextFileMarkerTrivia + KindNumericLiteral + KindBigIntLiteral + KindStringLiteral + KindJsxText + KindJsxTextAllWhiteSpaces + KindRegularExpressionLiteral + KindNoSubstitutionTemplateLiteral + // Pseudo-literals + KindTemplateHead + KindTemplateMiddle + KindTemplateTail + // Punctuation + KindOpenBraceToken + KindCloseBraceToken + KindOpenParenToken + KindCloseParenToken + KindOpenBracketToken + KindCloseBracketToken + KindDotToken + KindDotDotDotToken + KindSemicolonToken + KindCommaToken + KindQuestionDotToken + KindLessThanToken + KindLessThanSlashToken + KindGreaterThanToken + KindLessThanEqualsToken + KindGreaterThanEqualsToken + KindEqualsEqualsToken + KindExclamationEqualsToken + KindEqualsEqualsEqualsToken + KindExclamationEqualsEqualsToken + KindEqualsGreaterThanToken + KindPlusToken + KindMinusToken + KindAsteriskToken + KindAsteriskAsteriskToken + KindSlashToken + KindPercentToken + KindPlusPlusToken + KindMinusMinusToken + KindLessThanLessThanToken + KindGreaterThanGreaterThanToken + KindGreaterThanGreaterThanGreaterThanToken + KindAmpersandToken + KindBarToken + KindCaretToken + KindExclamationToken + KindTildeToken + KindAmpersandAmpersandToken + KindBarBarToken + KindQuestionToken + KindColonToken + KindAtToken + KindQuestionQuestionToken + /** Only the JSDoc scanner produces BacktickToken. The normal scanner produces NoSubstitutionTemplateLiteral and related kinds. */ + KindBacktickToken + /** Only the JSDoc scanner produces HashToken. The normal scanner produces PrivateIdentifier. */ + KindHashToken + // Assignments + KindEqualsToken + KindPlusEqualsToken + KindMinusEqualsToken + KindAsteriskEqualsToken + KindAsteriskAsteriskEqualsToken + KindSlashEqualsToken + KindPercentEqualsToken + KindLessThanLessThanEqualsToken + KindGreaterThanGreaterThanEqualsToken + KindGreaterThanGreaterThanGreaterThanEqualsToken + KindAmpersandEqualsToken + KindBarEqualsToken + KindBarBarEqualsToken + KindAmpersandAmpersandEqualsToken + KindQuestionQuestionEqualsToken + KindCaretEqualsToken + // Identifiers and PrivateIdentifier + KindIdentifier + KindPrivateIdentifier + KindJSDocCommentTextToken + // Reserved words + KindBreakKeyword + KindCaseKeyword + KindCatchKeyword + KindClassKeyword + KindConstKeyword + KindContinueKeyword + KindDebuggerKeyword + KindDefaultKeyword + KindDeleteKeyword + KindDoKeyword + KindElseKeyword + KindEnumKeyword + KindExportKeyword + KindExtendsKeyword + KindFalseKeyword + KindFinallyKeyword + KindForKeyword + KindFunctionKeyword + KindIfKeyword + KindImportKeyword + KindInKeyword + KindInstanceOfKeyword + KindNewKeyword + KindNullKeyword + KindReturnKeyword + KindSuperKeyword + KindSwitchKeyword + KindThisKeyword + KindThrowKeyword + KindTrueKeyword + KindTryKeyword + KindTypeOfKeyword + KindVarKeyword + KindVoidKeyword + KindWhileKeyword + KindWithKeyword + // Strict mode reserved words + KindImplementsKeyword + KindInterfaceKeyword + KindLetKeyword + KindPackageKeyword + KindPrivateKeyword + KindProtectedKeyword + KindPublicKeyword + KindStaticKeyword + KindYieldKeyword + // Contextual keywords + KindAbstractKeyword + KindAccessorKeyword + KindAsKeyword + KindAssertsKeyword + KindAssertKeyword + KindAnyKeyword + KindAsyncKeyword + KindAwaitKeyword + KindBooleanKeyword + KindConstructorKeyword + KindDeclareKeyword + KindGetKeyword + KindImmediateKeyword + KindInferKeyword + KindIntrinsicKeyword + KindIsKeyword + KindKeyOfKeyword + KindModuleKeyword + KindNamespaceKeyword + KindNeverKeyword + KindOutKeyword + KindReadonlyKeyword + KindRequireKeyword + KindNumberKeyword + KindObjectKeyword + KindSatisfiesKeyword + KindSetKeyword + KindStringKeyword + KindSymbolKeyword + KindTypeKeyword + KindUndefinedKeyword + KindUniqueKeyword + KindUnknownKeyword + KindUsingKeyword + KindFromKeyword + KindGlobalKeyword + KindBigIntKeyword + KindOverrideKeyword + KindOfKeyword + KindDeferKeyword // LastKeyword and LastToken and LastContextualKeyword + // Parse tree nodes + // Names + KindQualifiedName + KindComputedPropertyName + // Signature elements + KindTypeParameter + KindParameter + KindDecorator + // TypeMember + KindPropertySignature + KindPropertyDeclaration + KindMethodSignature + KindMethodDeclaration + KindClassStaticBlockDeclaration + KindConstructor + KindGetAccessor + KindSetAccessor + KindCallSignature + KindConstructSignature + KindIndexSignature + // Type + KindTypePredicate + KindTypeReference + KindFunctionType + KindConstructorType + KindTypeQuery + KindTypeLiteral + KindArrayType + KindTupleType + KindOptionalType + KindRestType + KindUnionType + KindIntersectionType + KindConditionalType + KindInferType + KindParenthesizedType + KindThisType + KindTypeOperator + KindIndexedAccessType + KindMappedType + KindLiteralType + KindNamedTupleMember + KindTemplateLiteralType + KindTemplateLiteralTypeSpan + KindImportType + // Binding patterns + KindObjectBindingPattern + KindArrayBindingPattern + KindBindingElement + // Expression + KindArrayLiteralExpression + KindObjectLiteralExpression + KindPropertyAccessExpression + KindElementAccessExpression + KindCallExpression + KindNewExpression + KindTaggedTemplateExpression + KindTypeAssertionExpression + KindParenthesizedExpression + KindFunctionExpression + KindArrowFunction + KindDeleteExpression + KindTypeOfExpression + KindVoidExpression + KindAwaitExpression + KindPrefixUnaryExpression + KindPostfixUnaryExpression + KindBinaryExpression + KindConditionalExpression + KindTemplateExpression + KindYieldExpression + KindSpreadElement + KindClassExpression + KindOmittedExpression + KindExpressionWithTypeArguments + KindAsExpression + KindNonNullExpression + KindMetaProperty + KindSyntheticExpression + KindSatisfiesExpression + // Misc + KindTemplateSpan + KindSemicolonClassElement + // Element + KindBlock + KindEmptyStatement + KindVariableStatement + KindExpressionStatement + KindIfStatement + KindDoStatement + KindWhileStatement + KindForStatement + KindForInStatement + KindForOfStatement + KindContinueStatement + KindBreakStatement + KindReturnStatement + KindWithStatement + KindSwitchStatement + KindLabeledStatement + KindThrowStatement + KindTryStatement + KindDebuggerStatement + KindVariableDeclaration + KindVariableDeclarationList + KindFunctionDeclaration + KindClassDeclaration + KindInterfaceDeclaration + KindTypeAliasDeclaration + KindEnumDeclaration + KindModuleDeclaration + KindModuleBlock + KindCaseBlock + KindNamespaceExportDeclaration + KindImportEqualsDeclaration + KindImportDeclaration + KindImportClause + KindNamespaceImport + KindNamedImports + KindImportSpecifier + KindExportAssignment + KindExportDeclaration + KindNamedExports + KindNamespaceExport + KindExportSpecifier + KindMissingDeclaration + // Module references + KindExternalModuleReference + // JSX + KindJsxElement + KindJsxSelfClosingElement + KindJsxOpeningElement + KindJsxClosingElement + KindJsxFragment + KindJsxOpeningFragment + KindJsxClosingFragment + KindJsxAttribute + KindJsxAttributes + KindJsxSpreadAttribute + KindJsxExpression + KindJsxNamespacedName + // Clauses + KindCaseClause + KindDefaultClause + KindHeritageClause + KindCatchClause + // Import attributes + KindImportAttributes + KindImportAttribute + // Property assignments + KindPropertyAssignment + KindShorthandPropertyAssignment + KindSpreadAssignment + // Enum + KindEnumMember + // Top-level nodes + KindSourceFile + KindBundle + // JSDoc nodes + KindJSDocTypeExpression + KindJSDocNameReference + KindJSDocMemberName // C#p + KindJSDocAllType // The * type + KindJSDocNullableType + KindJSDocNonNullableType + KindJSDocOptionalType + KindJSDocVariadicType + KindJSDoc + KindJSDocText + KindJSDocTypeLiteral + KindJSDocSignature + KindJSDocLink + KindJSDocLinkCode + KindJSDocLinkPlain + KindJSDocTag + KindJSDocAugmentsTag + KindJSDocImplementsTag + KindJSDocDeprecatedTag + KindJSDocPublicTag + KindJSDocPrivateTag + KindJSDocProtectedTag + KindJSDocReadonlyTag + KindJSDocOverrideTag + KindJSDocCallbackTag + KindJSDocOverloadTag + KindJSDocParameterTag + KindJSDocReturnTag + KindJSDocThisTag + KindJSDocTypeTag + KindJSDocTemplateTag + KindJSDocTypedefTag + KindJSDocSeeTag + KindJSDocPropertyTag + KindJSDocSatisfiesTag + KindJSDocImportTag + // Synthesized list + KindSyntaxList + // Reparsed JS nodes + KindJSTypeAliasDeclaration + KindJSExportAssignment + KindCommonJSExport + KindJSImportDeclaration + // Transformation nodes + KindNotEmittedStatement + KindPartiallyEmittedExpression + KindCommaListExpression + KindSyntheticReferenceExpression + KindNotEmittedTypeElement + // Enum value count + KindCount + // Markers + KindFirstAssignment = KindEqualsToken + KindLastAssignment = KindCaretEqualsToken + KindFirstCompoundAssignment = KindPlusEqualsToken + KindLastCompoundAssignment = KindCaretEqualsToken + KindFirstReservedWord = KindBreakKeyword + KindLastReservedWord = KindWithKeyword + KindFirstKeyword = KindBreakKeyword + KindLastKeyword = KindDeferKeyword + KindFirstFutureReservedWord = KindImplementsKeyword + KindLastFutureReservedWord = KindYieldKeyword + KindFirstTypeNode = KindTypePredicate + KindLastTypeNode = KindImportType + KindFirstPunctuation = KindOpenBraceToken + KindLastPunctuation = KindCaretEqualsToken + KindFirstToken = KindUnknown + KindLastToken = KindLastKeyword + KindFirstLiteralToken = KindNumericLiteral + KindLastLiteralToken = KindNoSubstitutionTemplateLiteral + KindFirstTemplateToken = KindNoSubstitutionTemplateLiteral + KindLastTemplateToken = KindTemplateTail + KindFirstBinaryOperator = KindLessThanToken + KindLastBinaryOperator = KindCaretEqualsToken + KindFirstStatement = KindVariableStatement + KindLastStatement = KindDebuggerStatement + KindFirstNode = KindQualifiedName + KindFirstJSDocNode = KindJSDocTypeExpression + KindLastJSDocNode = KindJSDocImportTag + KindFirstJSDocTagNode = KindJSDocTag + KindLastJSDocTagNode = KindJSDocImportTag + KindFirstContextualKeyword = KindAbstractKeyword + KindLastContextualKeyword = KindDeferKeyword + KindComment = KindSingleLineCommentTrivia | KindMultiLineCommentTrivia + KindFirstTriviaToken = KindSingleLineCommentTrivia + KindLastTriviaToken = KindConflictMarkerTrivia +) diff --git a/kitcom/internal/tsgo/ast/kind_stringer_generated.go b/kitcom/internal/tsgo/ast/kind_stringer_generated.go new file mode 100644 index 0000000..ac4a204 --- /dev/null +++ b/kitcom/internal/tsgo/ast/kind_stringer_generated.go @@ -0,0 +1,378 @@ +// Code generated by "stringer -type=Kind -output=kind_stringer_generated.go"; DO NOT EDIT. + +package ast + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[KindUnknown-0] + _ = x[KindEndOfFile-1] + _ = x[KindSingleLineCommentTrivia-2] + _ = x[KindMultiLineCommentTrivia-3] + _ = x[KindNewLineTrivia-4] + _ = x[KindWhitespaceTrivia-5] + _ = x[KindConflictMarkerTrivia-6] + _ = x[KindNonTextFileMarkerTrivia-7] + _ = x[KindNumericLiteral-8] + _ = x[KindBigIntLiteral-9] + _ = x[KindStringLiteral-10] + _ = x[KindJsxText-11] + _ = x[KindJsxTextAllWhiteSpaces-12] + _ = x[KindRegularExpressionLiteral-13] + _ = x[KindNoSubstitutionTemplateLiteral-14] + _ = x[KindTemplateHead-15] + _ = x[KindTemplateMiddle-16] + _ = x[KindTemplateTail-17] + _ = x[KindOpenBraceToken-18] + _ = x[KindCloseBraceToken-19] + _ = x[KindOpenParenToken-20] + _ = x[KindCloseParenToken-21] + _ = x[KindOpenBracketToken-22] + _ = x[KindCloseBracketToken-23] + _ = x[KindDotToken-24] + _ = x[KindDotDotDotToken-25] + _ = x[KindSemicolonToken-26] + _ = x[KindCommaToken-27] + _ = x[KindQuestionDotToken-28] + _ = x[KindLessThanToken-29] + _ = x[KindLessThanSlashToken-30] + _ = x[KindGreaterThanToken-31] + _ = x[KindLessThanEqualsToken-32] + _ = x[KindGreaterThanEqualsToken-33] + _ = x[KindEqualsEqualsToken-34] + _ = x[KindExclamationEqualsToken-35] + _ = x[KindEqualsEqualsEqualsToken-36] + _ = x[KindExclamationEqualsEqualsToken-37] + _ = x[KindEqualsGreaterThanToken-38] + _ = x[KindPlusToken-39] + _ = x[KindMinusToken-40] + _ = x[KindAsteriskToken-41] + _ = x[KindAsteriskAsteriskToken-42] + _ = x[KindSlashToken-43] + _ = x[KindPercentToken-44] + _ = x[KindPlusPlusToken-45] + _ = x[KindMinusMinusToken-46] + _ = x[KindLessThanLessThanToken-47] + _ = x[KindGreaterThanGreaterThanToken-48] + _ = x[KindGreaterThanGreaterThanGreaterThanToken-49] + _ = x[KindAmpersandToken-50] + _ = x[KindBarToken-51] + _ = x[KindCaretToken-52] + _ = x[KindExclamationToken-53] + _ = x[KindTildeToken-54] + _ = x[KindAmpersandAmpersandToken-55] + _ = x[KindBarBarToken-56] + _ = x[KindQuestionToken-57] + _ = x[KindColonToken-58] + _ = x[KindAtToken-59] + _ = x[KindQuestionQuestionToken-60] + _ = x[KindBacktickToken-61] + _ = x[KindHashToken-62] + _ = x[KindEqualsToken-63] + _ = x[KindPlusEqualsToken-64] + _ = x[KindMinusEqualsToken-65] + _ = x[KindAsteriskEqualsToken-66] + _ = x[KindAsteriskAsteriskEqualsToken-67] + _ = x[KindSlashEqualsToken-68] + _ = x[KindPercentEqualsToken-69] + _ = x[KindLessThanLessThanEqualsToken-70] + _ = x[KindGreaterThanGreaterThanEqualsToken-71] + _ = x[KindGreaterThanGreaterThanGreaterThanEqualsToken-72] + _ = x[KindAmpersandEqualsToken-73] + _ = x[KindBarEqualsToken-74] + _ = x[KindBarBarEqualsToken-75] + _ = x[KindAmpersandAmpersandEqualsToken-76] + _ = x[KindQuestionQuestionEqualsToken-77] + _ = x[KindCaretEqualsToken-78] + _ = x[KindIdentifier-79] + _ = x[KindPrivateIdentifier-80] + _ = x[KindJSDocCommentTextToken-81] + _ = x[KindBreakKeyword-82] + _ = x[KindCaseKeyword-83] + _ = x[KindCatchKeyword-84] + _ = x[KindClassKeyword-85] + _ = x[KindConstKeyword-86] + _ = x[KindContinueKeyword-87] + _ = x[KindDebuggerKeyword-88] + _ = x[KindDefaultKeyword-89] + _ = x[KindDeleteKeyword-90] + _ = x[KindDoKeyword-91] + _ = x[KindElseKeyword-92] + _ = x[KindEnumKeyword-93] + _ = x[KindExportKeyword-94] + _ = x[KindExtendsKeyword-95] + _ = x[KindFalseKeyword-96] + _ = x[KindFinallyKeyword-97] + _ = x[KindForKeyword-98] + _ = x[KindFunctionKeyword-99] + _ = x[KindIfKeyword-100] + _ = x[KindImportKeyword-101] + _ = x[KindInKeyword-102] + _ = x[KindInstanceOfKeyword-103] + _ = x[KindNewKeyword-104] + _ = x[KindNullKeyword-105] + _ = x[KindReturnKeyword-106] + _ = x[KindSuperKeyword-107] + _ = x[KindSwitchKeyword-108] + _ = x[KindThisKeyword-109] + _ = x[KindThrowKeyword-110] + _ = x[KindTrueKeyword-111] + _ = x[KindTryKeyword-112] + _ = x[KindTypeOfKeyword-113] + _ = x[KindVarKeyword-114] + _ = x[KindVoidKeyword-115] + _ = x[KindWhileKeyword-116] + _ = x[KindWithKeyword-117] + _ = x[KindImplementsKeyword-118] + _ = x[KindInterfaceKeyword-119] + _ = x[KindLetKeyword-120] + _ = x[KindPackageKeyword-121] + _ = x[KindPrivateKeyword-122] + _ = x[KindProtectedKeyword-123] + _ = x[KindPublicKeyword-124] + _ = x[KindStaticKeyword-125] + _ = x[KindYieldKeyword-126] + _ = x[KindAbstractKeyword-127] + _ = x[KindAccessorKeyword-128] + _ = x[KindAsKeyword-129] + _ = x[KindAssertsKeyword-130] + _ = x[KindAssertKeyword-131] + _ = x[KindAnyKeyword-132] + _ = x[KindAsyncKeyword-133] + _ = x[KindAwaitKeyword-134] + _ = x[KindBooleanKeyword-135] + _ = x[KindConstructorKeyword-136] + _ = x[KindDeclareKeyword-137] + _ = x[KindGetKeyword-138] + _ = x[KindImmediateKeyword-139] + _ = x[KindInferKeyword-140] + _ = x[KindIntrinsicKeyword-141] + _ = x[KindIsKeyword-142] + _ = x[KindKeyOfKeyword-143] + _ = x[KindModuleKeyword-144] + _ = x[KindNamespaceKeyword-145] + _ = x[KindNeverKeyword-146] + _ = x[KindOutKeyword-147] + _ = x[KindReadonlyKeyword-148] + _ = x[KindRequireKeyword-149] + _ = x[KindNumberKeyword-150] + _ = x[KindObjectKeyword-151] + _ = x[KindSatisfiesKeyword-152] + _ = x[KindSetKeyword-153] + _ = x[KindStringKeyword-154] + _ = x[KindSymbolKeyword-155] + _ = x[KindTypeKeyword-156] + _ = x[KindUndefinedKeyword-157] + _ = x[KindUniqueKeyword-158] + _ = x[KindUnknownKeyword-159] + _ = x[KindUsingKeyword-160] + _ = x[KindFromKeyword-161] + _ = x[KindGlobalKeyword-162] + _ = x[KindBigIntKeyword-163] + _ = x[KindOverrideKeyword-164] + _ = x[KindOfKeyword-165] + _ = x[KindDeferKeyword-166] + _ = x[KindQualifiedName-167] + _ = x[KindComputedPropertyName-168] + _ = x[KindTypeParameter-169] + _ = x[KindParameter-170] + _ = x[KindDecorator-171] + _ = x[KindPropertySignature-172] + _ = x[KindPropertyDeclaration-173] + _ = x[KindMethodSignature-174] + _ = x[KindMethodDeclaration-175] + _ = x[KindClassStaticBlockDeclaration-176] + _ = x[KindConstructor-177] + _ = x[KindGetAccessor-178] + _ = x[KindSetAccessor-179] + _ = x[KindCallSignature-180] + _ = x[KindConstructSignature-181] + _ = x[KindIndexSignature-182] + _ = x[KindTypePredicate-183] + _ = x[KindTypeReference-184] + _ = x[KindFunctionType-185] + _ = x[KindConstructorType-186] + _ = x[KindTypeQuery-187] + _ = x[KindTypeLiteral-188] + _ = x[KindArrayType-189] + _ = x[KindTupleType-190] + _ = x[KindOptionalType-191] + _ = x[KindRestType-192] + _ = x[KindUnionType-193] + _ = x[KindIntersectionType-194] + _ = x[KindConditionalType-195] + _ = x[KindInferType-196] + _ = x[KindParenthesizedType-197] + _ = x[KindThisType-198] + _ = x[KindTypeOperator-199] + _ = x[KindIndexedAccessType-200] + _ = x[KindMappedType-201] + _ = x[KindLiteralType-202] + _ = x[KindNamedTupleMember-203] + _ = x[KindTemplateLiteralType-204] + _ = x[KindTemplateLiteralTypeSpan-205] + _ = x[KindImportType-206] + _ = x[KindObjectBindingPattern-207] + _ = x[KindArrayBindingPattern-208] + _ = x[KindBindingElement-209] + _ = x[KindArrayLiteralExpression-210] + _ = x[KindObjectLiteralExpression-211] + _ = x[KindPropertyAccessExpression-212] + _ = x[KindElementAccessExpression-213] + _ = x[KindCallExpression-214] + _ = x[KindNewExpression-215] + _ = x[KindTaggedTemplateExpression-216] + _ = x[KindTypeAssertionExpression-217] + _ = x[KindParenthesizedExpression-218] + _ = x[KindFunctionExpression-219] + _ = x[KindArrowFunction-220] + _ = x[KindDeleteExpression-221] + _ = x[KindTypeOfExpression-222] + _ = x[KindVoidExpression-223] + _ = x[KindAwaitExpression-224] + _ = x[KindPrefixUnaryExpression-225] + _ = x[KindPostfixUnaryExpression-226] + _ = x[KindBinaryExpression-227] + _ = x[KindConditionalExpression-228] + _ = x[KindTemplateExpression-229] + _ = x[KindYieldExpression-230] + _ = x[KindSpreadElement-231] + _ = x[KindClassExpression-232] + _ = x[KindOmittedExpression-233] + _ = x[KindExpressionWithTypeArguments-234] + _ = x[KindAsExpression-235] + _ = x[KindNonNullExpression-236] + _ = x[KindMetaProperty-237] + _ = x[KindSyntheticExpression-238] + _ = x[KindSatisfiesExpression-239] + _ = x[KindTemplateSpan-240] + _ = x[KindSemicolonClassElement-241] + _ = x[KindBlock-242] + _ = x[KindEmptyStatement-243] + _ = x[KindVariableStatement-244] + _ = x[KindExpressionStatement-245] + _ = x[KindIfStatement-246] + _ = x[KindDoStatement-247] + _ = x[KindWhileStatement-248] + _ = x[KindForStatement-249] + _ = x[KindForInStatement-250] + _ = x[KindForOfStatement-251] + _ = x[KindContinueStatement-252] + _ = x[KindBreakStatement-253] + _ = x[KindReturnStatement-254] + _ = x[KindWithStatement-255] + _ = x[KindSwitchStatement-256] + _ = x[KindLabeledStatement-257] + _ = x[KindThrowStatement-258] + _ = x[KindTryStatement-259] + _ = x[KindDebuggerStatement-260] + _ = x[KindVariableDeclaration-261] + _ = x[KindVariableDeclarationList-262] + _ = x[KindFunctionDeclaration-263] + _ = x[KindClassDeclaration-264] + _ = x[KindInterfaceDeclaration-265] + _ = x[KindTypeAliasDeclaration-266] + _ = x[KindEnumDeclaration-267] + _ = x[KindModuleDeclaration-268] + _ = x[KindModuleBlock-269] + _ = x[KindCaseBlock-270] + _ = x[KindNamespaceExportDeclaration-271] + _ = x[KindImportEqualsDeclaration-272] + _ = x[KindImportDeclaration-273] + _ = x[KindImportClause-274] + _ = x[KindNamespaceImport-275] + _ = x[KindNamedImports-276] + _ = x[KindImportSpecifier-277] + _ = x[KindExportAssignment-278] + _ = x[KindExportDeclaration-279] + _ = x[KindNamedExports-280] + _ = x[KindNamespaceExport-281] + _ = x[KindExportSpecifier-282] + _ = x[KindMissingDeclaration-283] + _ = x[KindExternalModuleReference-284] + _ = x[KindJsxElement-285] + _ = x[KindJsxSelfClosingElement-286] + _ = x[KindJsxOpeningElement-287] + _ = x[KindJsxClosingElement-288] + _ = x[KindJsxFragment-289] + _ = x[KindJsxOpeningFragment-290] + _ = x[KindJsxClosingFragment-291] + _ = x[KindJsxAttribute-292] + _ = x[KindJsxAttributes-293] + _ = x[KindJsxSpreadAttribute-294] + _ = x[KindJsxExpression-295] + _ = x[KindJsxNamespacedName-296] + _ = x[KindCaseClause-297] + _ = x[KindDefaultClause-298] + _ = x[KindHeritageClause-299] + _ = x[KindCatchClause-300] + _ = x[KindImportAttributes-301] + _ = x[KindImportAttribute-302] + _ = x[KindPropertyAssignment-303] + _ = x[KindShorthandPropertyAssignment-304] + _ = x[KindSpreadAssignment-305] + _ = x[KindEnumMember-306] + _ = x[KindSourceFile-307] + _ = x[KindBundle-308] + _ = x[KindJSDocTypeExpression-309] + _ = x[KindJSDocNameReference-310] + _ = x[KindJSDocMemberName-311] + _ = x[KindJSDocAllType-312] + _ = x[KindJSDocNullableType-313] + _ = x[KindJSDocNonNullableType-314] + _ = x[KindJSDocOptionalType-315] + _ = x[KindJSDocVariadicType-316] + _ = x[KindJSDoc-317] + _ = x[KindJSDocText-318] + _ = x[KindJSDocTypeLiteral-319] + _ = x[KindJSDocSignature-320] + _ = x[KindJSDocLink-321] + _ = x[KindJSDocLinkCode-322] + _ = x[KindJSDocLinkPlain-323] + _ = x[KindJSDocTag-324] + _ = x[KindJSDocAugmentsTag-325] + _ = x[KindJSDocImplementsTag-326] + _ = x[KindJSDocDeprecatedTag-327] + _ = x[KindJSDocPublicTag-328] + _ = x[KindJSDocPrivateTag-329] + _ = x[KindJSDocProtectedTag-330] + _ = x[KindJSDocReadonlyTag-331] + _ = x[KindJSDocOverrideTag-332] + _ = x[KindJSDocCallbackTag-333] + _ = x[KindJSDocOverloadTag-334] + _ = x[KindJSDocParameterTag-335] + _ = x[KindJSDocReturnTag-336] + _ = x[KindJSDocThisTag-337] + _ = x[KindJSDocTypeTag-338] + _ = x[KindJSDocTemplateTag-339] + _ = x[KindJSDocTypedefTag-340] + _ = x[KindJSDocSeeTag-341] + _ = x[KindJSDocPropertyTag-342] + _ = x[KindJSDocSatisfiesTag-343] + _ = x[KindJSDocImportTag-344] + _ = x[KindSyntaxList-345] + _ = x[KindJSTypeAliasDeclaration-346] + _ = x[KindJSExportAssignment-347] + _ = x[KindCommonJSExport-348] + _ = x[KindJSImportDeclaration-349] + _ = x[KindNotEmittedStatement-350] + _ = x[KindPartiallyEmittedExpression-351] + _ = x[KindCommaListExpression-352] + _ = x[KindSyntheticReferenceExpression-353] + _ = x[KindNotEmittedTypeElement-354] + _ = x[KindCount-355] +} + +const _Kind_name = "KindUnknownKindEndOfFileKindSingleLineCommentTriviaKindMultiLineCommentTriviaKindNewLineTriviaKindWhitespaceTriviaKindConflictMarkerTriviaKindNonTextFileMarkerTriviaKindNumericLiteralKindBigIntLiteralKindStringLiteralKindJsxTextKindJsxTextAllWhiteSpacesKindRegularExpressionLiteralKindNoSubstitutionTemplateLiteralKindTemplateHeadKindTemplateMiddleKindTemplateTailKindOpenBraceTokenKindCloseBraceTokenKindOpenParenTokenKindCloseParenTokenKindOpenBracketTokenKindCloseBracketTokenKindDotTokenKindDotDotDotTokenKindSemicolonTokenKindCommaTokenKindQuestionDotTokenKindLessThanTokenKindLessThanSlashTokenKindGreaterThanTokenKindLessThanEqualsTokenKindGreaterThanEqualsTokenKindEqualsEqualsTokenKindExclamationEqualsTokenKindEqualsEqualsEqualsTokenKindExclamationEqualsEqualsTokenKindEqualsGreaterThanTokenKindPlusTokenKindMinusTokenKindAsteriskTokenKindAsteriskAsteriskTokenKindSlashTokenKindPercentTokenKindPlusPlusTokenKindMinusMinusTokenKindLessThanLessThanTokenKindGreaterThanGreaterThanTokenKindGreaterThanGreaterThanGreaterThanTokenKindAmpersandTokenKindBarTokenKindCaretTokenKindExclamationTokenKindTildeTokenKindAmpersandAmpersandTokenKindBarBarTokenKindQuestionTokenKindColonTokenKindAtTokenKindQuestionQuestionTokenKindBacktickTokenKindHashTokenKindEqualsTokenKindPlusEqualsTokenKindMinusEqualsTokenKindAsteriskEqualsTokenKindAsteriskAsteriskEqualsTokenKindSlashEqualsTokenKindPercentEqualsTokenKindLessThanLessThanEqualsTokenKindGreaterThanGreaterThanEqualsTokenKindGreaterThanGreaterThanGreaterThanEqualsTokenKindAmpersandEqualsTokenKindBarEqualsTokenKindBarBarEqualsTokenKindAmpersandAmpersandEqualsTokenKindQuestionQuestionEqualsTokenKindCaretEqualsTokenKindIdentifierKindPrivateIdentifierKindJSDocCommentTextTokenKindBreakKeywordKindCaseKeywordKindCatchKeywordKindClassKeywordKindConstKeywordKindContinueKeywordKindDebuggerKeywordKindDefaultKeywordKindDeleteKeywordKindDoKeywordKindElseKeywordKindEnumKeywordKindExportKeywordKindExtendsKeywordKindFalseKeywordKindFinallyKeywordKindForKeywordKindFunctionKeywordKindIfKeywordKindImportKeywordKindInKeywordKindInstanceOfKeywordKindNewKeywordKindNullKeywordKindReturnKeywordKindSuperKeywordKindSwitchKeywordKindThisKeywordKindThrowKeywordKindTrueKeywordKindTryKeywordKindTypeOfKeywordKindVarKeywordKindVoidKeywordKindWhileKeywordKindWithKeywordKindImplementsKeywordKindInterfaceKeywordKindLetKeywordKindPackageKeywordKindPrivateKeywordKindProtectedKeywordKindPublicKeywordKindStaticKeywordKindYieldKeywordKindAbstractKeywordKindAccessorKeywordKindAsKeywordKindAssertsKeywordKindAssertKeywordKindAnyKeywordKindAsyncKeywordKindAwaitKeywordKindBooleanKeywordKindConstructorKeywordKindDeclareKeywordKindGetKeywordKindImmediateKeywordKindInferKeywordKindIntrinsicKeywordKindIsKeywordKindKeyOfKeywordKindModuleKeywordKindNamespaceKeywordKindNeverKeywordKindOutKeywordKindReadonlyKeywordKindRequireKeywordKindNumberKeywordKindObjectKeywordKindSatisfiesKeywordKindSetKeywordKindStringKeywordKindSymbolKeywordKindTypeKeywordKindUndefinedKeywordKindUniqueKeywordKindUnknownKeywordKindUsingKeywordKindFromKeywordKindGlobalKeywordKindBigIntKeywordKindOverrideKeywordKindOfKeywordKindDeferKeywordKindQualifiedNameKindComputedPropertyNameKindTypeParameterKindParameterKindDecoratorKindPropertySignatureKindPropertyDeclarationKindMethodSignatureKindMethodDeclarationKindClassStaticBlockDeclarationKindConstructorKindGetAccessorKindSetAccessorKindCallSignatureKindConstructSignatureKindIndexSignatureKindTypePredicateKindTypeReferenceKindFunctionTypeKindConstructorTypeKindTypeQueryKindTypeLiteralKindArrayTypeKindTupleTypeKindOptionalTypeKindRestTypeKindUnionTypeKindIntersectionTypeKindConditionalTypeKindInferTypeKindParenthesizedTypeKindThisTypeKindTypeOperatorKindIndexedAccessTypeKindMappedTypeKindLiteralTypeKindNamedTupleMemberKindTemplateLiteralTypeKindTemplateLiteralTypeSpanKindImportTypeKindObjectBindingPatternKindArrayBindingPatternKindBindingElementKindArrayLiteralExpressionKindObjectLiteralExpressionKindPropertyAccessExpressionKindElementAccessExpressionKindCallExpressionKindNewExpressionKindTaggedTemplateExpressionKindTypeAssertionExpressionKindParenthesizedExpressionKindFunctionExpressionKindArrowFunctionKindDeleteExpressionKindTypeOfExpressionKindVoidExpressionKindAwaitExpressionKindPrefixUnaryExpressionKindPostfixUnaryExpressionKindBinaryExpressionKindConditionalExpressionKindTemplateExpressionKindYieldExpressionKindSpreadElementKindClassExpressionKindOmittedExpressionKindExpressionWithTypeArgumentsKindAsExpressionKindNonNullExpressionKindMetaPropertyKindSyntheticExpressionKindSatisfiesExpressionKindTemplateSpanKindSemicolonClassElementKindBlockKindEmptyStatementKindVariableStatementKindExpressionStatementKindIfStatementKindDoStatementKindWhileStatementKindForStatementKindForInStatementKindForOfStatementKindContinueStatementKindBreakStatementKindReturnStatementKindWithStatementKindSwitchStatementKindLabeledStatementKindThrowStatementKindTryStatementKindDebuggerStatementKindVariableDeclarationKindVariableDeclarationListKindFunctionDeclarationKindClassDeclarationKindInterfaceDeclarationKindTypeAliasDeclarationKindEnumDeclarationKindModuleDeclarationKindModuleBlockKindCaseBlockKindNamespaceExportDeclarationKindImportEqualsDeclarationKindImportDeclarationKindImportClauseKindNamespaceImportKindNamedImportsKindImportSpecifierKindExportAssignmentKindExportDeclarationKindNamedExportsKindNamespaceExportKindExportSpecifierKindMissingDeclarationKindExternalModuleReferenceKindJsxElementKindJsxSelfClosingElementKindJsxOpeningElementKindJsxClosingElementKindJsxFragmentKindJsxOpeningFragmentKindJsxClosingFragmentKindJsxAttributeKindJsxAttributesKindJsxSpreadAttributeKindJsxExpressionKindJsxNamespacedNameKindCaseClauseKindDefaultClauseKindHeritageClauseKindCatchClauseKindImportAttributesKindImportAttributeKindPropertyAssignmentKindShorthandPropertyAssignmentKindSpreadAssignmentKindEnumMemberKindSourceFileKindBundleKindJSDocTypeExpressionKindJSDocNameReferenceKindJSDocMemberNameKindJSDocAllTypeKindJSDocNullableTypeKindJSDocNonNullableTypeKindJSDocOptionalTypeKindJSDocVariadicTypeKindJSDocKindJSDocTextKindJSDocTypeLiteralKindJSDocSignatureKindJSDocLinkKindJSDocLinkCodeKindJSDocLinkPlainKindJSDocTagKindJSDocAugmentsTagKindJSDocImplementsTagKindJSDocDeprecatedTagKindJSDocPublicTagKindJSDocPrivateTagKindJSDocProtectedTagKindJSDocReadonlyTagKindJSDocOverrideTagKindJSDocCallbackTagKindJSDocOverloadTagKindJSDocParameterTagKindJSDocReturnTagKindJSDocThisTagKindJSDocTypeTagKindJSDocTemplateTagKindJSDocTypedefTagKindJSDocSeeTagKindJSDocPropertyTagKindJSDocSatisfiesTagKindJSDocImportTagKindSyntaxListKindJSTypeAliasDeclarationKindJSExportAssignmentKindCommonJSExportKindJSImportDeclarationKindNotEmittedStatementKindPartiallyEmittedExpressionKindCommaListExpressionKindSyntheticReferenceExpressionKindNotEmittedTypeElementKindCount" + +var _Kind_index = [...]uint16{0, 11, 24, 51, 77, 94, 114, 138, 165, 183, 200, 217, 228, 253, 281, 314, 330, 348, 364, 382, 401, 419, 438, 458, 479, 491, 509, 527, 541, 561, 578, 600, 620, 643, 669, 690, 716, 743, 775, 801, 814, 828, 845, 870, 884, 900, 917, 936, 961, 992, 1034, 1052, 1064, 1078, 1098, 1112, 1139, 1154, 1171, 1185, 1196, 1221, 1238, 1251, 1266, 1285, 1305, 1328, 1359, 1379, 1401, 1432, 1469, 1517, 1541, 1559, 1580, 1613, 1644, 1664, 1678, 1699, 1724, 1740, 1755, 1771, 1787, 1803, 1822, 1841, 1859, 1876, 1889, 1904, 1919, 1936, 1954, 1970, 1988, 2002, 2021, 2034, 2051, 2064, 2085, 2099, 2114, 2131, 2147, 2164, 2179, 2195, 2210, 2224, 2241, 2255, 2270, 2286, 2301, 2322, 2342, 2356, 2374, 2392, 2412, 2429, 2446, 2462, 2481, 2500, 2513, 2531, 2548, 2562, 2578, 2594, 2612, 2634, 2652, 2666, 2686, 2702, 2722, 2735, 2751, 2768, 2788, 2804, 2818, 2837, 2855, 2872, 2889, 2909, 2923, 2940, 2957, 2972, 2992, 3009, 3027, 3043, 3058, 3075, 3092, 3111, 3124, 3140, 3157, 3181, 3198, 3211, 3224, 3245, 3268, 3287, 3308, 3339, 3354, 3369, 3384, 3401, 3423, 3441, 3458, 3475, 3491, 3510, 3523, 3538, 3551, 3564, 3580, 3592, 3605, 3625, 3644, 3657, 3678, 3690, 3706, 3727, 3741, 3756, 3776, 3799, 3826, 3840, 3864, 3887, 3905, 3931, 3958, 3986, 4013, 4031, 4048, 4076, 4103, 4130, 4152, 4169, 4189, 4209, 4227, 4246, 4271, 4297, 4317, 4342, 4364, 4383, 4400, 4419, 4440, 4471, 4487, 4508, 4524, 4547, 4570, 4586, 4611, 4620, 4638, 4659, 4682, 4697, 4712, 4730, 4746, 4764, 4782, 4803, 4821, 4840, 4857, 4876, 4896, 4914, 4930, 4951, 4974, 5001, 5024, 5044, 5068, 5092, 5111, 5132, 5147, 5160, 5190, 5217, 5238, 5254, 5273, 5289, 5308, 5328, 5349, 5365, 5384, 5403, 5425, 5452, 5466, 5491, 5512, 5533, 5548, 5570, 5592, 5608, 5625, 5647, 5664, 5685, 5699, 5716, 5734, 5749, 5769, 5788, 5810, 5841, 5861, 5875, 5889, 5899, 5922, 5944, 5963, 5979, 6000, 6024, 6045, 6066, 6075, 6088, 6108, 6126, 6139, 6156, 6174, 6186, 6206, 6228, 6250, 6268, 6287, 6308, 6328, 6348, 6368, 6388, 6409, 6427, 6443, 6459, 6479, 6498, 6513, 6533, 6554, 6572, 6586, 6612, 6634, 6652, 6675, 6698, 6728, 6751, 6783, 6808, 6817} + +func (i Kind) String() string { + if i < 0 || i >= Kind(len(_Kind_index)-1) { + return "Kind(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _Kind_name[_Kind_index[i]:_Kind_index[i+1]] +} diff --git a/kitcom/internal/tsgo/ast/modifierflags.go b/kitcom/internal/tsgo/ast/modifierflags.go new file mode 100644 index 0000000..dfc4c21 --- /dev/null +++ b/kitcom/internal/tsgo/ast/modifierflags.go @@ -0,0 +1,53 @@ +package ast + +type ModifierFlags uint32 + +const ( + ModifierFlagsNone ModifierFlags = 0 + // Syntactic/JSDoc modifiers + ModifierFlagsPublic ModifierFlags = 1 << 0 // Property/Method + ModifierFlagsPrivate ModifierFlags = 1 << 1 // Property/Method + ModifierFlagsProtected ModifierFlags = 1 << 2 // Property/Method + ModifierFlagsReadonly ModifierFlags = 1 << 3 // Property/Method + ModifierFlagsOverride ModifierFlags = 1 << 4 // Override method + // Syntactic-only modifiers + ModifierFlagsExport ModifierFlags = 1 << 5 // Declarations + ModifierFlagsAbstract ModifierFlags = 1 << 6 // Class/Method/ConstructSignature + ModifierFlagsAmbient ModifierFlags = 1 << 7 // Declarations (declare keyword) + ModifierFlagsStatic ModifierFlags = 1 << 8 // Property/Method + ModifierFlagsAccessor ModifierFlags = 1 << 9 // Property + ModifierFlagsAsync ModifierFlags = 1 << 10 // Property/Method/Function + ModifierFlagsDefault ModifierFlags = 1 << 11 // Function/Class (export default declaration) + ModifierFlagsConst ModifierFlags = 1 << 12 // Const enum + ModifierFlagsIn ModifierFlags = 1 << 13 // Contravariance modifier + ModifierFlagsOut ModifierFlags = 1 << 14 // Covariance modifier + ModifierFlagsDecorator ModifierFlags = 1 << 15 // Contains a decorator + // JSDoc-only modifiers + ModifierFlagsDeprecated ModifierFlags = 1 << 16 // Deprecated tag + // Cache-only JSDoc-modifiers. Should match order of Syntactic/JSDoc modifiers, above. + ModifierFlagsJSDocPublic ModifierFlags = 1 << 23 // if this value changes, `selectEffectiveModifierFlags` must change accordingly + ModifierFlagsJSDocPrivate ModifierFlags = 1 << 24 + ModifierFlagsJSDocProtected ModifierFlags = 1 << 25 + ModifierFlagsJSDocReadonly ModifierFlags = 1 << 26 + ModifierFlagsJSDocOverride ModifierFlags = 1 << 27 + ModifierFlagsHasComputedJSDocModifiers ModifierFlags = 1 << 28 // Indicates the computed modifier flags include modifiers from JSDoc. + ModifierFlagsHasComputedFlags ModifierFlags = 1 << 29 // Modifier flags have been computed + + ModifierFlagsSyntacticOrJSDocModifiers = ModifierFlagsPublic | ModifierFlagsPrivate | ModifierFlagsProtected | ModifierFlagsReadonly | ModifierFlagsOverride + ModifierFlagsSyntacticOnlyModifiers = ModifierFlagsExport | ModifierFlagsAmbient | ModifierFlagsAbstract | ModifierFlagsStatic | ModifierFlagsAccessor | ModifierFlagsAsync | ModifierFlagsDefault | ModifierFlagsConst | ModifierFlagsIn | ModifierFlagsOut | ModifierFlagsDecorator + ModifierFlagsSyntacticModifiers = ModifierFlagsSyntacticOrJSDocModifiers | ModifierFlagsSyntacticOnlyModifiers + ModifierFlagsJSDocCacheOnlyModifiers = ModifierFlagsJSDocPublic | ModifierFlagsJSDocPrivate | ModifierFlagsJSDocProtected | ModifierFlagsJSDocReadonly | ModifierFlagsJSDocOverride + ModifierFlagsJSDocOnlyModifiers = ModifierFlagsDeprecated + ModifierFlagsNonCacheOnlyModifiers = ModifierFlagsSyntacticOrJSDocModifiers | ModifierFlagsSyntacticOnlyModifiers | ModifierFlagsJSDocOnlyModifiers + + ModifierFlagsAccessibilityModifier = ModifierFlagsPublic | ModifierFlagsPrivate | ModifierFlagsProtected + // Accessibility modifiers and 'readonly' can be attached to a parameter in a constructor to make it a property. + ModifierFlagsParameterPropertyModifier = ModifierFlagsAccessibilityModifier | ModifierFlagsReadonly | ModifierFlagsOverride + ModifierFlagsNonPublicAccessibilityModifier = ModifierFlagsPrivate | ModifierFlagsProtected + + ModifierFlagsTypeScriptModifier = ModifierFlagsAmbient | ModifierFlagsPublic | ModifierFlagsPrivate | ModifierFlagsProtected | ModifierFlagsReadonly | ModifierFlagsAbstract | ModifierFlagsConst | ModifierFlagsOverride | ModifierFlagsIn | ModifierFlagsOut + ModifierFlagsExportDefault = ModifierFlagsExport | ModifierFlagsDefault + ModifierFlagsAll = ModifierFlagsExport | ModifierFlagsAmbient | ModifierFlagsPublic | ModifierFlagsPrivate | ModifierFlagsProtected | ModifierFlagsStatic | ModifierFlagsReadonly | ModifierFlagsAbstract | ModifierFlagsAccessor | ModifierFlagsAsync | ModifierFlagsDefault | ModifierFlagsConst | ModifierFlagsDeprecated | ModifierFlagsOverride | ModifierFlagsIn | ModifierFlagsOut | ModifierFlagsDecorator + ModifierFlagsModifier = ModifierFlagsAll & ^ModifierFlagsDecorator + ModifierFlagsJavaScript = ModifierFlagsExport | ModifierFlagsStatic | ModifierFlagsAccessor | ModifierFlagsAsync | ModifierFlagsDefault +) diff --git a/kitcom/internal/tsgo/ast/nodeflags.go b/kitcom/internal/tsgo/ast/nodeflags.go new file mode 100644 index 0000000..2feb4f2 --- /dev/null +++ b/kitcom/internal/tsgo/ast/nodeflags.go @@ -0,0 +1,65 @@ +package ast + +type NodeFlags uint32 + +const ( + NodeFlagsNone NodeFlags = 0 + NodeFlagsLet NodeFlags = 1 << 0 // Variable declaration + NodeFlagsConst NodeFlags = 1 << 1 // Variable declaration + NodeFlagsUsing NodeFlags = 1 << 2 // Variable declaration + NodeFlagsReparsed NodeFlags = 1 << 3 // Node was synthesized during parsing + NodeFlagsSynthesized NodeFlags = 1 << 4 // Node was synthesized during transformation + NodeFlagsOptionalChain NodeFlags = 1 << 5 // Chained MemberExpression rooted to a pseudo-OptionalExpression + NodeFlagsExportContext NodeFlags = 1 << 6 // Export context (initialized by binding) + NodeFlagsContainsThis NodeFlags = 1 << 7 // Interface contains references to "this" + NodeFlagsHasImplicitReturn NodeFlags = 1 << 8 // If function implicitly returns on one of codepaths (initialized by binding) + NodeFlagsHasExplicitReturn NodeFlags = 1 << 9 // If function has explicit reachable return on one of codepaths (initialized by binding) + NodeFlagsDisallowInContext NodeFlags = 1 << 10 // If node was parsed in a context where 'in-expressions' are not allowed + NodeFlagsYieldContext NodeFlags = 1 << 11 // If node was parsed in the 'yield' context created when parsing a generator + NodeFlagsDecoratorContext NodeFlags = 1 << 12 // If node was parsed as part of a decorator + NodeFlagsAwaitContext NodeFlags = 1 << 13 // If node was parsed in the 'await' context created when parsing an async function + NodeFlagsDisallowConditionalTypesContext NodeFlags = 1 << 14 // If node was parsed in a context where conditional types are not allowed + NodeFlagsThisNodeHasError NodeFlags = 1 << 15 // If the parser encountered an error when parsing the code that created this node + NodeFlagsJavaScriptFile NodeFlags = 1 << 16 // If node was parsed in a JavaScript + NodeFlagsThisNodeOrAnySubNodesHasError NodeFlags = 1 << 17 // If this node or any of its children had an error + NodeFlagsHasAggregatedChildData NodeFlags = 1 << 18 // If we've computed data from children and cached it in this node + + // These flags will be set when the parser encounters a dynamic import expression or 'import.meta' to avoid + // walking the tree if the flags are not set. However, these flags are just a approximation + // (hence why it's named "PossiblyContainsDynamicImport") because once set, the flags never get cleared. + // During editing, if a dynamic import is removed, incremental parsing will *NOT* clear this flag. + // This means that the tree will always be traversed during module resolution, or when looking for external module indicators. + // However, the removal operation should not occur often and in the case of the + // removal, it is likely that users will add the import anyway. + // The advantage of this approach is its simplicity. For the case of batch compilation, + // we guarantee that users won't have to pay the price of walking the tree if a dynamic import isn't used. + NodeFlagsPossiblyContainsDynamicImport NodeFlags = 1 << 19 + NodeFlagsPossiblyContainsImportMeta NodeFlags = 1 << 20 + + NodeFlagsHasJSDoc NodeFlags = 1 << 21 // If node has preceding JSDoc comment(s) + NodeFlagsJSDoc NodeFlags = 1 << 22 // If node was parsed inside jsdoc + NodeFlagsAmbient NodeFlags = 1 << 23 // If node was inside an ambient context -- a declaration file, or inside something with the `declare` modifier. + NodeFlagsInWithStatement NodeFlags = 1 << 24 // If any ancestor of node was the `statement` of a WithStatement (not the `expression`) + NodeFlagsJsonFile NodeFlags = 1 << 25 // If node was parsed in a Json + NodeFlagsDeprecated NodeFlags = 1 << 26 // If has '@deprecated' JSDoc tag + + NodeFlagsBlockScoped = NodeFlagsLet | NodeFlagsConst | NodeFlagsUsing + NodeFlagsConstant = NodeFlagsConst | NodeFlagsUsing + NodeFlagsAwaitUsing = NodeFlagsConst | NodeFlagsUsing // Variable declaration (NOTE: on a single node these flags would otherwise be mutually exclusive) + + NodeFlagsReachabilityCheckFlags = NodeFlagsHasImplicitReturn | NodeFlagsHasExplicitReturn + + // Parsing context flags + NodeFlagsContextFlags NodeFlags = NodeFlagsDisallowInContext | NodeFlagsDisallowConditionalTypesContext | NodeFlagsYieldContext | NodeFlagsDecoratorContext | NodeFlagsAwaitContext | NodeFlagsJavaScriptFile | NodeFlagsInWithStatement | NodeFlagsAmbient + + // Exclude these flags when parsing a Type + NodeFlagsTypeExcludesFlags NodeFlags = NodeFlagsYieldContext | NodeFlagsAwaitContext + + // Represents all flags that are potentially set once and + // never cleared on SourceFiles which get re-used in between incremental parses. + // See the comment above on `PossiblyContainsDynamicImport` and `PossiblyContainsImportMeta`. + NodeFlagsPermanentlySetIncrementalFlags NodeFlags = NodeFlagsPossiblyContainsDynamicImport | NodeFlagsPossiblyContainsImportMeta + + // The following flags repurpose other NodeFlags as different meanings for Identifier nodes + NodeFlagsIdentifierHasExtendedUnicodeEscape NodeFlags = NodeFlagsContainsThis // Indicates whether the identifier contains an extended unicode escape sequence +) diff --git a/kitcom/internal/tsgo/ast/parseoptions.go b/kitcom/internal/tsgo/ast/parseoptions.go new file mode 100644 index 0000000..c1ed4ec --- /dev/null +++ b/kitcom/internal/tsgo/ast/parseoptions.go @@ -0,0 +1,168 @@ +package ast + +import ( + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/core" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/tspath" +) + +type JSDocParsingMode int + +const ( + JSDocParsingModeParseAll JSDocParsingMode = iota + JSDocParsingModeParseNone + JSDocParsingModeParseForTypeErrors + JSDocParsingModeParseForTypeInfo +) + +type SourceFileParseOptions struct { + FileName string + Path tspath.Path + CompilerOptions core.SourceFileAffectingCompilerOptions + ExternalModuleIndicatorOptions ExternalModuleIndicatorOptions + JSDocParsingMode JSDocParsingMode +} + +func GetSourceFileAffectingCompilerOptions(fileName string, options *core.CompilerOptions) core.SourceFileAffectingCompilerOptions { + // Declaration files are not parsed/bound differently depending on compiler options. + if tspath.IsDeclarationFileName(fileName) { + return core.SourceFileAffectingCompilerOptions{} + } + return options.SourceFileAffecting() +} + +type ExternalModuleIndicatorOptions struct { + jsx bool + force bool +} + +func GetExternalModuleIndicatorOptions(fileName string, options *core.CompilerOptions, metadata SourceFileMetaData) ExternalModuleIndicatorOptions { + if tspath.IsDeclarationFileName(fileName) { + return ExternalModuleIndicatorOptions{} + } + + switch options.GetEmitModuleDetectionKind() { + case core.ModuleDetectionKindForce: + // All non-declaration files are modules, declaration files still do the usual isFileProbablyExternalModule + return ExternalModuleIndicatorOptions{force: true} + case core.ModuleDetectionKindLegacy: + // Files are modules if they have imports, exports, or import.meta + return ExternalModuleIndicatorOptions{} + case core.ModuleDetectionKindAuto: + // If module is nodenext or node16, all esm format files are modules + // If jsx is react-jsx or react-jsxdev then jsx tags force module-ness + // otherwise, the presence of import or export statments (or import.meta) implies module-ness + return ExternalModuleIndicatorOptions{ + jsx: options.Jsx == core.JsxEmitReactJSX || options.Jsx == core.JsxEmitReactJSXDev, + force: isFileForcedToBeModuleByFormat(fileName, options, metadata), + } + default: + return ExternalModuleIndicatorOptions{} + } +} + +var isFileForcedToBeModuleByFormatExtensions = []string{tspath.ExtensionCjs, tspath.ExtensionCts, tspath.ExtensionMjs, tspath.ExtensionMts} + +func isFileForcedToBeModuleByFormat(fileName string, options *core.CompilerOptions, metadata SourceFileMetaData) bool { + // Excludes declaration files - they still require an explicit `export {}` or the like + // for back compat purposes. The only non-declaration files _not_ forced to be a module are `.js` files + // that aren't esm-mode (meaning not in a `type: module` scope). + if GetImpliedNodeFormatForEmitWorker(fileName, options.GetEmitModuleKind(), metadata) == core.ModuleKindESNext || tspath.FileExtensionIsOneOf(fileName, isFileForcedToBeModuleByFormatExtensions) { + return true + } + return false +} + +func SetExternalModuleIndicator(file *SourceFile, opts ExternalModuleIndicatorOptions) { + file.ExternalModuleIndicator = getExternalModuleIndicator(file, opts) +} + +func getExternalModuleIndicator(file *SourceFile, opts ExternalModuleIndicatorOptions) *Node { + if file.ScriptKind == core.ScriptKindJSON { + return nil + } + + if node := isFileProbablyExternalModule(file); node != nil { + return node + } + + if file.IsDeclarationFile { + return nil + } + + if opts.jsx { + if node := isFileModuleFromUsingJSXTag(file); node != nil { + return node + } + } + + if opts.force { + return file.AsNode() + } + + return nil +} + +func isFileProbablyExternalModule(sourceFile *SourceFile) *Node { + for _, statement := range sourceFile.Statements.Nodes { + if isAnExternalModuleIndicatorNode(statement) { + return statement + } + } + return getImportMetaIfNecessary(sourceFile) +} + +func isAnExternalModuleIndicatorNode(node *Node) bool { + return HasSyntacticModifier(node, ModifierFlagsExport) || + IsImportEqualsDeclaration(node) && IsExternalModuleReference(node.AsImportEqualsDeclaration().ModuleReference) || + IsImportDeclaration(node) || IsExportAssignment(node) || IsExportDeclaration(node) +} + +func getImportMetaIfNecessary(sourceFile *SourceFile) *Node { + if sourceFile.AsNode().Flags&NodeFlagsPossiblyContainsImportMeta != 0 { + return findChildNode(sourceFile.AsNode(), IsImportMeta) + } + return nil +} + +func findChildNode(root *Node, check func(*Node) bool) *Node { + var result *Node + var visit func(*Node) bool + visit = func(node *Node) bool { + if check(node) { + result = node + return true + } + return node.ForEachChild(visit) + } + visit(root) + return result +} + +func isFileModuleFromUsingJSXTag(file *SourceFile) *Node { + return walkTreeForJSXTags(file.AsNode()) +} + +// This is a somewhat unavoidable full tree walk to locate a JSX tag - `import.meta` requires the same, +// but we avoid that walk (or parts of it) if at all possible using the `PossiblyContainsImportMeta` node flag. +// Unfortunately, there's no `NodeFlag` space to do the same for JSX. +func walkTreeForJSXTags(node *Node) *Node { + var found *Node + + var visitor func(node *Node) bool + visitor = func(node *Node) bool { + if found != nil { + return true + } + if node.SubtreeFacts()&SubtreeContainsJsx == 0 { + return false + } + if IsJsxOpeningElement(node) || IsJsxFragment(node) { + found = node + return true + } + return node.ForEachChild(visitor) + } + visitor(node) + + return found +} diff --git a/kitcom/internal/tsgo/ast/precedence.go b/kitcom/internal/tsgo/ast/precedence.go new file mode 100644 index 0000000..e23d527 --- /dev/null +++ b/kitcom/internal/tsgo/ast/precedence.go @@ -0,0 +1,714 @@ +package ast + +import ( + "fmt" +) + +type OperatorPrecedence int + +const ( + // Expression: + // AssignmentExpression + // Expression `,` AssignmentExpression + OperatorPrecedenceComma OperatorPrecedence = iota + // NOTE: `Spread` is higher than `Comma` due to how it is parsed in |ElementList| + // SpreadElement: + // `...` AssignmentExpression + OperatorPrecedenceSpread + // AssignmentExpression: + // ConditionalExpression + // YieldExpression + // ArrowFunction + // AsyncArrowFunction + // LeftHandSideExpression `=` AssignmentExpression + // LeftHandSideExpression AssignmentOperator AssignmentExpression + // + // NOTE: AssignmentExpression is broken down into several precedences due to the requirements + // of the parenthesizer rules. + // AssignmentExpression: YieldExpression + // YieldExpression: + // `yield` + // `yield` AssignmentExpression + // `yield` `*` AssignmentExpression + OperatorPrecedenceYield + // AssignmentExpression: LeftHandSideExpression `=` AssignmentExpression + // AssignmentExpression: LeftHandSideExpression AssignmentOperator AssignmentExpression + // AssignmentOperator: one of + // `*=` `/=` `%=` `+=` `-=` `<<=` `>>=` `>>>=` `&=` `^=` `|=` `**=` + OperatorPrecedenceAssignment + // NOTE: `Conditional` is considered higher than `Assignment` here, but in reality they have + // the same precedence. + // AssignmentExpression: ConditionalExpression + // ConditionalExpression: + // ShortCircuitExpression + // ShortCircuitExpression `?` AssignmentExpression `:` AssignmentExpression + OperatorPrecedenceConditional + // LogicalORExpression: + // LogicalANDExpression + // LogicalORExpression `||` LogicalANDExpression + OperatorPrecedenceLogicalOR + // LogicalANDExpression: + // BitwiseORExpression + // LogicalANDExprerssion `&&` BitwiseORExpression + OperatorPrecedenceLogicalAND + // BitwiseORExpression: + // BitwiseXORExpression + // BitwiseORExpression `|` BitwiseXORExpression + OperatorPrecedenceBitwiseOR + // BitwiseXORExpression: + // BitwiseANDExpression + // BitwiseXORExpression `^` BitwiseANDExpression + OperatorPrecedenceBitwiseXOR + // BitwiseANDExpression: + // EqualityExpression + // BitwiseANDExpression `&` EqualityExpression + OperatorPrecedenceBitwiseAND + // EqualityExpression: + // RelationalExpression + // EqualityExpression `==` RelationalExpression + // EqualityExpression `!=` RelationalExpression + // EqualityExpression `===` RelationalExpression + // EqualityExpression `!==` RelationalExpression + OperatorPrecedenceEquality + // RelationalExpression: + // ShiftExpression + // RelationalExpression `<` ShiftExpression + // RelationalExpression `>` ShiftExpression + // RelationalExpression `<=` ShiftExpression + // RelationalExpression `>=` ShiftExpression + // RelationalExpression `instanceof` ShiftExpression + // RelationalExpression `in` ShiftExpression + // [+TypeScript] RelationalExpression `as` Type + OperatorPrecedenceRelational + // ShiftExpression: + // AdditiveExpression + // ShiftExpression `<<` AdditiveExpression + // ShiftExpression `>>` AdditiveExpression + // ShiftExpression `>>>` AdditiveExpression + OperatorPrecedenceShift + // AdditiveExpression: + // MultiplicativeExpression + // AdditiveExpression `+` MultiplicativeExpression + // AdditiveExpression `-` MultiplicativeExpression + OperatorPrecedenceAdditive + // MultiplicativeExpression: + // ExponentiationExpression + // MultiplicativeExpression MultiplicativeOperator ExponentiationExpression + // MultiplicativeOperator: one of `*`, `/`, `%` + OperatorPrecedenceMultiplicative + // ExponentiationExpression: + // UnaryExpression + // UpdateExpression `**` ExponentiationExpression + OperatorPrecedenceExponentiation + // UnaryExpression: + // UpdateExpression + // `delete` UnaryExpression + // `void` UnaryExpression + // `typeof` UnaryExpression + // `+` UnaryExpression + // `-` UnaryExpression + // `~` UnaryExpression + // `!` UnaryExpression + // AwaitExpression + // UpdateExpression: // TODO: Do we need to investigate the precedence here? + // `++` UnaryExpression + // `--` UnaryExpression + OperatorPrecedenceUnary + // UpdateExpression: + // LeftHandSideExpression + // LeftHandSideExpression `++` + // LeftHandSideExpression `--` + OperatorPrecedenceUpdate + // LeftHandSideExpression: + // NewExpression + // NewExpression: + // MemberExpression + // `new` NewExpression + OperatorPrecedenceLeftHandSide + // LeftHandSideExpression: + // OptionalExpression + // OptionalExpression: + // MemberExpression OptionalChain + // CallExpression OptionalChain + // OptionalExpression OptionalChain + OperatorPrecedenceOptionalChain + // LeftHandSideExpression: + // CallExpression + // CallExpression: + // CoverCallExpressionAndAsyncArrowHead + // SuperCall + // ImportCall + // CallExpression Arguments + // CallExpression `[` Expression `]` + // CallExpression `.` IdentifierName + // CallExpression TemplateLiteral + // MemberExpression: + // PrimaryExpression + // MemberExpression `[` Expression `]` + // MemberExpression `.` IdentifierName + // MemberExpression TemplateLiteral + // SuperProperty + // MetaProperty + // `new` MemberExpression Arguments + OperatorPrecedenceMember + // TODO: JSXElement? + // PrimaryExpression: + // `this` + // IdentifierReference + // Literal + // ArrayLiteral + // ObjectLiteral + // FunctionExpression + // ClassExpression + // GeneratorExpression + // AsyncFunctionExpression + // AsyncGeneratorExpression + // RegularExpressionLiteral + // TemplateLiteral + OperatorPrecedencePrimary + // PrimaryExpression: + // CoverParenthesizedExpressionAndArrowParameterList + OperatorPrecedenceParentheses + OperatorPrecedenceLowest = OperatorPrecedenceComma + OperatorPrecedenceHighest = OperatorPrecedenceParentheses + OperatorPrecedenceDisallowComma = OperatorPrecedenceYield + // ShortCircuitExpression: + // LogicalORExpression + // CoalesceExpression + // CoalesceExpression: + // CoalesceExpressionHead `??` BitwiseORExpression + // CoalesceExpressionHead: + // CoalesceExpression + // BitwiseORExpression + OperatorPrecedenceCoalesce = OperatorPrecedenceLogicalOR + // -1 is lower than all other precedences. Returning it will cause binary expression + // parsing to stop. + OperatorPrecedenceInvalid OperatorPrecedence = -1 +) + +func getOperator(expression *Expression) Kind { + switch expression.Kind { + case KindBinaryExpression: + return expression.AsBinaryExpression().OperatorToken.Kind + case KindPrefixUnaryExpression: + return expression.AsPrefixUnaryExpression().Operator + case KindPostfixUnaryExpression: + return expression.AsPostfixUnaryExpression().Operator + default: + return expression.Kind + } +} + +// Gets the precedence of an expression +func GetExpressionPrecedence(expression *Expression) OperatorPrecedence { + operator := getOperator(expression) + var flags OperatorPrecedenceFlags + if expression.Kind == KindNewExpression && expression.AsNewExpression().Arguments == nil { + flags = OperatorPrecedenceFlagsNewWithoutArguments + } else if IsOptionalChain(expression) { + flags = OperatorPrecedenceFlagsOptionalChain + } + return GetOperatorPrecedence(expression.Kind, operator, flags) +} + +type OperatorPrecedenceFlags int + +const ( + OperatorPrecedenceFlagsNone OperatorPrecedenceFlags = 0 + OperatorPrecedenceFlagsNewWithoutArguments OperatorPrecedenceFlags = 1 << 0 + OperatorPrecedenceFlagsOptionalChain OperatorPrecedenceFlags = 1 << 1 +) + +// Gets the precedence of an operator +func GetOperatorPrecedence(nodeKind Kind, operatorKind Kind, flags OperatorPrecedenceFlags) OperatorPrecedence { + switch nodeKind { + case KindCommaListExpression: + return OperatorPrecedenceComma + case KindSpreadElement: + return OperatorPrecedenceSpread + case KindYieldExpression: + return OperatorPrecedenceYield + // !!! By necessity, this differs from the old compiler to better align with ParenthesizerRules. consider backporting + case KindArrowFunction: + return OperatorPrecedenceAssignment + case KindConditionalExpression: + return OperatorPrecedenceConditional + case KindBinaryExpression: + switch operatorKind { + case KindCommaToken: + return OperatorPrecedenceComma + + case KindEqualsToken, + KindPlusEqualsToken, + KindMinusEqualsToken, + KindAsteriskAsteriskEqualsToken, + KindAsteriskEqualsToken, + KindSlashEqualsToken, + KindPercentEqualsToken, + KindLessThanLessThanEqualsToken, + KindGreaterThanGreaterThanEqualsToken, + KindGreaterThanGreaterThanGreaterThanEqualsToken, + KindAmpersandEqualsToken, + KindCaretEqualsToken, + KindBarEqualsToken, + KindBarBarEqualsToken, + KindAmpersandAmpersandEqualsToken, + KindQuestionQuestionEqualsToken: + return OperatorPrecedenceAssignment + + default: + return GetBinaryOperatorPrecedence(operatorKind) + } + // TODO: Should prefix `++` and `--` be moved to the `Update` precedence? + case KindTypeAssertionExpression, + KindNonNullExpression, + KindPrefixUnaryExpression, + KindTypeOfExpression, + KindVoidExpression, + KindDeleteExpression, + KindAwaitExpression: + return OperatorPrecedenceUnary + + case KindPostfixUnaryExpression: + return OperatorPrecedenceUpdate + + // !!! By necessity, this differs from the old compiler to better align with ParenthesizerRules. consider backporting + case KindPropertyAccessExpression, KindElementAccessExpression: + if flags&OperatorPrecedenceFlagsOptionalChain != 0 { + return OperatorPrecedenceOptionalChain + } + return OperatorPrecedenceMember + + case KindCallExpression: + if flags&OperatorPrecedenceFlagsOptionalChain != 0 { + return OperatorPrecedenceOptionalChain + } + return OperatorPrecedenceMember + + // !!! By necessity, this differs from the old compiler to better align with ParenthesizerRules. consider backporting + case KindNewExpression: + if flags&OperatorPrecedenceFlagsNewWithoutArguments != 0 { + return OperatorPrecedenceLeftHandSide + } + return OperatorPrecedenceMember + + // !!! By necessity, this differs from the old compiler to better align with ParenthesizerRules. consider backporting + case KindTaggedTemplateExpression, KindMetaProperty, KindExpressionWithTypeArguments: + return OperatorPrecedenceMember + + case KindAsExpression, + KindSatisfiesExpression: + return OperatorPrecedenceRelational + + case KindThisKeyword, + KindSuperKeyword, + KindImportKeyword, + KindIdentifier, + KindPrivateIdentifier, + KindNullKeyword, + KindTrueKeyword, + KindFalseKeyword, + KindNumericLiteral, + KindBigIntLiteral, + KindStringLiteral, + KindArrayLiteralExpression, + KindObjectLiteralExpression, + KindFunctionExpression, + KindClassExpression, + KindRegularExpressionLiteral, + KindNoSubstitutionTemplateLiteral, + KindTemplateExpression, + KindOmittedExpression, + KindJsxElement, + KindJsxSelfClosingElement, + KindJsxFragment: + return OperatorPrecedencePrimary + + // !!! By necessity, this differs from the old compiler to support emit. consider backporting + case KindParenthesizedExpression: + return OperatorPrecedenceParentheses + + default: + return OperatorPrecedenceInvalid + } +} + +// Gets the precedence of a binary operator +func GetBinaryOperatorPrecedence(operatorKind Kind) OperatorPrecedence { + switch operatorKind { + case KindQuestionQuestionToken: + return OperatorPrecedenceCoalesce + case KindBarBarToken: + return OperatorPrecedenceLogicalOR + case KindAmpersandAmpersandToken: + return OperatorPrecedenceLogicalAND + case KindBarToken: + return OperatorPrecedenceBitwiseOR + case KindCaretToken: + return OperatorPrecedenceBitwiseXOR + case KindAmpersandToken: + return OperatorPrecedenceBitwiseAND + case KindEqualsEqualsToken, KindExclamationEqualsToken, KindEqualsEqualsEqualsToken, KindExclamationEqualsEqualsToken: + return OperatorPrecedenceEquality + case KindLessThanToken, KindGreaterThanToken, KindLessThanEqualsToken, KindGreaterThanEqualsToken, + KindInstanceOfKeyword, KindInKeyword, KindAsKeyword, KindSatisfiesKeyword: + return OperatorPrecedenceRelational + case KindLessThanLessThanToken, KindGreaterThanGreaterThanToken, KindGreaterThanGreaterThanGreaterThanToken: + return OperatorPrecedenceShift + case KindPlusToken, KindMinusToken: + return OperatorPrecedenceAdditive + case KindAsteriskToken, KindSlashToken, KindPercentToken: + return OperatorPrecedenceMultiplicative + case KindAsteriskAsteriskToken: + return OperatorPrecedenceExponentiation + } + // -1 is lower than all other precedences. Returning it will cause binary expression + // parsing to stop. + return OperatorPrecedenceInvalid +} + +// Gets the leftmost expression of an expression, e.g. `a` in `a.b`, `a[b]`, `a++`, `a+b`, `a?b:c`, `a as B`, etc. +func GetLeftmostExpression(node *Expression, stopAtCallExpressions bool) *Expression { + for { + switch node.Kind { + case KindPostfixUnaryExpression: + node = node.AsPostfixUnaryExpression().Operand + continue + case KindBinaryExpression: + node = node.AsBinaryExpression().Left + continue + case KindConditionalExpression: + node = node.AsConditionalExpression().Condition + continue + case KindTaggedTemplateExpression: + node = node.AsTaggedTemplateExpression().Tag + continue + case KindCallExpression: + if stopAtCallExpressions { + return node + } + fallthrough + case KindAsExpression, + KindElementAccessExpression, + KindPropertyAccessExpression, + KindNonNullExpression, + KindPartiallyEmittedExpression, + KindSatisfiesExpression: + node = node.Expression() + continue + } + return node + } +} + +type TypePrecedence int32 + +const ( + // Conditional precedence (lowest) + // + // Type[Extends]: + // ConditionalType[?Extends] + // + // ConditionalType[Extends]: + // [~Extends] UnionType `extends` Type[+Extends] `?` Type[~Extends] `:` Type[~Extends] + // + TypePrecedenceConditional TypePrecedence = iota + + // JSDoc precedence (optional and variadic types) + // + // JSDocType: + // `...`? Type `=`? + TypePrecedenceJSDoc + + // Function precedence + // + // Type[Extends]: + // ConditionalType[?Extends] + // FunctionType[?Extends] + // ConstructorType[?Extends] + // + // ConditionalType[Extends]: + // UnionType + // + // FunctionType[Extends]: + // TypeParameters? ArrowParameters `=>` Type[?Extends] + // + // ConstructorType[Extends]: + // `abstract`? TypeParameters? ArrowParameters `=>` Type[?Extends] + // + TypePrecedenceFunction + + // Union precedence + // + // UnionType: + // `|`? UnionTypeNoBar + // + // UnionTypeNoBar: + // IntersectionType + // UnionTypeNoBar `|` IntersectionType + // + TypePrecedenceUnion + + // Intersection precedence + // + // IntersectionType: + // `&`? IntersectionTypeNoAmpersand + // + // IntersectionTypeNoAmpersand: + // TypeOperator + // IntersectionTypeNoAmpersand `&` TypeOperator + // + TypePrecedenceIntersection + + // TypeOperator precedence + // + // TypeOperator: + // PostfixType + // InferType + // `keyof` TypeOperator + // `unique` TypeOperator + // `readonly` PostfixType + // + // InferType: + // `infer` BindingIdentifier + // `infer` BindingIdentifier `extends` Type[+Extends] + // + TypePrecedenceTypeOperator + + // Postfix precedence + // + // PostfixType: + // NonArrayType + // OptionalType + // ArrayType + // IndexedAccessType + // + // OptionalType: + // PostfixType `?` + // + // ArrayType: + // PostfixType `[` `]` + // + // IndexedAccessType: + // PostfixType `[` Type[~Extends] `]` + // + TypePrecedencePostfix + + // NonArray precedence (highest) + // + // NonArrayType: + // KeywordType + // LiteralType + // ThisType + // ImportType + // TypeQuery + // MappedType + // TypeLiteral + // TupleType + // ParenthesizedType + // TypePredicate + // TypeReference + // TemplateType + // + // KeywordType: one of + // `any` `unknown` `string` `number` `bigint` + // `symbol` `boolean` `undefined` `never` `object` + // `intrinsic` `void` + // + // LiteralType: + // StringLiteral + // NoSubstitutionTemplateLiteral + // NumericLiteral + // BigIntLiteral + // `-` NumericLiteral + // `-` BigIntLiteral + // `true` + // `false` + // `null` + // + // ThisType: + // `this` + // + // ImportType: + // `typeof`? `import` `(` Type[~Extends] `,`? `)` ImportTypeQualifier? TypeArguments? + // `typeof`? `import` `(` Type[~Extends] `,` ImportTypeAttributes `,`? `)` ImportTypeQualifier? TypeArguments? + // + // ImportTypeQualifier: + // `.` EntityName + // + // ImportTypeAttributes: + // `{` `with` `:` ImportAttributes `,`? `}` + // + // TypeQuery: + // + // MappedType: + // `{` MappedTypePrefix? MappedTypePropertyName MappedTypeSuffix? `:` Type[~Extends] `;` `}` + // + // MappedTypePrefix: + // `readonly` + // `+` `readonly` + // `-` `readonly` + // + // MappedTypePropertyName: + // `[` BindingIdentifier `in` Type[~Extends] `]` + // `[` BindingIdentifier `in` Type[~Extends] `as` Type[~Extends] `]` + // + // MappedTypeSuffix: + // `?` + // `+` `?` + // `-` `?` + // + // TypeLiteral: + // `{` TypeElementList `}` + // + // TypeElementList: + // [empty] + // TypeElementList TypeElement + // + // TypeElement: + // PropertySignature + // MethodSignature + // IndexSignature + // CallSignature + // ConstructSignature + // + // PropertySignature: + // PropertyName `?`? TypeAnnotation? `;` + // + // MethodSignature: + // PropertyName `?`? TypeParameters? `(` FormalParameterList `)` TypeAnnotation? `;` + // `get` PropertyName TypeParameters? `(` FormalParameterList `)` TypeAnnotation? `;` // GetAccessor + // `set` PropertyName TypeParameters? `(` FormalParameterList `)` TypeAnnotation? `;` // SetAccessor + // + // IndexSignature: + // `[` IdentifierName`]` TypeAnnotation `;` + // + // CallSignature: + // TypeParameters? `(` FormalParameterList `)` TypeAnnotation? `;` + // + // ConstructSignature: + // `new` TypeParameters? `(` FormalParameterList `)` TypeAnnotation? `;` + // + // TupleType: + // `[` `]` + // `[` NamedTupleElementTypes `,`? `]` + // `[` TupleElementTypes `,`? `]` + // + // NamedTupleElementTypes: + // NamedTupleMember + // NamedTupleElementTypes `,` NamedTupleMember + // + // NamedTupleMember: + // IdentifierName `?`? `:` Type[~Extends] + // `...` IdentifierName `:` Type[~Extends] + // + // TupleElementTypes: + // TupleElementType + // TupleElementTypes `,` TupleElementType + // + // TupleElementType: + // Type[~Extends] + // OptionalType + // RestType + // + // RestType: + // `...` Type[~Extends] + // + // ParenthesizedType: + // `(` Type[~Extends] `)` + // + // TypePredicate: + // `asserts`? TypePredicateParameterName + // `asserts`? TypePredicateParameterName `is` Type[~Extends] + // + // TypePredicateParameterName: + // `this` + // IdentifierReference + // + // TypeReference: + // EntityName TypeArguments? + // + // TemplateType: + // TemplateHead Type[~Extends] TemplateTypeSpans + // + // TemplateTypeSpans: + // TemplateTail + // TemplateTypeMiddleList TemplateTail + // + // TemplateTypeMiddleList: + // TemplateMiddle Type[~Extends] + // TemplateTypeMiddleList TemplateMiddle Type[~Extends] + // + // TypeArguments: + // `<` TypeArgumentList `,`? `>` + // + // TypeArgumentList: + // Type[~Extends] + // TypeArgumentList `,` Type[~Extends] + // + TypePrecedenceNonArray + + TypePrecedenceLowest = TypePrecedenceConditional + TypePrecedenceHighest = TypePrecedenceNonArray +) + +// Gets the precedence of a TypeNode +func GetTypeNodePrecedence(n *TypeNode) TypePrecedence { + switch n.Kind { + case KindConditionalType: + return TypePrecedenceConditional + case KindJSDocOptionalType, KindJSDocVariadicType: + return TypePrecedenceJSDoc + case KindFunctionType, KindConstructorType: + return TypePrecedenceFunction + case KindUnionType: + return TypePrecedenceUnion + case KindIntersectionType: + return TypePrecedenceIntersection + case KindTypeOperator: + return TypePrecedenceTypeOperator + case KindInferType: + if n.AsInferTypeNode().TypeParameter.AsTypeParameter().Constraint != nil { + // `infer T extends U` must be treated as FunctionType precedence as the `extends` clause eagerly consumes + // TypeNode + return TypePrecedenceFunction + } + return TypePrecedenceTypeOperator + case KindIndexedAccessType, KindArrayType, KindOptionalType: + return TypePrecedencePostfix + case KindTypeQuery: + // TypeQuery is actually a NonArrayType, but we treat it as the same + // precedence as PostfixType + return TypePrecedencePostfix + case KindAnyKeyword, + KindUnknownKeyword, + KindStringKeyword, + KindNumberKeyword, + KindBigIntKeyword, + KindSymbolKeyword, + KindBooleanKeyword, + KindUndefinedKeyword, + KindNeverKeyword, + KindObjectKeyword, + KindIntrinsicKeyword, + KindVoidKeyword, + KindJSDocAllType, + KindJSDocNullableType, + KindJSDocNonNullableType, + KindLiteralType, + KindTypePredicate, + KindTypeReference, + KindTypeLiteral, + KindTupleType, + KindRestType, + KindParenthesizedType, + KindThisType, + KindMappedType, + KindNamedTupleMember, + KindTemplateLiteralType, + KindImportType: + return TypePrecedenceNonArray + default: + panic(fmt.Sprintf("unhandled TypeNode: %v", n.Kind)) + } +} diff --git a/kitcom/internal/tsgo/ast/subtreefacts.go b/kitcom/internal/tsgo/ast/subtreefacts.go new file mode 100644 index 0000000..db0be91 --- /dev/null +++ b/kitcom/internal/tsgo/ast/subtreefacts.go @@ -0,0 +1,131 @@ +package ast + +import ( + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/core" +) + +type SubtreeFacts int32 + +const ( + // Facts + // - Flags used to indicate that a node or subtree contains syntax relevant to a specific transform + + SubtreeContainsTypeScript SubtreeFacts = 1 << iota + SubtreeContainsJsx + SubtreeContainsESDecorators + SubtreeContainsUsing + SubtreeContainsClassStaticBlocks + SubtreeContainsESClassFields + SubtreeContainsLogicalAssignments + SubtreeContainsNullishCoalescing + SubtreeContainsOptionalChaining + SubtreeContainsMissingCatchClauseVariable + SubtreeContainsESObjectRestOrSpread // subtree has a `...` somewhere inside it, never cleared + SubtreeContainsForAwaitOrAsyncGenerator + SubtreeContainsAnyAwait + SubtreeContainsExponentiationOperator + + // Markers + // - Flags used to indicate that a node or subtree contains a particular kind of syntax. + + SubtreeContainsLexicalThis + SubtreeContainsLexicalSuper + SubtreeContainsRestOrSpread // marker on any `...` - cleared on binding pattern exit + SubtreeContainsObjectRestOrSpread // marker on any `{...x}` - cleared on most scope exits + SubtreeContainsAwait + SubtreeContainsDynamicImport + SubtreeContainsClassFields + SubtreeContainsDecorators + SubtreeContainsIdentifier + + SubtreeFactsComputed // NOTE: This should always be last + SubtreeFactsNone SubtreeFacts = 0 + + // Aliases (unused, for documentation purposes only - correspond to combinations in transformers/estransforms/definitions.go) + + SubtreeContainsESNext = SubtreeContainsESDecorators | SubtreeContainsUsing + SubtreeContainsES2022 = SubtreeContainsClassStaticBlocks | SubtreeContainsESClassFields + SubtreeContainsES2021 = SubtreeContainsLogicalAssignments + SubtreeContainsES2020 = SubtreeContainsNullishCoalescing | SubtreeContainsOptionalChaining + SubtreeContainsES2019 = SubtreeContainsMissingCatchClauseVariable + SubtreeContainsES2018 = SubtreeContainsESObjectRestOrSpread | SubtreeContainsForAwaitOrAsyncGenerator + SubtreeContainsES2017 = SubtreeContainsAnyAwait + SubtreeContainsES2016 = SubtreeContainsExponentiationOperator + + // Scope Exclusions + // - Bitmasks that exclude flags from propagating out of a specific context + // into the subtree flags of their container. + + SubtreeExclusionsNode = SubtreeFactsComputed + SubtreeExclusionsEraseable = ^SubtreeContainsTypeScript + SubtreeExclusionsOuterExpression = SubtreeExclusionsNode + SubtreeExclusionsPropertyAccess = SubtreeExclusionsNode + SubtreeExclusionsElementAccess = SubtreeExclusionsNode + SubtreeExclusionsArrowFunction = SubtreeExclusionsNode | SubtreeContainsAwait | SubtreeContainsObjectRestOrSpread + SubtreeExclusionsFunction = SubtreeExclusionsNode | SubtreeContainsLexicalThis | SubtreeContainsLexicalSuper | SubtreeContainsAwait | SubtreeContainsObjectRestOrSpread + SubtreeExclusionsConstructor = SubtreeExclusionsNode | SubtreeContainsLexicalThis | SubtreeContainsLexicalSuper | SubtreeContainsAwait | SubtreeContainsObjectRestOrSpread + SubtreeExclusionsMethod = SubtreeExclusionsNode | SubtreeContainsLexicalThis | SubtreeContainsLexicalSuper | SubtreeContainsAwait | SubtreeContainsObjectRestOrSpread + SubtreeExclusionsAccessor = SubtreeExclusionsNode | SubtreeContainsLexicalThis | SubtreeContainsLexicalSuper | SubtreeContainsAwait | SubtreeContainsObjectRestOrSpread + SubtreeExclusionsProperty = SubtreeExclusionsNode | SubtreeContainsLexicalThis | SubtreeContainsLexicalSuper + SubtreeExclusionsClass = SubtreeExclusionsNode + SubtreeExclusionsModule = SubtreeExclusionsNode | SubtreeContainsLexicalThis | SubtreeContainsLexicalSuper + SubtreeExclusionsObjectLiteral = SubtreeExclusionsNode | SubtreeContainsObjectRestOrSpread + SubtreeExclusionsArrayLiteral = SubtreeExclusionsNode + SubtreeExclusionsCall = SubtreeExclusionsNode + SubtreeExclusionsNew = SubtreeExclusionsNode + SubtreeExclusionsVariableDeclarationList = SubtreeExclusionsNode | SubtreeContainsObjectRestOrSpread + SubtreeExclusionsParameter = SubtreeExclusionsNode + SubtreeExclusionsCatchClause = SubtreeExclusionsNode | SubtreeContainsObjectRestOrSpread + SubtreeExclusionsBindingPattern = SubtreeExclusionsNode | SubtreeContainsRestOrSpread + + // Masks + // - Additional bitmasks + + SubtreeContainsLexicalThisOrSuper = SubtreeContainsLexicalThis | SubtreeContainsLexicalSuper +) + +func propagateEraseableSyntaxListSubtreeFacts(children *TypeArgumentList) SubtreeFacts { + return core.IfElse(children != nil, SubtreeContainsTypeScript, SubtreeFactsNone) +} + +func propagateEraseableSyntaxSubtreeFacts(child *TypeNode) SubtreeFacts { + return core.IfElse(child != nil, SubtreeContainsTypeScript, SubtreeFactsNone) +} + +func propagateObjectBindingElementSubtreeFacts(child *BindingElementNode) SubtreeFacts { + facts := propagateSubtreeFacts(child) + if facts&SubtreeContainsRestOrSpread != 0 { + facts &= ^SubtreeContainsRestOrSpread + facts |= SubtreeContainsObjectRestOrSpread | SubtreeContainsESObjectRestOrSpread + } + return facts +} + +func propagateBindingElementSubtreeFacts(child *BindingElementNode) SubtreeFacts { + return propagateSubtreeFacts(child) & ^SubtreeContainsRestOrSpread +} + +func propagateSubtreeFacts(child *Node) SubtreeFacts { + if child == nil { + return SubtreeFactsNone + } + return child.propagateSubtreeFacts() +} + +func propagateNodeListSubtreeFacts(children *NodeList, propagate func(*Node) SubtreeFacts) SubtreeFacts { + if children == nil { + return SubtreeFactsNone + } + facts := SubtreeFactsNone + for _, child := range children.Nodes { + facts |= propagate(child) + } + return facts +} + +func propagateModifierListSubtreeFacts(children *ModifierList) SubtreeFacts { + if children == nil { + return SubtreeFactsNone + } + return propagateNodeListSubtreeFacts(&children.NodeList, propagateSubtreeFacts) +} diff --git a/kitcom/internal/tsgo/ast/symbol.go b/kitcom/internal/tsgo/ast/symbol.go new file mode 100644 index 0000000..02ae1be --- /dev/null +++ b/kitcom/internal/tsgo/ast/symbol.go @@ -0,0 +1,59 @@ +package ast + +import ( + "sync/atomic" + + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/collections" +) + +// Symbol + +type Symbol struct { + Flags SymbolFlags + CheckFlags CheckFlags // Non-zero only in transient symbols created by Checker + Name string + Declarations []*Node + ValueDeclaration *Node + Members SymbolTable + Exports SymbolTable + id atomic.Uint64 + Parent *Symbol + ExportSymbol *Symbol + AssignmentDeclarationMembers collections.Set[*Node] // Set of detected assignment declarations + GlobalExports SymbolTable // Conditional global UMD exports +} + +// SymbolTable + +type SymbolTable map[string]*Symbol + +const InternalSymbolNamePrefix = "\xFE" // Invalid UTF8 sequence, will never occur as IdentifierName + +const ( + InternalSymbolNameCall = InternalSymbolNamePrefix + "call" // Call signatures + InternalSymbolNameConstructor = InternalSymbolNamePrefix + "constructor" // Constructor implementations + InternalSymbolNameNew = InternalSymbolNamePrefix + "new" // Constructor signatures + InternalSymbolNameIndex = InternalSymbolNamePrefix + "index" // Index signatures + InternalSymbolNameExportStar = InternalSymbolNamePrefix + "export" // Module export * declarations + InternalSymbolNameGlobal = InternalSymbolNamePrefix + "global" // Global self-reference + InternalSymbolNameMissing = InternalSymbolNamePrefix + "missing" // Indicates missing symbol + InternalSymbolNameType = InternalSymbolNamePrefix + "type" // Anonymous type literal symbol + InternalSymbolNameObject = InternalSymbolNamePrefix + "object" // Anonymous object literal declaration + InternalSymbolNameJSXAttributes = InternalSymbolNamePrefix + "jsxAttributes" // Anonymous JSX attributes object literal declaration + InternalSymbolNameClass = InternalSymbolNamePrefix + "class" // Unnamed class expression + InternalSymbolNameFunction = InternalSymbolNamePrefix + "function" // Unnamed function expression + InternalSymbolNameComputed = InternalSymbolNamePrefix + "computed" // Computed property name declaration with dynamic name + InternalSymbolNameInstantiationExpression = InternalSymbolNamePrefix + "instantiationExpression" // Instantiation expressions + InternalSymbolNameImportAttributes = InternalSymbolNamePrefix + "importAttributes" + InternalSymbolNameExportEquals = "export=" // Export assignment symbol + InternalSymbolNameDefault = "default" // Default export symbol (technically not wholly internal, but included here for usability) + InternalSymbolNameThis = "this" + InternalSymbolNameModuleExports = "module.exports" +) + +func SymbolName(symbol *Symbol) string { + if symbol.ValueDeclaration != nil && IsPrivateIdentifierClassElementDeclaration(symbol.ValueDeclaration) { + return symbol.ValueDeclaration.Name().Text() + } + return symbol.Name +} diff --git a/kitcom/internal/tsgo/ast/symbolflags.go b/kitcom/internal/tsgo/ast/symbolflags.go new file mode 100644 index 0000000..9f65726 --- /dev/null +++ b/kitcom/internal/tsgo/ast/symbolflags.go @@ -0,0 +1,86 @@ +package ast + +// SymbolFlags + +type SymbolFlags uint32 + +const ( + SymbolFlagsNone SymbolFlags = 0 + SymbolFlagsFunctionScopedVariable SymbolFlags = 1 << 0 // Variable (var) or parameter + SymbolFlagsBlockScopedVariable SymbolFlags = 1 << 1 // A block-scoped variable (let or const) + SymbolFlagsProperty SymbolFlags = 1 << 2 // Property or enum member + SymbolFlagsEnumMember SymbolFlags = 1 << 3 // Enum member + SymbolFlagsFunction SymbolFlags = 1 << 4 // Function + SymbolFlagsClass SymbolFlags = 1 << 5 // Class + SymbolFlagsInterface SymbolFlags = 1 << 6 // Interface + SymbolFlagsConstEnum SymbolFlags = 1 << 7 // Const enum + SymbolFlagsRegularEnum SymbolFlags = 1 << 8 // Enum + SymbolFlagsValueModule SymbolFlags = 1 << 9 // Instantiated module + SymbolFlagsNamespaceModule SymbolFlags = 1 << 10 // Uninstantiated module + SymbolFlagsTypeLiteral SymbolFlags = 1 << 11 // Type Literal or mapped type + SymbolFlagsObjectLiteral SymbolFlags = 1 << 12 // Object Literal + SymbolFlagsMethod SymbolFlags = 1 << 13 // Method + SymbolFlagsConstructor SymbolFlags = 1 << 14 // Constructor + SymbolFlagsGetAccessor SymbolFlags = 1 << 15 // Get accessor + SymbolFlagsSetAccessor SymbolFlags = 1 << 16 // Set accessor + SymbolFlagsSignature SymbolFlags = 1 << 17 // Call, construct, or index signature + SymbolFlagsTypeParameter SymbolFlags = 1 << 18 // Type parameter + SymbolFlagsTypeAlias SymbolFlags = 1 << 19 // Type alias + SymbolFlagsExportValue SymbolFlags = 1 << 20 // Exported value marker (see comment in declareModuleMember in binder) + SymbolFlagsAlias SymbolFlags = 1 << 21 // An alias for another symbol (see comment in isAliasSymbolDeclaration in checker) + SymbolFlagsPrototype SymbolFlags = 1 << 22 // Prototype property (no source representation) + SymbolFlagsExportStar SymbolFlags = 1 << 23 // Export * declaration + SymbolFlagsOptional SymbolFlags = 1 << 24 // Optional property + SymbolFlagsTransient SymbolFlags = 1 << 25 // Transient symbol (created during type check) + SymbolFlagsAssignment SymbolFlags = 1 << 26 // Assignment to property on function acting as declaration (eg `func.prop = 1`) + SymbolFlagsModuleExports SymbolFlags = 1 << 27 // Symbol for CommonJS `module` of `module.exports` + SymbolFlagsConstEnumOnlyModule SymbolFlags = 1 << 28 // Module contains only const enums or other modules with only const enums + SymbolFlagsReplaceableByMethod SymbolFlags = 1 << 29 + SymbolFlagsGlobalLookup SymbolFlags = 1 << 30 // Flag to signal this is a global lookup + SymbolFlagsAll SymbolFlags = 1<<30 - 1 // All flags except SymbolFlagsGlobalLookup + + SymbolFlagsEnum = SymbolFlagsRegularEnum | SymbolFlagsConstEnum + SymbolFlagsVariable = SymbolFlagsFunctionScopedVariable | SymbolFlagsBlockScopedVariable + SymbolFlagsValue = SymbolFlagsVariable | SymbolFlagsProperty | SymbolFlagsEnumMember | SymbolFlagsObjectLiteral | SymbolFlagsFunction | SymbolFlagsClass | SymbolFlagsEnum | SymbolFlagsValueModule | SymbolFlagsMethod | SymbolFlagsGetAccessor | SymbolFlagsSetAccessor + SymbolFlagsType = SymbolFlagsClass | SymbolFlagsInterface | SymbolFlagsEnum | SymbolFlagsEnumMember | SymbolFlagsTypeLiteral | SymbolFlagsTypeParameter | SymbolFlagsTypeAlias + SymbolFlagsNamespace = SymbolFlagsValueModule | SymbolFlagsNamespaceModule | SymbolFlagsEnum + SymbolFlagsModule = SymbolFlagsValueModule | SymbolFlagsNamespaceModule + SymbolFlagsAccessor = SymbolFlagsGetAccessor | SymbolFlagsSetAccessor + + // Variables can be redeclared, but can not redeclare a block-scoped declaration with the + // same name, or any other value that is not a variable, e.g. ValueModule or Class + SymbolFlagsFunctionScopedVariableExcludes = SymbolFlagsValue & ^SymbolFlagsFunctionScopedVariable + + // Block-scoped declarations are not allowed to be re-declared + // they can not merge with anything in the value space + SymbolFlagsBlockScopedVariableExcludes = SymbolFlagsValue + + SymbolFlagsParameterExcludes = SymbolFlagsValue + SymbolFlagsPropertyExcludes = SymbolFlagsValue & ^SymbolFlagsProperty + SymbolFlagsEnumMemberExcludes = SymbolFlagsValue | SymbolFlagsType + SymbolFlagsFunctionExcludes = SymbolFlagsValue & ^(SymbolFlagsFunction | SymbolFlagsValueModule | SymbolFlagsClass) + SymbolFlagsClassExcludes = (SymbolFlagsValue | SymbolFlagsType) & ^(SymbolFlagsValueModule | SymbolFlagsInterface | SymbolFlagsFunction) // class-interface mergability done in checker.ts + SymbolFlagsInterfaceExcludes = SymbolFlagsType & ^(SymbolFlagsInterface | SymbolFlagsClass) + SymbolFlagsRegularEnumExcludes = (SymbolFlagsValue | SymbolFlagsType) & ^(SymbolFlagsRegularEnum | SymbolFlagsValueModule) // regular enums merge only with regular enums and modules + SymbolFlagsConstEnumExcludes = (SymbolFlagsValue | SymbolFlagsType) & ^SymbolFlagsConstEnum // const enums merge only with const enums + SymbolFlagsValueModuleExcludes = SymbolFlagsValue & ^(SymbolFlagsFunction | SymbolFlagsClass | SymbolFlagsRegularEnum | SymbolFlagsValueModule) + SymbolFlagsNamespaceModuleExcludes = SymbolFlagsNone + SymbolFlagsMethodExcludes = SymbolFlagsValue & ^SymbolFlagsMethod + SymbolFlagsGetAccessorExcludes = SymbolFlagsValue & ^SymbolFlagsSetAccessor + SymbolFlagsSetAccessorExcludes = SymbolFlagsValue & ^SymbolFlagsGetAccessor + SymbolFlagsAccessorExcludes = SymbolFlagsValue + SymbolFlagsTypeParameterExcludes = SymbolFlagsType & ^SymbolFlagsTypeParameter + SymbolFlagsTypeAliasExcludes = SymbolFlagsType + SymbolFlagsAliasExcludes = SymbolFlagsAlias + SymbolFlagsModuleMember = SymbolFlagsVariable | SymbolFlagsFunction | SymbolFlagsClass | SymbolFlagsInterface | SymbolFlagsEnum | SymbolFlagsModule | SymbolFlagsTypeAlias | SymbolFlagsAlias + SymbolFlagsExportHasLocal = SymbolFlagsFunction | SymbolFlagsClass | SymbolFlagsEnum | SymbolFlagsValueModule + SymbolFlagsBlockScoped = SymbolFlagsBlockScopedVariable | SymbolFlagsClass | SymbolFlagsEnum + SymbolFlagsPropertyOrAccessor = SymbolFlagsProperty | SymbolFlagsAccessor + SymbolFlagsClassMember = SymbolFlagsMethod | SymbolFlagsAccessor | SymbolFlagsProperty + SymbolFlagsExportSupportsDefaultModifier = SymbolFlagsClass | SymbolFlagsFunction | SymbolFlagsInterface + SymbolFlagsExportDoesNotSupportDefaultModifier = ^SymbolFlagsExportSupportsDefaultModifier + // The set of things we consider semantically classifiable. Used to speed up the LS during + // classification. + SymbolFlagsClassifiable = SymbolFlagsClass | SymbolFlagsEnum | SymbolFlagsTypeAlias | SymbolFlagsInterface | SymbolFlagsTypeParameter | SymbolFlagsModule | SymbolFlagsAlias + SymbolFlagsLateBindingContainer = SymbolFlagsClass | SymbolFlagsInterface | SymbolFlagsTypeLiteral | SymbolFlagsObjectLiteral | SymbolFlagsFunction +) diff --git a/kitcom/internal/tsgo/ast/tokenflags.go b/kitcom/internal/tsgo/ast/tokenflags.go new file mode 100644 index 0000000..d30cf49 --- /dev/null +++ b/kitcom/internal/tsgo/ast/tokenflags.go @@ -0,0 +1,31 @@ +package ast + +type TokenFlags int32 + +const ( + TokenFlagsNone TokenFlags = 0 + TokenFlagsPrecedingLineBreak TokenFlags = 1 << 0 + TokenFlagsPrecedingJSDocComment TokenFlags = 1 << 1 + TokenFlagsUnterminated TokenFlags = 1 << 2 + TokenFlagsExtendedUnicodeEscape TokenFlags = 1 << 3 // e.g. `\u{10ffff}` + TokenFlagsScientific TokenFlags = 1 << 4 // e.g. `10e2` + TokenFlagsOctal TokenFlags = 1 << 5 // e.g. `0777` + TokenFlagsHexSpecifier TokenFlags = 1 << 6 // e.g. `0x00000000` + TokenFlagsBinarySpecifier TokenFlags = 1 << 7 // e.g. `0b0110010000000000` + TokenFlagsOctalSpecifier TokenFlags = 1 << 8 // e.g. `0o777` + TokenFlagsContainsSeparator TokenFlags = 1 << 9 // e.g. `0b1100_0101` + TokenFlagsUnicodeEscape TokenFlags = 1 << 10 // e.g. `\u00a0` + TokenFlagsContainsInvalidEscape TokenFlags = 1 << 11 // e.g. `\uhello` + TokenFlagsHexEscape TokenFlags = 1 << 12 // e.g. `\xa0` + TokenFlagsContainsLeadingZero TokenFlags = 1 << 13 // e.g. `0888` + TokenFlagsContainsInvalidSeparator TokenFlags = 1 << 14 // e.g. `0_1` + TokenFlagsPrecedingJSDocLeadingAsterisks TokenFlags = 1 << 15 + TokenFlagsSingleQuote TokenFlags = 1 << 16 // e.g. `'abc'` + TokenFlagsBinaryOrOctalSpecifier TokenFlags = TokenFlagsBinarySpecifier | TokenFlagsOctalSpecifier + TokenFlagsWithSpecifier TokenFlags = TokenFlagsHexSpecifier | TokenFlagsBinaryOrOctalSpecifier + TokenFlagsStringLiteralFlags TokenFlags = TokenFlagsUnterminated | TokenFlagsHexEscape | TokenFlagsUnicodeEscape | TokenFlagsExtendedUnicodeEscape | TokenFlagsContainsInvalidEscape | TokenFlagsSingleQuote + TokenFlagsNumericLiteralFlags TokenFlags = TokenFlagsScientific | TokenFlagsOctal | TokenFlagsContainsLeadingZero | TokenFlagsWithSpecifier | TokenFlagsContainsSeparator | TokenFlagsContainsInvalidSeparator + TokenFlagsTemplateLiteralLikeFlags TokenFlags = TokenFlagsUnterminated | TokenFlagsHexEscape | TokenFlagsUnicodeEscape | TokenFlagsExtendedUnicodeEscape | TokenFlagsContainsInvalidEscape + TokenFlagsRegularExpressionLiteralFlags TokenFlags = TokenFlagsUnterminated + TokenFlagsIsInvalid TokenFlags = TokenFlagsOctal | TokenFlagsContainsLeadingZero | TokenFlagsContainsInvalidSeparator | TokenFlagsContainsInvalidEscape +) diff --git a/kitcom/internal/tsgo/ast/utilities.go b/kitcom/internal/tsgo/ast/utilities.go new file mode 100644 index 0000000..f569280 --- /dev/null +++ b/kitcom/internal/tsgo/ast/utilities.go @@ -0,0 +1,3892 @@ +package ast + +import ( + "fmt" + "slices" + "strings" + "sync" + "sync/atomic" + + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/core" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/debug" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/tspath" +) + +// Atomic ids + +var ( + nextNodeId atomic.Uint64 + nextSymbolId atomic.Uint64 +) + +func GetNodeId(node *Node) NodeId { + id := node.id.Load() + if id == 0 { + // Worst case, we burn a few ids if we have to CAS. + id = nextNodeId.Add(1) + if !node.id.CompareAndSwap(0, id) { + id = node.id.Load() + } + } + return NodeId(id) +} + +func GetSymbolId(symbol *Symbol) SymbolId { + id := symbol.id.Load() + if id == 0 { + // Worst case, we burn a few ids if we have to CAS. + id = nextSymbolId.Add(1) + if !symbol.id.CompareAndSwap(0, id) { + id = symbol.id.Load() + } + } + return SymbolId(id) +} + +func GetSymbolTable(data *SymbolTable) SymbolTable { + if *data == nil { + *data = make(SymbolTable) + } + return *data +} + +func GetMembers(symbol *Symbol) SymbolTable { + return GetSymbolTable(&symbol.Members) +} + +func GetExports(symbol *Symbol) SymbolTable { + return GetSymbolTable(&symbol.Exports) +} + +func GetLocals(container *Node) SymbolTable { + return GetSymbolTable(&container.LocalsContainerData().Locals) +} + +// Determines if a node is missing (either `nil` or empty) +func NodeIsMissing(node *Node) bool { + return node == nil || node.Loc.Pos() == node.Loc.End() && node.Loc.Pos() >= 0 && node.Kind != KindEndOfFile +} + +// Determines if a node is present +func NodeIsPresent(node *Node) bool { + return !NodeIsMissing(node) +} + +// Determines if a node contains synthetic positions +func NodeIsSynthesized(node *Node) bool { + return PositionIsSynthesized(node.Loc.Pos()) || PositionIsSynthesized(node.Loc.End()) +} + +func RangeIsSynthesized(loc core.TextRange) bool { + return PositionIsSynthesized(loc.Pos()) || PositionIsSynthesized(loc.End()) +} + +// Determines whether a position is synthetic +func PositionIsSynthesized(pos int) bool { + return pos < 0 +} + +func FindLastVisibleNode(nodes []*Node) *Node { + fromEnd := 1 + for fromEnd <= len(nodes) && nodes[len(nodes)-fromEnd].Flags&NodeFlagsReparsed != 0 { + fromEnd++ + } + if fromEnd <= len(nodes) { + return nodes[len(nodes)-fromEnd] + } + return nil +} + +func NodeKindIs(node *Node, kinds ...Kind) bool { + return slices.Contains(kinds, node.Kind) +} + +func IsModifierKind(token Kind) bool { + switch token { + case KindAbstractKeyword, + KindAccessorKeyword, + KindAsyncKeyword, + KindConstKeyword, + KindDeclareKeyword, + KindDefaultKeyword, + KindExportKeyword, + KindInKeyword, + KindPublicKeyword, + KindPrivateKeyword, + KindProtectedKeyword, + KindReadonlyKeyword, + KindStaticKeyword, + KindOutKeyword, + KindOverrideKeyword: + return true + } + return false +} + +func IsModifier(node *Node) bool { + return IsModifierKind(node.Kind) +} + +func IsModifierLike(node *Node) bool { + return IsModifier(node) || IsDecorator(node) +} + +func IsKeywordKind(token Kind) bool { + return KindFirstKeyword <= token && token <= KindLastKeyword +} + +func IsPunctuationKind(token Kind) bool { + return KindFirstPunctuation <= token && token <= KindLastPunctuation +} + +func IsAssignmentOperator(token Kind) bool { + return token >= KindFirstAssignment && token <= KindLastAssignment +} + +func IsAssignmentExpression(node *Node, excludeCompoundAssignment bool) bool { + if node.Kind == KindBinaryExpression { + expr := node.AsBinaryExpression() + return (expr.OperatorToken.Kind == KindEqualsToken || !excludeCompoundAssignment && IsAssignmentOperator(expr.OperatorToken.Kind)) && + IsLeftHandSideExpression(expr.Left) + } + return false +} + +func GetRightMostAssignedExpression(node *Node) *Node { + for IsAssignmentExpression(node, true /*excludeCompoundAssignment*/) { + node = node.AsBinaryExpression().Right + } + return node +} + +func IsDestructuringAssignment(node *Node) bool { + if IsAssignmentExpression(node, true /*excludeCompoundAssignment*/) { + kind := node.AsBinaryExpression().Left.Kind + return kind == KindObjectLiteralExpression || kind == KindArrayLiteralExpression + } + return false +} + +// A node is an assignment target if it is on the left hand side of an '=' token, if it is parented by a property +// assignment in an object literal that is an assignment target, or if it is parented by an array literal that is +// an assignment target. Examples include 'a = xxx', '{ p: a } = xxx', '[{ a }] = xxx'. +// (Note that `p` is not a target in the above examples, only `a`.) +func IsAssignmentTarget(node *Node) bool { + return GetAssignmentTarget(node) != nil +} + +// Returns the BinaryExpression, PrefixUnaryExpression, PostfixUnaryExpression, or ForInOrOfStatement that references +// the given node as an assignment target +func GetAssignmentTarget(node *Node) *Node { + for { + parent := node.Parent + switch parent.Kind { + case KindBinaryExpression: + if IsAssignmentOperator(parent.AsBinaryExpression().OperatorToken.Kind) && parent.AsBinaryExpression().Left == node { + return parent + } + return nil + case KindPrefixUnaryExpression: + if parent.AsPrefixUnaryExpression().Operator == KindPlusPlusToken || parent.AsPrefixUnaryExpression().Operator == KindMinusMinusToken { + return parent + } + return nil + case KindPostfixUnaryExpression: + if parent.AsPostfixUnaryExpression().Operator == KindPlusPlusToken || parent.AsPostfixUnaryExpression().Operator == KindMinusMinusToken { + return parent + } + return nil + case KindForInStatement, KindForOfStatement: + if parent.AsForInOrOfStatement().Initializer == node { + return parent + } + return nil + case KindParenthesizedExpression, KindArrayLiteralExpression, KindSpreadElement, KindNonNullExpression: + node = parent + case KindSpreadAssignment: + node = parent.Parent + case KindShorthandPropertyAssignment: + if parent.AsShorthandPropertyAssignment().Name() != node { + return nil + } + node = parent.Parent + case KindPropertyAssignment: + if parent.AsPropertyAssignment().Name() == node { + return nil + } + node = parent.Parent + default: + return nil + } + } +} + +func IsLogicalBinaryOperator(token Kind) bool { + return token == KindBarBarToken || token == KindAmpersandAmpersandToken +} + +func IsLogicalOrCoalescingBinaryOperator(token Kind) bool { + return IsLogicalBinaryOperator(token) || token == KindQuestionQuestionToken +} + +func IsLogicalOrCoalescingBinaryExpression(expr *Node) bool { + return IsBinaryExpression(expr) && IsLogicalOrCoalescingBinaryOperator(expr.AsBinaryExpression().OperatorToken.Kind) +} + +func IsLogicalOrCoalescingAssignmentOperator(token Kind) bool { + return token == KindBarBarEqualsToken || token == KindAmpersandAmpersandEqualsToken || token == KindQuestionQuestionEqualsToken +} + +func IsLogicalOrCoalescingAssignmentExpression(expr *Node) bool { + return IsBinaryExpression(expr) && IsLogicalOrCoalescingAssignmentOperator(expr.AsBinaryExpression().OperatorToken.Kind) +} + +func IsLogicalExpression(node *Node) bool { + for { + if node.Kind == KindParenthesizedExpression { + node = node.AsParenthesizedExpression().Expression + } else if node.Kind == KindPrefixUnaryExpression && node.AsPrefixUnaryExpression().Operator == KindExclamationToken { + node = node.AsPrefixUnaryExpression().Operand + } else { + return IsLogicalOrCoalescingBinaryExpression(node) + } + } +} + +func IsTokenKind(token Kind) bool { + return KindFirstToken <= token && token <= KindLastToken +} + +func IsAccessor(node *Node) bool { + return node.Kind == KindGetAccessor || node.Kind == KindSetAccessor +} + +func IsPropertyNameLiteral(node *Node) bool { + switch node.Kind { + case KindIdentifier, + KindStringLiteral, + KindNoSubstitutionTemplateLiteral, + KindNumericLiteral: + return true + } + return false +} + +func IsMemberName(node *Node) bool { + return node.Kind == KindIdentifier || node.Kind == KindPrivateIdentifier +} + +func IsEntityName(node *Node) bool { + return node.Kind == KindIdentifier || node.Kind == KindQualifiedName +} + +func IsPropertyName(node *Node) bool { + switch node.Kind { + case KindIdentifier, + KindPrivateIdentifier, + KindStringLiteral, + KindNumericLiteral, + KindComputedPropertyName: + return true + } + return false +} + +// Return true if the given identifier is classified as an IdentifierName by inspecting the parent of the node +func IsIdentifierName(node *Node) bool { + parent := node.Parent + switch parent.Kind { + case KindPropertyDeclaration, KindPropertySignature, KindMethodDeclaration, KindMethodSignature, KindGetAccessor, + KindSetAccessor, KindEnumMember, KindPropertyAssignment, KindPropertyAccessExpression: + return parent.Name() == node + case KindQualifiedName: + return parent.AsQualifiedName().Right == node + case KindBindingElement: + return parent.AsBindingElement().PropertyName == node + case KindImportSpecifier: + return parent.AsImportSpecifier().PropertyName == node + case KindExportSpecifier, KindJsxAttribute, KindJsxSelfClosingElement, KindJsxOpeningElement, KindJsxClosingElement: + return true + } + return false +} + +func IsPushOrUnshiftIdentifier(node *Node) bool { + text := node.Text() + return text == "push" || text == "unshift" +} + +func IsBooleanLiteral(node *Node) bool { + return node.Kind == KindTrueKeyword || node.Kind == KindFalseKeyword +} + +func IsLiteralKind(kind Kind) bool { + return KindFirstLiteralToken <= kind && kind <= KindLastLiteralToken +} + +func IsLiteralExpression(node *Node) bool { + return IsLiteralKind(node.Kind) +} + +func IsStringLiteralLike(node *Node) bool { + switch node.Kind { + case KindStringLiteral, KindNoSubstitutionTemplateLiteral: + return true + } + return false +} + +func IsStringOrNumericLiteralLike(node *Node) bool { + return IsStringLiteralLike(node) || IsNumericLiteral(node) +} + +func IsSignedNumericLiteral(node *Node) bool { + if node.Kind == KindPrefixUnaryExpression { + node := node.AsPrefixUnaryExpression() + return (node.Operator == KindPlusToken || node.Operator == KindMinusToken) && IsNumericLiteral(node.Operand) + } + return false +} + +// Determines if a node is part of an OptionalChain +func IsOptionalChain(node *Node) bool { + if node.Flags&NodeFlagsOptionalChain != 0 { + switch node.Kind { + case KindPropertyAccessExpression, + KindElementAccessExpression, + KindCallExpression, + KindNonNullExpression: + return true + } + } + return false +} + +func getQuestionDotToken(node *Expression) *TokenNode { + switch node.Kind { + case KindPropertyAccessExpression: + return node.AsPropertyAccessExpression().QuestionDotToken + case KindElementAccessExpression: + return node.AsElementAccessExpression().QuestionDotToken + case KindCallExpression: + return node.AsCallExpression().QuestionDotToken + } + panic("Unhandled case in getQuestionDotToken") +} + +// Determines if node is the root expression of an OptionalChain +func IsOptionalChainRoot(node *Expression) bool { + return IsOptionalChain(node) && !IsNonNullExpression(node) && getQuestionDotToken(node) != nil +} + +// Determines whether a node is the outermost `OptionalChain` in an ECMAScript `OptionalExpression`: +// +// 1. For `a?.b.c`, the outermost chain is `a?.b.c` (`c` is the end of the chain starting at `a?.`) +// 2. For `a?.b!`, the outermost chain is `a?.b` (`b` is the end of the chain starting at `a?.`) +// 3. For `(a?.b.c).d`, the outermost chain is `a?.b.c` (`c` is the end of the chain starting at `a?.` since parens end the chain) +// 4. For `a?.b.c?.d`, both `a?.b.c` and `a?.b.c?.d` are outermost (`c` is the end of the chain starting at `a?.`, and `d` is +// the end of the chain starting at `c?.`) +// 5. For `a?.(b?.c).d`, both `b?.c` and `a?.(b?.c)d` are outermost (`c` is the end of the chain starting at `b`, and `d` is +// the end of the chain starting at `a?.`) +func IsOutermostOptionalChain(node *Expression) bool { + parent := node.Parent + return !IsOptionalChain(parent) || // cases 1, 2, and 3 + IsOptionalChainRoot(parent) || // case 4 + node != parent.Expression() // case 5 +} + +// Determines whether a node is the expression preceding an optional chain (i.e. `a` in `a?.b`). +func IsExpressionOfOptionalChainRoot(node *Node) bool { + return IsOptionalChainRoot(node.Parent) && node.Parent.Expression() == node +} + +func IsNullishCoalesce(node *Node) bool { + return node.Kind == KindBinaryExpression && node.AsBinaryExpression().OperatorToken.Kind == KindQuestionQuestionToken +} + +func IsAssertionExpression(node *Node) bool { + kind := node.Kind + return kind == KindTypeAssertionExpression || kind == KindAsExpression +} + +func isLeftHandSideExpressionKind(kind Kind) bool { + switch kind { + case KindPropertyAccessExpression, KindElementAccessExpression, KindNewExpression, KindCallExpression, + KindJsxElement, KindJsxSelfClosingElement, KindJsxFragment, KindTaggedTemplateExpression, KindArrayLiteralExpression, + KindParenthesizedExpression, KindObjectLiteralExpression, KindClassExpression, KindFunctionExpression, KindIdentifier, + KindPrivateIdentifier, KindRegularExpressionLiteral, KindNumericLiteral, KindBigIntLiteral, KindStringLiteral, + KindNoSubstitutionTemplateLiteral, KindTemplateExpression, KindFalseKeyword, KindNullKeyword, KindThisKeyword, + KindTrueKeyword, KindSuperKeyword, KindNonNullExpression, KindExpressionWithTypeArguments, KindMetaProperty, + KindImportKeyword, KindMissingDeclaration: + return true + } + return false +} + +// Determines whether a node is a LeftHandSideExpression based only on its kind. +func IsLeftHandSideExpression(node *Node) bool { + return isLeftHandSideExpressionKind(node.Kind) +} + +func isUnaryExpressionKind(kind Kind) bool { + switch kind { + case KindPrefixUnaryExpression, + KindPostfixUnaryExpression, + KindDeleteExpression, + KindTypeOfExpression, + KindVoidExpression, + KindAwaitExpression, + KindTypeAssertionExpression: + return true + } + return isLeftHandSideExpressionKind(kind) +} + +// Determines whether a node is a UnaryExpression based only on its kind. +func IsUnaryExpression(node *Node) bool { + return isUnaryExpressionKind(node.Kind) +} + +func isExpressionKind(kind Kind) bool { + switch kind { + case KindConditionalExpression, + KindYieldExpression, + KindArrowFunction, + KindBinaryExpression, + KindSpreadElement, + KindAsExpression, + KindOmittedExpression, + KindCommaListExpression, + KindPartiallyEmittedExpression, + KindSatisfiesExpression: + return true + } + return isUnaryExpressionKind(kind) +} + +// Determines whether a node is an expression based only on its kind. +func IsExpression(node *Node) bool { + return isExpressionKind(node.Kind) +} + +func IsCommaExpression(node *Node) bool { + return node.Kind == KindBinaryExpression && node.AsBinaryExpression().OperatorToken.Kind == KindCommaToken +} + +func IsCommaSequence(node *Node) bool { + // !!! + // New compiler just has binary expressinons. + // Maybe this should consider KindCommaListExpression even though we don't generate them. + return IsCommaExpression(node) +} + +func IsIterationStatement(node *Node, lookInLabeledStatements bool) bool { + switch node.Kind { + case KindForStatement, + KindForInStatement, + KindForOfStatement, + KindDoStatement, + KindWhileStatement: + return true + case KindLabeledStatement: + return lookInLabeledStatements && IsIterationStatement((node.AsLabeledStatement()).Statement, lookInLabeledStatements) + } + + return false +} + +// Determines if a node is a property or element access expression +func IsAccessExpression(node *Node) bool { + return node.Kind == KindPropertyAccessExpression || node.Kind == KindElementAccessExpression +} + +func isFunctionLikeDeclarationKind(kind Kind) bool { + switch kind { + case KindFunctionDeclaration, + KindMethodDeclaration, + KindConstructor, + KindGetAccessor, + KindSetAccessor, + KindFunctionExpression, + KindArrowFunction: + return true + } + return false +} + +// Determines if a node is function-like (but is not a signature declaration) +func IsFunctionLikeDeclaration(node *Node) bool { + // TODO(rbuckton): Move `node != nil` test to call sites + return node != nil && isFunctionLikeDeclarationKind(node.Kind) +} + +func IsFunctionLikeKind(kind Kind) bool { + switch kind { + case KindMethodSignature, + KindCallSignature, + KindJSDocSignature, + KindConstructSignature, + KindIndexSignature, + KindFunctionType, + KindConstructorType: + return true + } + return isFunctionLikeDeclarationKind(kind) +} + +// Determines if a node is function- or signature-like. +func IsFunctionLike(node *Node) bool { + // TODO(rbuckton): Move `node != nil` test to call sites + return node != nil && IsFunctionLikeKind(node.Kind) +} + +func IsFunctionLikeOrClassStaticBlockDeclaration(node *Node) bool { + return node != nil && (IsFunctionLike(node) || IsClassStaticBlockDeclaration(node)) +} + +func IsFunctionOrSourceFile(node *Node) bool { + return IsFunctionLike(node) || IsSourceFile(node) +} + +func IsClassLike(node *Node) bool { + return node.Kind == KindClassDeclaration || node.Kind == KindClassExpression +} + +func IsClassOrInterfaceLike(node *Node) bool { + return node.Kind == KindClassDeclaration || node.Kind == KindClassExpression || node.Kind == KindInterfaceDeclaration +} + +func IsClassElement(node *Node) bool { + switch node.Kind { + case KindConstructor, + KindPropertyDeclaration, + KindMethodDeclaration, + KindGetAccessor, + KindSetAccessor, + KindIndexSignature, + KindClassStaticBlockDeclaration, + KindSemicolonClassElement: + return true + } + return false +} + +func isMethodOrAccessor(node *Node) bool { + switch node.Kind { + case KindMethodDeclaration, KindGetAccessor, KindSetAccessor: + return true + } + return false +} + +func IsPrivateIdentifierClassElementDeclaration(node *Node) bool { + return (IsPropertyDeclaration(node) || isMethodOrAccessor(node)) && IsPrivateIdentifier(node.Name()) +} + +func IsObjectLiteralOrClassExpressionMethodOrAccessor(node *Node) bool { + kind := node.Kind + return (kind == KindMethodDeclaration || kind == KindGetAccessor || kind == KindSetAccessor) && + (node.Parent.Kind == KindObjectLiteralExpression || node.Parent.Kind == KindClassExpression) +} + +func IsTypeElement(node *Node) bool { + switch node.Kind { + case KindConstructSignature, + KindCallSignature, + KindPropertySignature, + KindMethodSignature, + KindIndexSignature, + KindGetAccessor, + KindSetAccessor, + KindNotEmittedTypeElement: + return true + } + return false +} + +func IsObjectLiteralElement(node *Node) bool { + switch node.Kind { + case KindPropertyAssignment, + KindShorthandPropertyAssignment, + KindSpreadAssignment, + KindMethodDeclaration, + KindGetAccessor, + KindSetAccessor: + return true + } + return false +} + +func IsObjectLiteralMethod(node *Node) bool { + return node != nil && node.Kind == KindMethodDeclaration && node.Parent.Kind == KindObjectLiteralExpression +} + +func IsAutoAccessorPropertyDeclaration(node *Node) bool { + return IsPropertyDeclaration(node) && HasAccessorModifier(node) +} + +func IsParameterPropertyDeclaration(node *Node, parent *Node) bool { + return IsParameter(node) && HasSyntacticModifier(node, ModifierFlagsParameterPropertyModifier) && parent.Kind == KindConstructor +} + +func IsJsxChild(node *Node) bool { + switch node.Kind { + case KindJsxElement, + KindJsxExpression, + KindJsxSelfClosingElement, + KindJsxText, + KindJsxFragment: + return true + } + return false +} + +func IsJsxAttributeLike(node *Node) bool { + return IsJsxAttribute(node) || IsJsxSpreadAttribute(node) +} + +func isDeclarationStatementKind(kind Kind) bool { + switch kind { + case KindFunctionDeclaration, + KindMissingDeclaration, + KindClassDeclaration, + KindInterfaceDeclaration, + KindTypeAliasDeclaration, + KindJSTypeAliasDeclaration, + KindEnumDeclaration, + KindModuleDeclaration, + KindImportDeclaration, + KindJSImportDeclaration, + KindImportEqualsDeclaration, + KindExportDeclaration, + KindExportAssignment, + KindJSExportAssignment, + KindCommonJSExport, + KindNamespaceExportDeclaration: + return true + } + return false +} + +// Determines whether a node is a DeclarationStatement. Ideally this does not use Parent pointers, but it may use them +// to rule out a Block node that is part of `try` or `catch` or is the Block-like body of a function. +// +// NOTE: ECMA262 would just call this a Declaration +func IsDeclarationStatement(node *Node) bool { + return isDeclarationStatementKind(node.Kind) +} + +func isStatementKindButNotDeclarationKind(kind Kind) bool { + switch kind { + case KindBreakStatement, + KindContinueStatement, + KindDebuggerStatement, + KindDoStatement, + KindExpressionStatement, + KindEmptyStatement, + KindForInStatement, + KindForOfStatement, + KindForStatement, + KindIfStatement, + KindLabeledStatement, + KindReturnStatement, + KindSwitchStatement, + KindThrowStatement, + KindTryStatement, + KindVariableStatement, + KindWhileStatement, + KindWithStatement, + KindNotEmittedStatement: + return true + } + return false +} + +// Determines whether a node is a Statement that is not also a Declaration. Ideally this does not use Parent pointers, +// but it may use them to rule out a Block node that is part of `try` or `catch` or is the Block-like body of a function. +// +// NOTE: ECMA262 would just call this a Statement +func IsStatementButNotDeclaration(node *Node) bool { + return isStatementKindButNotDeclarationKind(node.Kind) +} + +// Determines whether a node is a Statement. Ideally this does not use Parent pointers, but it may use +// them to rule out a Block node that is part of `try` or `catch` or is the Block-like body of a function. +// +// NOTE: ECMA262 would call this either a StatementListItem or ModuleListItem +func IsStatement(node *Node) bool { + kind := node.Kind + return isStatementKindButNotDeclarationKind(kind) || isDeclarationStatementKind(kind) || isBlockStatement(node) +} + +// Determines whether a node is a BlockStatement. If parents are available, this ensures the Block is +// not part of a `try` statement, `catch` clause, or the Block-like body of a function +func isBlockStatement(node *Node) bool { + if node.Kind != KindBlock { + return false + } + if node.Parent != nil && (node.Parent.Kind == KindTryStatement || node.Parent.Kind == KindCatchClause) { + return false + } + return !IsFunctionBlock(node) +} + +// Determines whether a node is the Block-like body of a function by walking the parent of the node +func IsFunctionBlock(node *Node) bool { + return node != nil && node.Kind == KindBlock && node.Parent != nil && IsFunctionLike(node.Parent) +} + +func GetStatementsOfBlock(block *Node) *StatementList { + switch block.Kind { + case KindBlock: + return block.AsBlock().Statements + case KindModuleBlock: + return block.AsModuleBlock().Statements + case KindSourceFile: + return block.AsSourceFile().Statements + } + panic("Unhandled case in getStatementsOfBlock") +} + +func IsBlockOrCatchScoped(declaration *Node) bool { + return GetCombinedNodeFlags(declaration)&NodeFlagsBlockScoped != 0 || IsCatchClauseVariableDeclarationOrBindingElement(declaration) +} + +func IsCatchClauseVariableDeclarationOrBindingElement(declaration *Node) bool { + node := GetRootDeclaration(declaration) + return node.Kind == KindVariableDeclaration && node.Parent.Kind == KindCatchClause +} + +func IsTypeNodeKind(kind Kind) bool { + switch kind { + case KindAnyKeyword, + KindUnknownKeyword, + KindNumberKeyword, + KindBigIntKeyword, + KindObjectKeyword, + KindBooleanKeyword, + KindStringKeyword, + KindSymbolKeyword, + KindVoidKeyword, + KindUndefinedKeyword, + KindNeverKeyword, + KindIntrinsicKeyword, + KindExpressionWithTypeArguments, + KindJSDocAllType, + KindJSDocNullableType, + KindJSDocNonNullableType, + KindJSDocOptionalType, + KindJSDocVariadicType: + return true + } + return kind >= KindFirstTypeNode && kind <= KindLastTypeNode +} + +func IsTypeNode(node *Node) bool { + return IsTypeNodeKind(node.Kind) +} + +func IsJSDocKind(kind Kind) bool { + return KindFirstJSDocNode <= kind && kind <= KindLastJSDocNode +} + +func isJSDocTypeAssertion(_ *Node) bool { + return false // !!! +} + +func IsPrologueDirective(node *Node) bool { + return node.Kind == KindExpressionStatement && + node.AsExpressionStatement().Expression.Kind == KindStringLiteral +} + +type OuterExpressionKinds int16 + +const ( + OEKParentheses OuterExpressionKinds = 1 << 0 + OEKTypeAssertions OuterExpressionKinds = 1 << 1 + OEKNonNullAssertions OuterExpressionKinds = 1 << 2 + OEKPartiallyEmittedExpressions OuterExpressionKinds = 1 << 3 + OEKExpressionsWithTypeArguments OuterExpressionKinds = 1 << 4 + OEKSatisfies OuterExpressionKinds = 1 << 5 + OEKExcludeJSDocTypeAssertion = 1 << 6 + OEKAssertions = OEKTypeAssertions | OEKNonNullAssertions | OEKSatisfies + OEKAll = OEKParentheses | OEKAssertions | OEKPartiallyEmittedExpressions | OEKExpressionsWithTypeArguments +) + +// Determines whether node is an "outer expression" of the provided kinds +func IsOuterExpression(node *Expression, kinds OuterExpressionKinds) bool { + switch node.Kind { + case KindParenthesizedExpression: + return kinds&OEKParentheses != 0 && !(kinds&OEKExcludeJSDocTypeAssertion != 0 && isJSDocTypeAssertion(node)) + case KindTypeAssertionExpression, KindAsExpression: + return kinds&OEKTypeAssertions != 0 + case KindSatisfiesExpression: + return kinds&(OEKExpressionsWithTypeArguments|OEKSatisfies) != 0 + case KindExpressionWithTypeArguments: + return kinds&OEKExpressionsWithTypeArguments != 0 + case KindNonNullExpression: + return kinds&OEKNonNullAssertions != 0 + case KindPartiallyEmittedExpression: + return kinds&OEKPartiallyEmittedExpressions != 0 + } + return false +} + +// Descends into an expression, skipping past "outer expressions" of the provided kinds +func SkipOuterExpressions(node *Expression, kinds OuterExpressionKinds) *Expression { + for IsOuterExpression(node, kinds) { + node = node.Expression() + } + return node +} + +// Skips past the parentheses of an expression +func SkipParentheses(node *Expression) *Expression { + return SkipOuterExpressions(node, OEKParentheses) +} + +func SkipTypeParentheses(node *Node) *Node { + for IsParenthesizedTypeNode(node) { + node = node.AsParenthesizedTypeNode().Type + } + return node +} + +func SkipPartiallyEmittedExpressions(node *Expression) *Expression { + return SkipOuterExpressions(node, OEKPartiallyEmittedExpressions) +} + +// Walks up the parents of a parenthesized expression to find the containing node +func WalkUpParenthesizedExpressions(node *Expression) *Node { + for node != nil && node.Kind == KindParenthesizedExpression { + node = node.Parent + } + return node +} + +// Walks up the parents of a parenthesized type to find the containing node +func WalkUpParenthesizedTypes(node *TypeNode) *Node { + for node != nil && node.Kind == KindParenthesizedType { + node = node.Parent + } + return node +} + +// Walks up the parents of a node to find the containing SourceFile +func GetSourceFileOfNode(node *Node) *SourceFile { + for node != nil { + if node.Kind == KindSourceFile { + return node.AsSourceFile() + } + node = node.Parent + } + return nil +} + +var setParentInChildrenPool = sync.Pool{ + New: func() any { + return newParentInChildrenSetter() + }, +} + +func newParentInChildrenSetter() func(node *Node) bool { + // Consolidate state into one allocation. + // Similar to https://go.dev/cl/552375. + var state struct { + parent *Node + visit func(*Node) bool + } + + state.visit = func(node *Node) bool { + if state.parent != nil { + node.Parent = state.parent + } + saveParent := state.parent + state.parent = node + node.ForEachChild(state.visit) + state.parent = saveParent + return false + } + + return state.visit +} + +func SetParentInChildren(node *Node) { + fn := setParentInChildrenPool.Get().(func(node *Node) bool) + defer setParentInChildrenPool.Put(fn) + fn(node) +} + +// This should never be called outside the parser +func SetImportsOfSourceFile(node *SourceFile, imports []*LiteralLikeNode) { + node.imports = imports +} + +// Walks up the parents of a node to find the ancestor that matches the callback +func FindAncestor(node *Node, callback func(*Node) bool) *Node { + for node != nil { + if callback(node) { + return node + } + node = node.Parent + } + return nil +} + +// Walks up the parents of a node to find the ancestor that matches the kind +func FindAncestorKind(node *Node, kind Kind) *Node { + for node != nil { + if node.Kind == kind { + return node + } + node = node.Parent + } + return nil +} + +type FindAncestorResult int32 + +const ( + FindAncestorFalse FindAncestorResult = iota + FindAncestorTrue + FindAncestorQuit +) + +func ToFindAncestorResult(b bool) FindAncestorResult { + if b { + return FindAncestorTrue + } + return FindAncestorFalse +} + +// Walks up the parents of a node to find the ancestor that matches the callback +func FindAncestorOrQuit(node *Node, callback func(*Node) FindAncestorResult) *Node { + for node != nil { + switch callback(node) { + case FindAncestorQuit: + return nil + case FindAncestorTrue: + return node + } + node = node.Parent + } + return nil +} + +func IsNodeDescendantOf(node *Node, ancestor *Node) bool { + for node != nil { + if node == ancestor { + return true + } + node = node.Parent + } + return false +} + +func ModifierToFlag(token Kind) ModifierFlags { + switch token { + case KindStaticKeyword: + return ModifierFlagsStatic + case KindPublicKeyword: + return ModifierFlagsPublic + case KindProtectedKeyword: + return ModifierFlagsProtected + case KindPrivateKeyword: + return ModifierFlagsPrivate + case KindAbstractKeyword: + return ModifierFlagsAbstract + case KindAccessorKeyword: + return ModifierFlagsAccessor + case KindExportKeyword: + return ModifierFlagsExport + case KindDeclareKeyword: + return ModifierFlagsAmbient + case KindConstKeyword: + return ModifierFlagsConst + case KindDefaultKeyword: + return ModifierFlagsDefault + case KindAsyncKeyword: + return ModifierFlagsAsync + case KindReadonlyKeyword: + return ModifierFlagsReadonly + case KindOverrideKeyword: + return ModifierFlagsOverride + case KindInKeyword: + return ModifierFlagsIn + case KindOutKeyword: + return ModifierFlagsOut + case KindDecorator: + return ModifierFlagsDecorator + } + return ModifierFlagsNone +} + +func ModifiersToFlags(modifiers []*Node) ModifierFlags { + var flags ModifierFlags + for _, modifier := range modifiers { + flags |= ModifierToFlag(modifier.Kind) + } + return flags +} + +func HasSyntacticModifier(node *Node, flags ModifierFlags) bool { + return node.ModifierFlags()&flags != 0 +} + +func HasAccessorModifier(node *Node) bool { + return HasSyntacticModifier(node, ModifierFlagsAccessor) +} + +func HasStaticModifier(node *Node) bool { + return HasSyntacticModifier(node, ModifierFlagsStatic) +} + +func IsStatic(node *Node) bool { + // https://tc39.es/ecma262/#sec-static-semantics-isstatic + return IsClassElement(node) && HasStaticModifier(node) || IsClassStaticBlockDeclaration(node) +} + +func CanHaveSymbol(node *Node) bool { + switch node.Kind { + case KindArrowFunction, KindBinaryExpression, KindBindingElement, KindCallExpression, KindCallSignature, + KindClassDeclaration, KindClassExpression, KindClassStaticBlockDeclaration, KindConstructor, KindConstructorType, + KindConstructSignature, KindElementAccessExpression, KindEnumDeclaration, KindEnumMember, KindExportAssignment, + KindExportDeclaration, KindExportSpecifier, KindFunctionDeclaration, KindFunctionExpression, KindFunctionType, + KindGetAccessor, KindImportClause, KindImportEqualsDeclaration, KindImportSpecifier, KindIndexSignature, + KindInterfaceDeclaration, KindJSExportAssignment, KindJSTypeAliasDeclaration, KindCommonJSExport, + KindJsxAttribute, KindJsxAttributes, KindJsxSpreadAttribute, KindMappedType, KindMethodDeclaration, + KindMethodSignature, KindModuleDeclaration, KindNamedTupleMember, KindNamespaceExport, KindNamespaceExportDeclaration, + KindNamespaceImport, KindNewExpression, KindNoSubstitutionTemplateLiteral, KindNumericLiteral, KindObjectLiteralExpression, + KindParameter, KindPropertyAccessExpression, KindPropertyAssignment, KindPropertyDeclaration, KindPropertySignature, + KindSetAccessor, KindShorthandPropertyAssignment, KindSourceFile, KindSpreadAssignment, KindStringLiteral, + KindTypeAliasDeclaration, KindTypeLiteral, KindTypeParameter, KindVariableDeclaration: + return true + } + return false +} + +func CanHaveIllegalDecorators(node *Node) bool { + switch node.Kind { + case KindPropertyAssignment, KindShorthandPropertyAssignment, + KindFunctionDeclaration, KindConstructor, + KindIndexSignature, KindClassStaticBlockDeclaration, + KindMissingDeclaration, KindVariableStatement, + KindInterfaceDeclaration, KindTypeAliasDeclaration, + KindEnumDeclaration, KindModuleDeclaration, + KindImportEqualsDeclaration, KindImportDeclaration, KindJSImportDeclaration, + KindNamespaceExportDeclaration, KindExportDeclaration, + KindExportAssignment: + return true + } + return false +} + +func CanHaveIllegalModifiers(node *Node) bool { + switch node.Kind { + case KindClassStaticBlockDeclaration, + KindPropertyAssignment, + KindShorthandPropertyAssignment, + KindMissingDeclaration, + KindNamespaceExportDeclaration: + return true + } + return false +} + +func CanHaveModifiers(node *Node) bool { + switch node.Kind { + case KindTypeParameter, + KindParameter, + KindPropertySignature, + KindPropertyDeclaration, + KindMethodSignature, + KindMethodDeclaration, + KindConstructor, + KindGetAccessor, + KindSetAccessor, + KindIndexSignature, + KindConstructorType, + KindFunctionExpression, + KindArrowFunction, + KindClassExpression, + KindVariableStatement, + KindFunctionDeclaration, + KindClassDeclaration, + KindInterfaceDeclaration, + KindTypeAliasDeclaration, + KindEnumDeclaration, + KindModuleDeclaration, + KindImportEqualsDeclaration, + KindImportDeclaration, + KindJSImportDeclaration, + KindExportAssignment, + KindExportDeclaration: + return true + } + return false +} + +func CanHaveDecorators(node *Node) bool { + switch node.Kind { + case KindParameter, + KindPropertyDeclaration, + KindMethodDeclaration, + KindGetAccessor, + KindSetAccessor, + KindClassExpression, + KindClassDeclaration: + return true + } + return false +} + +func IsFunctionOrModuleBlock(node *Node) bool { + return IsSourceFile(node) || IsModuleBlock(node) || IsBlock(node) && IsFunctionLike(node.Parent) +} + +func IsFunctionExpressionOrArrowFunction(node *Node) bool { + return IsFunctionExpression(node) || IsArrowFunction(node) +} + +// Warning: This has the same semantics as the forEach family of functions in that traversal terminates +// in the event that 'visitor' returns true. +func ForEachReturnStatement(body *Node, visitor func(stmt *Node) bool) bool { + var traverse func(*Node) bool + traverse = func(node *Node) bool { + switch node.Kind { + case KindReturnStatement: + return visitor(node) + case KindCaseBlock, KindBlock, KindIfStatement, KindDoStatement, KindWhileStatement, KindForStatement, KindForInStatement, + KindForOfStatement, KindWithStatement, KindSwitchStatement, KindCaseClause, KindDefaultClause, KindLabeledStatement, + KindTryStatement, KindCatchClause: + return node.ForEachChild(traverse) + } + return false + } + return traverse(body) +} + +func GetRootDeclaration(node *Node) *Node { + for node.Kind == KindBindingElement { + node = node.Parent.Parent + } + return node +} + +func getCombinedFlags[T ~uint32](node *Node, getFlags func(*Node) T) T { + node = GetRootDeclaration(node) + flags := getFlags(node) + if node.Kind == KindVariableDeclaration { + node = node.Parent + } + if node != nil && node.Kind == KindVariableDeclarationList { + flags |= getFlags(node) + node = node.Parent + } + if node != nil && node.Kind == KindVariableStatement { + flags |= getFlags(node) + } + return flags +} + +func GetCombinedModifierFlags(node *Node) ModifierFlags { + return getCombinedFlags(node, (*Node).ModifierFlags) +} + +func GetCombinedNodeFlags(node *Node) NodeFlags { + return getCombinedFlags(node, getNodeFlags) +} + +func getNodeFlags(node *Node) NodeFlags { + return node.Flags +} + +// Gets whether a bound `VariableDeclaration` or `VariableDeclarationList` is part of an `await using` declaration. +func IsVarAwaitUsing(node *Node) bool { + return GetCombinedNodeFlags(node)&NodeFlagsBlockScoped == NodeFlagsAwaitUsing +} + +// Gets whether a bound `VariableDeclaration` or `VariableDeclarationList` is part of a `using` declaration. +func IsVarUsing(node *Node) bool { + return GetCombinedNodeFlags(node)&NodeFlagsBlockScoped == NodeFlagsUsing +} + +// Gets whether a bound `VariableDeclaration` or `VariableDeclarationList` is part of a `const` declaration. +func IsVarConst(node *Node) bool { + return GetCombinedNodeFlags(node)&NodeFlagsBlockScoped == NodeFlagsConst +} + +// Gets whether a bound `VariableDeclaration` or `VariableDeclarationList` is part of a `const`, `using` or `await using` declaration. +func IsVarConstLike(node *Node) bool { + switch GetCombinedNodeFlags(node) & NodeFlagsBlockScoped { + case NodeFlagsConst, NodeFlagsUsing, NodeFlagsAwaitUsing: + return true + } + return false +} + +// Gets whether a bound `VariableDeclaration` or `VariableDeclarationList` is part of a `let` declaration. +func IsVarLet(node *Node) bool { + return GetCombinedNodeFlags(node)&NodeFlagsBlockScoped == NodeFlagsLet +} + +func IsImportMeta(node *Node) bool { + if node.Kind == KindMetaProperty { + return node.AsMetaProperty().KeywordToken == KindImportKeyword && node.AsMetaProperty().Name().AsIdentifier().Text == "meta" + } + return false +} + +func WalkUpBindingElementsAndPatterns(binding *Node) *Node { + node := binding.Parent + for IsBindingElement(node.Parent) { + node = node.Parent.Parent + } + return node.Parent +} + +func IsSourceFileJS(file *SourceFile) bool { + return file.ScriptKind == core.ScriptKindJS || file.ScriptKind == core.ScriptKindJSX +} + +func IsInJSFile(node *Node) bool { + return node != nil && node.Flags&NodeFlagsJavaScriptFile != 0 +} + +func IsDeclaration(node *Node) bool { + if node.Kind == KindTypeParameter { + return node.Parent != nil + } + return IsDeclarationNode(node) +} + +// True if `name` is the name of a declaration node +func IsDeclarationName(name *Node) bool { + return !IsSourceFile(name) && !IsBindingPattern(name) && IsDeclaration(name.Parent) && name.Parent.Name() == name +} + +// Like 'isDeclarationName', but returns true for LHS of `import { x as y }` or `export { x as y }`. +func IsDeclarationNameOrImportPropertyName(name *Node) bool { + switch name.Parent.Kind { + case KindImportSpecifier, KindExportSpecifier: + return IsIdentifier(name) || name.Kind == KindStringLiteral + default: + return IsDeclarationName(name) + } +} + +func IsLiteralComputedPropertyDeclarationName(node *Node) bool { + return IsStringOrNumericLiteralLike(node) && + node.Parent.Kind == KindComputedPropertyName && + IsDeclaration(node.Parent.Parent) +} + +func IsExternalModuleImportEqualsDeclaration(node *Node) bool { + return node.Kind == KindImportEqualsDeclaration && node.AsImportEqualsDeclaration().ModuleReference.Kind == KindExternalModuleReference +} + +func IsModuleOrEnumDeclaration(node *Node) bool { + return node.Kind == KindModuleDeclaration || node.Kind == KindEnumDeclaration +} + +func IsLiteralImportTypeNode(node *Node) bool { + return IsImportTypeNode(node) && IsLiteralTypeNode(node.AsImportTypeNode().Argument) && IsStringLiteral(node.AsImportTypeNode().Argument.AsLiteralTypeNode().Literal) +} + +func IsJsxTagName(node *Node) bool { + parent := node.Parent + switch parent.Kind { + case KindJsxOpeningElement, KindJsxClosingElement, KindJsxSelfClosingElement: + return parent.TagName() == node + } + return false +} + +func IsImportOrExportSpecifier(node *Node) bool { + return IsImportSpecifier(node) || IsExportSpecifier(node) +} + +func isVoidZero(node *Node) bool { + return IsVoidExpression(node) && IsNumericLiteral(node.Expression()) && node.Expression().Text() == "0" +} + +func IsVoidExpression(node *Node) bool { + return node.Kind == KindVoidExpression +} + +func IsExportsIdentifier(node *Node) bool { + return IsIdentifier(node) && node.Text() == "exports" +} + +func IsModuleIdentifier(node *Node) bool { + return IsIdentifier(node) && node.Text() == "module" +} + +func IsThisIdentifier(node *Node) bool { + return IsIdentifier(node) && node.Text() == "this" +} + +func IsThisParameter(node *Node) bool { + return IsParameter(node) && node.Name() != nil && IsThisIdentifier(node.Name()) +} + +func IsBindableStaticAccessExpression(node *Node, excludeThisKeyword bool) bool { + return IsPropertyAccessExpression(node) && + (!excludeThisKeyword && node.Expression().Kind == KindThisKeyword || IsIdentifier(node.Name()) && IsBindableStaticNameExpression(node.Expression() /*excludeThisKeyword*/, true)) || + IsBindableStaticElementAccessExpression(node, excludeThisKeyword) +} + +func IsBindableStaticElementAccessExpression(node *Node, excludeThisKeyword bool) bool { + return IsLiteralLikeElementAccess(node) && + ((!excludeThisKeyword && node.Expression().Kind == KindThisKeyword) || + IsEntityNameExpression(node.Expression()) || + IsBindableStaticAccessExpression(node.Expression(), true /*excludeThisKeyword*/)) +} + +func IsLiteralLikeElementAccess(node *Node) bool { + return IsElementAccessExpression(node) && IsStringOrNumericLiteralLike(node.AsElementAccessExpression().ArgumentExpression) +} + +func IsBindableStaticNameExpression(node *Node, excludeThisKeyword bool) bool { + return IsEntityNameExpression(node) || IsBindableStaticAccessExpression(node, excludeThisKeyword) +} + +// Does not handle signed numeric names like `a[+0]` - handling those would require handling prefix unary expressions +// throughout late binding handling as well, which is awkward (but ultimately probably doable if there is demand) +func GetElementOrPropertyAccessName(node *Node) *Node { + switch node.Kind { + case KindPropertyAccessExpression: + if IsIdentifier(node.Name()) { + return node.Name() + } + return nil + case KindElementAccessExpression: + if arg := SkipParentheses(node.AsElementAccessExpression().ArgumentExpression); IsStringOrNumericLiteralLike(arg) { + return arg + } + return nil + } + panic("Unhandled case in GetElementOrPropertyAccessName") +} + +func GetInitializerOfBinaryExpression(expr *BinaryExpression) *Expression { + for IsBinaryExpression(expr.Right) { + expr = expr.Right.AsBinaryExpression() + } + return expr.Right.Expression() +} + +func IsExpressionWithTypeArgumentsInClassExtendsClause(node *Node) bool { + return TryGetClassExtendingExpressionWithTypeArguments(node) != nil +} + +func TryGetClassExtendingExpressionWithTypeArguments(node *Node) *ClassLikeDeclaration { + cls, isImplements := TryGetClassImplementingOrExtendingExpressionWithTypeArguments(node) + if cls != nil && !isImplements { + return cls + } + return nil +} + +func TryGetClassImplementingOrExtendingExpressionWithTypeArguments(node *Node) (class *ClassLikeDeclaration, isImplements bool) { + if IsExpressionWithTypeArguments(node) { + if IsHeritageClause(node.Parent) && IsClassLike(node.Parent.Parent) { + return node.Parent.Parent, node.Parent.AsHeritageClause().Token == KindImplementsKeyword + } + } + return nil, false +} + +func GetNameOfDeclaration(declaration *Node) *Node { + if declaration == nil { + return nil + } + nonAssignedName := GetNonAssignedNameOfDeclaration(declaration) + if nonAssignedName != nil { + return nonAssignedName + } + if IsFunctionExpression(declaration) || IsArrowFunction(declaration) || IsClassExpression(declaration) { + return getAssignedName(declaration) + } + return nil +} + +func GetImportClauseOfDeclaration(declaration *Declaration) *ImportClause { + switch declaration.Kind { + case KindImportDeclaration: + return declaration.AsImportDeclaration().ImportClause.AsImportClause() + case KindJSDocImportTag: + return declaration.AsJSDocImportTag().ImportClause.AsImportClause() + } + return nil +} + +func GetNonAssignedNameOfDeclaration(declaration *Node) *Node { + // !!! + switch declaration.Kind { + case KindBinaryExpression: + bin := declaration.AsBinaryExpression() + kind := GetAssignmentDeclarationKind(bin) + if kind == JSDeclarationKindProperty || kind == JSDeclarationKindThisProperty { + if name := GetElementOrPropertyAccessName(bin.Left); name != nil { + return name + } else { + return bin.Left + } + } + return nil + case KindExportAssignment, KindJSExportAssignment: + expr := declaration.AsExportAssignment().Expression + if IsIdentifier(expr) { + return expr + } + return nil + } + return declaration.Name() +} + +func getAssignedName(node *Node) *Node { + parent := node.Parent + if parent != nil { + switch parent.Kind { + case KindPropertyAssignment: + return parent.AsPropertyAssignment().Name() + case KindBindingElement: + return parent.AsBindingElement().Name() + case KindBinaryExpression: + if node == parent.AsBinaryExpression().Right { + left := parent.AsBinaryExpression().Left + switch left.Kind { + case KindIdentifier: + return left + case KindPropertyAccessExpression: + return left.AsPropertyAccessExpression().Name() + case KindElementAccessExpression: + arg := SkipParentheses(left.AsElementAccessExpression().ArgumentExpression) + if IsStringOrNumericLiteralLike(arg) { + return arg + } + } + } + case KindCommonJSExport: + return parent.AsCommonJSExport().Name() + case KindVariableDeclaration: + name := parent.AsVariableDeclaration().Name() + if IsIdentifier(name) { + return name + } + } + } + return nil +} + +type JSDeclarationKind int + +const ( + JSDeclarationKindNone JSDeclarationKind = iota + /// module.exports = expr + JSDeclarationKindModuleExports + /// exports.name = expr + /// module.exports.name = expr + JSDeclarationKindExportsProperty + /// className.prototype.name = expr + JSDeclarationKindPrototypeProperty + /// this.name = expr + JSDeclarationKindThisProperty + /// F.name = expr, F[name] = expr + JSDeclarationKindProperty +) + +func GetAssignmentDeclarationKind(bin *BinaryExpression) JSDeclarationKind { + if bin.OperatorToken.Kind != KindEqualsToken || !IsAccessExpression(bin.Left) { + return JSDeclarationKindNone + } + if IsInJSFile(bin.Left) && IsModuleExportsAccessExpression(bin.Left) { + return JSDeclarationKindModuleExports + } else if IsInJSFile(bin.Left) && + (IsModuleExportsAccessExpression(bin.Left.Expression()) || IsExportsIdentifier(bin.Left.Expression())) && + GetElementOrPropertyAccessName(bin.Left) != nil { + return JSDeclarationKindExportsProperty + } + if IsInJSFile(bin.Left) && bin.Left.Expression().Kind == KindThisKeyword { + return JSDeclarationKindThisProperty + } + if bin.Left.Kind == KindPropertyAccessExpression && IsEntityNameExpressionEx(bin.Left.Expression(), IsInJSFile(bin.Left)) && IsIdentifier(bin.Left.Name()) || + bin.Left.Kind == KindElementAccessExpression && IsEntityNameExpressionEx(bin.Left.Expression(), IsInJSFile(bin.Left)) { + return JSDeclarationKindProperty + } + return JSDeclarationKindNone +} + +/** + * A declaration has a dynamic name if all of the following are true: + * 1. The declaration has a computed property name. + * 2. The computed name is *not* expressed as a StringLiteral. + * 3. The computed name is *not* expressed as a NumericLiteral. + * 4. The computed name is *not* expressed as a PlusToken or MinusToken + * immediately followed by a NumericLiteral. + */ +func HasDynamicName(declaration *Node) bool { + name := GetNameOfDeclaration(declaration) + return name != nil && IsDynamicName(name) +} + +func IsDynamicName(name *Node) bool { + var expr *Node + switch name.Kind { + case KindComputedPropertyName: + expr = name.AsComputedPropertyName().Expression + case KindElementAccessExpression: + expr = SkipParentheses(name.AsElementAccessExpression().ArgumentExpression) + default: + return false + } + return !IsStringOrNumericLiteralLike(expr) && !IsSignedNumericLiteral(expr) +} + +func IsEntityNameExpression(node *Node) bool { + return IsEntityNameExpressionEx(node, false /*allowJS*/) +} + +func IsEntityNameExpressionEx(node *Node, allowJS bool) bool { + if node.Kind == KindIdentifier || IsPropertyAccessEntityNameExpression(node, allowJS) { + return true + } + if allowJS { + return node.Kind == KindThisKeyword || isElementAccessEntityNameExpression(node, allowJS) + } + return false +} + +func IsPropertyAccessEntityNameExpression(node *Node, allowJS bool) bool { + if node.Kind == KindPropertyAccessExpression { + expr := node.AsPropertyAccessExpression() + return expr.Name().Kind == KindIdentifier && IsEntityNameExpressionEx(expr.Expression, allowJS) + } + return false +} + +func isElementAccessEntityNameExpression(node *Node, allowJS bool) bool { + if node.Kind == KindElementAccessExpression { + expr := node.AsElementAccessExpression() + if IsStringOrNumericLiteralLike(SkipParentheses(expr.ArgumentExpression)) { + return IsEntityNameExpressionEx(expr.Expression, allowJS) + } + } + return false +} + +func IsDottedName(node *Node) bool { + switch node.Kind { + case KindIdentifier, KindThisKeyword, KindSuperKeyword, KindMetaProperty: + return true + case KindPropertyAccessExpression, KindParenthesizedExpression: + return IsDottedName(node.Expression()) + } + return false +} + +func HasSamePropertyAccessName(node1, node2 *Node) bool { + if node1.Kind == KindIdentifier && node2.Kind == KindIdentifier { + return node1.Text() == node2.Text() + } else if node1.Kind == KindPropertyAccessExpression && node2.Kind == KindPropertyAccessExpression { + return node1.AsPropertyAccessExpression().Name().Text() == node2.AsPropertyAccessExpression().Name().Text() && + HasSamePropertyAccessName(node1.AsPropertyAccessExpression().Expression, node2.AsPropertyAccessExpression().Expression) + } + return false +} + +func IsAmbientModule(node *Node) bool { + return IsModuleDeclaration(node) && (node.AsModuleDeclaration().Name().Kind == KindStringLiteral || IsGlobalScopeAugmentation(node)) +} + +func IsExternalModule(file *SourceFile) bool { + return file.ExternalModuleIndicator != nil +} + +func IsExternalOrCommonJSModule(file *SourceFile) bool { + return file.ExternalModuleIndicator != nil || file.CommonJSModuleIndicator != nil +} + +// TODO: Should we deprecate `IsExternalOrCommonJSModule` in favor of this function? +func IsEffectiveExternalModule(node *SourceFile, compilerOptions *core.CompilerOptions) bool { + return IsExternalModule(node) || (isCommonJSContainingModuleKind(compilerOptions.GetEmitModuleKind()) && node.CommonJSModuleIndicator != nil) +} + +func isCommonJSContainingModuleKind(kind core.ModuleKind) bool { + return kind == core.ModuleKindCommonJS || core.ModuleKindNode16 <= kind && kind <= core.ModuleKindNodeNext +} + +func IsExternalModuleIndicator(node *Statement) bool { + // Exported top-level member indicates moduleness + return IsAnyImportOrReExport(node) || IsExportAssignment(node) || HasSyntacticModifier(node, ModifierFlagsExport) +} + +func IsExportNamespaceAsDefaultDeclaration(node *Node) bool { + if IsExportDeclaration(node) { + decl := node.AsExportDeclaration() + return IsNamespaceExport(decl.ExportClause) && ModuleExportNameIsDefault(decl.ExportClause.Name()) + } + return false +} + +func IsGlobalScopeAugmentation(node *Node) bool { + return IsModuleDeclaration(node) && node.AsModuleDeclaration().Keyword == KindGlobalKeyword +} + +func IsModuleAugmentationExternal(node *Node) bool { + // external module augmentation is a ambient module declaration that is either: + // - defined in the top level scope and source file is an external module + // - defined inside ambient module declaration located in the top level scope and source file not an external module + switch node.Parent.Kind { + case KindSourceFile: + return IsExternalModule(node.Parent.AsSourceFile()) + case KindModuleBlock: + grandParent := node.Parent.Parent + return IsAmbientModule(grandParent) && IsSourceFile(grandParent.Parent) && !IsExternalModule(grandParent.Parent.AsSourceFile()) + } + return false +} + +func IsModuleWithStringLiteralName(node *Node) bool { + return IsModuleDeclaration(node) && node.Name().Kind == KindStringLiteral +} + +func GetContainingClass(node *Node) *Node { + return FindAncestor(node.Parent, IsClassLike) +} + +func GetExtendsHeritageClauseElement(node *Node) *ExpressionWithTypeArgumentsNode { + return core.FirstOrNil(GetExtendsHeritageClauseElements(node)) +} + +func GetExtendsHeritageClauseElements(node *Node) []*ExpressionWithTypeArgumentsNode { + return GetHeritageElements(node, KindExtendsKeyword) +} + +func GetImplementsHeritageClauseElements(node *Node) []*ExpressionWithTypeArgumentsNode { + return GetHeritageElements(node, KindImplementsKeyword) +} + +func GetHeritageElements(node *Node, kind Kind) []*Node { + clause := GetHeritageClause(node, kind) + if clause != nil { + return clause.AsHeritageClause().Types.Nodes + } + return nil +} + +func GetHeritageClause(node *Node, kind Kind) *Node { + clauses := getHeritageClauses(node) + if clauses != nil { + for _, clause := range clauses.Nodes { + if clause.AsHeritageClause().Token == kind { + return clause + } + } + } + return nil +} + +func getHeritageClauses(node *Node) *NodeList { + switch node.Kind { + case KindClassDeclaration: + return node.AsClassDeclaration().HeritageClauses + case KindClassExpression: + return node.AsClassExpression().HeritageClauses + case KindInterfaceDeclaration: + return node.AsInterfaceDeclaration().HeritageClauses + } + return nil +} + +func IsPartOfTypeQuery(node *Node) bool { + for node.Kind == KindQualifiedName || node.Kind == KindIdentifier { + node = node.Parent + } + return node.Kind == KindTypeQuery +} + +/** + * This function returns true if the this node's root declaration is a parameter. + * For example, passing a `ParameterDeclaration` will return true, as will passing a + * binding element that is a child of a `ParameterDeclaration`. + * + * If you are looking to test that a `Node` is a `ParameterDeclaration`, use `isParameter`. + */ +func IsPartOfParameterDeclaration(node *Node) bool { + return GetRootDeclaration(node).Kind == KindParameter +} + +func IsInTopLevelContext(node *Node) bool { + // The name of a class or function declaration is a BindingIdentifier in its surrounding scope. + if IsIdentifier(node) { + parent := node.Parent + if (IsClassDeclaration(parent) || IsFunctionDeclaration(parent)) && parent.Name() == node { + node = parent + } + } + container := GetThisContainer(node, true /*includeArrowFunctions*/, false /*includeClassComputedPropertyName*/) + return IsSourceFile(container) +} + +func GetThisContainer(node *Node, includeArrowFunctions bool, includeClassComputedPropertyName bool) *Node { + for { + node = node.Parent + if node == nil { + panic("nil parent in getThisContainer") + } + switch node.Kind { + case KindComputedPropertyName: + if includeClassComputedPropertyName && IsClassLike(node.Parent.Parent) { + return node + } + node = node.Parent.Parent + case KindDecorator: + if node.Parent.Kind == KindParameter && IsClassElement(node.Parent.Parent) { + // If the decorator's parent is a Parameter, we resolve the this container from + // the grandparent class declaration. + node = node.Parent.Parent + } else if IsClassElement(node.Parent) { + // If the decorator's parent is a class element, we resolve the 'this' container + // from the parent class declaration. + node = node.Parent + } + case KindArrowFunction: + if includeArrowFunctions { + return node + } + case KindFunctionDeclaration, KindFunctionExpression, KindModuleDeclaration, KindClassStaticBlockDeclaration, + KindPropertyDeclaration, KindPropertySignature, KindMethodDeclaration, KindMethodSignature, KindConstructor, + KindGetAccessor, KindSetAccessor, KindCallSignature, KindConstructSignature, KindIndexSignature, + KindEnumDeclaration, KindSourceFile: + return node + } + } +} + +func GetSuperContainer(node *Node, stopOnFunctions bool) *Node { + for node = node.Parent; node != nil; node = node.Parent { + switch node.Kind { + case KindComputedPropertyName: + node = node.Parent + case KindFunctionDeclaration, KindFunctionExpression, KindArrowFunction: + if !stopOnFunctions { + continue + } + return node + case KindPropertyDeclaration, KindPropertySignature, KindMethodDeclaration, KindMethodSignature, KindConstructor, KindGetAccessor, KindSetAccessor, KindClassStaticBlockDeclaration: + return node + case KindDecorator: + // Decorators are always applied outside of the body of a class or method. + if node.Parent.Kind == KindParameter && IsClassElement(node.Parent.Parent) { + // If the decorator's parent is a Parameter, we resolve the this container from + // the grandparent class declaration. + node = node.Parent.Parent + } else if IsClassElement(node.Parent) { + // If the decorator's parent is a class element, we resolve the 'this' container + // from the parent class declaration. + node = node.Parent + } + } + } + return nil +} + +func GetImmediatelyInvokedFunctionExpression(fn *Node) *Node { + if IsFunctionExpressionOrArrowFunction(fn) { + prev := fn + parent := fn.Parent + for IsParenthesizedExpression(parent) { + prev = parent + parent = parent.Parent + } + if IsCallExpression(parent) && parent.AsCallExpression().Expression == prev { + return parent + } + } + return nil +} + +func IsEnumConst(node *Node) bool { + return GetCombinedModifierFlags(node)&ModifierFlagsConst != 0 +} + +func ExportAssignmentIsAlias(node *Node) bool { + e := node.AsExportAssignment().Expression + return IsEntityNameExpression(e) || IsClassExpression(e) +} + +func IsInstanceOfExpression(node *Node) bool { + return IsBinaryExpression(node) && node.AsBinaryExpression().OperatorToken.Kind == KindInstanceOfKeyword +} + +func IsAnyImportOrReExport(node *Node) bool { + return IsAnyImportSyntax(node) || IsExportDeclaration(node) +} + +func IsAnyImportSyntax(node *Node) bool { + return NodeKindIs(node, KindImportDeclaration, KindJSImportDeclaration, KindImportEqualsDeclaration) +} + +func IsJsonSourceFile(file *SourceFile) bool { + return file.ScriptKind == core.ScriptKindJSON +} + +func IsInJsonFile(node *Node) bool { + return node.Flags&NodeFlagsJsonFile != 0 +} + +func GetExternalModuleName(node *Node) *Expression { + switch node.Kind { + case KindImportDeclaration, KindJSImportDeclaration: + return node.AsImportDeclaration().ModuleSpecifier + case KindExportDeclaration: + return node.AsExportDeclaration().ModuleSpecifier + case KindImportEqualsDeclaration: + if node.AsImportEqualsDeclaration().ModuleReference.Kind == KindExternalModuleReference { + return node.AsImportEqualsDeclaration().ModuleReference.AsExternalModuleReference().Expression + } + return nil + case KindImportType: + return getImportTypeNodeLiteral(node) + case KindCallExpression: + return core.FirstOrNil(node.AsCallExpression().Arguments.Nodes) + case KindModuleDeclaration: + if IsStringLiteral(node.AsModuleDeclaration().Name()) { + return node.AsModuleDeclaration().Name() + } + return nil + } + panic("Unhandled case in getExternalModuleName") +} + +func GetImportAttributes(node *Node) *Node { + switch node.Kind { + case KindImportDeclaration, KindJSImportDeclaration: + return node.AsImportDeclaration().Attributes + case KindExportDeclaration: + return node.AsExportDeclaration().Attributes + } + panic("Unhandled case in getImportAttributes") +} + +func getImportTypeNodeLiteral(node *Node) *Node { + if IsImportTypeNode(node) { + importTypeNode := node.AsImportTypeNode() + if IsLiteralTypeNode(importTypeNode.Argument) { + literalTypeNode := importTypeNode.Argument.AsLiteralTypeNode() + if IsStringLiteral(literalTypeNode.Literal) { + return literalTypeNode.Literal + } + } + } + return nil +} + +func IsExpressionNode(node *Node) bool { + switch node.Kind { + case KindSuperKeyword, KindNullKeyword, KindTrueKeyword, KindFalseKeyword, KindRegularExpressionLiteral, + KindArrayLiteralExpression, KindObjectLiteralExpression, KindPropertyAccessExpression, KindElementAccessExpression, + KindCallExpression, KindNewExpression, KindTaggedTemplateExpression, KindAsExpression, KindTypeAssertionExpression, + KindSatisfiesExpression, KindNonNullExpression, KindParenthesizedExpression, KindFunctionExpression, + KindClassExpression, KindArrowFunction, KindVoidExpression, KindDeleteExpression, KindTypeOfExpression, + KindPrefixUnaryExpression, KindPostfixUnaryExpression, KindBinaryExpression, KindConditionalExpression, + KindSpreadElement, KindTemplateExpression, KindOmittedExpression, KindJsxElement, KindJsxSelfClosingElement, + KindJsxFragment, KindYieldExpression, KindAwaitExpression: + return true + case KindMetaProperty: + // `import.defer` in `import.defer(...)` is not an expression + return !IsImportCall(node.Parent) || node.Parent.AsCallExpression().Expression != node + case KindExpressionWithTypeArguments: + return !IsHeritageClause(node.Parent) + case KindQualifiedName: + for node.Parent.Kind == KindQualifiedName { + node = node.Parent + } + return IsTypeQueryNode(node.Parent) || IsJSDocLinkLike(node.Parent) || IsJSDocNameReference(node.Parent) || isJSXTagName(node) + case KindPrivateIdentifier: + return IsBinaryExpression(node.Parent) && node.Parent.AsBinaryExpression().Left == node && node.Parent.AsBinaryExpression().OperatorToken.Kind == KindInKeyword + case KindIdentifier: + if IsTypeQueryNode(node.Parent) || IsJSDocLinkLike(node.Parent) || IsJSDocNameReference(node.Parent) || isJSXTagName(node) { + return true + } + fallthrough + case KindNumericLiteral, KindBigIntLiteral, KindStringLiteral, KindNoSubstitutionTemplateLiteral, KindThisKeyword: + return IsInExpressionContext(node) + default: + return false + } +} + +func IsInExpressionContext(node *Node) bool { + parent := node.Parent + switch parent.Kind { + case KindVariableDeclaration: + return parent.AsVariableDeclaration().Initializer == node + case KindParameter: + return parent.AsParameterDeclaration().Initializer == node + case KindPropertyDeclaration: + return parent.AsPropertyDeclaration().Initializer == node + case KindPropertySignature: + return parent.AsPropertySignatureDeclaration().Initializer == node + case KindEnumMember: + return parent.AsEnumMember().Initializer == node + case KindPropertyAssignment: + return parent.AsPropertyAssignment().Initializer == node + case KindBindingElement: + return parent.AsBindingElement().Initializer == node + case KindExpressionStatement: + return parent.AsExpressionStatement().Expression == node + case KindIfStatement: + return parent.AsIfStatement().Expression == node + case KindDoStatement: + return parent.AsDoStatement().Expression == node + case KindWhileStatement: + return parent.AsWhileStatement().Expression == node + case KindReturnStatement: + return parent.AsReturnStatement().Expression == node + case KindWithStatement: + return parent.AsWithStatement().Expression == node + case KindSwitchStatement: + return parent.AsSwitchStatement().Expression == node + case KindCaseClause, KindDefaultClause: + return parent.AsCaseOrDefaultClause().Expression == node + case KindThrowStatement: + return parent.AsThrowStatement().Expression == node + case KindForStatement: + s := parent.AsForStatement() + return s.Initializer == node && s.Initializer.Kind != KindVariableDeclarationList || s.Condition == node || s.Incrementor == node + case KindForInStatement, KindForOfStatement: + s := parent.AsForInOrOfStatement() + return s.Initializer == node && s.Initializer.Kind != KindVariableDeclarationList || s.Expression == node + case KindTypeAssertionExpression: + return parent.AsTypeAssertion().Expression == node + case KindAsExpression: + return parent.AsAsExpression().Expression == node + case KindTemplateSpan: + return parent.AsTemplateSpan().Expression == node + case KindComputedPropertyName: + return parent.AsComputedPropertyName().Expression == node + case KindDecorator, KindJsxExpression, KindJsxSpreadAttribute, KindSpreadAssignment: + return true + case KindExpressionWithTypeArguments: + return parent.AsExpressionWithTypeArguments().Expression == node && !IsPartOfTypeNode(parent) + case KindShorthandPropertyAssignment: + return parent.AsShorthandPropertyAssignment().ObjectAssignmentInitializer == node + case KindSatisfiesExpression: + return parent.AsSatisfiesExpression().Expression == node + default: + return IsExpressionNode(parent) + } +} + +func IsPartOfTypeNode(node *Node) bool { + kind := node.Kind + if kind >= KindFirstTypeNode && kind <= KindLastTypeNode { + return true + } + switch node.Kind { + case KindAnyKeyword, KindUnknownKeyword, KindNumberKeyword, KindBigIntKeyword, KindStringKeyword, + KindBooleanKeyword, KindSymbolKeyword, KindObjectKeyword, KindUndefinedKeyword, KindNullKeyword, + KindNeverKeyword: + return true + case KindVoidKeyword: + return node.Parent.Kind != KindVoidExpression + case KindExpressionWithTypeArguments: + return isPartOfTypeExpressionWithTypeArguments(node) + case KindTypeParameter: + return node.Parent.Kind == KindMappedType || node.Parent.Kind == KindInferType + case KindIdentifier: + parent := node.Parent + if IsQualifiedName(parent) && parent.AsQualifiedName().Right == node { + return isPartOfTypeNodeInParent(parent) + } + if IsPropertyAccessExpression(parent) && parent.AsPropertyAccessExpression().Name() == node { + return isPartOfTypeNodeInParent(parent) + } + return isPartOfTypeNodeInParent(node) + case KindQualifiedName, KindPropertyAccessExpression, KindThisKeyword: + return isPartOfTypeNodeInParent(node) + } + return false +} + +func isPartOfTypeNodeInParent(node *Node) bool { + parent := node.Parent + if parent.Kind == KindTypeQuery { + return false + } + if parent.Kind == KindImportType { + return !parent.AsImportTypeNode().IsTypeOf + } + + // Do not recursively call isPartOfTypeNode on the parent. In the example: + // + // let a: A.B.C; + // + // Calling isPartOfTypeNode would consider the qualified name A.B a type node. + // Only C and A.B.C are type nodes. + if parent.Kind >= KindFirstTypeNode && parent.Kind <= KindLastTypeNode { + return true + } + switch parent.Kind { + case KindExpressionWithTypeArguments: + return isPartOfTypeExpressionWithTypeArguments(parent) + case KindTypeParameter: + return node == parent.AsTypeParameter().Constraint + case KindVariableDeclaration, KindParameter, KindPropertyDeclaration, KindPropertySignature, KindFunctionDeclaration, + KindFunctionExpression, KindArrowFunction, KindConstructor, KindMethodDeclaration, KindMethodSignature, + KindGetAccessor, KindSetAccessor, KindCallSignature, KindConstructSignature, KindIndexSignature, + KindTypeAssertionExpression: + return node == parent.Type() + case KindCallExpression, KindNewExpression, KindTaggedTemplateExpression: + return slices.Contains(parent.TypeArguments(), node) + } + return false +} + +func isPartOfTypeExpressionWithTypeArguments(node *Node) bool { + parent := node.Parent + return IsHeritageClause(parent) && (!IsClassLike(parent.Parent) || parent.AsHeritageClause().Token == KindImplementsKeyword) || + IsJSDocImplementsTag(parent) || + IsJSDocAugmentsTag(parent) +} + +func IsJSDocLinkLike(node *Node) bool { + return NodeKindIs(node, KindJSDocLink, KindJSDocLinkCode, KindJSDocLinkPlain) +} + +func IsJSDocTag(node *Node) bool { + return node.Kind >= KindFirstJSDocTagNode && node.Kind <= KindLastJSDocTagNode +} + +func isJSXTagName(node *Node) bool { + parent := node.Parent + switch parent.Kind { + case KindJsxOpeningElement: + return parent.AsJsxOpeningElement().TagName == node + case KindJsxSelfClosingElement: + return parent.AsJsxSelfClosingElement().TagName == node + case KindJsxClosingElement: + return parent.AsJsxClosingElement().TagName == node + } + return false +} + +func IsSuperCall(node *Node) bool { + return IsCallExpression(node) && node.AsCallExpression().Expression.Kind == KindSuperKeyword +} + +func IsImportCall(node *Node) bool { + if !IsCallExpression(node) { + return false + } + e := node.AsCallExpression().Expression + return e.Kind == KindImportKeyword || IsMetaProperty(e) && e.AsMetaProperty().KeywordToken == KindImportKeyword && e.Text() == "defer" +} + +func IsComputedNonLiteralName(name *Node) bool { + return IsComputedPropertyName(name) && !IsStringOrNumericLiteralLike(name.Expression()) +} + +func IsQuestionToken(node *Node) bool { + return node != nil && node.Kind == KindQuestionToken +} + +func GetTextOfPropertyName(name *Node) string { + text, _ := TryGetTextOfPropertyName(name) + return text +} + +func TryGetTextOfPropertyName(name *Node) (string, bool) { + switch name.Kind { + case KindIdentifier, KindPrivateIdentifier, KindStringLiteral, KindNumericLiteral, KindBigIntLiteral, + KindNoSubstitutionTemplateLiteral: + return name.Text(), true + case KindComputedPropertyName: + if IsStringOrNumericLiteralLike(name.Expression()) { + return name.Expression().Text(), true + } + case KindJsxNamespacedName: + return name.AsJsxNamespacedName().Namespace.Text() + ":" + name.Name().Text(), true + } + return "", false +} + +func IsJSDocNode(node *Node) bool { + return node.Kind >= KindFirstJSDocNode && node.Kind <= KindLastJSDocNode +} + +func IsNonWhitespaceToken(node *Node) bool { + return IsTokenKind(node.Kind) && !IsWhitespaceOnlyJsxText(node) +} + +func IsWhitespaceOnlyJsxText(node *Node) bool { + return node.Kind == KindJsxText && node.AsJsxText().ContainsOnlyTriviaWhiteSpaces +} + +func GetNewTargetContainer(node *Node) *Node { + container := GetThisContainer(node, false /*includeArrowFunctions*/, false /*includeClassComputedPropertyName*/) + if container != nil { + switch container.Kind { + case KindConstructor, KindFunctionDeclaration, KindFunctionExpression: + return container + } + } + return nil +} + +func GetEnclosingBlockScopeContainer(node *Node) *Node { + return FindAncestor(node.Parent, func(current *Node) bool { + return IsBlockScope(current, current.Parent) + }) +} + +func IsBlockScope(node *Node, parentNode *Node) bool { + switch node.Kind { + case KindSourceFile, KindCaseBlock, KindCatchClause, KindModuleDeclaration, KindForStatement, KindForInStatement, KindForOfStatement, + KindConstructor, KindMethodDeclaration, KindGetAccessor, KindSetAccessor, KindFunctionDeclaration, KindFunctionExpression, + KindArrowFunction, KindPropertyDeclaration, KindClassStaticBlockDeclaration: + return true + case KindBlock: + // function block is not considered block-scope container + // see comment in binder.ts: bind(...), case for SyntaxKind.Block + return !IsFunctionLikeOrClassStaticBlockDeclaration(parentNode) + } + return false +} + +type SemanticMeaning int32 + +const ( + SemanticMeaningNone SemanticMeaning = 0 + SemanticMeaningValue SemanticMeaning = 1 << 0 + SemanticMeaningType SemanticMeaning = 1 << 1 + SemanticMeaningNamespace SemanticMeaning = 1 << 2 + SemanticMeaningAll SemanticMeaning = SemanticMeaningValue | SemanticMeaningType | SemanticMeaningNamespace +) + +func GetMeaningFromDeclaration(node *Node) SemanticMeaning { + switch node.Kind { + case KindVariableDeclaration: + return SemanticMeaningValue + case KindParameter, + KindBindingElement, + KindPropertyDeclaration, + KindPropertySignature, + KindPropertyAssignment, + KindShorthandPropertyAssignment, + KindMethodDeclaration, + KindMethodSignature, + KindConstructor, + KindGetAccessor, + KindSetAccessor, + KindFunctionDeclaration, + KindFunctionExpression, + KindArrowFunction, + KindCatchClause, + KindJsxAttribute: + return SemanticMeaningValue + + case KindTypeParameter, + KindInterfaceDeclaration, + KindTypeAliasDeclaration, + KindJSTypeAliasDeclaration, + KindTypeLiteral: + return SemanticMeaningType + case KindEnumMember, KindClassDeclaration: + return SemanticMeaningValue | SemanticMeaningType + + case KindModuleDeclaration: + if IsAmbientModule(node) { + return SemanticMeaningNamespace | SemanticMeaningValue + } else if GetModuleInstanceState(node) == ModuleInstanceStateInstantiated { + return SemanticMeaningNamespace | SemanticMeaningValue + } else { + return SemanticMeaningNamespace + } + + case KindEnumDeclaration, + KindNamedImports, + KindImportSpecifier, + KindImportEqualsDeclaration, + KindImportDeclaration, + KindJSImportDeclaration, + KindExportAssignment, + KindJSExportAssignment, + KindExportDeclaration: + return SemanticMeaningAll + + // An external module can be a Value + case KindSourceFile: + return SemanticMeaningNamespace | SemanticMeaningValue + } + + return SemanticMeaningAll +} + +func IsPropertyAccessOrQualifiedName(node *Node) bool { + return node.Kind == KindPropertyAccessExpression || node.Kind == KindQualifiedName +} + +func IsLabelName(node *Node) bool { + return IsLabelOfLabeledStatement(node) || IsJumpStatementTarget(node) +} + +func IsLabelOfLabeledStatement(node *Node) bool { + if !IsIdentifier(node) { + return false + } + if !IsLabeledStatement(node.Parent) { + return false + } + return node == node.Parent.Label() +} + +func IsJumpStatementTarget(node *Node) bool { + if !IsIdentifier(node) { + return false + } + if !IsBreakOrContinueStatement(node.Parent) { + return false + } + return node == node.Parent.Label() +} + +func IsBreakOrContinueStatement(node *Node) bool { + return NodeKindIs(node, KindBreakStatement, KindContinueStatement) +} + +// GetModuleInstanceState is used during binding as well as in transformations and tests, and therefore may be invoked +// with a node that does not yet have its `Parent` pointer set. In this case, an `ancestors` represents a stack of +// virtual `Parent` pointers that can be used to walk up the tree. Since `getModuleInstanceStateForAliasTarget` may +// potentially walk up out of the provided `Node`, merely setting the parent pointers for a given `ModuleDeclaration` +// prior to invoking `GetModuleInstanceState` is not sufficient. It is, however, necessary that the `Parent` pointers +// for all ancestors of the `Node` provided to `GetModuleInstanceState` have been set. + +// Push a virtual parent pointer onto `ancestors` and return it. +func pushAncestor(ancestors []*Node, parent *Node) []*Node { + return append(ancestors, parent) +} + +// If a virtual `Parent` exists on the stack, returns the previous stack entry and the virtual `Parent“. +// Otherwise, we return `nil` and the value of `node.Parent`. +func popAncestor(ancestors []*Node, node *Node) ([]*Node, *Node) { + if len(ancestors) == 0 { + return nil, node.Parent + } + n := len(ancestors) - 1 + return ancestors[:n], ancestors[n] +} + +type ModuleInstanceState int32 + +const ( + ModuleInstanceStateUnknown ModuleInstanceState = iota + ModuleInstanceStateNonInstantiated + ModuleInstanceStateInstantiated + ModuleInstanceStateConstEnumOnly +) + +func GetModuleInstanceState(node *Node) ModuleInstanceState { + return getModuleInstanceState(node, nil, nil) +} + +func getModuleInstanceState(node *Node, ancestors []*Node, visited map[NodeId]ModuleInstanceState) ModuleInstanceState { + module := node.AsModuleDeclaration() + if module.Body != nil { + return getModuleInstanceStateCached(module.Body, pushAncestor(ancestors, node), visited) + } else { + return ModuleInstanceStateInstantiated + } +} + +func getModuleInstanceStateCached(node *Node, ancestors []*Node, visited map[NodeId]ModuleInstanceState) ModuleInstanceState { + if visited == nil { + visited = make(map[NodeId]ModuleInstanceState) + } + nodeId := GetNodeId(node) + if cached, ok := visited[nodeId]; ok { + if cached != ModuleInstanceStateUnknown { + return cached + } + return ModuleInstanceStateNonInstantiated + } + visited[nodeId] = ModuleInstanceStateUnknown + result := getModuleInstanceStateWorker(node, ancestors, visited) + visited[nodeId] = result + return result +} + +func getModuleInstanceStateWorker(node *Node, ancestors []*Node, visited map[NodeId]ModuleInstanceState) ModuleInstanceState { + // A module is uninstantiated if it contains only + switch node.Kind { + case KindInterfaceDeclaration, KindTypeAliasDeclaration, KindJSTypeAliasDeclaration: + return ModuleInstanceStateNonInstantiated + case KindEnumDeclaration: + if IsEnumConst(node) { + return ModuleInstanceStateConstEnumOnly + } + case KindImportDeclaration, KindJSImportDeclaration, KindImportEqualsDeclaration: + if !HasSyntacticModifier(node, ModifierFlagsExport) { + return ModuleInstanceStateNonInstantiated + } + case KindExportDeclaration: + decl := node.AsExportDeclaration() + if decl.ModuleSpecifier == nil && decl.ExportClause != nil && decl.ExportClause.Kind == KindNamedExports { + state := ModuleInstanceStateNonInstantiated + ancestors = pushAncestor(ancestors, node) + ancestors = pushAncestor(ancestors, decl.ExportClause) + for _, specifier := range decl.ExportClause.AsNamedExports().Elements.Nodes { + specifierState := getModuleInstanceStateForAliasTarget(specifier, ancestors, visited) + if specifierState > state { + state = specifierState + } + if state == ModuleInstanceStateInstantiated { + return state + } + } + return state + } + case KindModuleBlock: + state := ModuleInstanceStateNonInstantiated + ancestors = pushAncestor(ancestors, node) + node.ForEachChild(func(n *Node) bool { + childState := getModuleInstanceStateCached(n, ancestors, visited) + switch childState { + case ModuleInstanceStateNonInstantiated: + return false + case ModuleInstanceStateConstEnumOnly: + state = ModuleInstanceStateConstEnumOnly + return false + case ModuleInstanceStateInstantiated: + state = ModuleInstanceStateInstantiated + return true + } + panic("Unhandled case in getModuleInstanceStateWorker") + }) + return state + case KindModuleDeclaration: + return getModuleInstanceState(node, ancestors, visited) + } + return ModuleInstanceStateInstantiated +} + +func getModuleInstanceStateForAliasTarget(node *Node, ancestors []*Node, visited map[NodeId]ModuleInstanceState) ModuleInstanceState { + spec := node.AsExportSpecifier() + name := spec.PropertyName + if name == nil { + name = spec.Name() + } + if name.Kind != KindIdentifier { + // Skip for invalid syntax like this: export { "x" } + return ModuleInstanceStateInstantiated + } + for ancestors, p := popAncestor(ancestors, node); p != nil; ancestors, p = popAncestor(ancestors, p) { + if IsBlock(p) || IsModuleBlock(p) || IsSourceFile(p) { + statements := GetStatementsOfBlock(p) + found := ModuleInstanceStateUnknown + statementsAncestors := pushAncestor(ancestors, p) + for _, statement := range statements.Nodes { + if NodeHasName(statement, name) { + state := getModuleInstanceStateCached(statement, statementsAncestors, visited) + if found == ModuleInstanceStateUnknown || state > found { + found = state + } + if found == ModuleInstanceStateInstantiated { + return found + } + if statement.Kind == KindImportEqualsDeclaration { + // Treat re-exports of import aliases as instantiated since they're ambiguous. This is consistent + // with `export import x = mod.x` being treated as instantiated: + // import x = mod.x; + // export { x }; + found = ModuleInstanceStateInstantiated + } + } + } + if found != ModuleInstanceStateUnknown { + return found + } + } + } + // Couldn't locate, assume could refer to a value + return ModuleInstanceStateInstantiated +} + +func NodeHasName(statement *Node, id *Node) bool { + name := statement.Name() + if name != nil { + return IsIdentifier(name) && name.AsIdentifier().Text == id.AsIdentifier().Text + } + if IsVariableStatement(statement) { + declarations := statement.AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes + return core.Some(declarations, func(d *Node) bool { return NodeHasName(d, id) }) + } + return false +} + +func IsInternalModuleImportEqualsDeclaration(node *Node) bool { + return IsImportEqualsDeclaration(node) && node.AsImportEqualsDeclaration().ModuleReference.Kind != KindExternalModuleReference +} + +func GetAssertedTypeNode(node *Node) *Node { + switch node.Kind { + case KindAsExpression: + return node.AsAsExpression().Type + case KindSatisfiesExpression: + return node.AsSatisfiesExpression().Type + case KindTypeAssertionExpression: + return node.AsTypeAssertion().Type + } + panic("Unhandled case in getAssertedTypeNode") +} + +func IsConstAssertion(node *Node) bool { + switch node.Kind { + case KindAsExpression, KindTypeAssertionExpression: + return IsConstTypeReference(GetAssertedTypeNode(node)) + } + return false +} + +func IsConstTypeReference(node *Node) bool { + return IsTypeReferenceNode(node) && len(node.TypeArguments()) == 0 && IsIdentifier(node.AsTypeReferenceNode().TypeName) && node.AsTypeReferenceNode().TypeName.Text() == "const" +} + +func IsGlobalSourceFile(node *Node) bool { + return node.Kind == KindSourceFile && !IsExternalOrCommonJSModule(node.AsSourceFile()) +} + +func IsParameterLike(node *Node) bool { + switch node.Kind { + case KindParameter, KindTypeParameter: + return true + } + return false +} + +func GetDeclarationOfKind(symbol *Symbol, kind Kind) *Node { + for _, declaration := range symbol.Declarations { + if declaration.Kind == kind { + return declaration + } + } + return nil +} + +func FindConstructorDeclaration(node *ClassLikeDeclaration) *Node { + for _, member := range node.ClassLikeData().Members.Nodes { + if IsConstructorDeclaration(member) && NodeIsPresent(member.AsConstructorDeclaration().Body) { + return member + } + } + return nil +} + +func GetFirstIdentifier(node *Node) *Node { + switch node.Kind { + case KindIdentifier: + return node + case KindQualifiedName: + return GetFirstIdentifier(node.AsQualifiedName().Left) + case KindPropertyAccessExpression: + return GetFirstIdentifier(node.AsPropertyAccessExpression().Expression) + } + panic("Unhandled case in GetFirstIdentifier") +} + +func GetNamespaceDeclarationNode(node *Node) *Node { + switch node.Kind { + case KindImportDeclaration, KindJSImportDeclaration: + importClause := node.AsImportDeclaration().ImportClause + if importClause != nil && importClause.AsImportClause().NamedBindings != nil && IsNamespaceImport(importClause.AsImportClause().NamedBindings) { + return importClause.AsImportClause().NamedBindings + } + case KindImportEqualsDeclaration: + return node + case KindExportDeclaration: + exportClause := node.AsExportDeclaration().ExportClause + if exportClause != nil && IsNamespaceExport(exportClause) { + return exportClause + } + default: + panic("Unhandled case in getNamespaceDeclarationNode") + } + return nil +} + +func ModuleExportNameIsDefault(node *Node) bool { + return node.Text() == InternalSymbolNameDefault +} + +func IsDefaultImport(node *Node /*ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration*/) bool { + switch node.Kind { + case KindImportDeclaration, KindJSImportDeclaration: + importClause := node.AsImportDeclaration().ImportClause + return importClause != nil && importClause.AsImportClause().name != nil + } + return false +} + +func GetImpliedNodeFormatForFile(path string, packageJsonType string) core.ModuleKind { + impliedNodeFormat := core.ResolutionModeNone + if tspath.FileExtensionIsOneOf(path, []string{tspath.ExtensionDmts, tspath.ExtensionMts, tspath.ExtensionMjs}) { + impliedNodeFormat = core.ResolutionModeESM + } else if tspath.FileExtensionIsOneOf(path, []string{tspath.ExtensionDcts, tspath.ExtensionCts, tspath.ExtensionCjs}) { + impliedNodeFormat = core.ResolutionModeCommonJS + } else if tspath.FileExtensionIsOneOf(path, []string{tspath.ExtensionDts, tspath.ExtensionTs, tspath.ExtensionTsx, tspath.ExtensionJs, tspath.ExtensionJsx}) { + impliedNodeFormat = core.IfElse(packageJsonType == "module", core.ResolutionModeESM, core.ResolutionModeCommonJS) + } + + return impliedNodeFormat +} + +func GetEmitModuleFormatOfFileWorker(fileName string, options *core.CompilerOptions, sourceFileMetaData SourceFileMetaData) core.ModuleKind { + result := GetImpliedNodeFormatForEmitWorker(fileName, options.GetEmitModuleKind(), sourceFileMetaData) + if result != core.ModuleKindNone { + return result + } + return options.GetEmitModuleKind() +} + +func GetImpliedNodeFormatForEmitWorker(fileName string, emitModuleKind core.ModuleKind, sourceFileMetaData SourceFileMetaData) core.ResolutionMode { + if core.ModuleKindNode16 <= emitModuleKind && emitModuleKind <= core.ModuleKindNodeNext { + return sourceFileMetaData.ImpliedNodeFormat + } + if sourceFileMetaData.ImpliedNodeFormat == core.ModuleKindCommonJS && + (sourceFileMetaData.PackageJsonType == "commonjs" || + tspath.FileExtensionIsOneOf(fileName, []string{tspath.ExtensionCjs, tspath.ExtensionCts})) { + return core.ModuleKindCommonJS + } + if sourceFileMetaData.ImpliedNodeFormat == core.ModuleKindESNext && + (sourceFileMetaData.PackageJsonType == "module" || + tspath.FileExtensionIsOneOf(fileName, []string{tspath.ExtensionMjs, tspath.ExtensionMts})) { + return core.ModuleKindESNext + } + return core.ModuleKindNone +} + +func GetDeclarationContainer(node *Node) *Node { + return FindAncestor(GetRootDeclaration(node), func(node *Node) bool { + switch node.Kind { + case KindVariableDeclaration, + KindVariableDeclarationList, + KindImportSpecifier, + KindNamedImports, + KindNamespaceImport, + KindImportClause: + return false + default: + return true + } + }).Parent +} + +// Indicates that a symbol is an alias that does not merge with a local declaration. +// OR Is a JSContainer which may merge an alias with a local declaration +func IsNonLocalAlias(symbol *Symbol, excludes SymbolFlags) bool { + if symbol == nil { + return false + } + return symbol.Flags&(SymbolFlagsAlias|excludes) == SymbolFlagsAlias || + symbol.Flags&SymbolFlagsAlias != 0 && symbol.Flags&SymbolFlagsAssignment != 0 +} + +// An alias symbol is created by one of the following declarations: +// +// import = ... +// const = ... (JS only) +// const { , ... } = ... (JS only) +// import from ... +// import * as from ... +// import { x as } from ... +// export { x as } from ... +// export * as ns from ... +// export = +// export default +// module.exports = (JS only) +func IsAliasSymbolDeclaration(node *Node) bool { + switch node.Kind { + case KindImportEqualsDeclaration, KindNamespaceExportDeclaration, KindNamespaceImport, KindNamespaceExport, + KindImportSpecifier, KindExportSpecifier: + return true + case KindImportClause: + return node.AsImportClause().Name() != nil + case KindExportAssignment, KindJSExportAssignment: + return ExportAssignmentIsAlias(node) + case KindVariableDeclaration, KindBindingElement: + return IsVariableDeclarationInitializedToRequire(node) + } + return false +} + +func IsParseTreeNode(node *Node) bool { + return node.Flags&NodeFlagsSynthesized == 0 +} + +// Returns a token if position is in [start-of-leading-trivia, end), includes JSDoc only if requested +func GetNodeAtPosition(file *SourceFile, position int, includeJSDoc bool) *Node { + current := file.AsNode() + for { + var child *Node + if includeJSDoc { + for _, jsdoc := range current.JSDoc(file) { + if nodeContainsPosition(jsdoc, position) { + child = jsdoc + break + } + } + } + if child == nil { + current.ForEachChild(func(node *Node) bool { + if nodeContainsPosition(node, position) && node.Kind != KindJSExportAssignment && node.Kind != KindCommonJSExport { + child = node + return true + } + return false + }) + } + if child == nil || IsMetaProperty(child) { + return current + } + current = child + } +} + +func nodeContainsPosition(node *Node, position int) bool { + return node.Kind >= KindFirstNode && node.Pos() <= position && (position < node.End() || position == node.End() && node.Kind == KindEndOfFile) +} + +func findImportOrRequire(text string, start int) (index int, size int) { + index = max(start, 0) + n := len(text) + for index < n { + next := strings.IndexAny(text[index:], "ir") + if next < 0 { + break + } + index += next + + var expected string + if text[index] == 'i' { + size = 6 + expected = "import" + } else { + size = 7 + expected = "require" + } + if index+size <= n && text[index:index+size] == expected { + return index, size + } + index++ + } + + return -1, 0 +} + +func ForEachDynamicImportOrRequireCall( + file *SourceFile, + includeTypeSpaceImports bool, + requireStringLiteralLikeArgument bool, + cb func(node *Node, argument *Expression) bool, +) bool { + isJavaScriptFile := IsInJSFile(file.AsNode()) + lastIndex, size := findImportOrRequire(file.Text(), 0) + for lastIndex >= 0 { + node := GetNodeAtPosition(file, lastIndex, isJavaScriptFile && includeTypeSpaceImports) + if isJavaScriptFile && IsRequireCall(node, requireStringLiteralLikeArgument) { + if cb(node, node.Arguments()[0]) { + return true + } + } else if IsImportCall(node) && len(node.Arguments()) > 0 && (!requireStringLiteralLikeArgument || IsStringLiteralLike(node.Arguments()[0])) { + if cb(node, node.Arguments()[0]) { + return true + } + } else if includeTypeSpaceImports && IsLiteralImportTypeNode(node) { + if cb(node, node.AsImportTypeNode().Argument.AsLiteralTypeNode().Literal) { + return true + } + } + // skip past import/require + lastIndex += size + lastIndex, size = findImportOrRequire(file.Text(), lastIndex) + } + return false +} + +// Returns true if the node is a CallExpression to the identifier 'require' with +// exactly one argument (of the form 'require("name")'). +// This function does not test if the node is in a JavaScript file or not. +func IsRequireCall(node *Node, requireStringLiteralLikeArgument bool) bool { + if !IsCallExpression(node) { + return false + } + call := node.AsCallExpression() + if !IsIdentifier(call.Expression) || call.Expression.Text() != "require" { + return false + } + if len(call.Arguments.Nodes) != 1 { + return false + } + return !requireStringLiteralLikeArgument || IsStringLiteralLike(call.Arguments.Nodes[0]) +} + +func IsRequireVariableStatement(node *Node) bool { + if IsVariableStatement(node) { + if declarations := node.AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes; len(declarations) > 0 { + return core.Every(declarations, IsVariableDeclarationInitializedToRequire) + } + } + return false +} + +func GetJSXImplicitImportBase(compilerOptions *core.CompilerOptions, file *SourceFile) string { + jsxImportSourcePragma := GetPragmaFromSourceFile(file, "jsximportsource") + jsxRuntimePragma := GetPragmaFromSourceFile(file, "jsxruntime") + if GetPragmaArgument(jsxRuntimePragma, "factory") == "classic" { + return "" + } + if compilerOptions.Jsx == core.JsxEmitReactJSX || + compilerOptions.Jsx == core.JsxEmitReactJSXDev || + compilerOptions.JsxImportSource != "" || + jsxImportSourcePragma != nil || + GetPragmaArgument(jsxRuntimePragma, "factory") == "automatic" { + result := GetPragmaArgument(jsxImportSourcePragma, "factory") + if result == "" { + result = compilerOptions.JsxImportSource + } + if result == "" { + result = "react" + } + return result + } + return "" +} + +func GetJSXRuntimeImport(base string, options *core.CompilerOptions) string { + if base == "" { + return base + } + return base + "/" + core.IfElse(options.Jsx == core.JsxEmitReactJSXDev, "jsx-dev-runtime", "jsx-runtime") +} + +func GetPragmaFromSourceFile(file *SourceFile, name string) *Pragma { + var result *Pragma + if file != nil { + for i := range file.Pragmas { + if file.Pragmas[i].Name == name { + result = &file.Pragmas[i] // Last one wins + } + } + } + return result +} + +func GetPragmaArgument(pragma *Pragma, name string) string { + if pragma != nil { + if arg, ok := pragma.Args[name]; ok { + return arg.Value + } + } + return "" +} + +// Of the form: `const x = require("x")` or `const { x } = require("x")` or with `var` or `let` +// The variable must not be exported and must not have a type annotation, even a jsdoc one. +// The initializer must be a call to `require` with a string literal or a string literal-like argument. +func IsVariableDeclarationInitializedToRequire(node *Node) bool { + if !IsInJSFile(node) { + return false + } + if node.Kind == KindBindingElement { + node = node.Parent.Parent + } + if node.Kind != KindVariableDeclaration { + return false + } + + return node.Parent.Parent.ModifierFlags()&ModifierFlagsExport == 0 && + node.AsVariableDeclaration().Initializer != nil && + node.Type() == nil && + IsRequireCall(node.AsVariableDeclaration().Initializer, true /*requireStringLiteralLikeArgument*/) +} + +func IsModuleExportsAccessExpression(node *Node) bool { + if IsAccessExpression(node) && IsModuleIdentifier(node.Expression()) { + if name := GetElementOrPropertyAccessName(node); name != nil { + return name.Text() == "exports" + } + } + return false +} + +func IsCheckJSEnabledForFile(sourceFile *SourceFile, compilerOptions *core.CompilerOptions) bool { + if sourceFile.CheckJsDirective != nil { + return sourceFile.CheckJsDirective.Enabled + } + return compilerOptions.CheckJs == core.TSTrue +} + +func IsPlainJSFile(file *SourceFile, checkJs core.Tristate) bool { + return file != nil && (file.ScriptKind == core.ScriptKindJS || file.ScriptKind == core.ScriptKindJSX) && file.CheckJsDirective == nil && checkJs == core.TSUnknown +} + +func GetLeftmostAccessExpression(expr *Node) *Node { + for IsAccessExpression(expr) { + expr = expr.Expression() + } + return expr +} + +func IsTypeOnlyImportDeclaration(node *Node) bool { + switch node.Kind { + case KindImportSpecifier: + return node.IsTypeOnly() || node.Parent.Parent.IsTypeOnly() + case KindNamespaceImport: + return node.Parent.IsTypeOnly() + case KindImportClause, KindImportEqualsDeclaration: + return node.IsTypeOnly() + } + return false +} + +func isTypeOnlyExportDeclaration(node *Node) bool { + switch node.Kind { + case KindExportSpecifier: + return node.AsExportSpecifier().IsTypeOnly || node.Parent.Parent.AsExportDeclaration().IsTypeOnly + case KindExportDeclaration: + d := node.AsExportDeclaration() + return d.IsTypeOnly && d.ModuleSpecifier != nil && d.ExportClause == nil + case KindNamespaceExport: + return node.Parent.AsExportDeclaration().IsTypeOnly + } + return false +} + +func IsTypeOnlyImportOrExportDeclaration(node *Node) bool { + return IsTypeOnlyImportDeclaration(node) || isTypeOnlyExportDeclaration(node) +} + +func IsExclusivelyTypeOnlyImportOrExport(node *Node) bool { + switch node.Kind { + case KindExportDeclaration: + return node.AsExportDeclaration().IsTypeOnly + case KindImportDeclaration, KindJSImportDeclaration: + if importClause := node.AsImportDeclaration().ImportClause; importClause != nil { + return importClause.AsImportClause().IsTypeOnly() + } + case KindJSDocImportTag: + if importClause := node.AsJSDocImportTag().ImportClause; importClause != nil { + return importClause.AsImportClause().IsTypeOnly() + } + } + return false +} + +func GetClassLikeDeclarationOfSymbol(symbol *Symbol) *Node { + return core.Find(symbol.Declarations, IsClassLike) +} + +func IsCallLikeExpression(node *Node) bool { + switch node.Kind { + case KindJsxOpeningElement, KindJsxSelfClosingElement, KindJsxOpeningFragment, KindCallExpression, KindNewExpression, + KindTaggedTemplateExpression, KindDecorator: + return true + case KindBinaryExpression: + return node.AsBinaryExpression().OperatorToken.Kind == KindInstanceOfKeyword + } + return false +} + +func IsJsxCallLike(node *Node) bool { + switch node.Kind { + case KindJsxOpeningElement, KindJsxSelfClosingElement, KindJsxOpeningFragment: + return true + } + return false +} + +func IsCallLikeOrFunctionLikeExpression(node *Node) bool { + return IsCallLikeExpression(node) || IsFunctionExpressionOrArrowFunction(node) +} + +func NodeHasKind(node *Node, kind Kind) bool { + if node == nil { + return false + } + return node.Kind == kind +} + +func IsContextualKeyword(token Kind) bool { + return KindFirstContextualKeyword <= token && token <= KindLastContextualKeyword +} + +func IsThisInTypeQuery(node *Node) bool { + if !IsThisIdentifier(node) { + return false + } + for IsQualifiedName(node.Parent) && node.Parent.AsQualifiedName().Left == node { + node = node.Parent + } + return node.Parent.Kind == KindTypeQuery +} + +// Gets whether a bound `VariableDeclaration` or `VariableDeclarationList` is part of a `let` declaration. +func IsLet(node *Node) bool { + return GetCombinedNodeFlags(node)&NodeFlagsBlockScoped == NodeFlagsLet +} + +func IsClassMemberModifier(token Kind) bool { + return IsParameterPropertyModifier(token) || token == KindStaticKeyword || + token == KindOverrideKeyword || token == KindAccessorKeyword +} + +func IsParameterPropertyModifier(kind Kind) bool { + return ModifierToFlag(kind)&ModifierFlagsParameterPropertyModifier != 0 +} + +func ForEachChildAndJSDoc(node *Node, sourceFile *SourceFile, v Visitor) bool { + if node.Flags&NodeFlagsHasJSDoc != 0 { + if visitNodes(v, node.JSDoc(sourceFile)) { + return true + } + } + return node.ForEachChild(v) +} + +func IsTypeReferenceType(node *Node) bool { + return node.Kind == KindTypeReference || node.Kind == KindExpressionWithTypeArguments +} + +func IsVariableLike(node *Node) bool { + switch node.Kind { + case KindBindingElement, KindEnumMember, KindParameter, KindPropertyAssignment, KindPropertyDeclaration, + KindPropertySignature, KindShorthandPropertyAssignment, KindVariableDeclaration: + return true + } + return false +} + +func HasInitializer(node *Node) bool { + switch node.Kind { + case KindVariableDeclaration, KindParameter, KindBindingElement, KindPropertyDeclaration, + KindPropertyAssignment, KindEnumMember, KindForStatement, KindForInStatement, KindForOfStatement, + KindJsxAttribute: + return node.Initializer() != nil + default: + return false + } +} + +func GetTypeAnnotationNode(node *Node) *TypeNode { + switch node.Kind { + case KindVariableDeclaration, KindParameter, KindPropertySignature, KindPropertyDeclaration, + KindTypePredicate, KindParenthesizedType, KindTypeOperator, KindMappedType, KindTypeAssertionExpression, + KindAsExpression, KindSatisfiesExpression, KindTypeAliasDeclaration, KindJSTypeAliasDeclaration, + KindNamedTupleMember, KindOptionalType, KindRestType, KindTemplateLiteralTypeSpan, KindJSDocTypeExpression, + KindJSDocPropertyTag, KindJSDocNullableType, KindJSDocNonNullableType, KindJSDocOptionalType: + return node.Type() + default: + funcLike := node.FunctionLikeData() + if funcLike != nil { + return funcLike.Type + } + return nil + } +} + +func IsObjectTypeDeclaration(node *Node) bool { + return IsClassLike(node) || IsInterfaceDeclaration(node) || IsTypeLiteralNode(node) +} + +func IsClassOrTypeElement(node *Node) bool { + return IsClassElement(node) || IsTypeElement(node) +} + +func GetClassExtendsHeritageElement(node *Node) *ExpressionWithTypeArgumentsNode { + heritageElements := GetHeritageElements(node, KindExtendsKeyword) + if len(heritageElements) > 0 { + return heritageElements[0] + } + return nil +} + +func GetImplementsTypeNodes(node *Node) []*ExpressionWithTypeArgumentsNode { + return GetHeritageElements(node, KindImplementsKeyword) +} + +func IsTypeKeywordToken(node *Node) bool { + return node.Kind == KindTypeKeyword +} + +// See `IsJSDocSingleCommentNode`. +func IsJSDocSingleCommentNodeList(nodeList *NodeList) bool { + if nodeList == nil || len(nodeList.Nodes) == 0 { + return false + } + parent := nodeList.Nodes[0].Parent + return IsJSDocSingleCommentNode(parent) && nodeList == parent.CommentList() +} + +// See `IsJSDocSingleCommentNode`. +func IsJSDocSingleCommentNodeComment(node *Node) bool { + if node == nil || node.Parent == nil { + return false + } + return IsJSDocSingleCommentNode(node.Parent) && node == node.Parent.CommentList().Nodes[0] +} + +// In Strada, if a JSDoc node has a single comment, that comment is represented as a string property +// as a simplification, and therefore that comment is not visited by `forEachChild`. +func IsJSDocSingleCommentNode(node *Node) bool { + return hasComment(node.Kind) && node.CommentList() != nil && len(node.CommentList().Nodes) == 1 +} + +func IsValidTypeOnlyAliasUseSite(useSite *Node) bool { + return useSite.Flags&(NodeFlagsAmbient|NodeFlagsJSDoc) != 0 || + IsPartOfTypeQuery(useSite) || + isIdentifierInNonEmittingHeritageClause(useSite) || + isPartOfPossiblyValidTypeOrAbstractComputedPropertyName(useSite) || + !(IsExpressionNode(useSite) || isShorthandPropertyNameUseSite(useSite)) +} + +func isIdentifierInNonEmittingHeritageClause(node *Node) bool { + if !IsIdentifier(node) { + return false + } + parent := node.Parent + for IsPropertyAccessExpression(parent) || IsExpressionWithTypeArguments(parent) { + parent = parent.Parent + } + return IsHeritageClause(parent) && (parent.AsHeritageClause().Token == KindImplementsKeyword || IsInterfaceDeclaration(parent.Parent)) +} + +func isPartOfPossiblyValidTypeOrAbstractComputedPropertyName(node *Node) bool { + for NodeKindIs(node, KindIdentifier, KindPropertyAccessExpression) { + node = node.Parent + } + if node.Kind != KindComputedPropertyName { + return false + } + if HasSyntacticModifier(node.Parent, ModifierFlagsAbstract) { + return true + } + return NodeKindIs(node.Parent.Parent, KindInterfaceDeclaration, KindTypeLiteral) +} + +func isShorthandPropertyNameUseSite(useSite *Node) bool { + return IsIdentifier(useSite) && IsShorthandPropertyAssignment(useSite.Parent) && useSite.Parent.AsShorthandPropertyAssignment().Name() == useSite +} + +func GetPropertyNameForPropertyNameNode(name *Node) string { + switch name.Kind { + case KindIdentifier, KindPrivateIdentifier, KindStringLiteral, KindNoSubstitutionTemplateLiteral, + KindNumericLiteral, KindBigIntLiteral, KindJsxNamespacedName: + return name.Text() + case KindComputedPropertyName: + nameExpression := name.AsComputedPropertyName().Expression + if IsStringOrNumericLiteralLike(nameExpression) { + return nameExpression.Text() + } + if IsSignedNumericLiteral(nameExpression) { + text := nameExpression.AsPrefixUnaryExpression().Operand.Text() + if nameExpression.AsPrefixUnaryExpression().Operator == KindMinusToken { + text = "-" + text + } + return text + } + return InternalSymbolNameMissing + } + panic("Unhandled case in getPropertyNameForPropertyNameNode") +} + +func IsPartOfTypeOnlyImportOrExportDeclaration(node *Node) bool { + return FindAncestor(node, IsTypeOnlyImportOrExportDeclaration) != nil +} + +func IsPartOfExclusivelyTypeOnlyImportOrExportDeclaration(node *Node) bool { + return FindAncestor(node, IsExclusivelyTypeOnlyImportOrExport) != nil +} + +func IsEmittableImport(node *Node) bool { + switch node.Kind { + case KindImportDeclaration: + return node.AsImportDeclaration().ImportClause != nil && !node.AsImportDeclaration().ImportClause.IsTypeOnly() + case KindExportDeclaration: + return !node.AsExportDeclaration().IsTypeOnly + case KindImportEqualsDeclaration: + return !node.AsImportEqualsDeclaration().IsTypeOnly + case KindCallExpression: + return IsImportCall(node) + } + return false +} + +func IsResolutionModeOverrideHost(node *Node) bool { + if node == nil { + return false + } + switch node.Kind { + case KindImportType, KindExportDeclaration, KindImportDeclaration, KindJSImportDeclaration: + return true + } + return false +} + +func HasResolutionModeOverride(node *Node) bool { + if node == nil { + return false + } + var attributes *ImportAttributesNode + switch node.Kind { + case KindImportType: + attributes = node.AsImportTypeNode().Attributes + case KindImportDeclaration, KindJSImportDeclaration: + attributes = node.AsImportDeclaration().Attributes + case KindExportDeclaration: + attributes = node.AsExportDeclaration().Attributes + } + if attributes != nil { + _, ok := attributes.GetResolutionModeOverride() + return ok + } + return false +} + +func IsStringTextContainingNode(node *Node) bool { + return node.Kind == KindStringLiteral || IsTemplateLiteralKind(node.Kind) +} + +func IsTemplateLiteralKind(kind Kind) bool { + return KindFirstTemplateToken <= kind && kind <= KindLastTemplateToken +} + +func IsTemplateLiteralToken(node *Node) bool { + return IsTemplateLiteralKind(node.Kind) +} + +func GetExternalModuleImportEqualsDeclarationExpression(node *Node) *Node { + debug.Assert(IsExternalModuleImportEqualsDeclaration(node)) + return node.AsImportEqualsDeclaration().ModuleReference.AsExternalModuleReference().Expression +} + +func CreateModifiersFromModifierFlags(flags ModifierFlags, createModifier func(kind Kind) *Node) []*Node { + var result []*Node + if flags&ModifierFlagsExport != 0 { + result = append(result, createModifier(KindExportKeyword)) + } + if flags&ModifierFlagsAmbient != 0 { + result = append(result, createModifier(KindDeclareKeyword)) + } + if flags&ModifierFlagsDefault != 0 { + result = append(result, createModifier(KindDefaultKeyword)) + } + if flags&ModifierFlagsConst != 0 { + result = append(result, createModifier(KindConstKeyword)) + } + if flags&ModifierFlagsPublic != 0 { + result = append(result, createModifier(KindPublicKeyword)) + } + if flags&ModifierFlagsPrivate != 0 { + result = append(result, createModifier(KindPrivateKeyword)) + } + if flags&ModifierFlagsProtected != 0 { + result = append(result, createModifier(KindProtectedKeyword)) + } + if flags&ModifierFlagsAbstract != 0 { + result = append(result, createModifier(KindAbstractKeyword)) + } + if flags&ModifierFlagsStatic != 0 { + result = append(result, createModifier(KindStaticKeyword)) + } + if flags&ModifierFlagsOverride != 0 { + result = append(result, createModifier(KindOverrideKeyword)) + } + if flags&ModifierFlagsReadonly != 0 { + result = append(result, createModifier(KindReadonlyKeyword)) + } + if flags&ModifierFlagsAccessor != 0 { + result = append(result, createModifier(KindAccessorKeyword)) + } + if flags&ModifierFlagsAsync != 0 { + result = append(result, createModifier(KindAsyncKeyword)) + } + if flags&ModifierFlagsIn != 0 { + result = append(result, createModifier(KindInKeyword)) + } + if flags&ModifierFlagsOut != 0 { + result = append(result, createModifier(KindOutKeyword)) + } + return result +} + +func GetThisParameter(signature *Node) *Node { + // callback tags do not currently support this parameters + if len(signature.Parameters()) != 0 { + thisParameter := signature.Parameters()[0] + if IsThisParameter(thisParameter) { + return thisParameter + } + } + return nil +} + +func ReplaceModifiers(factory *NodeFactory, node *Node, modifierArray *ModifierList) *Node { + switch node.Kind { + case KindTypeParameter: + return factory.UpdateTypeParameterDeclaration( + node.AsTypeParameter(), + modifierArray, + node.Name(), + node.AsTypeParameter().Constraint, + node.AsTypeParameter().DefaultType, + ) + case KindParameter: + return factory.UpdateParameterDeclaration( + node.AsParameterDeclaration(), + modifierArray, + node.AsParameterDeclaration().DotDotDotToken, + node.Name(), + node.AsParameterDeclaration().QuestionToken, + node.Type(), + node.Initializer(), + ) + case KindConstructorType: + return factory.UpdateConstructorTypeNode( + node.AsConstructorTypeNode(), + modifierArray, + node.TypeParameterList(), + node.ParameterList(), + node.Type(), + ) + case KindPropertySignature: + return factory.UpdatePropertySignatureDeclaration( + node.AsPropertySignatureDeclaration(), + modifierArray, + node.Name(), + node.AsPropertySignatureDeclaration().PostfixToken, + node.Type(), + node.Initializer(), + ) + case KindPropertyDeclaration: + return factory.UpdatePropertyDeclaration( + node.AsPropertyDeclaration(), + modifierArray, + node.Name(), + node.AsPropertyDeclaration().PostfixToken, + node.Type(), + node.Initializer(), + ) + case KindMethodSignature: + return factory.UpdateMethodSignatureDeclaration( + node.AsMethodSignatureDeclaration(), + modifierArray, + node.Name(), + node.AsMethodSignatureDeclaration().PostfixToken, + node.TypeParameterList(), + node.ParameterList(), + node.Type(), + ) + case KindMethodDeclaration: + return factory.UpdateMethodDeclaration( + node.AsMethodDeclaration(), + modifierArray, + node.AsMethodDeclaration().AsteriskToken, + node.Name(), + node.AsMethodDeclaration().PostfixToken, + node.TypeParameterList(), + node.ParameterList(), + node.Type(), + node.AsMethodDeclaration().FullSignature, + node.Body(), + ) + case KindConstructor: + return factory.UpdateConstructorDeclaration( + node.AsConstructorDeclaration(), + modifierArray, + node.TypeParameterList(), + node.ParameterList(), + node.Type(), + node.AsConstructorDeclaration().FullSignature, + node.Body(), + ) + case KindGetAccessor: + return factory.UpdateGetAccessorDeclaration( + node.AsGetAccessorDeclaration(), + modifierArray, + node.Name(), + node.TypeParameterList(), + node.ParameterList(), + node.Type(), + node.AsGetAccessorDeclaration().FullSignature, + node.Body(), + ) + case KindSetAccessor: + return factory.UpdateSetAccessorDeclaration( + node.AsSetAccessorDeclaration(), + modifierArray, + node.Name(), + node.TypeParameterList(), + node.ParameterList(), + node.Type(), + node.AsSetAccessorDeclaration().FullSignature, + node.Body(), + ) + case KindIndexSignature: + return factory.UpdateIndexSignatureDeclaration( + node.AsIndexSignatureDeclaration(), + modifierArray, + node.ParameterList(), + node.Type(), + ) + case KindFunctionExpression: + return factory.UpdateFunctionExpression( + node.AsFunctionExpression(), + modifierArray, + node.AsFunctionExpression().AsteriskToken, + node.Name(), + node.TypeParameterList(), + node.ParameterList(), + node.Type(), + node.AsFunctionExpression().FullSignature, + node.Body(), + ) + case KindArrowFunction: + return factory.UpdateArrowFunction( + node.AsArrowFunction(), + modifierArray, + node.TypeParameterList(), + node.ParameterList(), + node.Type(), + node.AsArrowFunction().FullSignature, + node.AsArrowFunction().EqualsGreaterThanToken, + node.Body(), + ) + case KindClassExpression: + return factory.UpdateClassExpression( + node.AsClassExpression(), + modifierArray, + node.Name(), + node.TypeParameterList(), + node.AsClassExpression().HeritageClauses, + node.MemberList(), + ) + case KindVariableStatement: + return factory.UpdateVariableStatement( + node.AsVariableStatement(), + modifierArray, + node.AsVariableStatement().DeclarationList, + ) + case KindFunctionDeclaration: + return factory.UpdateFunctionDeclaration( + node.AsFunctionDeclaration(), + modifierArray, + node.AsFunctionDeclaration().AsteriskToken, + node.Name(), + node.TypeParameterList(), + node.ParameterList(), + node.Type(), + node.AsFunctionDeclaration().FullSignature, + node.Body(), + ) + case KindClassDeclaration: + return factory.UpdateClassDeclaration( + node.AsClassDeclaration(), + modifierArray, + node.Name(), + node.TypeParameterList(), + node.AsClassDeclaration().HeritageClauses, + node.MemberList(), + ) + case KindInterfaceDeclaration: + return factory.UpdateInterfaceDeclaration( + node.AsInterfaceDeclaration(), + modifierArray, + node.Name(), + node.TypeParameterList(), + node.AsInterfaceDeclaration().HeritageClauses, + node.MemberList(), + ) + case KindTypeAliasDeclaration: + return factory.UpdateTypeAliasDeclaration( + node.AsTypeAliasDeclaration(), + modifierArray, + node.Name(), + node.TypeParameterList(), + node.Type(), + ) + case KindEnumDeclaration: + return factory.UpdateEnumDeclaration( + node.AsEnumDeclaration(), + modifierArray, + node.Name(), + node.MemberList(), + ) + case KindModuleDeclaration: + return factory.UpdateModuleDeclaration( + node.AsModuleDeclaration(), + modifierArray, + node.AsModuleDeclaration().Keyword, + node.Name(), + node.Body(), + ) + case KindImportEqualsDeclaration: + return factory.UpdateImportEqualsDeclaration( + node.AsImportEqualsDeclaration(), + modifierArray, + node.IsTypeOnly(), + node.Name(), + node.AsImportEqualsDeclaration().ModuleReference, + ) + case KindImportDeclaration: + return factory.UpdateImportDeclaration( + node.AsImportDeclaration(), + modifierArray, + node.AsImportDeclaration().ImportClause, + node.AsImportDeclaration().ModuleSpecifier, + node.AsImportDeclaration().Attributes, + ) + case KindExportAssignment: + return factory.UpdateExportAssignment( + node.AsExportAssignment(), + modifierArray, + node.Type(), + node.Expression(), + ) + case KindExportDeclaration: + return factory.UpdateExportDeclaration( + node.AsExportDeclaration(), + modifierArray, + node.IsTypeOnly(), + node.AsExportDeclaration().ExportClause, + node.AsExportDeclaration().ModuleSpecifier, + node.AsExportDeclaration().Attributes, + ) + } + panic(fmt.Sprintf("Node that does not have modifiers tried to have modifier replaced: %d", node.Kind)) +} + +func IsLateVisibilityPaintedStatement(node *Node) bool { + switch node.Kind { + case KindImportDeclaration, + KindJSImportDeclaration, + KindImportEqualsDeclaration, + KindVariableStatement, + KindClassDeclaration, + KindFunctionDeclaration, + KindModuleDeclaration, + KindTypeAliasDeclaration, + KindJSTypeAliasDeclaration, + KindInterfaceDeclaration, + KindEnumDeclaration: + return true + default: + return false + } +} + +func IsExternalModuleAugmentation(node *Node) bool { + return IsAmbientModule(node) && IsModuleAugmentationExternal(node) +} + +func GetSourceFileOfModule(module *Symbol) *SourceFile { + declaration := module.ValueDeclaration + if declaration == nil { + declaration = getNonAugmentationDeclaration(module) + } + return GetSourceFileOfNode(declaration) +} + +func getNonAugmentationDeclaration(symbol *Symbol) *Node { + return core.Find(symbol.Declarations, func(d *Node) bool { + return !IsExternalModuleAugmentation(d) && !IsGlobalScopeAugmentation(d) + }) +} + +func IsTypeDeclaration(node *Node) bool { + switch node.Kind { + case KindTypeParameter, KindClassDeclaration, KindInterfaceDeclaration, KindTypeAliasDeclaration, KindJSTypeAliasDeclaration, KindEnumDeclaration: + return true + case KindImportClause: + return node.AsImportClause().PhaseModifier == KindTypeKeyword + case KindImportSpecifier: + return node.Parent.Parent.AsImportClause().PhaseModifier == KindTypeKeyword + case KindExportSpecifier: + return node.Parent.Parent.AsExportDeclaration().IsTypeOnly + default: + return false + } +} + +func IsTypeDeclarationName(name *Node) bool { + return name.Kind == KindIdentifier && + IsTypeDeclaration(name.Parent) && + GetNameOfDeclaration(name.Parent) == name +} + +func IsRightSideOfQualifiedNameOrPropertyAccess(node *Node) bool { + parent := node.Parent + switch parent.Kind { + case KindQualifiedName: + return parent.AsQualifiedName().Right == node + case KindPropertyAccessExpression: + return parent.AsPropertyAccessExpression().Name() == node + case KindMetaProperty: + return parent.AsMetaProperty().Name() == node + } + return false +} + +func ShouldTransformImportCall(fileName string, options *core.CompilerOptions, impliedNodeFormatForEmit core.ModuleKind) bool { + moduleKind := options.GetEmitModuleKind() + if core.ModuleKindNode16 <= moduleKind && moduleKind <= core.ModuleKindNodeNext || moduleKind == core.ModuleKindPreserve { + return false + } + return impliedNodeFormatForEmit < core.ModuleKindES2015 +} + +func HasQuestionToken(node *Node) bool { + return IsQuestionToken(node.PostfixToken()) +} + +func IsJsxOpeningLikeElement(node *Node) bool { + return IsJsxOpeningElement(node) || IsJsxSelfClosingElement(node) +} + +func GetInvokedExpression(node *Node) *Node { + switch node.Kind { + case KindTaggedTemplateExpression: + return node.AsTaggedTemplateExpression().Tag + case KindJsxOpeningElement, KindJsxSelfClosingElement: + return node.TagName() + case KindBinaryExpression: + return node.AsBinaryExpression().Right + case KindJsxOpeningFragment: + return node + default: + return node.Expression() + } +} + +func IsCallOrNewExpression(node *Node) bool { + return IsCallExpression(node) || IsNewExpression(node) +} + +func IndexOfNode(nodes []*Node, node *Node) int { + index, ok := slices.BinarySearchFunc(nodes, node, compareNodePositions) + if ok { + return index + } + return -1 +} + +func compareNodePositions(n1, n2 *Node) int { + return n1.Pos() - n2.Pos() +} + +func IsUnterminatedLiteral(node *Node) bool { + return IsLiteralKind(node.Kind) && node.LiteralLikeData().TokenFlags&TokenFlagsUnterminated != 0 || + IsTemplateLiteralKind(node.Kind) && node.TemplateLiteralLikeData().TemplateFlags&TokenFlagsUnterminated != 0 +} + +// Gets a value indicating whether a class element is either a static or an instance property declaration with an initializer. +func IsInitializedProperty(member *ClassElement) bool { + return member.Kind == KindPropertyDeclaration && + member.Initializer() != nil +} + +func IsTrivia(token Kind) bool { + return KindFirstTriviaToken <= token && token <= KindLastTriviaToken +} + +func HasDecorators(node *Node) bool { + return HasSyntacticModifier(node, ModifierFlagsDecorator) +} + +type hasFileNameImpl struct { + fileName string + path tspath.Path +} + +func NewHasFileName(fileName string, path tspath.Path) HasFileName { + return &hasFileNameImpl{ + fileName: fileName, + path: path, + } +} + +func (h *hasFileNameImpl) FileName() string { + return h.fileName +} + +func (h *hasFileNameImpl) Path() tspath.Path { + return h.path +} + +func GetSemanticJsxChildren(children []*JsxChild) []*JsxChild { + return core.Filter(children, func(i *JsxChild) bool { + switch i.Kind { + case KindJsxExpression: + return i.Expression() != nil + case KindJsxText: + return !i.AsJsxText().ContainsOnlyTriviaWhiteSpaces + default: + return true + } + }) +} + +// Returns true if the node kind has a comment property. +func hasComment(kind Kind) bool { + switch kind { + case KindJSDoc, KindJSDocTag, KindJSDocAugmentsTag, KindJSDocImplementsTag, + KindJSDocDeprecatedTag, KindJSDocPublicTag, KindJSDocPrivateTag, KindJSDocProtectedTag, + KindJSDocReadonlyTag, KindJSDocOverrideTag, KindJSDocCallbackTag, KindJSDocOverloadTag, + KindJSDocParameterTag, KindJSDocPropertyTag, KindJSDocReturnTag, KindJSDocThisTag, + KindJSDocTypeTag, KindJSDocTemplateTag, KindJSDocTypedefTag, KindJSDocSeeTag, + KindJSDocSatisfiesTag, KindJSDocImportTag: + return true + default: + return false + } +} + +func IsAssignmentPattern(node *Node) bool { + return node.Kind == KindArrayLiteralExpression || node.Kind == KindObjectLiteralExpression +} + +func GetElementsOfBindingOrAssignmentPattern(name *Node) []*Node { + switch name.Kind { + case KindObjectBindingPattern, KindArrayBindingPattern: + // `a` in `{a}` + // `a` in `[a]` + return name.AsBindingPattern().Elements.Nodes + case KindArrayLiteralExpression: + // `a` in `[a]` + return name.AsArrayLiteralExpression().Elements.Nodes + case KindObjectLiteralExpression: + // `a` in `{a}` + return name.AsObjectLiteralExpression().Properties.Nodes + } + return nil +} + +func IsDeclarationBindingElement(bindingElement *Node) bool { + switch bindingElement.Kind { + case KindVariableDeclaration, KindParameter, KindBindingElement: + return true + default: + return false + } +} + +/** + * Gets the name of an BindingOrAssignmentElement. + */ +func GetTargetOfBindingOrAssignmentElement(bindingElement *Node) *Node { + if IsDeclarationBindingElement(bindingElement) { + // `a` in `let { a } = ...` + // `a` in `let { a = 1 } = ...` + // `b` in `let { a: b } = ...` + // `b` in `let { a: b = 1 } = ...` + // `a` in `let { ...a } = ...` + // `{b}` in `let { a: {b} } = ...` + // `{b}` in `let { a: {b} = 1 } = ...` + // `[b]` in `let { a: [b] } = ...` + // `[b]` in `let { a: [b] = 1 } = ...` + // `a` in `let [a] = ...` + // `a` in `let [a = 1] = ...` + // `a` in `let [...a] = ...` + // `{a}` in `let [{a}] = ...` + // `{a}` in `let [{a} = 1] = ...` + // `[a]` in `let [[a]] = ...` + // `[a]` in `let [[a] = 1] = ...` + return bindingElement.Name() + } + + if IsObjectLiteralElement(bindingElement) { + switch bindingElement.Kind { + case KindPropertyAssignment: + // `b` in `({ a: b } = ...)` + // `b` in `({ a: b = 1 } = ...)` + // `{b}` in `({ a: {b} } = ...)` + // `{b}` in `({ a: {b} = 1 } = ...)` + // `[b]` in `({ a: [b] } = ...)` + // `[b]` in `({ a: [b] = 1 } = ...)` + // `b.c` in `({ a: b.c } = ...)` + // `b.c` in `({ a: b.c = 1 } = ...)` + // `b[0]` in `({ a: b[0] } = ...)` + // `b[0]` in `({ a: b[0] = 1 } = ...)` + return GetTargetOfBindingOrAssignmentElement(bindingElement.Initializer()) + case KindShorthandPropertyAssignment: + // `a` in `({ a } = ...)` + // `a` in `({ a = 1 } = ...)` + return bindingElement.Name() + case KindSpreadAssignment: + // `a` in `({ ...a } = ...)` + return GetTargetOfBindingOrAssignmentElement(bindingElement.AsSpreadAssignment().Expression) + } + + // no target + return nil + } + + if IsAssignmentExpression(bindingElement /*excludeCompoundAssignment*/, true) { + // `a` in `[a = 1] = ...` + // `{a}` in `[{a} = 1] = ...` + // `[a]` in `[[a] = 1] = ...` + // `a.b` in `[a.b = 1] = ...` + // `a[0]` in `[a[0] = 1] = ...` + return GetTargetOfBindingOrAssignmentElement(bindingElement.AsBinaryExpression().Left) + } + + if IsSpreadElement(bindingElement) { + // `a` in `[...a] = ...` + return GetTargetOfBindingOrAssignmentElement(bindingElement.AsSpreadElement().Expression) + } + + // `a` in `[a] = ...` + // `{a}` in `[{a}] = ...` + // `[a]` in `[[a]] = ...` + // `a.b` in `[a.b] = ...` + // `a[0]` in `[a[0]] = ...` + return bindingElement +} + +func TryGetPropertyNameOfBindingOrAssignmentElement(bindingElement *Node) *Node { + switch bindingElement.Kind { + case KindBindingElement: + // `a` in `let { a: b } = ...` + // `[a]` in `let { [a]: b } = ...` + // `"a"` in `let { "a": b } = ...` + // `1` in `let { 1: b } = ...` + if bindingElement.AsBindingElement().PropertyName != nil { + propertyName := bindingElement.AsBindingElement().PropertyName + // if ast.IsPrivateIdentifier(propertyName) { + // return Debug.failBadSyntaxKind(propertyName) // !!! + // } + if IsComputedPropertyName(propertyName) && IsStringOrNumericLiteralLike(propertyName.AsComputedPropertyName().Expression) { + return propertyName.AsComputedPropertyName().Expression + } + return propertyName + } + case KindPropertyAssignment: + // `a` in `({ a: b } = ...)` + // `[a]` in `({ [a]: b } = ...)` + // `"a"` in `({ "a": b } = ...)` + // `1` in `({ 1: b } = ...)` + if bindingElement.Name() != nil { + propertyName := bindingElement.Name() + // if ast.IsPrivateIdentifier(propertyName) { + // return Debug.failBadSyntaxKind(propertyName) // !!! + // } + if IsComputedPropertyName(propertyName) && IsStringOrNumericLiteralLike(propertyName.AsComputedPropertyName().Expression) { + return propertyName.AsComputedPropertyName().Expression + } + return propertyName + } + case KindSpreadAssignment: + // `a` in `({ ...a } = ...)` + // if ast.IsPrivateIdentifier(bindingElement.Name()) { + // return Debug.failBadSyntaxKind(bindingElement.Name()) // !!! + // } + return bindingElement.Name() + } + + target := GetTargetOfBindingOrAssignmentElement(bindingElement) + if target != nil && IsPropertyName(target) { + return target + } + return nil +} + +/** + * Walk an AssignmentPattern to determine if it contains object rest (`...`) syntax. We cannot rely on + * propagation of `TransformFlags.ContainsObjectRestOrSpread` since it isn't propagated by default in + * ObjectLiteralExpression and ArrayLiteralExpression since we do not know whether they belong to an + * AssignmentPattern at the time the nodes are parsed. + */ +func ContainsObjectRestOrSpread(node *Node) bool { + if node.SubtreeFacts()&SubtreeContainsObjectRestOrSpread != 0 { + return true + } + if node.SubtreeFacts()&SubtreeContainsESObjectRestOrSpread != 0 { + // check for nested spread assignments, otherwise '{ x: { a, ...b } = foo } = c' + // will not be correctly interpreted by the rest/spread transformer + for _, element := range GetElementsOfBindingOrAssignmentPattern(node) { + target := GetTargetOfBindingOrAssignmentElement(element) + if target != nil && IsAssignmentPattern(target) { + if target.SubtreeFacts()&SubtreeContainsObjectRestOrSpread != 0 { + return true + } + if target.SubtreeFacts()&SubtreeContainsESObjectRestOrSpread != 0 { + if ContainsObjectRestOrSpread(target) { + return true + } + } + } + } + } + return false +} + +func IsEmptyObjectLiteral(expression *Node) bool { + return expression.Kind == KindObjectLiteralExpression && len(expression.AsObjectLiteralExpression().Properties.Nodes) == 0 +} + +func IsEmptyArrayLiteral(expression *Node) bool { + return expression.Kind == KindArrayLiteralExpression && len(expression.AsArrayLiteralExpression().Elements.Nodes) == 0 +} + +func GetRestIndicatorOfBindingOrAssignmentElement(bindingElement *Node) *Node { + switch bindingElement.Kind { + case KindParameter: + return bindingElement.AsParameterDeclaration().DotDotDotToken + case KindBindingElement: + return bindingElement.AsBindingElement().DotDotDotToken + case KindSpreadElement, KindSpreadAssignment: + return bindingElement + } + return nil +} + +func IsJSDocNameReferenceContext(node *Node) bool { + return node.Flags&NodeFlagsJSDoc != 0 && FindAncestor(node, func(node *Node) bool { + return IsJSDocNameReference(node) || IsJSDocLinkLike(node) + }) != nil +} + +func IsImportOrImportEqualsDeclaration(node *Node) bool { + return IsImportDeclaration(node) || IsImportEqualsDeclaration(node) +} + +func IsKeyword(token Kind) bool { + return KindFirstKeyword <= token && token <= KindLastKeyword +} + +func IsNonContextualKeyword(token Kind) bool { + return IsKeyword(token) && !IsContextualKeyword(token) +} + +func HasModifier(node *Node, flags ModifierFlags) bool { + return node.ModifierFlags()&flags != 0 +} + +func IsExpandoInitializer(initializer *Node) bool { + if initializer == nil { + return false + } + if IsFunctionExpressionOrArrowFunction(initializer) { + return true + } + if IsInJSFile(initializer) { + return IsClassExpression(initializer) || (IsObjectLiteralExpression(initializer) && len(initializer.AsObjectLiteralExpression().Properties.Nodes) == 0) + } + return false +} + +func GetContainingFunction(node *Node) *Node { + return FindAncestor(node.Parent, IsFunctionLike) +} diff --git a/kitcom/internal/tsgo/ast/visitor.go b/kitcom/internal/tsgo/ast/visitor.go new file mode 100644 index 0000000..b0b7db5 --- /dev/null +++ b/kitcom/internal/tsgo/ast/visitor.go @@ -0,0 +1,278 @@ +package ast + +import ( + "slices" +) + +// NodeVisitor + +type NodeVisitor struct { + Visit func(node *Node) *Node // Required. The callback used to visit a node + Factory *NodeFactory // Required. The NodeFactory used to produce new nodes when passed to VisitEachChild + Hooks NodeVisitorHooks // Hooks to be invoked when visiting a node +} + +// These hooks are used to intercept the default behavior of the visitor +type NodeVisitorHooks struct { + VisitNode func(node *Node, v *NodeVisitor) *Node // Overrides visiting a Node. Only invoked by the VisitEachChild method on a given Node subtype. + VisitToken func(node *TokenNode, v *NodeVisitor) *Node // Overrides visiting a TokenNode. Only invoked by the VisitEachChild method on a given Node subtype. + VisitNodes func(nodes *NodeList, v *NodeVisitor) *NodeList // Overrides visiting a NodeList. Only invoked by the VisitEachChild method on a given Node subtype. + VisitModifiers func(nodes *ModifierList, v *NodeVisitor) *ModifierList // Overrides visiting a ModifierList. Only invoked by the VisitEachChild method on a given Node subtype. + VisitEmbeddedStatement func(node *Statement, v *NodeVisitor) *Statement // Overrides visiting a Node when it is the embedded statement body of an iteration statement, `if` statement, or `with` statement. Only invoked by the VisitEachChild method on a given Node subtype. + VisitIterationBody func(node *Statement, v *NodeVisitor) *Statement // Overrides visiting a Node when it is the embedded statement body of an iteration statement. Only invoked by the VisitEachChild method on a given Node subtype. + VisitParameters func(nodes *ParameterList, v *NodeVisitor) *ParameterList // Overrides visiting a ParameterList. Only invoked by the VisitEachChild method on a given Node subtype. + VisitFunctionBody func(node *BlockOrExpression, v *NodeVisitor) *BlockOrExpression // Overrides visiting a function body. Only invoked by the VisitEachChild method on a given Node subtype. + VisitTopLevelStatements func(nodes *StatementList, v *NodeVisitor) *StatementList // Overrides visiting a variable environment. Only invoked by the VisitEachChild method on a given Node subtype. +} + +func NewNodeVisitor(visit func(node *Node) *Node, factory *NodeFactory, hooks NodeVisitorHooks) *NodeVisitor { + if factory == nil { + factory = &NodeFactory{} + } + return &NodeVisitor{Visit: visit, Factory: factory, Hooks: hooks} +} + +func (v *NodeVisitor) VisitSourceFile(node *SourceFile) *SourceFile { + return v.VisitNode(node.AsNode()).AsSourceFile() +} + +// Visits a Node, possibly returning a new Node in its place. +// +// - If the input node is nil, then the output is nil. +// - If v.Visit is nil, then the output is the input. +// - If v.Visit returns nil, then the output is nil. +// - If v.Visit returns a SyntaxList Node, then the output is the only child of the SyntaxList Node. +func (v *NodeVisitor) VisitNode(node *Node) *Node { + if node == nil || v.Visit == nil { + return node + } + + if v.Visit != nil { + visited := v.Visit(node) + if visited != nil && visited.Kind == KindSyntaxList { + nodes := visited.AsSyntaxList().Children + if len(nodes) != 1 { + panic("Expected only a single node to be written to output") + } + visited = nodes[0] + if visited != nil && visited.Kind == KindSyntaxList { + panic("The result of visiting and lifting a Node may not be SyntaxList") + } + } + return visited + } + + return node +} + +// Visits an embedded Statement (i.e., the single statement body of a loop, `if..else` branch, etc.), possibly returning a new Statement in its place. +// +// - If the input node is nil, then the output is nil. +// - If v.Visit is nil, then the output is the input. +// - If v.Visit returns nil, then the output is nil. +// - If v.Visit returns a SyntaxList Node, then the output is either the only child of the SyntaxList Node, or a Block containing the nodes in the list. +func (v *NodeVisitor) VisitEmbeddedStatement(node *Statement) *Statement { + if node == nil || v.Visit == nil { + return node + } + + if v.Visit != nil { + return v.liftToBlock(v.Visit(node)) + } + + return node +} + +// Visits a NodeList, possibly returning a new NodeList in its place. +// +// - If the input NodeList is nil, the output is nil. +// - If v.Visit is nil, then the output is the input. +// - If v.Visit returns nil, the visited Node will be absent in the output. +// - If v.Visit returns a different Node than the input, a new NodeList will be generated and returned. +// - If v.Visit returns a SyntaxList Node, then the children of that node will be merged into the output and a new NodeList will be returned. +// - If this method returns a new NodeList for any reason, it will have the same Loc as the input NodeList. +func (v *NodeVisitor) VisitNodes(nodes *NodeList) *NodeList { + if nodes == nil || v.Visit == nil { + return nodes + } + + if result, changed := v.VisitSlice(nodes.Nodes); changed { + list := v.Factory.NewNodeList(result) + list.Loc = nodes.Loc + return list + } + + return nodes +} + +// Visits a ModifierList, possibly returning a new ModifierList in its place. +// +// - If the input ModifierList is nil, the output is nil. +// - If v.Visit is nil, then the output is the input. +// - If v.Visit returns nil, the visited Node will be absent in the output. +// - If v.Visit returns a different Node than the input, a new ModifierList will be generated and returned. +// - If v.Visit returns a SyntaxList Node, then the children of that node will be merged into the output and a new NodeList will be returned. +// - If this method returns a new NodeList for any reason, it will have the same Loc as the input NodeList. +func (v *NodeVisitor) VisitModifiers(nodes *ModifierList) *ModifierList { + if nodes == nil || v.Visit == nil { + return nodes + } + + if result, changed := v.VisitSlice(nodes.Nodes); changed { + list := v.Factory.NewModifierList(result) + list.Loc = nodes.Loc + return list + } + + return nodes +} + +// Visits a slice of Nodes, returning the resulting slice and a value indicating whether the slice was changed. +// +// - If the input slice is nil, the output is nil. +// - If v.Visit is nil, then the output is the input. +// - If v.Visit returns nil, the visited Node will be absent in the output. +// - If v.Visit returns a different Node than the input, a new slice will be generated and returned. +// - If v.Visit returns a SyntaxList Node, then the children of that node will be merged into the output and a new slice will be returned. +func (v *NodeVisitor) VisitSlice(nodes []*Node) (result []*Node, changed bool) { + if nodes == nil || v.Visit == nil { + return nodes, false + } + + for i := 0; i < len(nodes); i++ { + node := nodes[i] + if v.Visit == nil { + break + } + + visited := v.Visit(node) + if visited == nil || visited != node { + updated := slices.Clone(nodes[:i]) + + for { + // finish prior loop + switch { + case visited == nil: // do nothing + case visited.Kind == KindSyntaxList: + updated = append(updated, visited.AsSyntaxList().Children...) + default: + updated = append(updated, visited) + } + + i++ + + // loop over remaining elements + if i >= len(nodes) { + break + } + + if v.Visit != nil { + node = nodes[i] + visited = v.Visit(node) + } else { + updated = append(updated, nodes[i:]...) + break + } + } + + return updated, true + } + } + + return nodes, false +} + +// Visits each child of a Node, possibly returning a new Node of the same kind in its place. +func (v *NodeVisitor) VisitEachChild(node *Node) *Node { + if node == nil || v.Visit == nil { + return node + } + + return node.VisitEachChild(v) +} + +func (v *NodeVisitor) visitNode(node *Node) *Node { + if v.Hooks.VisitNode != nil { + return v.Hooks.VisitNode(node, v) + } + return v.VisitNode(node) +} + +func (v *NodeVisitor) visitEmbeddedStatement(node *Node) *Node { + if v.Hooks.VisitEmbeddedStatement != nil { + return v.Hooks.VisitEmbeddedStatement(node, v) + } + if v.Hooks.VisitNode != nil { + return v.liftToBlock(v.Hooks.VisitNode(node, v)) + } + return v.VisitEmbeddedStatement(node) +} + +func (v *NodeVisitor) visitIterationBody(node *Statement) *Statement { + if v.Hooks.VisitIterationBody != nil { + return v.Hooks.VisitIterationBody(node, v) + } + return v.visitEmbeddedStatement(node) +} + +func (v *NodeVisitor) visitFunctionBody(node *BlockOrExpression) *BlockOrExpression { + if v.Hooks.VisitFunctionBody != nil { + return v.Hooks.VisitFunctionBody(node, v) + } + return v.visitNode(node) +} + +func (v *NodeVisitor) visitToken(node *Node) *Node { + if v.Hooks.VisitToken != nil { + return v.Hooks.VisitToken(node, v) + } + return v.VisitNode(node) +} + +func (v *NodeVisitor) visitNodes(nodes *NodeList) *NodeList { + if v.Hooks.VisitNodes != nil { + return v.Hooks.VisitNodes(nodes, v) + } + return v.VisitNodes(nodes) +} + +func (v *NodeVisitor) visitModifiers(nodes *ModifierList) *ModifierList { + if v.Hooks.VisitModifiers != nil { + return v.Hooks.VisitModifiers(nodes, v) + } + return v.VisitModifiers(nodes) +} + +func (v *NodeVisitor) visitParameters(nodes *ParameterList) *ParameterList { + if v.Hooks.VisitParameters != nil { + return v.Hooks.VisitParameters(nodes, v) + } + return v.visitNodes(nodes) +} + +func (v *NodeVisitor) visitTopLevelStatements(nodes *StatementList) *StatementList { + if v.Hooks.VisitTopLevelStatements != nil { + return v.Hooks.VisitTopLevelStatements(nodes, v) + } + return v.visitNodes(nodes) +} + +func (v *NodeVisitor) liftToBlock(node *Statement) *Statement { + var nodes []*Node + if node != nil { + if node.Kind == KindSyntaxList { + nodes = node.AsSyntaxList().Children + } else { + nodes = []*Node{node} + } + } + if len(nodes) == 1 { + node = nodes[0] + } else { + node = v.Factory.NewBlock(v.Factory.NewNodeList(nodes), true /*multiLine*/) + } + if node.Kind == KindSyntaxList { + panic("The result of visiting and lifting a Node may not be SyntaxList") + } + return node +} diff --git a/kitcom/internal/tsgo/collections/multimap.go b/kitcom/internal/tsgo/collections/multimap.go new file mode 100644 index 0000000..e7df1ae --- /dev/null +++ b/kitcom/internal/tsgo/collections/multimap.go @@ -0,0 +1,69 @@ +package collections + +import ( + "iter" + "maps" + "slices" +) + +type MultiMap[K comparable, V comparable] struct { + M map[K][]V +} + +func GroupBy[K comparable, V comparable](items []V, groupId func(V) K) *MultiMap[K, V] { + m := &MultiMap[K, V]{} + for _, item := range items { + m.Add(groupId(item), item) + } + return m +} + +func (s *MultiMap[K, V]) Has(key K) bool { + _, ok := s.M[key] + return ok +} + +func (s *MultiMap[K, V]) Get(key K) []V { + return s.M[key] +} + +func (s *MultiMap[K, V]) Add(key K, value V) { + if s.M == nil { + s.M = make(map[K][]V) + } + s.M[key] = append(s.M[key], value) +} + +func (s *MultiMap[K, V]) Remove(key K, value V) { + if values, ok := s.M[key]; ok { + i := slices.Index(values, value) + if i >= 0 { + if len(values) == 1 { + delete(s.M, key) + } else { + values = append(values[:i], values[i+1:]...) + s.M[key] = values + } + } + } +} + +func (s *MultiMap[K, V]) RemoveAll(key K) { + delete(s.M, key) +} + +func (s *MultiMap[K, V]) Len() int { + return len(s.M) +} + +func (s *MultiMap[K, V]) Keys() iter.Seq[K] { + return maps.Keys(s.M) +} + +func (s *MultiMap[K, V]) Values() iter.Seq[[]V] { + return maps.Values(s.M) +} + +func (s *MultiMap[K, V]) Clear() { + clear(s.M) +} diff --git a/kitcom/internal/tsgo/collections/ordered_map.go b/kitcom/internal/tsgo/collections/ordered_map.go new file mode 100644 index 0000000..02f0a56 --- /dev/null +++ b/kitcom/internal/tsgo/collections/ordered_map.go @@ -0,0 +1,317 @@ +package collections + +import ( + "encoding" + "errors" + "iter" + "maps" + "reflect" + "slices" + "strconv" + + "github.com/go-json-experiment/json" + "github.com/go-json-experiment/json/jsontext" +) + +// OrderedMap is an insertion ordered map. +type OrderedMap[K comparable, V any] struct { + _ noCopy + keys []K + mp map[K]V +} + +// noCopy may be embedded into structs which must not be copied +// after the first use. +// +// See https://golang.org/issues/8005#issuecomment-190753527 +// for details. +type noCopy struct{} + +// Lock is a no-op used by -copylocks checker from `go vet`. +func (*noCopy) Lock() {} +func (*noCopy) Unlock() {} + +// NewOrderedMapWithSizeHint creates a new OrderedMap with a hint for the number of elements it will contain. +func NewOrderedMapWithSizeHint[K comparable, V any](hint int) *OrderedMap[K, V] { + m := newMapWithSizeHint[K, V](hint) + return &m +} + +func newMapWithSizeHint[K comparable, V any](hint int) OrderedMap[K, V] { + return OrderedMap[K, V]{ + keys: make([]K, 0, hint), + mp: make(map[K]V, hint), + } +} + +type MapEntry[K comparable, V any] struct { + Key K + Value V +} + +func NewOrderedMapFromList[K comparable, V any](items []MapEntry[K, V]) *OrderedMap[K, V] { + mp := NewOrderedMapWithSizeHint[K, V](len(items)) + for _, item := range items { + mp.Set(item.Key, item.Value) + } + return mp +} + +// Set sets a key-value pair in the map. +func (m *OrderedMap[K, V]) Set(key K, value V) { + if m.mp == nil { + m.mp = make(map[K]V) + } + + if _, ok := m.mp[key]; !ok { + m.keys = append(m.keys, key) + } + m.mp[key] = value +} + +// Get retrieves a value from the map. +func (m *OrderedMap[K, V]) Get(key K) (V, bool) { + v, ok := m.mp[key] + return v, ok +} + +// GetOrZero retrieves a value from the map, or returns the zero value of the value type if the key is not present. +func (m *OrderedMap[K, V]) GetOrZero(key K) V { + return m.mp[key] +} + +// EntryAt retrieves the key-value pair at the specified index. +func (m *OrderedMap[K, V]) EntryAt(index int) (K, V, bool) { + if index < 0 || index >= len(m.keys) { + var zero K + var zeroV V + return zero, zeroV, false + } + + key := m.keys[index] + value := m.mp[key] + return key, value, true +} + +// Has returns true if the map contains the key. +func (m *OrderedMap[K, V]) Has(key K) bool { + _, ok := m.mp[key] + return ok +} + +// Delete removes a key-value pair from the map. +func (m *OrderedMap[K, V]) Delete(key K) (V, bool) { + v, ok := m.mp[key] + if !ok { + var zero V + return zero, false + } + + delete(m.mp, key) + i := slices.Index(m.keys, key) + // If we're just removing the first or last element, avoid shifting everything around. + if i == 0 { + var zero K + m.keys[0] = zero + m.keys = m.keys[1:] + } else if end := len(m.keys) - 1; i == end { + var zero K + m.keys[end] = zero + m.keys = m.keys[:end] + } else { + m.keys = slices.Delete(m.keys, i, i+1) + } + + return v, true +} + +// Keys returns an iterator over the keys in the map. +// A slice of the keys can be obtained by calling `slices.Collect`. +func (m *OrderedMap[K, V]) Keys() iter.Seq[K] { + return func(yield func(K) bool) { + if m == nil { + return + } + + // We use a for loop here to ensure we enumerate new items added during iteration. + //nolint:intrange + for i := 0; i < len(m.keys); i++ { + if !yield(m.keys[i]) { + break + } + } + } +} + +// Values returns an iterator over the values in the map. +// A slice of the values can be obtained by calling `slices.Collect`. +func (m *OrderedMap[K, V]) Values() iter.Seq[V] { + return func(yield func(V) bool) { + if m == nil { + return + } + + // We use a for loop here to ensure we enumerate new items added during iteration. + //nolint:intrange + for i := 0; i < len(m.keys); i++ { + if !yield(m.mp[m.keys[i]]) { + break + } + } + } +} + +// Entries returns an iterator over the key-value pairs in the map. +func (m *OrderedMap[K, V]) Entries() iter.Seq2[K, V] { + return func(yield func(K, V) bool) { + if m == nil { + return + } + + // We use a for loop here to ensure we enumerate new items added during iteration. + //nolint:intrange + for i := 0; i < len(m.keys); i++ { + key := m.keys[i] + if !yield(key, m.mp[key]) { + break + } + } + } +} + +// Clear removes all key-value pairs from the map. +// The space allocated for the map will be reused. +func (m *OrderedMap[K, V]) Clear() { + clear(m.keys) + m.keys = m.keys[:0] + clear(m.mp) +} + +// Size returns the number of key-value pairs in the map. +func (m *OrderedMap[K, V]) Size() int { + if m == nil { + return 0 + } + + return len(m.keys) +} + +// Clone returns a shallow copy of the map. +func (m *OrderedMap[K, V]) Clone() *OrderedMap[K, V] { + if m == nil { + return nil + } + + m2 := m.clone() + return &m2 +} + +func (m *OrderedMap[K, V]) clone() OrderedMap[K, V] { + return OrderedMap[K, V]{ + keys: slices.Clone(m.keys), + mp: maps.Clone(m.mp), + } +} + +var _ json.MarshalerTo = (*OrderedMap[string, string])(nil) + +func (m *OrderedMap[K, V]) MarshalJSONTo(enc *jsontext.Encoder) error { + if err := enc.WriteToken(jsontext.BeginObject); err != nil { + return err + } + + for _, k := range m.keys { + // TODO: is this needed? Can we just MarshalEncode k directly? + keyString, err := resolveKeyName(reflect.ValueOf(k)) + if err != nil { + return err + } + + if err := json.MarshalEncode(enc, keyString); err != nil { + return err + } + + if err := json.MarshalEncode(enc, m.mp[k]); err != nil { + return err + } + } + + return enc.WriteToken(jsontext.EndObject) +} + +func resolveKeyName(k reflect.Value) (string, error) { + if k.Kind() == reflect.String { + return k.String(), nil + } + if tm, ok := reflect.TypeAssert[encoding.TextMarshaler](k); ok { + if k.Kind() == reflect.Pointer && k.IsNil() { + return "", nil + } + buf, err := tm.MarshalText() + return string(buf), err + } + switch k.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return strconv.FormatInt(k.Int(), 10), nil + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return strconv.FormatUint(k.Uint(), 10), nil + } + panic("unexpected map key type") +} + +var _ json.UnmarshalerFrom = (*OrderedMap[string, string])(nil) + +func (m *OrderedMap[K, V]) UnmarshalJSONFrom(dec *jsontext.Decoder) error { + token, err := dec.ReadToken() + if err != nil { + return err + } + if token.Kind() == 'n' { // jsontext.Null.Kind() + // By convention, to approximate the behavior of Unmarshal itself, + // Unmarshalers implement UnmarshalJSON([]byte("null")) as a no-op. + // https://pkg.go.dev/encoding/json#Unmarshaler + // TODO: reconsider + return nil + } + if token.Kind() != '{' { // jsontext.ObjectStart.Kind() + return errors.New("cannot unmarshal non-object JSON value into Map") + } + for dec.PeekKind() != '}' { // jsontext.ObjectEnd.Kind() + var key K + var value V + if err := json.UnmarshalDecode(dec, &key); err != nil { + return err + } + if err := json.UnmarshalDecode(dec, &value); err != nil { + return err + } + m.Set(key, value) + } + if _, err := dec.ReadToken(); err != nil { + return err + } + return nil +} + +func DiffOrderedMaps[K comparable, V comparable](m1 *OrderedMap[K, V], m2 *OrderedMap[K, V], onAdded func(key K, value V), onRemoved func(key K, value V), onModified func(key K, oldValue V, newValue V)) { + DiffOrderedMapsFunc(m1, m2, func(a, b V) bool { + return a == b + }, onAdded, onRemoved, onModified) +} + +func DiffOrderedMapsFunc[K comparable, V any](m1 *OrderedMap[K, V], m2 *OrderedMap[K, V], equalValues func(a, b V) bool, onAdded func(key K, value V), onRemoved func(key K, value V), onModified func(key K, oldValue V, newValue V)) { + for k, v2 := range m2.Entries() { + if _, ok := m1.Get(k); !ok { + onAdded(k, v2) + } + } + for k, v1 := range m1.Entries() { + if v2, ok := m2.Get(k); ok { + if !equalValues(v1, v2) { + onModified(k, v1, v2) + } + } else { + onRemoved(k, v1) + } + } +} diff --git a/kitcom/internal/tsgo/collections/ordered_set.go b/kitcom/internal/tsgo/collections/ordered_set.go new file mode 100644 index 0000000..4609627 --- /dev/null +++ b/kitcom/internal/tsgo/collections/ordered_set.go @@ -0,0 +1,54 @@ +package collections + +import "iter" + +// OrderedSet an insertion ordered set. +type OrderedSet[T comparable] struct { + m OrderedMap[T, struct{}] +} + +// NewOrderedSetWithSizeHint creates a new OrderedSet with a hint for the number of elements it will contain. +func NewOrderedSetWithSizeHint[T comparable](hint int) *OrderedSet[T] { + return &OrderedSet[T]{ + m: newMapWithSizeHint[T, struct{}](hint), + } +} + +// Add adds a value to the set. +func (s *OrderedSet[T]) Add(value T) { + s.m.Set(value, struct{}{}) +} + +// Has returns true if the set contains the value. +func (s *OrderedSet[T]) Has(value T) bool { + return s.m.Has(value) +} + +// Delete removes a value from the set. +func (s *OrderedSet[T]) Delete(value T) bool { + _, ok := s.m.Delete(value) + return ok +} + +// Values returns an iterator over the values in the set. +func (s *OrderedSet[T]) Values() iter.Seq[T] { + return s.m.Keys() +} + +// Clear removes all elements from the set. +// The space allocated for the set will be reused. +func (s *OrderedSet[T]) Clear() { + s.m.Clear() +} + +// Size returns the number of elements in the set. +func (s *OrderedSet[T]) Size() int { + return s.m.Size() +} + +// Clone returns a shallow copy of the set. +func (s *OrderedSet[T]) Clone() *OrderedSet[T] { + return &OrderedSet[T]{ + m: s.m.clone(), + } +} diff --git a/kitcom/internal/tsgo/collections/set.go b/kitcom/internal/tsgo/collections/set.go new file mode 100644 index 0000000..6dfd3c9 --- /dev/null +++ b/kitcom/internal/tsgo/collections/set.go @@ -0,0 +1,77 @@ +package collections + +import "maps" + +type Set[T comparable] struct { + M map[T]struct{} +} + +// NewSetWithSizeHint creates a new Set with a hint for the number of elements it will contain. +func NewSetWithSizeHint[T comparable](hint int) *Set[T] { + return &Set[T]{ + M: make(map[T]struct{}, hint), + } +} + +func (s *Set[T]) Has(key T) bool { + _, ok := s.M[key] + return ok +} + +func (s *Set[T]) Add(key T) { + if s.M == nil { + s.M = make(map[T]struct{}) + } + s.M[key] = struct{}{} +} + +func (s *Set[T]) Delete(key T) { + delete(s.M, key) +} + +func (s *Set[T]) Len() int { + return len(s.M) +} + +func (s *Set[T]) Keys() map[T]struct{} { + return s.M +} + +func (s *Set[T]) Clear() { + clear(s.M) +} + +// Returns true if the key was not already present in the set. +func (s *Set[T]) AddIfAbsent(key T) bool { + if s.Has(key) { + return false + } + s.Add(key) + return true +} + +func (s *Set[T]) Clone() *Set[T] { + if s == nil { + return nil + } + clone := &Set[T]{M: maps.Clone(s.M)} + return clone +} + +func (s *Set[T]) Equals(other *Set[T]) bool { + if s == other { + return true + } + if s == nil || other == nil { + return false + } + return maps.Equal(s.M, other.M) +} + +func NewSetFromItems[T comparable](items ...T) *Set[T] { + s := &Set[T]{} + for _, item := range items { + s.Add(item) + } + return s +} diff --git a/kitcom/internal/tsgo/collections/syncmap.go b/kitcom/internal/tsgo/collections/syncmap.go new file mode 100644 index 0000000..9a020bc --- /dev/null +++ b/kitcom/internal/tsgo/collections/syncmap.go @@ -0,0 +1,84 @@ +package collections + +import ( + "iter" + "sync" +) + +type SyncMap[K comparable, V any] struct { + _ [0]K + _ [0]V + m sync.Map +} + +func (s *SyncMap[K, V]) Load(key K) (value V, ok bool) { + val, ok := s.m.Load(key) + if !ok { + return value, ok + } + return val.(V), true +} + +func (s *SyncMap[K, V]) Store(key K, value V) { + s.m.Store(key, value) +} + +func (s *SyncMap[K, V]) LoadOrStore(key K, value V) (actual V, loaded bool) { + actualAny, loaded := s.m.LoadOrStore(key, value) + return actualAny.(V), loaded +} + +func (s *SyncMap[K, V]) Delete(key K) { + s.m.Delete(key) +} + +func (s *SyncMap[K, V]) Clear() { + s.m.Clear() +} + +func (s *SyncMap[K, V]) Range(f func(key K, value V) bool) { + s.m.Range(func(key, value any) bool { + return f(key.(K), value.(V)) + }) +} + +// Size returns the approximate number of items in the map. +// Note that this is not a precise count, as the map may be modified +// concurrently while this method is running. +func (s *SyncMap[K, V]) Size() int { + count := 0 + s.m.Range(func(_, _ any) bool { + count++ + return true + }) + return count +} + +func (s *SyncMap[K, V]) ToMap() map[K]V { + m := make(map[K]V, s.Size()) + s.m.Range(func(key, value any) bool { + m[key.(K)] = value.(V) + return true + }) + return m +} + +func (s *SyncMap[K, V]) Keys() iter.Seq[K] { + return func(yield func(K) bool) { + s.m.Range(func(key, value any) bool { + if !yield(key.(K)) { + return false + } + return true + }) + } +} + +func (s *SyncMap[K, V]) Clone() *SyncMap[K, V] { + clone := &SyncMap[K, V]{} + s.m.Range(func(key, value any) bool { + clone.m.Store(key, value) + return true + }) + return clone +} diff --git a/kitcom/internal/tsgo/collections/syncset.go b/kitcom/internal/tsgo/collections/syncset.go new file mode 100644 index 0000000..74b52fb --- /dev/null +++ b/kitcom/internal/tsgo/collections/syncset.go @@ -0,0 +1,67 @@ +package collections + +import "iter" + +type SyncSet[T comparable] struct { + m SyncMap[T, struct{}] +} + +func (s *SyncSet[T]) Has(key T) bool { + _, ok := s.m.Load(key) + return ok +} + +func (s *SyncSet[T]) Add(key T) { + s.AddIfAbsent(key) +} + +// AddIfAbsent adds the key to the set if it is not already present +// using LoadOrStore. It returns true if the key was not already present +// (opposite of the return value of LoadOrStore). +func (s *SyncSet[T]) AddIfAbsent(key T) bool { + _, loaded := s.m.LoadOrStore(key, struct{}{}) + return !loaded +} + +func (s *SyncSet[T]) Delete(key T) { + s.m.Delete(key) +} + +func (s *SyncSet[T]) Range(fn func(key T) bool) { + s.m.Range(func(key T, value struct{}) bool { + return fn(key) + }) +} + +// Size returns the approximate number of items in the map. +// Note that this is not a precise count, as the map may be modified +// concurrently while this method is running. +func (s *SyncSet[T]) Size() int { + count := 0 + s.m.Range(func(_ T, _ struct{}) bool { + count++ + return true + }) + return count +} + +func (s *SyncSet[T]) ToSlice() []T { + var arr []T + arr = make([]T, 0, s.m.Size()) + s.m.Range(func(key T, value struct{}) bool { + arr = append(arr, key) + return true + }) + return arr +} + +func (s *SyncSet[T]) Keys() iter.Seq[T] { + return func(yield func(T) bool) { + s.m.Range(func(key T, value struct{}) bool { + if !yield(key) { + return false + } + return true + }) + } +} diff --git a/kitcom/internal/tsgo/core/bfs.go b/kitcom/internal/tsgo/core/bfs.go new file mode 100644 index 0000000..f17b17f --- /dev/null +++ b/kitcom/internal/tsgo/core/bfs.go @@ -0,0 +1,206 @@ +package core + +import ( + "math" + "sync" + "sync/atomic" + + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/collections" +) + +type BreadthFirstSearchResult[N any] struct { + Stopped bool + Path []N +} + +type breadthFirstSearchJob[N any] struct { + node N + parent *breadthFirstSearchJob[N] +} + +type BreadthFirstSearchLevel[K comparable, N any] struct { + jobs *collections.OrderedMap[K, *breadthFirstSearchJob[N]] +} + +func (l *BreadthFirstSearchLevel[K, N]) Has(key K) bool { + return l.jobs.Has(key) +} + +func (l *BreadthFirstSearchLevel[K, N]) Delete(key K) { + l.jobs.Delete(key) +} + +func (l *BreadthFirstSearchLevel[K, N]) Range(f func(node N) bool) { + for job := range l.jobs.Values() { + if !f(job.node) { + return + } + } +} + +type BreadthFirstSearchOptions[K comparable, N any] struct { + // Visited is a set of nodes that have already been visited. + // If nil, a new set will be created. + Visited *collections.SyncSet[K] + // PreprocessLevel is a function that, if provided, will be called + // before each level, giving the caller an opportunity to remove nodes. + PreprocessLevel func(*BreadthFirstSearchLevel[K, N]) +} + +// BreadthFirstSearchParallel performs a breadth-first search on a graph +// starting from the given node. It processes nodes in parallel and returns the path +// from the first node that satisfies the `visit` function back to the start node. +func BreadthFirstSearchParallel[N comparable]( + start N, + neighbors func(N) []N, + visit func(node N) (isResult bool, stop bool), +) BreadthFirstSearchResult[N] { + return BreadthFirstSearchParallelEx(start, neighbors, visit, BreadthFirstSearchOptions[N, N]{}, Identity) +} + +// BreadthFirstSearchParallelEx is an extension of BreadthFirstSearchParallel that allows +// the caller to pass a pre-seeded set of already-visited nodes and a preprocessing function +// that can be used to remove nodes from each level before parallel processing. +func BreadthFirstSearchParallelEx[K comparable, N any]( + start N, + neighbors func(N) []N, + visit func(node N) (isResult bool, stop bool), + options BreadthFirstSearchOptions[K, N], + getKey func(N) K, +) BreadthFirstSearchResult[N] { + visited := options.Visited + if visited == nil { + visited = &collections.SyncSet[K]{} + } + + type result struct { + stop bool + job *breadthFirstSearchJob[N] + next *collections.OrderedMap[K, *breadthFirstSearchJob[N]] + } + + var fallback *breadthFirstSearchJob[N] + // processLevel processes each node at the current level in parallel. + // It produces either a list of jobs to be processed in the next level, + // or a result if the visit function returns true for any node. + processLevel := func(index int, jobs *collections.OrderedMap[K, *breadthFirstSearchJob[N]]) result { + var lowestFallback atomic.Int64 + var lowestGoal atomic.Int64 + var nextJobCount atomic.Int64 + lowestGoal.Store(math.MaxInt64) + lowestFallback.Store(math.MaxInt64) + if options.PreprocessLevel != nil { + options.PreprocessLevel(&BreadthFirstSearchLevel[K, N]{jobs: jobs}) + } + next := make([][]*breadthFirstSearchJob[N], jobs.Size()) + var wg sync.WaitGroup + i := 0 + for j := range jobs.Values() { + wg.Add(1) + go func(i int, j *breadthFirstSearchJob[N]) { + defer wg.Done() + if int64(i) >= lowestGoal.Load() { + return // Stop processing if we already found a lower result + } + + // If we have already visited this node, skip it. + if !visited.AddIfAbsent(getKey(j.node)) { + // Note that if we are here, we already visited this node at a + // previous *level*, which means `visit` must have returned false, + // so we don't need to update our result indices. This holds true + // because we deduplicated jobs before queuing the level. + return + } + + isResult, stop := visit(j.node) + if isResult { + // We found a result, so we will stop at this level, but an + // earlier job may still find a true result at a lower index. + if stop { + updateMin(&lowestGoal, int64(i)) + return + } + if fallback == nil { + updateMin(&lowestFallback, int64(i)) + } + } + + if int64(i) >= lowestGoal.Load() { + // If `visit` is expensive, it's likely that by the time we get here, + // a different job has already found a lower index result, so we + // don't even need to collect the next jobs. + return + } + // Add the next level jobs + neighborNodes := neighbors(j.node) + if len(neighborNodes) > 0 { + nextJobCount.Add(int64(len(neighborNodes))) + next[i] = Map(neighborNodes, func(child N) *breadthFirstSearchJob[N] { + return &breadthFirstSearchJob[N]{node: child, parent: j} + }) + } + }(i, j) + i++ + } + wg.Wait() + if index := lowestGoal.Load(); index != math.MaxInt64 { + // If we found a result, return it immediately. + _, job, _ := jobs.EntryAt(int(index)) + return result{stop: true, job: job} + } + if fallback == nil { + if index := lowestFallback.Load(); index != math.MaxInt64 { + _, fallback, _ = jobs.EntryAt(int(index)) + } + } + nextJobs := collections.NewOrderedMapWithSizeHint[K, *breadthFirstSearchJob[N]](int(nextJobCount.Load())) + for _, jobs := range next { + for _, j := range jobs { + if !nextJobs.Has(getKey(j.node)) { + // Deduplicate synchronously to avoid messy locks and spawning + // unnecessary goroutines. + nextJobs.Set(getKey(j.node), j) + } + } + } + return result{next: nextJobs} + } + + createPath := func(job *breadthFirstSearchJob[N]) []N { + var path []N + for job != nil { + path = append(path, job.node) + job = job.parent + } + return path + } + + levelIndex := 0 + level := collections.NewOrderedMapFromList([]collections.MapEntry[K, *breadthFirstSearchJob[N]]{ + {Key: getKey(start), Value: &breadthFirstSearchJob[N]{node: start}}, + }) + for level.Size() > 0 { + result := processLevel(levelIndex, level) + if result.stop { + return BreadthFirstSearchResult[N]{Stopped: true, Path: createPath(result.job)} + } else if result.job != nil && fallback == nil { + fallback = result.job + } + level = result.next + levelIndex++ + } + return BreadthFirstSearchResult[N]{Stopped: false, Path: createPath(fallback)} +} + +// updateMin updates the atomic integer `a` to the candidate value if it is less than the current value. +func updateMin(a *atomic.Int64, candidate int64) bool { + for { + current := a.Load() + if current < candidate { + return false + } + if a.CompareAndSwap(current, candidate) { + return true + } + } +} diff --git a/kitcom/internal/tsgo/core/binarysearch.go b/kitcom/internal/tsgo/core/binarysearch.go new file mode 100644 index 0000000..5c8182c --- /dev/null +++ b/kitcom/internal/tsgo/core/binarysearch.go @@ -0,0 +1,26 @@ +package core + +// BinarySearchUniqueFunc works like [slices.BinarySearchFunc], but avoids extra +// invocations of the comparison function by assuming that only one element +// in the slice could match the target. Also, unlike [slices.BinarySearchFunc], +// the comparison function is passed the current index of the element being +// compared, instead of the target element. +func BinarySearchUniqueFunc[S ~[]E, E any](x S, cmp func(int, E) int) (int, bool) { + n := len(x) + if n == 0 { + return 0, false + } + low, high := 0, n-1 + for low <= high { + middle := low + ((high - low) >> 1) + value := cmp(middle, x[middle]) + if value < 0 { + low = middle + 1 + } else if value > 0 { + high = middle - 1 + } else { + return middle, true + } + } + return low, false +} diff --git a/kitcom/internal/tsgo/core/buildoptions.go b/kitcom/internal/tsgo/core/buildoptions.go new file mode 100644 index 0000000..c7cde75 --- /dev/null +++ b/kitcom/internal/tsgo/core/buildoptions.go @@ -0,0 +1,15 @@ +package core + +type BuildOptions struct { + _ noCopy + + Dry Tristate `json:"dry,omitzero"` + Force Tristate `json:"force,omitzero"` + Verbose Tristate `json:"verbose,omitzero"` + StopBuildOnErrors Tristate `json:"stopBuildOnErrors,omitzero"` + + // CompilerOptions are not parsed here and will be available on ParsedBuildCommandLine + + // Internal fields + Clean Tristate `json:"clean,omitzero"` +} diff --git a/kitcom/internal/tsgo/core/compileroptions.go b/kitcom/internal/tsgo/core/compileroptions.go new file mode 100644 index 0000000..608afa2 --- /dev/null +++ b/kitcom/internal/tsgo/core/compileroptions.go @@ -0,0 +1,545 @@ +package core + +import ( + "reflect" + "strings" + "sync" + + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/collections" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/tspath" +) + +//go:generate go tool golang.org/x/tools/cmd/stringer -type=ModuleKind -trimprefix=ModuleKind -output=modulekind_stringer_generated.go +//go:generate go tool golang.org/x/tools/cmd/stringer -type=ScriptTarget -trimprefix=ScriptTarget -output=scripttarget_stringer_generated.go +//go:generate go tool mvdan.cc/gofumpt -w modulekind_stringer_generated.go scripttarget_stringer_generated.go + +type CompilerOptions struct { + _ noCopy + + AllowJs Tristate `json:"allowJs,omitzero"` + AllowArbitraryExtensions Tristate `json:"allowArbitraryExtensions,omitzero"` + AllowSyntheticDefaultImports Tristate `json:"allowSyntheticDefaultImports,omitzero"` + AllowImportingTsExtensions Tristate `json:"allowImportingTsExtensions,omitzero"` + AllowNonTsExtensions Tristate `json:"allowNonTsExtensions,omitzero"` + AllowUmdGlobalAccess Tristate `json:"allowUmdGlobalAccess,omitzero"` + AllowUnreachableCode Tristate `json:"allowUnreachableCode,omitzero"` + AllowUnusedLabels Tristate `json:"allowUnusedLabels,omitzero"` + AssumeChangesOnlyAffectDirectDependencies Tristate `json:"assumeChangesOnlyAffectDirectDependencies,omitzero"` + AlwaysStrict Tristate `json:"alwaysStrict,omitzero"` + CheckJs Tristate `json:"checkJs,omitzero"` + CustomConditions []string `json:"customConditions,omitzero"` + Composite Tristate `json:"composite,omitzero"` + EmitDeclarationOnly Tristate `json:"emitDeclarationOnly,omitzero"` + EmitBOM Tristate `json:"emitBOM,omitzero"` + EmitDecoratorMetadata Tristate `json:"emitDecoratorMetadata,omitzero"` + DownlevelIteration Tristate `json:"downlevelIteration,omitzero"` + Declaration Tristate `json:"declaration,omitzero"` + DeclarationDir string `json:"declarationDir,omitzero"` + DeclarationMap Tristate `json:"declarationMap,omitzero"` + DisableSizeLimit Tristate `json:"disableSizeLimit,omitzero"` + DisableSourceOfProjectReferenceRedirect Tristate `json:"disableSourceOfProjectReferenceRedirect,omitzero"` + DisableSolutionSearching Tristate `json:"disableSolutionSearching,omitzero"` + DisableReferencedProjectLoad Tristate `json:"disableReferencedProjectLoad,omitzero"` + ErasableSyntaxOnly Tristate `json:"erasableSyntaxOnly,omitzero"` + ESModuleInterop Tristate `json:"esModuleInterop,omitzero"` + ExactOptionalPropertyTypes Tristate `json:"exactOptionalPropertyTypes,omitzero"` + ExperimentalDecorators Tristate `json:"experimentalDecorators,omitzero"` + ForceConsistentCasingInFileNames Tristate `json:"forceConsistentCasingInFileNames,omitzero"` + IsolatedModules Tristate `json:"isolatedModules,omitzero"` + IsolatedDeclarations Tristate `json:"isolatedDeclarations,omitzero"` + IgnoreDeprecations string `json:"ignoreDeprecations,omitzero"` + ImportHelpers Tristate `json:"importHelpers,omitzero"` + InlineSourceMap Tristate `json:"inlineSourceMap,omitzero"` + InlineSources Tristate `json:"inlineSources,omitzero"` + Init Tristate `json:"init,omitzero"` + Incremental Tristate `json:"incremental,omitzero"` + Jsx JsxEmit `json:"jsx,omitzero"` + JsxFactory string `json:"jsxFactory,omitzero"` + JsxFragmentFactory string `json:"jsxFragmentFactory,omitzero"` + JsxImportSource string `json:"jsxImportSource,omitzero"` + Lib []string `json:"lib,omitzero"` + LibReplacement Tristate `json:"libReplacement,omitzero"` + Locale string `json:"locale,omitzero"` + MapRoot string `json:"mapRoot,omitzero"` + Module ModuleKind `json:"module,omitzero"` + ModuleResolution ModuleResolutionKind `json:"moduleResolution,omitzero"` + ModuleSuffixes []string `json:"moduleSuffixes,omitzero"` + ModuleDetection ModuleDetectionKind `json:"moduleDetection,omitzero"` + NewLine NewLineKind `json:"newLine,omitzero"` + NoEmit Tristate `json:"noEmit,omitzero"` + NoCheck Tristate `json:"noCheck,omitzero"` + NoErrorTruncation Tristate `json:"noErrorTruncation,omitzero"` + NoFallthroughCasesInSwitch Tristate `json:"noFallthroughCasesInSwitch,omitzero"` + NoImplicitAny Tristate `json:"noImplicitAny,omitzero"` + NoImplicitThis Tristate `json:"noImplicitThis,omitzero"` + NoImplicitReturns Tristate `json:"noImplicitReturns,omitzero"` + NoEmitHelpers Tristate `json:"noEmitHelpers,omitzero"` + NoLib Tristate `json:"noLib,omitzero"` + NoPropertyAccessFromIndexSignature Tristate `json:"noPropertyAccessFromIndexSignature,omitzero"` + NoUncheckedIndexedAccess Tristate `json:"noUncheckedIndexedAccess,omitzero"` + NoEmitOnError Tristate `json:"noEmitOnError,omitzero"` + NoUnusedLocals Tristate `json:"noUnusedLocals,omitzero"` + NoUnusedParameters Tristate `json:"noUnusedParameters,omitzero"` + NoResolve Tristate `json:"noResolve,omitzero"` + NoImplicitOverride Tristate `json:"noImplicitOverride,omitzero"` + NoUncheckedSideEffectImports Tristate `json:"noUncheckedSideEffectImports,omitzero"` + OutDir string `json:"outDir,omitzero"` + Paths *collections.OrderedMap[string, []string] `json:"paths,omitzero"` + PreserveConstEnums Tristate `json:"preserveConstEnums,omitzero"` + PreserveSymlinks Tristate `json:"preserveSymlinks,omitzero"` + Project string `json:"project,omitzero"` + ResolveJsonModule Tristate `json:"resolveJsonModule,omitzero"` + ResolvePackageJsonExports Tristate `json:"resolvePackageJsonExports,omitzero"` + ResolvePackageJsonImports Tristate `json:"resolvePackageJsonImports,omitzero"` + RemoveComments Tristate `json:"removeComments,omitzero"` + RewriteRelativeImportExtensions Tristate `json:"rewriteRelativeImportExtensions,omitzero"` + ReactNamespace string `json:"reactNamespace,omitzero"` + RootDir string `json:"rootDir,omitzero"` + RootDirs []string `json:"rootDirs,omitzero"` + SkipLibCheck Tristate `json:"skipLibCheck,omitzero"` + Strict Tristate `json:"strict,omitzero"` + StrictBindCallApply Tristate `json:"strictBindCallApply,omitzero"` + StrictBuiltinIteratorReturn Tristate `json:"strictBuiltinIteratorReturn,omitzero"` + StrictFunctionTypes Tristate `json:"strictFunctionTypes,omitzero"` + StrictNullChecks Tristate `json:"strictNullChecks,omitzero"` + StrictPropertyInitialization Tristate `json:"strictPropertyInitialization,omitzero"` + StripInternal Tristate `json:"stripInternal,omitzero"` + SkipDefaultLibCheck Tristate `json:"skipDefaultLibCheck,omitzero"` + SourceMap Tristate `json:"sourceMap,omitzero"` + SourceRoot string `json:"sourceRoot,omitzero"` + SuppressOutputPathCheck Tristate `json:"suppressOutputPathCheck,omitzero"` + Target ScriptTarget `json:"target,omitzero"` + TraceResolution Tristate `json:"traceResolution,omitzero"` + TsBuildInfoFile string `json:"tsBuildInfoFile,omitzero"` + TypeRoots []string `json:"typeRoots,omitzero"` + Types []string `json:"types,omitzero"` + UseDefineForClassFields Tristate `json:"useDefineForClassFields,omitzero"` + UseUnknownInCatchVariables Tristate `json:"useUnknownInCatchVariables,omitzero"` + VerbatimModuleSyntax Tristate `json:"verbatimModuleSyntax,omitzero"` + MaxNodeModuleJsDepth *int `json:"maxNodeModuleJsDepth,omitzero"` + + // Deprecated: Do not use outside of options parsing and validation. + BaseUrl string `json:"baseUrl,omitzero"` + // Deprecated: Do not use outside of options parsing and validation. + OutFile string `json:"outFile,omitzero"` + + // Internal fields + ConfigFilePath string `json:"configFilePath,omitzero"` + NoDtsResolution Tristate `json:"noDtsResolution,omitzero"` + PathsBasePath string `json:"pathsBasePath,omitzero"` + Diagnostics Tristate `json:"diagnostics,omitzero"` + ExtendedDiagnostics Tristate `json:"extendedDiagnostics,omitzero"` + GenerateCpuProfile string `json:"generateCpuProfile,omitzero"` + GenerateTrace string `json:"generateTrace,omitzero"` + ListEmittedFiles Tristate `json:"listEmittedFiles,omitzero"` + ListFiles Tristate `json:"listFiles,omitzero"` + ExplainFiles Tristate `json:"explainFiles,omitzero"` + ListFilesOnly Tristate `json:"listFilesOnly,omitzero"` + NoEmitForJsFiles Tristate `json:"noEmitForJsFiles,omitzero"` + PreserveWatchOutput Tristate `json:"preserveWatchOutput,omitzero"` + Pretty Tristate `json:"pretty,omitzero"` + Version Tristate `json:"version,omitzero"` + Watch Tristate `json:"watch,omitzero"` + ShowConfig Tristate `json:"showConfig,omitzero"` + Build Tristate `json:"build,omitzero"` + Help Tristate `json:"help,omitzero"` + All Tristate `json:"all,omitzero"` + + PprofDir string `json:"pprofDir,omitzero"` + SingleThreaded Tristate `json:"singleThreaded,omitzero"` + Quiet Tristate `json:"quiet,omitzero"` + + sourceFileAffectingCompilerOptionsOnce sync.Once + sourceFileAffectingCompilerOptions SourceFileAffectingCompilerOptions +} + +// noCopy may be embedded into structs which must not be copied +// after the first use. +// +// See https://golang.org/issues/8005#issuecomment-190753527 +// for details. +type noCopy struct{} + +// Lock is a no-op used by -copylocks checker from `go vet`. +func (*noCopy) Lock() {} +func (*noCopy) Unlock() {} + +var optionsType = reflect.TypeFor[CompilerOptions]() + +// Clone creates a shallow copy of the CompilerOptions. +func (options *CompilerOptions) Clone() *CompilerOptions { + // TODO: this could be generated code instead of reflection. + target := &CompilerOptions{} + + sourceValue := reflect.ValueOf(options).Elem() + targetValue := reflect.ValueOf(target).Elem() + + for i := range sourceValue.NumField() { + if optionsType.Field(i).IsExported() { + targetValue.Field(i).Set(sourceValue.Field(i)) + } + } + + return target +} + +func (options *CompilerOptions) GetEmitScriptTarget() ScriptTarget { + if options.Target != ScriptTargetNone { + return options.Target + } + switch options.GetEmitModuleKind() { + case ModuleKindNode16, ModuleKindNode18: + return ScriptTargetES2022 + case ModuleKindNode20: + return ScriptTargetES2023 + case ModuleKindNodeNext: + return ScriptTargetESNext + default: + return ScriptTargetES5 + } +} + +func (options *CompilerOptions) GetEmitModuleKind() ModuleKind { + if options.Module != ModuleKindNone { + return options.Module + } + if options.Target >= ScriptTargetES2015 { + return ModuleKindES2015 + } + return ModuleKindCommonJS +} + +func (options *CompilerOptions) GetModuleResolutionKind() ModuleResolutionKind { + if options.ModuleResolution != ModuleResolutionKindUnknown { + return options.ModuleResolution + } + switch options.GetEmitModuleKind() { + case ModuleKindNode16, ModuleKindNode18, ModuleKindNode20: + return ModuleResolutionKindNode16 + case ModuleKindNodeNext: + return ModuleResolutionKindNodeNext + default: + return ModuleResolutionKindBundler + } +} + +func (options *CompilerOptions) GetEmitModuleDetectionKind() ModuleDetectionKind { + if options.ModuleDetection != ModuleDetectionKindNone { + return options.ModuleDetection + } + switch options.GetEmitModuleKind() { + case ModuleKindNode16, ModuleKindNode20, ModuleKindNodeNext: + return ModuleDetectionKindForce + default: + return ModuleDetectionKindAuto + } +} + +func (options *CompilerOptions) GetResolvePackageJsonExports() bool { + return options.ResolvePackageJsonExports.IsTrueOrUnknown() +} + +func (options *CompilerOptions) GetResolvePackageJsonImports() bool { + return options.ResolvePackageJsonImports.IsTrueOrUnknown() +} + +func (options *CompilerOptions) GetAllowImportingTsExtensions() bool { + return options.AllowImportingTsExtensions.IsTrue() || options.RewriteRelativeImportExtensions.IsTrue() +} + +func (options *CompilerOptions) AllowImportingTsExtensionsFrom(fileName string) bool { + return options.GetAllowImportingTsExtensions() || tspath.IsDeclarationFileName(fileName) +} + +func (options *CompilerOptions) GetESModuleInterop() bool { + if options.ESModuleInterop != TSUnknown { + return options.ESModuleInterop == TSTrue + } + switch options.GetEmitModuleKind() { + case ModuleKindNode16, ModuleKindNode18, ModuleKindNode20, ModuleKindNodeNext, ModuleKindPreserve: + return true + } + return false +} + +func (options *CompilerOptions) GetAllowSyntheticDefaultImports() bool { + if options.AllowSyntheticDefaultImports != TSUnknown { + return options.AllowSyntheticDefaultImports == TSTrue + } + return options.GetESModuleInterop() || + options.GetEmitModuleKind() == ModuleKindSystem || + options.GetModuleResolutionKind() == ModuleResolutionKindBundler +} + +func (options *CompilerOptions) GetResolveJsonModule() bool { + if options.ResolveJsonModule != TSUnknown { + return options.ResolveJsonModule == TSTrue + } + switch options.GetEmitModuleKind() { + // TODO in 6.0: add Node16/Node18 + case ModuleKindNode20, ModuleKindESNext: + return true + } + return options.GetModuleResolutionKind() == ModuleResolutionKindBundler +} + +func (options *CompilerOptions) ShouldPreserveConstEnums() bool { + return options.PreserveConstEnums == TSTrue || options.GetIsolatedModules() +} + +func (options *CompilerOptions) GetAllowJS() bool { + if options.AllowJs != TSUnknown { + return options.AllowJs == TSTrue + } + return options.CheckJs == TSTrue +} + +func (options *CompilerOptions) GetJSXTransformEnabled() bool { + jsx := options.Jsx + return jsx == JsxEmitReact || jsx == JsxEmitReactJSX || jsx == JsxEmitReactJSXDev +} + +func (options *CompilerOptions) GetStrictOptionValue(value Tristate) bool { + if value != TSUnknown { + return value == TSTrue + } + return options.Strict == TSTrue +} + +func (options *CompilerOptions) GetEffectiveTypeRoots(currentDirectory string) (result []string, fromConfig bool) { + if options.TypeRoots != nil { + return options.TypeRoots, true + } + var baseDir string + if options.ConfigFilePath != "" { + baseDir = tspath.GetDirectoryPath(options.ConfigFilePath) + } else { + baseDir = currentDirectory + if baseDir == "" { + // This was accounted for in the TS codebase, but only for third-party API usage + // where the module resolution host does not provide a getCurrentDirectory(). + panic("cannot get effective type roots without a config file path or current directory") + } + } + + typeRoots := make([]string, 0, strings.Count(baseDir, "/")) + tspath.ForEachAncestorDirectory(baseDir, func(dir string) (any, bool) { + typeRoots = append(typeRoots, tspath.CombinePaths(dir, "node_modules", "@types")) + return nil, false + }) + return typeRoots, false +} + +func (options *CompilerOptions) GetIsolatedModules() bool { + return options.IsolatedModules == TSTrue || options.VerbatimModuleSyntax == TSTrue +} + +func (options *CompilerOptions) IsIncremental() bool { + return options.Incremental.IsTrue() || options.Composite.IsTrue() +} + +func (options *CompilerOptions) GetEmitStandardClassFields() bool { + return options.UseDefineForClassFields != TSFalse && options.GetEmitScriptTarget() >= ScriptTargetES2022 +} + +func (options *CompilerOptions) GetEmitDeclarations() bool { + return options.Declaration.IsTrue() || options.Composite.IsTrue() +} + +func (options *CompilerOptions) GetAreDeclarationMapsEnabled() bool { + return options.DeclarationMap == TSTrue && options.GetEmitDeclarations() +} + +func (options *CompilerOptions) HasJsonModuleEmitEnabled() bool { + switch options.GetEmitModuleKind() { + case ModuleKindNone, ModuleKindSystem, ModuleKindUMD: + return false + } + return true +} + +func (options *CompilerOptions) GetPathsBasePath(currentDirectory string) string { + if options.Paths.Size() == 0 { + return "" + } + if options.PathsBasePath != "" { + return options.PathsBasePath + } + return currentDirectory +} + +// SourceFileAffectingCompilerOptions are the precomputed CompilerOptions values which +// affect the parse and bind of a source file. +type SourceFileAffectingCompilerOptions struct { + AllowUnreachableCode Tristate + AllowUnusedLabels Tristate + BindInStrictMode bool + ShouldPreserveConstEnums bool +} + +func (options *CompilerOptions) SourceFileAffecting() SourceFileAffectingCompilerOptions { + options.sourceFileAffectingCompilerOptionsOnce.Do(func() { + options.sourceFileAffectingCompilerOptions = SourceFileAffectingCompilerOptions{ + AllowUnreachableCode: options.AllowUnreachableCode, + AllowUnusedLabels: options.AllowUnusedLabels, + BindInStrictMode: options.AlwaysStrict.IsTrue() || options.Strict.IsTrue(), + ShouldPreserveConstEnums: options.ShouldPreserveConstEnums(), + } + }) + return options.sourceFileAffectingCompilerOptions +} + +type ModuleDetectionKind int32 + +const ( + ModuleDetectionKindNone ModuleDetectionKind = 0 + ModuleDetectionKindAuto ModuleDetectionKind = 1 + ModuleDetectionKindLegacy ModuleDetectionKind = 2 + ModuleDetectionKindForce ModuleDetectionKind = 3 +) + +type ModuleKind int32 + +const ( + ModuleKindNone ModuleKind = 0 + ModuleKindCommonJS ModuleKind = 1 + // Deprecated: Do not use outside of options parsing and validation. + ModuleKindAMD ModuleKind = 2 + // Deprecated: Do not use outside of options parsing and validation. + ModuleKindUMD ModuleKind = 3 + // Deprecated: Do not use outside of options parsing and validation. + ModuleKindSystem ModuleKind = 4 + // NOTE: ES module kinds should be contiguous to more easily check whether a module kind is *any* ES module kind. + // Non-ES module kinds should not come between ES2015 (the earliest ES module kind) and ESNext (the last ES + // module kind). + ModuleKindES2015 ModuleKind = 5 + ModuleKindES2020 ModuleKind = 6 + ModuleKindES2022 ModuleKind = 7 + ModuleKindESNext ModuleKind = 99 + // Node16+ is an amalgam of commonjs (albeit updated) and es2022+, and represents a distinct module system from es2020/esnext + ModuleKindNode16 ModuleKind = 100 + ModuleKindNode18 ModuleKind = 101 + ModuleKindNode20 ModuleKind = 102 + ModuleKindNodeNext ModuleKind = 199 + // Emit as written + ModuleKindPreserve ModuleKind = 200 +) + +func (moduleKind ModuleKind) IsNonNodeESM() bool { + return moduleKind >= ModuleKindES2015 && moduleKind <= ModuleKindESNext +} + +func (moduleKind ModuleKind) SupportsImportAttributes() bool { + return ModuleKindNode18 <= moduleKind && moduleKind <= ModuleKindNodeNext || + moduleKind == ModuleKindPreserve || + moduleKind == ModuleKindESNext +} + +type ResolutionMode = ModuleKind // ModuleKindNone | ModuleKindCommonJS | ModuleKindESNext + +const ( + ResolutionModeNone = ModuleKindNone + ResolutionModeCommonJS = ModuleKindCommonJS + ResolutionModeESM = ModuleKindESNext +) + +type ModuleResolutionKind int32 + +const ( + ModuleResolutionKindUnknown ModuleResolutionKind = 0 + // Starting with node16, node's module resolver has significant departures from traditional cjs resolution + // to better support ECMAScript modules and their use within node - however more features are still being added. + // TypeScript's Node ESM support was introduced after Node 12 went end-of-life, and Node 14 is the earliest stable + // version that supports both pattern trailers - *but*, Node 16 is the first version that also supports ECMAScript 2022. + // In turn, we offer both a `NodeNext` moving resolution target, and a `Node16` version-anchored resolution target + ModuleResolutionKindNode16 ModuleResolutionKind = 3 + ModuleResolutionKindNodeNext ModuleResolutionKind = 99 // Not simply `Node16` so that compiled code linked against TS can use the `Next` value reliably (same as with `ModuleKind`) + ModuleResolutionKindBundler ModuleResolutionKind = 100 +) + +var ModuleKindToModuleResolutionKind = map[ModuleKind]ModuleResolutionKind{ + ModuleKindNode16: ModuleResolutionKindNode16, + ModuleKindNodeNext: ModuleResolutionKindNodeNext, +} + +// We don't use stringer on this for now, because these values +// are user-facing in --traceResolution, and stringer currently +// lacks the ability to remove the "ModuleResolutionKind" prefix +// when generating code for multiple types into the same output +// file. Additionally, since there's no TS equivalent of +// `ModuleResolutionKindUnknown`, we want to panic on that case, +// as it probably represents a mistake when porting TS to Go. +func (m ModuleResolutionKind) String() string { + switch m { + case ModuleResolutionKindUnknown: + panic("should not use zero value of ModuleResolutionKind") + case ModuleResolutionKindNode16: + return "Node16" + case ModuleResolutionKindNodeNext: + return "NodeNext" + case ModuleResolutionKindBundler: + return "Bundler" + default: + panic("unhandled case in ModuleResolutionKind.String") + } +} + +type NewLineKind int32 + +const ( + NewLineKindNone NewLineKind = 0 + NewLineKindCRLF NewLineKind = 1 + NewLineKindLF NewLineKind = 2 +) + +func GetNewLineKind(s string) NewLineKind { + switch s { + case "\r\n": + return NewLineKindCRLF + case "\n": + return NewLineKindLF + default: + return NewLineKindNone + } +} + +func (newLine NewLineKind) GetNewLineCharacter() string { + switch newLine { + case NewLineKindCRLF: + return "\r\n" + default: + return "\n" + } +} + +type ScriptTarget int32 + +const ( + ScriptTargetNone ScriptTarget = 0 + ScriptTargetES3 ScriptTarget = 0 // Deprecated + ScriptTargetES5 ScriptTarget = 1 + ScriptTargetES2015 ScriptTarget = 2 + ScriptTargetES2016 ScriptTarget = 3 + ScriptTargetES2017 ScriptTarget = 4 + ScriptTargetES2018 ScriptTarget = 5 + ScriptTargetES2019 ScriptTarget = 6 + ScriptTargetES2020 ScriptTarget = 7 + ScriptTargetES2021 ScriptTarget = 8 + ScriptTargetES2022 ScriptTarget = 9 + ScriptTargetES2023 ScriptTarget = 10 + ScriptTargetES2024 ScriptTarget = 11 + ScriptTargetESNext ScriptTarget = 99 + ScriptTargetJSON ScriptTarget = 100 + ScriptTargetLatest ScriptTarget = ScriptTargetESNext +) + +type JsxEmit int32 + +const ( + JsxEmitNone JsxEmit = 0 + JsxEmitPreserve JsxEmit = 1 + JsxEmitReactNative JsxEmit = 2 + JsxEmitReact JsxEmit = 3 + JsxEmitReactJSX JsxEmit = 4 + JsxEmitReactJSXDev JsxEmit = 5 +) diff --git a/kitcom/internal/tsgo/core/context.go b/kitcom/internal/tsgo/core/context.go new file mode 100644 index 0000000..ddd0192 --- /dev/null +++ b/kitcom/internal/tsgo/core/context.go @@ -0,0 +1,36 @@ +package core + +import ( + "context" + + "golang.org/x/text/language" +) + +type key int + +const ( + requestIDKey key = iota + localeKey +) + +func WithRequestID(ctx context.Context, id string) context.Context { + return context.WithValue(ctx, requestIDKey, id) +} + +func GetRequestID(ctx context.Context) string { + if id, ok := ctx.Value(requestIDKey).(string); ok { + return id + } + return "" +} + +func WithLocale(ctx context.Context, locale language.Tag) context.Context { + return context.WithValue(ctx, localeKey, locale) +} + +func GetLocale(ctx context.Context) language.Tag { + if locale, ok := ctx.Value(localeKey).(language.Tag); ok { + return locale + } + return language.Und +} diff --git a/kitcom/internal/tsgo/core/core.go b/kitcom/internal/tsgo/core/core.go new file mode 100644 index 0000000..e4c15ca --- /dev/null +++ b/kitcom/internal/tsgo/core/core.go @@ -0,0 +1,689 @@ +package core + +import ( + "iter" + "maps" + "math" + "slices" + "sort" + "strings" + "sync" + "unicode" + "unicode/utf8" + + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/debug" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/jsonutil" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/stringutil" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/tspath" +) + +func Filter[T any](slice []T, f func(T) bool) []T { + for i, value := range slice { + if !f(value) { + result := slices.Clone(slice[:i]) + for i++; i < len(slice); i++ { + value = slice[i] + if f(value) { + result = append(result, value) + } + } + return result + } + } + return slice +} + +func FilterIndex[T any](slice []T, f func(T, int, []T) bool) []T { + for i, value := range slice { + if !f(value, i, slice) { + result := slices.Clone(slice[:i]) + for i++; i < len(slice); i++ { + value = slice[i] + if f(value, i, slice) { + result = append(result, value) + } + } + return result + } + } + return slice +} + +func Map[T, U any](slice []T, f func(T) U) []U { + if slice == nil { + return nil + } + result := make([]U, len(slice)) + for i, value := range slice { + result[i] = f(value) + } + return result +} + +func TryMap[T, U any](slice []T, f func(T) (U, error)) ([]U, error) { + if len(slice) == 0 { + return nil, nil + } + result := make([]U, len(slice)) + for i, value := range slice { + mapped, err := f(value) + if err != nil { + return nil, err + } + result[i] = mapped + } + return result, nil +} + +func MapIndex[T, U any](slice []T, f func(T, int) U) []U { + if slice == nil { + return nil + } + result := make([]U, len(slice)) + for i, value := range slice { + result[i] = f(value, i) + } + return result +} + +func MapNonNil[T any, U comparable](slice []T, f func(T) U) []U { + var result []U + for _, value := range slice { + mapped := f(value) + if mapped != *new(U) { + result = append(result, mapped) + } + } + return result +} + +func MapFiltered[T any, U any](slice []T, f func(T) (U, bool)) []U { + var result []U + for _, value := range slice { + mapped, ok := f(value) + if !ok { + continue + } + result = append(result, mapped) + } + return result +} + +func FlatMap[T any, U comparable](slice []T, f func(T) []U) []U { + var result []U + for _, value := range slice { + mapped := f(value) + if len(mapped) != 0 { + result = append(result, mapped...) + } + } + return result +} + +func SameMap[T comparable](slice []T, f func(T) T) []T { + for i, value := range slice { + mapped := f(value) + if mapped != value { + result := make([]T, len(slice)) + copy(result, slice[:i]) + result[i] = mapped + for j := i + 1; j < len(slice); j++ { + result[j] = f(slice[j]) + } + return result + } + } + return slice +} + +func SameMapIndex[T comparable](slice []T, f func(T, int) T) []T { + for i, value := range slice { + mapped := f(value, i) + if mapped != value { + result := make([]T, len(slice)) + copy(result, slice[:i]) + result[i] = mapped + for j := i + 1; j < len(slice); j++ { + result[j] = f(slice[j], j) + } + return result + } + } + return slice +} + +func Same[T any](s1 []T, s2 []T) bool { + if len(s1) == len(s2) { + return len(s1) == 0 || &s1[0] == &s2[0] + } + return false +} + +func Some[T any](slice []T, f func(T) bool) bool { + for _, value := range slice { + if f(value) { + return true + } + } + return false +} + +func Every[T any](slice []T, f func(T) bool) bool { + for _, value := range slice { + if !f(value) { + return false + } + } + return true +} + +func Or[T any](funcs ...func(T) bool) func(T) bool { + return func(input T) bool { + for _, f := range funcs { + if f(input) { + return true + } + } + return false + } +} + +func Find[T any](slice []T, f func(T) bool) T { + for _, value := range slice { + if f(value) { + return value + } + } + return *new(T) +} + +func FindLast[T any](slice []T, f func(T) bool) T { + for i := len(slice) - 1; i >= 0; i-- { + value := slice[i] + if f(value) { + return value + } + } + return *new(T) +} + +func FindIndex[T any](slice []T, f func(T) bool) int { + for i, value := range slice { + if f(value) { + return i + } + } + return -1 +} + +func FindLastIndex[T any](slice []T, f func(T) bool) int { + for i := len(slice) - 1; i >= 0; i-- { + value := slice[i] + if f(value) { + return i + } + } + return -1 +} + +func FirstOrNil[T any](slice []T) T { + if len(slice) != 0 { + return slice[0] + } + return *new(T) +} + +func LastOrNil[T any](slice []T) T { + if len(slice) != 0 { + return slice[len(slice)-1] + } + return *new(T) +} + +func ElementOrNil[T any](slice []T, index int) T { + if index < len(slice) { + return slice[index] + } + return *new(T) +} + +func FirstOrNilSeq[T any](seq iter.Seq[T]) T { + if seq != nil { + for value := range seq { + return value + } + } + return *new(T) +} + +func FirstNonNil[T any, U comparable](slice []T, f func(T) U) U { + for _, value := range slice { + mapped := f(value) + if mapped != *new(U) { + return mapped + } + } + return *new(U) +} + +func Concatenate[T any](s1 []T, s2 []T) []T { + if len(s2) == 0 { + return s1 + } + if len(s1) == 0 { + return s2 + } + return slices.Concat(s1, s2) +} + +func Splice[T any](s1 []T, start int, deleteCount int, items ...T) []T { + if start < 0 { + start = len(s1) + start + } + if start < 0 { + start = 0 + } + if start > len(s1) { + start = len(s1) + } + if deleteCount < 0 { + deleteCount = 0 + } + end := min(start+max(deleteCount, 0), len(s1)) + if start == end && len(items) == 0 { + return s1 + } + return slices.Concat(s1[:start], items, s1[end:]) +} + +func CountWhere[T any](slice []T, f func(T) bool) int { + count := 0 + for _, value := range slice { + if f(value) { + count++ + } + } + return count +} + +func ReplaceElement[T any](slice []T, i int, t T) []T { + result := slices.Clone(slice) + result[i] = t + return result +} + +func InsertSorted[T any](slice []T, element T, cmp func(T, T) int) []T { + i, _ := slices.BinarySearchFunc(slice, element, cmp) + return slices.Insert(slice, i, element) +} + +func AppendIfUnique[T comparable](slice []T, element T) []T { + if slices.Contains(slice, element) { + return slice + } + return append(slice, element) +} + +func Memoize[T any](create func() T) func() T { + var value T + return func() T { + if create != nil { + value = create() + create = nil + } + return value + } +} + +// Returns whenTrue if b is true; otherwise, returns whenFalse. IfElse should only be used when branches are either +// constant or precomputed as both branches will be evaluated regardless as to the value of b. +func IfElse[T any](b bool, whenTrue T, whenFalse T) T { + if b { + return whenTrue + } + return whenFalse +} + +// Returns value if value is not the zero value of T; Otherwise, returns defaultValue. OrElse should only be used when +// defaultValue is constant or precomputed as its argument will be evaluated regardless as to the content of value. +func OrElse[T comparable](value T, defaultValue T) T { + if value != *new(T) { + return value + } + return defaultValue +} + +// Returns `a` if `a` is not `nil`; Otherwise, returns `b`. Coalesce is roughly analogous to `??` in JS, except that it +// non-shortcutting, so it is advised to only use a constant or precomputed value for `b` +func Coalesce[T *U, U any](a T, b T) T { + if a == nil { + return b + } else { + return a + } +} + +type ECMALineStarts []TextPos + +func ComputeECMALineStarts(text string) ECMALineStarts { + result := make([]TextPos, 0, strings.Count(text, "\n")+1) + return slices.AppendSeq(result, ComputeECMALineStartsSeq(text)) +} + +func ComputeECMALineStartsSeq(text string) iter.Seq[TextPos] { + return func(yield func(TextPos) bool) { + textLen := TextPos(len(text)) + var pos TextPos + var lineStart TextPos + for pos < textLen { + b := text[pos] + if b < utf8.RuneSelf { + pos++ + switch b { + case '\r': + if pos < textLen && text[pos] == '\n' { + pos++ + } + fallthrough + case '\n': + if !yield(lineStart) { + return + } + lineStart = pos + } + } else { + ch, size := utf8.DecodeRuneInString(text[pos:]) + pos += TextPos(size) + if stringutil.IsLineBreak(ch) { + if !yield(lineStart) { + return + } + lineStart = pos + } + } + } + yield(lineStart) + } +} + +func PositionToLineAndCharacter(position int, lineStarts []TextPos) (line int, character int) { + line = sort.Search(len(lineStarts), func(i int) bool { + return int(lineStarts[i]) > position + }) - 1 + if line < 0 { + line = 0 + } + return line, position - int(lineStarts[line]) +} + +func Flatten[T any](array [][]T) []T { + var result []T + for _, subArray := range array { + result = append(result, subArray...) + } + return result +} + +func Must[T any](v T, err error) T { + if err != nil { + panic(err) + } + return v +} + +// Extracts the first value of a multi-value return. +func FirstResult[T1 any](t1 T1, _ ...any) T1 { + return t1 +} + +func StringifyJson(input any, prefix string, indent string) (string, error) { + output, err := jsonutil.MarshalIndent(input, prefix, indent) + return string(output), err +} + +func GetScriptKindFromFileName(fileName string) ScriptKind { + dotPos := strings.LastIndex(fileName, ".") + if dotPos >= 0 { + switch strings.ToLower(fileName[dotPos:]) { + case tspath.ExtensionJs, tspath.ExtensionCjs, tspath.ExtensionMjs: + return ScriptKindJS + case tspath.ExtensionJsx: + return ScriptKindJSX + case tspath.ExtensionTs, tspath.ExtensionCts, tspath.ExtensionMts: + return ScriptKindTS + case tspath.ExtensionTsx: + return ScriptKindTSX + case tspath.ExtensionJson: + return ScriptKindJSON + } + } + return ScriptKindUnknown +} + +// Given a name and a list of names that are *not* equal to the name, return a spelling suggestion if there is one that is close enough. +// Names less than length 3 only check for case-insensitive equality. +// +// find the candidate with the smallest Levenshtein distance, +// +// except for candidates: +// * With no name +// * Whose length differs from the target name by more than 0.34 of the length of the name. +// * Whose levenshtein distance is more than 0.4 of the length of the name +// (0.4 allows 1 substitution/transposition for every 5 characters, +// and 1 insertion/deletion at 3 characters) +// +// @internal +func GetSpellingSuggestion[T any](name string, candidates []T, getName func(T) string) T { + maximumLengthDifference := max(2, int(float64(len(name))*0.34)) + bestDistance := math.Floor(float64(len(name))*0.4) + 1 // If the best result is worse than this, don't bother. + runeName := []rune(name) + buffers := levenshteinBuffersPool.Get().(*levenshteinBuffers) + defer levenshteinBuffersPool.Put(buffers) + var bestCandidate T + for _, candidate := range candidates { + candidateName := getName(candidate) + maxLen := max(len(candidateName), len(name)) + minLen := min(len(candidateName), len(name)) + if candidateName != "" && maxLen-minLen <= maximumLengthDifference { + if candidateName == name { + continue + } + // Only consider candidates less than 3 characters long when they differ by case. + // Otherwise, don't bother, since a user would usually notice differences of a 2-character name. + if len(candidateName) < 3 && !strings.EqualFold(candidateName, name) { + continue + } + distance := levenshteinWithMax(buffers, runeName, []rune(candidateName), bestDistance-0.1) + if distance < 0 { + continue + } + debug.Assert(distance < bestDistance) // Else `levenshteinWithMax` should return undefined + bestDistance = distance + bestCandidate = candidate + } + } + return bestCandidate +} + +type levenshteinBuffers struct { + previous []float64 + current []float64 +} + +var levenshteinBuffersPool = sync.Pool{ + New: func() any { + return &levenshteinBuffers{} + }, +} + +func levenshteinWithMax(buffers *levenshteinBuffers, s1 []rune, s2 []rune, maxValue float64) float64 { + bufferSize := len(s2) + 1 + buffers.previous = slices.Grow(buffers.previous[:0], bufferSize)[:bufferSize] + buffers.current = slices.Grow(buffers.current[:0], bufferSize)[:bufferSize] + + previous := buffers.previous + current := buffers.current + + big := maxValue + 0.01 + for i := range previous { + previous[i] = float64(i) + } + for i := 1; i <= len(s1); i++ { + c1 := s1[i-1] + minJ := max(int(math.Ceil(float64(i)-maxValue)), 1) + maxJ := min(int(math.Floor(maxValue+float64(i))), len(s2)) + colMin := float64(i) + current[0] = colMin + for j := 1; j < minJ; j++ { + current[j] = big + } + for j := minJ; j <= maxJ; j++ { + var substitutionDistance, dist float64 + if unicode.ToLower(s1[i-1]) == unicode.ToLower(s2[j-1]) { + substitutionDistance = previous[j-1] + 0.1 + } else { + substitutionDistance = previous[j-1] + 2 + } + if c1 == s2[j-1] { + dist = previous[j-1] + } else { + dist = math.Min(previous[j]+1, math.Min(current[j-1]+1, substitutionDistance)) + } + current[j] = dist + colMin = math.Min(colMin, dist) + } + for j := maxJ + 1; j <= len(s2); j++ { + current[j] = big + } + if colMin > maxValue { + // Give up -- everything in this column is > max and it can't get better in future columns. + return -1 + } + previous, current = current, previous + } + res := previous[len(s2)] + if res > maxValue { + return -1 + } + return res +} + +func Identity[T any](t T) T { + return t +} + +func CheckEachDefined[S any](s []*S, msg string) []*S { + for _, value := range s { + if value == nil { + panic(msg) + } + } + return s +} + +func IndexAfter(s string, pattern string, startIndex int) int { + matched := strings.Index(s[startIndex:], pattern) + if matched == -1 { + return -1 + } else { + return matched + startIndex + } +} + +func ShouldRewriteModuleSpecifier(specifier string, compilerOptions *CompilerOptions) bool { + return compilerOptions.RewriteRelativeImportExtensions.IsTrue() && tspath.PathIsRelative(specifier) && !tspath.IsDeclarationFileName(specifier) && tspath.HasTSFileExtension(specifier) +} + +func SingleElementSlice[T any](element *T) []*T { + if element == nil { + return nil + } + return []*T{element} +} + +func ConcatenateSeq[T any](seqs ...iter.Seq[T]) iter.Seq[T] { + return func(yield func(T) bool) { + for _, seq := range seqs { + if seq == nil { + continue + } + for e := range seq { + if !yield(e) { + return + } + } + } + } +} + +func comparableValuesEqual[T comparable](a, b T) bool { + return a == b +} + +func DiffMaps[K comparable, V comparable](m1 map[K]V, m2 map[K]V, onAdded func(K, V), onRemoved func(K, V), onChanged func(K, V, V)) { + DiffMapsFunc(m1, m2, comparableValuesEqual, onAdded, onRemoved, onChanged) +} + +func DiffMapsFunc[K comparable, V any](m1 map[K]V, m2 map[K]V, equalValues func(V, V) bool, onAdded func(K, V), onRemoved func(K, V), onChanged func(K, V, V)) { + for k, v2 := range m2 { + if _, ok := m1[k]; !ok { + onAdded(k, v2) + } + } + for k, v1 := range m1 { + if v2, ok := m2[k]; ok { + if !equalValues(v1, v2) { + onChanged(k, v1, v2) + } + } else { + onRemoved(k, v1) + } + } +} + +// CopyMapInto is maps.Copy, unless dst is nil, in which case it clones and returns src. +// Use CopyMapInto anywhere you would use maps.Copy preceded by a nil check and map initialization. +func CopyMapInto[M1 ~map[K]V, M2 ~map[K]V, K comparable, V any](dst M1, src M2) map[K]V { + if dst == nil { + return maps.Clone(src) + } + maps.Copy(dst, src) + return dst +} + +func Deduplicate[T comparable](slice []T) []T { + if len(slice) > 1 { + for i, value := range slice { + if slices.Contains(slice[:i], value) { + result := slices.Clone(slice[:i]) + for i++; i < len(slice); i++ { + value = slice[i] + if !slices.Contains(result, value) { + result = append(result, value) + } + } + return result + } + } + } + return slice +} + +func DeduplicateSorted[T any](slice []T, isEqual func(a, b T) bool) []T { + if len(slice) == 0 { + return slice + } + last := slice[0] + deduplicated := slice[:1] + for i := 1; i < len(slice); i++ { + next := slice[i] + if isEqual(last, next) { + continue + } + + deduplicated = append(deduplicated, next) + last = next + } + + return deduplicated +} diff --git a/kitcom/internal/tsgo/core/languagevariant.go b/kitcom/internal/tsgo/core/languagevariant.go new file mode 100644 index 0000000..e5ad990 --- /dev/null +++ b/kitcom/internal/tsgo/core/languagevariant.go @@ -0,0 +1,11 @@ +package core + +//go:generate go tool golang.org/x/tools/cmd/stringer -type=LanguageVariant -output=languagevariant_stringer_generated.go +//go:generate go tool mvdan.cc/gofumpt -w languagevariant_stringer_generated.go + +type LanguageVariant int32 + +const ( + LanguageVariantStandard LanguageVariant = iota + LanguageVariantJSX +) diff --git a/kitcom/internal/tsgo/core/languagevariant_stringer_generated.go b/kitcom/internal/tsgo/core/languagevariant_stringer_generated.go new file mode 100644 index 0000000..ae5cca5 --- /dev/null +++ b/kitcom/internal/tsgo/core/languagevariant_stringer_generated.go @@ -0,0 +1,24 @@ +// Code generated by "stringer -type=LanguageVariant -output=languagevariant_stringer_generated.go"; DO NOT EDIT. + +package core + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[LanguageVariantStandard-0] + _ = x[LanguageVariantJSX-1] +} + +const _LanguageVariant_name = "LanguageVariantStandardLanguageVariantJSX" + +var _LanguageVariant_index = [...]uint8{0, 23, 41} + +func (i LanguageVariant) String() string { + if i < 0 || i >= LanguageVariant(len(_LanguageVariant_index)-1) { + return "LanguageVariant(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _LanguageVariant_name[_LanguageVariant_index[i]:_LanguageVariant_index[i+1]] +} diff --git a/kitcom/internal/tsgo/core/linkstore.go b/kitcom/internal/tsgo/core/linkstore.go new file mode 100644 index 0000000..c1b05ee --- /dev/null +++ b/kitcom/internal/tsgo/core/linkstore.go @@ -0,0 +1,30 @@ +package core + +// Links store + +type LinkStore[K comparable, V any] struct { + entries map[K]*V + pool Pool[V] +} + +func (s *LinkStore[K, V]) Get(key K) *V { + value := s.entries[key] + if value != nil { + return value + } + if s.entries == nil { + s.entries = make(map[K]*V) + } + value = s.pool.New() + s.entries[key] = value + return value +} + +func (s *LinkStore[K, V]) Has(key K) bool { + _, ok := s.entries[key] + return ok +} + +func (s *LinkStore[K, V]) TryGet(key K) *V { + return s.entries[key] +} diff --git a/kitcom/internal/tsgo/core/modulekind_stringer_generated.go b/kitcom/internal/tsgo/core/modulekind_stringer_generated.go new file mode 100644 index 0000000..5fc4c77 --- /dev/null +++ b/kitcom/internal/tsgo/core/modulekind_stringer_generated.go @@ -0,0 +1,52 @@ +// Code generated by "stringer -type=ModuleKind -trimprefix=ModuleKind -output=modulekind_stringer_generated.go"; DO NOT EDIT. + +package core + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[ModuleKindNone-0] + _ = x[ModuleKindCommonJS-1] + _ = x[ModuleKindAMD-2] + _ = x[ModuleKindUMD-3] + _ = x[ModuleKindSystem-4] + _ = x[ModuleKindES2015-5] + _ = x[ModuleKindES2020-6] + _ = x[ModuleKindES2022-7] + _ = x[ModuleKindESNext-99] + _ = x[ModuleKindNode16-100] + _ = x[ModuleKindNode18-101] + _ = x[ModuleKindNode20-102] + _ = x[ModuleKindNodeNext-199] + _ = x[ModuleKindPreserve-200] +} + +const ( + _ModuleKind_name_0 = "NoneCommonJSAMDUMDSystemES2015ES2020ES2022" + _ModuleKind_name_1 = "ESNextNode16Node18Node20" + _ModuleKind_name_2 = "NodeNextPreserve" +) + +var ( + _ModuleKind_index_0 = [...]uint8{0, 4, 12, 15, 18, 24, 30, 36, 42} + _ModuleKind_index_1 = [...]uint8{0, 6, 12, 18, 24} + _ModuleKind_index_2 = [...]uint8{0, 8, 16} +) + +func (i ModuleKind) String() string { + switch { + case 0 <= i && i <= 7: + return _ModuleKind_name_0[_ModuleKind_index_0[i]:_ModuleKind_index_0[i+1]] + case 99 <= i && i <= 102: + i -= 99 + return _ModuleKind_name_1[_ModuleKind_index_1[i]:_ModuleKind_index_1[i+1]] + case 199 <= i && i <= 200: + i -= 199 + return _ModuleKind_name_2[_ModuleKind_index_2[i]:_ModuleKind_index_2[i+1]] + default: + return "ModuleKind(" + strconv.FormatInt(int64(i), 10) + ")" + } +} diff --git a/kitcom/internal/tsgo/core/nodemodules.go b/kitcom/internal/tsgo/core/nodemodules.go new file mode 100644 index 0000000..a3abda6 --- /dev/null +++ b/kitcom/internal/tsgo/core/nodemodules.go @@ -0,0 +1,88 @@ +package core + +import ( + "maps" + "sync" +) + +var UnprefixedNodeCoreModules = map[string]bool{ + "assert": true, + "assert/strict": true, + "async_hooks": true, + "buffer": true, + "child_process": true, + "cluster": true, + "console": true, + "constants": true, + "crypto": true, + "dgram": true, + "diagnostics_channel": true, + "dns": true, + "dns/promises": true, + "domain": true, + "events": true, + "fs": true, + "fs/promises": true, + "http": true, + "http2": true, + "https": true, + "inspector": true, + "inspector/promises": true, + "module": true, + "net": true, + "os": true, + "path": true, + "path/posix": true, + "path/win32": true, + "perf_hooks": true, + "process": true, + "punycode": true, + "querystring": true, + "readline": true, + "readline/promises": true, + "repl": true, + "stream": true, + "stream/consumers": true, + "stream/promises": true, + "stream/web": true, + "string_decoder": true, + "sys": true, + "test/mock_loader": true, + "timers": true, + "timers/promises": true, + "tls": true, + "trace_events": true, + "tty": true, + "url": true, + "util": true, + "util/types": true, + "v8": true, + "vm": true, + "wasi": true, + "worker_threads": true, + "zlib": true, +} + +var ExclusivelyPrefixedNodeCoreModules = map[string]bool{ + "node:sea": true, + "node:sqlite": true, + "node:test": true, + "node:test/reporters": true, +} + +var NodeCoreModules = sync.OnceValue(func() map[string]bool { + nodeCoreModules := make(map[string]bool, len(UnprefixedNodeCoreModules)*2+len(ExclusivelyPrefixedNodeCoreModules)) + for unprefixed := range UnprefixedNodeCoreModules { + nodeCoreModules[unprefixed] = true + nodeCoreModules["node:"+unprefixed] = true + } + maps.Copy(nodeCoreModules, ExclusivelyPrefixedNodeCoreModules) + return nodeCoreModules +}) + +func NonRelativeModuleNameForTypingCache(moduleName string) string { + if NodeCoreModules()[moduleName] { + return "node" + } + return moduleName +} diff --git a/kitcom/internal/tsgo/core/parsedoptions.go b/kitcom/internal/tsgo/core/parsedoptions.go new file mode 100644 index 0000000..3aba067 --- /dev/null +++ b/kitcom/internal/tsgo/core/parsedoptions.go @@ -0,0 +1,10 @@ +package core + +type ParsedOptions struct { + CompilerOptions *CompilerOptions `json:"compilerOptions"` + WatchOptions *WatchOptions `json:"watchOptions"` + TypeAcquisition *TypeAcquisition `json:"typeAcquisition"` + + FileNames []string `json:"fileNames"` + ProjectReferences []*ProjectReference `json:"projectReferences"` +} diff --git a/kitcom/internal/tsgo/core/pattern.go b/kitcom/internal/tsgo/core/pattern.go new file mode 100644 index 0000000..883dbe6 --- /dev/null +++ b/kitcom/internal/tsgo/core/pattern.go @@ -0,0 +1,52 @@ +package core + +import "strings" + +type Pattern struct { + Text string + StarIndex int // -1 for exact match +} + +func TryParsePattern(pattern string) Pattern { + starIndex := strings.Index(pattern, "*") + if starIndex == -1 || !strings.Contains(pattern[starIndex+1:], "*") { + return Pattern{Text: pattern, StarIndex: starIndex} + } + return Pattern{} +} + +func (p *Pattern) IsValid() bool { + return p.StarIndex == -1 || p.StarIndex < len(p.Text) +} + +func (p *Pattern) Matches(candidate string) bool { + if p.StarIndex == -1 { + return p.Text == candidate + } + return len(candidate) >= p.StarIndex && + strings.HasPrefix(candidate, p.Text[:p.StarIndex]) && + strings.HasSuffix(candidate, p.Text[p.StarIndex+1:]) +} + +func (p *Pattern) MatchedText(candidate string) string { + if !p.Matches(candidate) { + panic("candidate does not match pattern") + } + if p.StarIndex == -1 { + return "" + } + return candidate[p.StarIndex : len(candidate)-len(p.Text)+p.StarIndex+1] +} + +func FindBestPatternMatch[T any](values []T, getPattern func(v T) Pattern, candidate string) T { + var bestPattern T + longestMatchPrefixLength := -1 + for _, value := range values { + pattern := getPattern(value) + if (pattern.StarIndex == -1 || pattern.StarIndex > longestMatchPrefixLength) && pattern.Matches(candidate) { + bestPattern = value + longestMatchPrefixLength = pattern.StarIndex + } + } + return bestPattern +} diff --git a/kitcom/internal/tsgo/core/pool.go b/kitcom/internal/tsgo/core/pool.go new file mode 100644 index 0000000..346674c --- /dev/null +++ b/kitcom/internal/tsgo/core/pool.go @@ -0,0 +1,66 @@ +package core + +import "slices" + +// Pool allocator + +type Pool[T any] struct { + data []T +} + +// Allocate a single element in the pool and return a pointer to the element. If the pool is at capacity, +// a new pool of the next size up is allocated. +func (p *Pool[T]) New() *T { + if len(p.data) == cap(p.data) { + nextSize := nextPoolSize(len(p.data)) + // Use the same trick as slices.Concat; Grow rounds up to the next size class. + p.data = slices.Grow[[]T](nil, nextSize) + } + index := len(p.data) + p.data = p.data[:index+1] + return &p.data[index] +} + +// Allocate a slice of the given size in the pool. If the requested size is beyond the capacity of the pool +// and a pool of the next size up still wouldn't fit the slice, make a separate memory allocation for the slice. +// Otherwise, grow the pool if necessary and allocate a slice out of it. The length and capacity of the resulting +// slice are equal to the given size. +func (p *Pool[T]) NewSlice(size int) []T { + if size == 0 { + return nil + } + if len(p.data)+size > cap(p.data) { + nextSize := nextPoolSize(len(p.data)) + if size > nextSize { + return make([]T, size) + } + // Use the same trick as slices.Concat; Grow rounds up to the next size class. + p.data = slices.Grow[[]T](nil, nextSize) + } + newLen := len(p.data) + size + slice := p.data[len(p.data):newLen:newLen] + p.data = p.data[:newLen] + return slice +} + +func (p *Pool[T]) NewSlice1(t T) []T { + slice := p.NewSlice(1) + slice[0] = t + return slice +} + +func (p *Pool[T]) Clone(t []T) []T { + if len(t) == 0 { + return nil + } + slice := p.NewSlice(len(t)) + copy(slice, t) + return slice +} + +func nextPoolSize(size int) int { + // This compiles down branch-free. + size = max(size, 1) + size = min(size*2, 256) + return size +} diff --git a/kitcom/internal/tsgo/core/projectreference.go b/kitcom/internal/tsgo/core/projectreference.go new file mode 100644 index 0000000..7ed6a1c --- /dev/null +++ b/kitcom/internal/tsgo/core/projectreference.go @@ -0,0 +1,20 @@ +package core + +import "efprojects.com/kitten-ipc/kitcom/internal/tsgo/tspath" + +type ProjectReference struct { + Path string + OriginalPath string + Circular bool +} + +func ResolveProjectReferencePath(ref *ProjectReference) string { + return ResolveConfigFileNameOfProjectReference(ref.Path) +} + +func ResolveConfigFileNameOfProjectReference(path string) string { + if tspath.FileExtensionIs(path, tspath.ExtensionJson) { + return path + } + return tspath.CombinePaths(path, "tsconfig.json") +} diff --git a/kitcom/internal/tsgo/core/scriptkind.go b/kitcom/internal/tsgo/core/scriptkind.go new file mode 100644 index 0000000..aa61528 --- /dev/null +++ b/kitcom/internal/tsgo/core/scriptkind.go @@ -0,0 +1,21 @@ +package core + +//go:generate go tool golang.org/x/tools/cmd/stringer -type=ScriptKind -output=scriptkind_stringer_generated.go +//go:generate go tool mvdan.cc/gofumpt -w scriptkind_stringer_generated.go + +type ScriptKind int32 + +const ( + ScriptKindUnknown ScriptKind = iota + ScriptKindJS + ScriptKindJSX + ScriptKindTS + ScriptKindTSX + ScriptKindExternal + ScriptKindJSON + /** + * Used on extensions that doesn't define the ScriptKind but the content defines it. + * Deferred extensions are going to be included in all project contexts. + */ + ScriptKindDeferred +) diff --git a/kitcom/internal/tsgo/core/scriptkind_stringer_generated.go b/kitcom/internal/tsgo/core/scriptkind_stringer_generated.go new file mode 100644 index 0000000..ba50779 --- /dev/null +++ b/kitcom/internal/tsgo/core/scriptkind_stringer_generated.go @@ -0,0 +1,30 @@ +// Code generated by "stringer -type=ScriptKind -output=scriptkind_stringer_generated.go"; DO NOT EDIT. + +package core + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[ScriptKindUnknown-0] + _ = x[ScriptKindJS-1] + _ = x[ScriptKindJSX-2] + _ = x[ScriptKindTS-3] + _ = x[ScriptKindTSX-4] + _ = x[ScriptKindExternal-5] + _ = x[ScriptKindJSON-6] + _ = x[ScriptKindDeferred-7] +} + +const _ScriptKind_name = "ScriptKindUnknownScriptKindJSScriptKindJSXScriptKindTSScriptKindTSXScriptKindExternalScriptKindJSONScriptKindDeferred" + +var _ScriptKind_index = [...]uint8{0, 17, 29, 42, 54, 67, 85, 99, 117} + +func (i ScriptKind) String() string { + if i < 0 || i >= ScriptKind(len(_ScriptKind_index)-1) { + return "ScriptKind(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _ScriptKind_name[_ScriptKind_index[i]:_ScriptKind_index[i+1]] +} diff --git a/kitcom/internal/tsgo/core/scripttarget_stringer_generated.go b/kitcom/internal/tsgo/core/scripttarget_stringer_generated.go new file mode 100644 index 0000000..ad25dc2 --- /dev/null +++ b/kitcom/internal/tsgo/core/scripttarget_stringer_generated.go @@ -0,0 +1,49 @@ +// Code generated by "stringer -type=ScriptTarget -trimprefix=ScriptTarget -output=scripttarget_stringer_generated.go"; DO NOT EDIT. + +package core + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[ScriptTargetNone-0] + _ = x[ScriptTargetES3-0] + _ = x[ScriptTargetES5-1] + _ = x[ScriptTargetES2015-2] + _ = x[ScriptTargetES2016-3] + _ = x[ScriptTargetES2017-4] + _ = x[ScriptTargetES2018-5] + _ = x[ScriptTargetES2019-6] + _ = x[ScriptTargetES2020-7] + _ = x[ScriptTargetES2021-8] + _ = x[ScriptTargetES2022-9] + _ = x[ScriptTargetES2023-10] + _ = x[ScriptTargetES2024-11] + _ = x[ScriptTargetESNext-99] + _ = x[ScriptTargetJSON-100] + _ = x[ScriptTargetLatest-99] +} + +const ( + _ScriptTarget_name_0 = "NoneES5ES2015ES2016ES2017ES2018ES2019ES2020ES2021ES2022ES2023ES2024" + _ScriptTarget_name_1 = "ESNextJSON" +) + +var ( + _ScriptTarget_index_0 = [...]uint8{0, 4, 7, 13, 19, 25, 31, 37, 43, 49, 55, 61, 67} + _ScriptTarget_index_1 = [...]uint8{0, 6, 10} +) + +func (i ScriptTarget) String() string { + switch { + case 0 <= i && i <= 11: + return _ScriptTarget_name_0[_ScriptTarget_index_0[i]:_ScriptTarget_index_0[i+1]] + case 99 <= i && i <= 100: + i -= 99 + return _ScriptTarget_name_1[_ScriptTarget_index_1[i]:_ScriptTarget_index_1[i+1]] + default: + return "ScriptTarget(" + strconv.FormatInt(int64(i), 10) + ")" + } +} diff --git a/kitcom/internal/tsgo/core/stack.go b/kitcom/internal/tsgo/core/stack.go new file mode 100644 index 0000000..6b8bf9a --- /dev/null +++ b/kitcom/internal/tsgo/core/stack.go @@ -0,0 +1,33 @@ +package core + +type Stack[T any] struct { + data []T +} + +func (s *Stack[T]) Push(item T) { + s.data = append(s.data, item) +} + +func (s *Stack[T]) Pop() T { + l := len(s.data) + if l == 0 { + panic("stack is empty") + } + item := s.data[l-1] + var zero T + s.data[l-1] = zero + s.data = s.data[:l-1] + return item +} + +func (s *Stack[T]) Peek() T { + l := len(s.data) + if l == 0 { + panic("stack is empty") + } + return s.data[l-1] +} + +func (s *Stack[T]) Len() int { + return len(s.data) +} diff --git a/kitcom/internal/tsgo/core/text.go b/kitcom/internal/tsgo/core/text.go new file mode 100644 index 0000000..d911b83 --- /dev/null +++ b/kitcom/internal/tsgo/core/text.go @@ -0,0 +1,66 @@ +package core + +// TextPos + +type TextPos int32 + +// TextRange + +type TextRange struct { + pos TextPos + end TextPos +} + +func NewTextRange(pos int, end int) TextRange { + return TextRange{pos: TextPos(pos), end: TextPos(end)} +} + +func UndefinedTextRange() TextRange { + return TextRange{pos: TextPos(-1), end: TextPos(-1)} +} + +func (t TextRange) Pos() int { + return int(t.pos) +} + +func (t TextRange) End() int { + return int(t.end) +} + +func (t TextRange) Len() int { + return int(t.end - t.pos) +} + +func (t TextRange) IsValid() bool { + return t.pos >= 0 || t.end >= 0 +} + +func (t TextRange) Contains(pos int) bool { + return pos >= int(t.pos) && pos < int(t.end) +} + +func (t TextRange) ContainsInclusive(pos int) bool { + return pos >= int(t.pos) && pos <= int(t.end) +} + +func (t TextRange) ContainsExclusive(pos int) bool { + return int(t.pos) < pos && pos < int(t.end) +} + +func (t TextRange) WithPos(pos int) TextRange { + return TextRange{pos: TextPos(pos), end: t.end} +} + +func (t TextRange) WithEnd(end int) TextRange { + return TextRange{pos: t.pos, end: TextPos(end)} +} + +func (t TextRange) ContainedBy(t2 TextRange) bool { + return t2.pos <= t.pos && t2.end >= t.end +} + +func (t TextRange) Overlaps(t2 TextRange) bool { + start := max(t.pos, t2.pos) + end := min(t.end, t2.end) + return start < end +} diff --git a/kitcom/internal/tsgo/core/textchange.go b/kitcom/internal/tsgo/core/textchange.go new file mode 100644 index 0000000..9945af4 --- /dev/null +++ b/kitcom/internal/tsgo/core/textchange.go @@ -0,0 +1,30 @@ +package core + +import "strings" + +type TextChange struct { + TextRange + NewText string +} + +func (t TextChange) ApplyTo(text string) string { + return text[:t.Pos()] + t.NewText + text[t.End():] +} + +func ApplyBulkEdits(text string, edits []TextChange) string { + b := strings.Builder{} + b.Grow(len(text)) + lastEnd := 0 + for _, e := range edits { + start := e.TextRange.Pos() + if start != lastEnd { + b.WriteString(text[lastEnd:e.TextRange.Pos()]) + } + b.WriteString(e.NewText) + + lastEnd = e.TextRange.End() + } + b.WriteString(text[lastEnd:]) + + return b.String() +} diff --git a/kitcom/internal/tsgo/core/tristate.go b/kitcom/internal/tsgo/core/tristate.go new file mode 100644 index 0000000..34841b7 --- /dev/null +++ b/kitcom/internal/tsgo/core/tristate.go @@ -0,0 +1,71 @@ +package core + +//go:generate go tool golang.org/x/tools/cmd/stringer -type=Tristate -output=tristate_stringer_generated.go +//go:generate go tool mvdan.cc/gofumpt -w tristate_stringer_generated.go + +// Tristate + +type Tristate byte + +const ( + TSUnknown Tristate = iota + TSFalse + TSTrue +) + +func (t Tristate) IsTrue() bool { + return t == TSTrue +} + +func (t Tristate) IsTrueOrUnknown() bool { + return t == TSTrue || t == TSUnknown +} + +func (t Tristate) IsFalse() bool { + return t == TSFalse +} + +func (t Tristate) IsFalseOrUnknown() bool { + return t == TSFalse || t == TSUnknown +} + +func (t Tristate) IsUnknown() bool { + return t == TSUnknown +} + +func (t Tristate) DefaultIfUnknown(value Tristate) Tristate { + if t == TSUnknown { + return value + } + return t +} + +func (t *Tristate) UnmarshalJSON(data []byte) error { + switch string(data) { + case "true": + *t = TSTrue + case "false": + *t = TSFalse + default: + *t = TSUnknown + } + return nil +} + +func (t Tristate) MarshalJSON() ([]byte, error) { + switch t { + case TSTrue: + return []byte("true"), nil + case TSFalse: + return []byte("false"), nil + default: + return []byte("null"), nil + } +} + +func BoolToTristate(b bool) Tristate { + if b { + return TSTrue + } + return TSFalse +} diff --git a/kitcom/internal/tsgo/core/tristate_stringer_generated.go b/kitcom/internal/tsgo/core/tristate_stringer_generated.go new file mode 100644 index 0000000..05db2d7 --- /dev/null +++ b/kitcom/internal/tsgo/core/tristate_stringer_generated.go @@ -0,0 +1,25 @@ +// Code generated by "stringer -type=Tristate -output=tristate_stringer_generated.go"; DO NOT EDIT. + +package core + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[TSUnknown-0] + _ = x[TSFalse-1] + _ = x[TSTrue-2] +} + +const _Tristate_name = "TSUnknownTSFalseTSTrue" + +var _Tristate_index = [...]uint8{0, 9, 16, 22} + +func (i Tristate) String() string { + if i >= Tristate(len(_Tristate_index)-1) { + return "Tristate(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _Tristate_name[_Tristate_index[i]:_Tristate_index[i+1]] +} diff --git a/kitcom/internal/tsgo/core/typeacquisition.go b/kitcom/internal/tsgo/core/typeacquisition.go new file mode 100644 index 0000000..6edc0ea --- /dev/null +++ b/kitcom/internal/tsgo/core/typeacquisition.go @@ -0,0 +1,24 @@ +package core + +import "slices" + +type TypeAcquisition struct { + Enable Tristate `json:"enable,omitzero"` + Include []string `json:"include,omitzero"` + Exclude []string `json:"exclude,omitzero"` + DisableFilenameBasedTypeAcquisition Tristate `json:"disableFilenameBasedTypeAcquisition,omitzero"` +} + +func (ta *TypeAcquisition) Equals(other *TypeAcquisition) bool { + if ta == other { + return true + } + if ta == nil || other == nil { + return false + } + + return (ta.Enable == other.Enable && + slices.Equal(ta.Include, other.Include) && + slices.Equal(ta.Exclude, other.Exclude) && + ta.DisableFilenameBasedTypeAcquisition == other.DisableFilenameBasedTypeAcquisition) +} diff --git a/kitcom/internal/tsgo/core/version.go b/kitcom/internal/tsgo/core/version.go new file mode 100644 index 0000000..9e04cb5 --- /dev/null +++ b/kitcom/internal/tsgo/core/version.go @@ -0,0 +1,33 @@ +package core + +import ( + "strings" +) + +// This is a var so it can be overridden by ldflags. +var version = "7.0.0-dev" + +func Version() string { + return version +} + +var versionMajorMinor = func() string { + seenMajor := false + i := strings.IndexFunc(version, func(r rune) bool { + if r == '.' { + if seenMajor { + return true + } + seenMajor = true + } + return false + }) + if i == -1 { + panic("invalid version string: " + version) + } + return version[:i] +}() + +func VersionMajorMinor() string { + return versionMajorMinor +} diff --git a/kitcom/internal/tsgo/core/watchoptions.go b/kitcom/internal/tsgo/core/watchoptions.go new file mode 100644 index 0000000..42d8577 --- /dev/null +++ b/kitcom/internal/tsgo/core/watchoptions.go @@ -0,0 +1,53 @@ +package core + +import "time" + +type WatchOptions struct { + Interval *int `json:"watchInterval"` + FileKind WatchFileKind `json:"watchFile"` + DirectoryKind WatchDirectoryKind `json:"watchDirectory"` + FallbackPolling PollingKind `json:"fallbackPolling"` + SyncWatchDir Tristate `json:"synchronousWatchDirectory"` + ExcludeDir []string `json:"excludeDirectories"` + ExcludeFiles []string `json:"excludeFiles"` +} + +type WatchFileKind int32 + +const ( + WatchFileKindNone WatchFileKind = 0 + WatchFileKindFixedPollingInterval WatchFileKind = 1 + WatchFileKindPriorityPollingInterval WatchFileKind = 2 + WatchFileKindDynamicPriorityPolling WatchFileKind = 3 + WatchFileKindFixedChunkSizePolling WatchFileKind = 4 + WatchFileKindUseFsEvents WatchFileKind = 5 + WatchFileKindUseFsEventsOnParentDirectory WatchFileKind = 6 +) + +type WatchDirectoryKind int32 + +const ( + WatchDirectoryKindNone WatchDirectoryKind = 0 + WatchDirectoryKindUseFsEvents WatchDirectoryKind = 1 + WatchDirectoryKindFixedPollingInterval WatchDirectoryKind = 2 + WatchDirectoryKindDynamicPriorityPolling WatchDirectoryKind = 3 + WatchDirectoryKindFixedChunkSizePolling WatchDirectoryKind = 4 +) + +type PollingKind int32 + +const ( + PollingKindNone PollingKind = 0 + PollingKindFixedInterval PollingKind = 1 + PollingKindPriorityInterval PollingKind = 2 + PollingKindDynamicPriority PollingKind = 3 + PollingKindFixedChunkSize PollingKind = 4 +) + +func (w *WatchOptions) WatchInterval() time.Duration { + watchInterval := 1000 * time.Millisecond + if w != nil && w.Interval != nil { + watchInterval = time.Duration(*w.Interval) * time.Millisecond + } + return watchInterval +} diff --git a/kitcom/internal/tsgo/core/workgroup.go b/kitcom/internal/tsgo/core/workgroup.go new file mode 100644 index 0000000..fcdd133 --- /dev/null +++ b/kitcom/internal/tsgo/core/workgroup.go @@ -0,0 +1,125 @@ +package core + +import ( + "context" + "sync" + "sync/atomic" + + "golang.org/x/sync/errgroup" +) + +type WorkGroup interface { + // Queue queues a function to run. It may be invoked immediately, or deferred until RunAndWait. + // It is not safe to call Queue after RunAndWait has returned. + Queue(fn func()) + + // RunAndWait runs all queued functions, blocking until they have all completed. + RunAndWait() +} + +func NewWorkGroup(singleThreaded bool) WorkGroup { + if singleThreaded { + return &singleThreadedWorkGroup{} + } + return ¶llelWorkGroup{} +} + +type parallelWorkGroup struct { + done atomic.Bool + wg sync.WaitGroup +} + +var _ WorkGroup = (*parallelWorkGroup)(nil) + +func (w *parallelWorkGroup) Queue(fn func()) { + if w.done.Load() { + panic("Queue called after RunAndWait returned") + } + + w.wg.Add(1) + go func() { + defer w.wg.Done() + fn() + }() +} + +func (w *parallelWorkGroup) RunAndWait() { + defer w.done.Store(true) + w.wg.Wait() +} + +type singleThreadedWorkGroup struct { + done atomic.Bool + fnsMu sync.Mutex + fns []func() +} + +var _ WorkGroup = (*singleThreadedWorkGroup)(nil) + +func (w *singleThreadedWorkGroup) Queue(fn func()) { + if w.done.Load() { + panic("Queue called after RunAndWait returned") + } + + w.fnsMu.Lock() + defer w.fnsMu.Unlock() + w.fns = append(w.fns, fn) +} + +func (w *singleThreadedWorkGroup) RunAndWait() { + defer w.done.Store(true) + for { + fn := w.pop() + if fn == nil { + return + } + fn() + } +} + +func (w *singleThreadedWorkGroup) pop() func() { + w.fnsMu.Lock() + defer w.fnsMu.Unlock() + if len(w.fns) == 0 { + return nil + } + end := len(w.fns) - 1 + fn := w.fns[end] + w.fns[end] = nil // Allow GC + w.fns = w.fns[:end] + return fn +} + +// ThrottleGroup is like errgroup.Group but with global concurrency limiting via a semaphore. +type ThrottleGroup struct { + semaphore chan struct{} + group *errgroup.Group +} + +// NewThrottleGroup creates a new ThrottleGroup with the given context and semaphore for concurrency limiting. +func NewThrottleGroup(ctx context.Context, semaphore chan struct{}) *ThrottleGroup { + g, _ := errgroup.WithContext(ctx) + return &ThrottleGroup{ + semaphore: semaphore, + group: g, + } +} + +// Go runs the given function in a new goroutine, but first acquires a slot from the semaphore. +// The semaphore slot is released when the function completes. +func (tg *ThrottleGroup) Go(fn func() error) { + tg.group.Go(func() error { + // Acquire semaphore slot - this will block until a slot is available + tg.semaphore <- struct{}{} + defer func() { + // Release semaphore slot when done + <-tg.semaphore + }() + return fn() + }) +} + +// Wait waits for all goroutines to complete and returns the first error encountered, if any. +func (tg *ThrottleGroup) Wait() error { + return tg.group.Wait() +} diff --git a/kitcom/internal/tsgo/debug/debug.go b/kitcom/internal/tsgo/debug/debug.go new file mode 100644 index 0000000..2c52678 --- /dev/null +++ b/kitcom/internal/tsgo/debug/debug.go @@ -0,0 +1,198 @@ +//go:build !release + +package debug + +import ( + "fmt" + "reflect" +) + +func Assert(expression bool, message ...string) { + if !expression { + var msg string + if len(message) > 0 { + msg = "False expression: " + message[0] + } else { + msg = "False expression." + } + Fail(msg) + } +} + +func isNil[T any](value T) bool { + v := reflect.ValueOf(value) + switch v.Kind() { + case reflect.Pointer, reflect.UnsafePointer, reflect.Interface, reflect.Slice, reflect.Map, reflect.Chan, reflect.Func: + { + return v.IsNil() + } + default: + { + return false + } + } +} + +func AssertNil(value any, message ...string) { + if value != nil && !isNil(value) { + var msg string + if len(message) > 0 { + msg = "Nil expression: " + message[0] + } else { + msg = "Nil expression." + } + Fail(msg) + } +} + +func AssertEqual(a fmt.Stringer, b fmt.Stringer, message ...string) { + if a != b { + var msg string + if len(message) == 0 { + msg = "" + } else { + msg = message[0] + } + Fail(fmt.Sprintf("Expected %s == %s. %s", a.String(), b.String(), msg)) + } +} + +func AssertLessThan(a int, b int, message ...string) { + if a >= b { + var msg string + if len(message) == 0 { + msg = "" + } else { + msg = message[0] + } + Fail(fmt.Sprintf("Expected %d < %d. %s", a, b, msg)) + } +} + +func AssertLessThanOrEqual(a int, b int, message ...string) { + if a > b { + var msg string + if len(message) == 0 { + msg = "" + } else { + msg = message[0] + } + Fail(fmt.Sprintf("Expected %d <= %d. %s", a, b, msg)) + } +} + +func AssertGreaterThan(a int, b int, message ...string) { + if a <= b { + var msg string + if len(message) == 0 { + msg = "" + } else { + msg = message[0] + } + Fail(fmt.Sprintf("Expected %d > %d. %s", a, b, msg)) + } +} + +func AssertGreaterThanOrEqual(a int, b int, message ...string) { + if a < b { + var msg string + if len(message) == 0 { + msg = "" + } else { + msg = message[0] + } + Fail(fmt.Sprintf("Expected %d >= %d. %s", a, b, msg)) + } +} + +func AssertIsDefined(value any, message ...string) { + if value == nil || isNil(value) { // handle all `nil` interfaces + var msg string + if len(message) == 0 { + msg = "" + } else { + msg = message[0] + } + Fail(msg) + } +} + +func CheckDefined[T any](value T, message ...string) T { + AssertIsDefined(value, message...) + return value +} + +func AssertEachIsDefined[TElem any](value []TElem, message ...string) { + for _, elem := range value { + AssertIsDefined(elem, message...) + } +} + +func CheckEachIsDefined[TElem any](value []TElem, message ...string) []TElem { + AssertEachIsDefined(value, message...) + return value +} + +var unexpectedNode []string = []string{"Unexpected node."} + +func AssertEachNode[TElem any](nodes []TElem, test func(elem TElem) bool, message ...string) { + if len(message) == 0 { + message = unexpectedNode + } + for _, elem := range nodes { + AssertNode(elem, test, message...) + } +} + +func AssertNode[TElem any](node TElem, test func(elem TElem) bool, message ...string) { + if len(message) == 0 { + message = unexpectedNode + } + AssertIsDefined(node, message...) + if test != nil { + Assert(test(node), message...) + } +} + +func AssertNotNode[TElem any](node TElem, test func(elem TElem) bool, message ...string) { + if isNil(node) { + return + } + if test == nil { + return + } + if len(message) == 0 { + message = unexpectedNode + } + Assert(!test(node), message...) +} + +func AssertOptionalNode[TElem any](node TElem, test func(elem TElem) bool, message ...string) { + if isNil(node) { + return + } + if test == nil { + return + } + if len(message) == 0 { + message = unexpectedNode + } + Assert(test(node), message...) +} + +func AssertOptionalToken[TElem interface{ KindValue() int16 }](node TElem, kind int16, message ...string) { + if isNil(node) { + return + } + if len(message) == 0 { + message = unexpectedNode + } + Assert(node.KindValue() == kind, message...) +} + +func AssertMissingNode[TElem any](node TElem, message ...string) { + if len(message) == 0 { + message = unexpectedNode + } + Assert(isNil(node), message...) +} diff --git a/kitcom/internal/tsgo/debug/release.go b/kitcom/internal/tsgo/debug/release.go new file mode 100644 index 0000000..f96ed90 --- /dev/null +++ b/kitcom/internal/tsgo/debug/release.go @@ -0,0 +1,26 @@ +//go:build release + +package debug + +import ( + "fmt" +) + +func Assert(expression bool, message ...string) {} +func AssertNil(value any, message ...string) {} +func AssertEqual(a fmt.Stringer, b fmt.Stringer, msg ...string) {} +func AssertLessThan(a int, b int, message ...string) {} +func AssertLessThanOrEqual(a int, b int, message ...string) {} +func AssertGreaterThan(a int, b int, message ...string) {} +func AssertGreaterThanOrEqual(a int, b int, message ...string) {} +func AssertIsDefined(value any, message ...string) {} +func CheckDefined[T any](value T, message ...string) T { return value } +func AssertEachIsDefined[TElem any](value []TElem, message ...string) {} +func CheckEachIsDefined[TElem any](value []TElem, message ...string) []TElem { return value } +func AssertEachNode[TElem any](nodes []TElem, test func(elem TElem) bool, message ...string) {} +func AssertNode[TElem any](node TElem, test func(elem TElem) bool, message ...string) {} +func AssertNotNode[TElem any](node TElem, test func(elem TElem) bool, message ...string) {} +func AssertOptionalNode[TElem any](node TElem, test func(elem TElem) bool, message ...string) {} +func AssertOptionalToken[TElem interface{ KindValue() int }](node TElem, kind int, message ...string) { +} +func AssertMissingNode[TElem any](node TElem, message ...string) {} diff --git a/kitcom/internal/tsgo/debug/shared.go b/kitcom/internal/tsgo/debug/shared.go new file mode 100644 index 0000000..aa2ff66 --- /dev/null +++ b/kitcom/internal/tsgo/debug/shared.go @@ -0,0 +1,43 @@ +package debug + +import ( + "fmt" +) + +func Fail(reason string) { + if len(reason) == 0 { + reason = "Debug failure." + } else { + reason = "Debug failure. " + reason + } + // runtime.Breakpoint() + panic(reason) +} + +func FailBadSyntaxKind(node interface{ KindString() string }, message ...string) { + var msg string + if len(message) == 0 { + msg = "Unexpected node." + } else { + msg = message[0] + } + Fail(fmt.Sprintf("%s\r\nNode %s was unexpected.", msg, node.KindString())) +} + +func AssertNever(member any, message ...string) { + var msg string + if len(message) == 0 { + msg = "Illegal value:" + } else { + msg = message[0] + } + var detail string + if member, ok := member.(interface{ KindString() string }); ok { + detail = member.KindString() + } else if member, ok := member.(fmt.Stringer); ok { + detail = member.String() + } else { + detail = fmt.Sprintf("%v", member) + } + Fail(fmt.Sprintf("%s %s", msg, detail)) +} diff --git a/kitcom/internal/tsgo/diagnostics/diagnostics.go b/kitcom/internal/tsgo/diagnostics/diagnostics.go new file mode 100644 index 0000000..62f1a1d --- /dev/null +++ b/kitcom/internal/tsgo/diagnostics/diagnostics.go @@ -0,0 +1,63 @@ +// Package diagnostics contains generated localizable diagnostic messages. +package diagnostics + +import "efprojects.com/kitten-ipc/kitcom/internal/tsgo/stringutil" + +//go:generate go run generate.go -output ./diagnostics_generated.go +//go:generate go tool golang.org/x/tools/cmd/stringer -type=Category -output=stringer_generated.go +//go:generate go tool mvdan.cc/gofumpt -w diagnostics_generated.go stringer_generated.go + +type Category int32 + +const ( + CategoryWarning Category = iota + CategoryError + CategorySuggestion + CategoryMessage +) + +func (category Category) Name() string { + switch category { + case CategoryWarning: + return "warning" + case CategoryError: + return "error" + case CategorySuggestion: + return "suggestion" + case CategoryMessage: + return "message" + } + panic("Unhandled diagnostic category") +} + +type Message struct { + code int32 + category Category + key string + text string + reportsUnnecessary bool + elidedInCompatibilityPyramid bool + reportsDeprecated bool +} + +func (m *Message) Code() int32 { return m.code } +func (m *Message) Category() Category { return m.category } +func (m *Message) Key() string { return m.key } +func (m *Message) Message() string { return m.text } +func (m *Message) ReportsUnnecessary() bool { return m.reportsUnnecessary } +func (m *Message) ElidedInCompatibilityPyramid() bool { return m.elidedInCompatibilityPyramid } +func (m *Message) ReportsDeprecated() bool { return m.reportsDeprecated } + +func (m *Message) Format(args ...any) string { + text := m.Message() + if len(args) != 0 { + text = stringutil.Format(text, args) + } + return text +} + +func FormatMessage(m *Message, args ...any) *Message { + result := *m + result.text = stringutil.Format(m.text, args) + return &result +} diff --git a/kitcom/internal/tsgo/diagnostics/diagnostics_generated.go b/kitcom/internal/tsgo/diagnostics/diagnostics_generated.go new file mode 100644 index 0000000..c40232c --- /dev/null +++ b/kitcom/internal/tsgo/diagnostics/diagnostics_generated.go @@ -0,0 +1,4255 @@ +// Code generated by generate.go; DO NOT EDIT. + +package diagnostics + +var Unterminated_string_literal = &Message{code: 1002, category: CategoryError, key: "Unterminated_string_literal_1002", text: "Unterminated string literal."} + +var Identifier_expected = &Message{code: 1003, category: CategoryError, key: "Identifier_expected_1003", text: "Identifier expected."} + +var X_0_expected = &Message{code: 1005, category: CategoryError, key: "_0_expected_1005", text: "'{0}' expected."} + +var A_file_cannot_have_a_reference_to_itself = &Message{code: 1006, category: CategoryError, key: "A_file_cannot_have_a_reference_to_itself_1006", text: "A file cannot have a reference to itself."} + +var The_parser_expected_to_find_a_1_to_match_the_0_token_here = &Message{code: 1007, category: CategoryError, key: "The_parser_expected_to_find_a_1_to_match_the_0_token_here_1007", text: "The parser expected to find a '{1}' to match the '{0}' token here."} + +var Trailing_comma_not_allowed = &Message{code: 1009, category: CategoryError, key: "Trailing_comma_not_allowed_1009", text: "Trailing comma not allowed."} + +var Asterisk_Slash_expected = &Message{code: 1010, category: CategoryError, key: "Asterisk_Slash_expected_1010", text: "'*/' expected."} + +var An_element_access_expression_should_take_an_argument = &Message{code: 1011, category: CategoryError, key: "An_element_access_expression_should_take_an_argument_1011", text: "An element access expression should take an argument."} + +var Unexpected_token = &Message{code: 1012, category: CategoryError, key: "Unexpected_token_1012", text: "Unexpected token."} + +var A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma = &Message{code: 1013, category: CategoryError, key: "A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma_1013", text: "A rest parameter or binding pattern may not have a trailing comma."} + +var A_rest_parameter_must_be_last_in_a_parameter_list = &Message{code: 1014, category: CategoryError, key: "A_rest_parameter_must_be_last_in_a_parameter_list_1014", text: "A rest parameter must be last in a parameter list."} + +var Parameter_cannot_have_question_mark_and_initializer = &Message{code: 1015, category: CategoryError, key: "Parameter_cannot_have_question_mark_and_initializer_1015", text: "Parameter cannot have question mark and initializer."} + +var A_required_parameter_cannot_follow_an_optional_parameter = &Message{code: 1016, category: CategoryError, key: "A_required_parameter_cannot_follow_an_optional_parameter_1016", text: "A required parameter cannot follow an optional parameter."} + +var An_index_signature_cannot_have_a_rest_parameter = &Message{code: 1017, category: CategoryError, key: "An_index_signature_cannot_have_a_rest_parameter_1017", text: "An index signature cannot have a rest parameter."} + +var An_index_signature_parameter_cannot_have_an_accessibility_modifier = &Message{code: 1018, category: CategoryError, key: "An_index_signature_parameter_cannot_have_an_accessibility_modifier_1018", text: "An index signature parameter cannot have an accessibility modifier."} + +var An_index_signature_parameter_cannot_have_a_question_mark = &Message{code: 1019, category: CategoryError, key: "An_index_signature_parameter_cannot_have_a_question_mark_1019", text: "An index signature parameter cannot have a question mark."} + +var An_index_signature_parameter_cannot_have_an_initializer = &Message{code: 1020, category: CategoryError, key: "An_index_signature_parameter_cannot_have_an_initializer_1020", text: "An index signature parameter cannot have an initializer."} + +var An_index_signature_must_have_a_type_annotation = &Message{code: 1021, category: CategoryError, key: "An_index_signature_must_have_a_type_annotation_1021", text: "An index signature must have a type annotation."} + +var An_index_signature_parameter_must_have_a_type_annotation = &Message{code: 1022, category: CategoryError, key: "An_index_signature_parameter_must_have_a_type_annotation_1022", text: "An index signature parameter must have a type annotation."} + +var X_readonly_modifier_can_only_appear_on_a_property_declaration_or_index_signature = &Message{code: 1024, category: CategoryError, key: "readonly_modifier_can_only_appear_on_a_property_declaration_or_index_signature_1024", text: "'readonly' modifier can only appear on a property declaration or index signature."} + +var An_index_signature_cannot_have_a_trailing_comma = &Message{code: 1025, category: CategoryError, key: "An_index_signature_cannot_have_a_trailing_comma_1025", text: "An index signature cannot have a trailing comma."} + +var Accessibility_modifier_already_seen = &Message{code: 1028, category: CategoryError, key: "Accessibility_modifier_already_seen_1028", text: "Accessibility modifier already seen."} + +var X_0_modifier_must_precede_1_modifier = &Message{code: 1029, category: CategoryError, key: "_0_modifier_must_precede_1_modifier_1029", text: "'{0}' modifier must precede '{1}' modifier."} + +var X_0_modifier_already_seen = &Message{code: 1030, category: CategoryError, key: "_0_modifier_already_seen_1030", text: "'{0}' modifier already seen."} + +var X_0_modifier_cannot_appear_on_class_elements_of_this_kind = &Message{code: 1031, category: CategoryError, key: "_0_modifier_cannot_appear_on_class_elements_of_this_kind_1031", text: "'{0}' modifier cannot appear on class elements of this kind."} + +var X_super_must_be_followed_by_an_argument_list_or_member_access = &Message{code: 1034, category: CategoryError, key: "super_must_be_followed_by_an_argument_list_or_member_access_1034", text: "'super' must be followed by an argument list or member access."} + +var Only_ambient_modules_can_use_quoted_names = &Message{code: 1035, category: CategoryError, key: "Only_ambient_modules_can_use_quoted_names_1035", text: "Only ambient modules can use quoted names."} + +var Statements_are_not_allowed_in_ambient_contexts = &Message{code: 1036, category: CategoryError, key: "Statements_are_not_allowed_in_ambient_contexts_1036", text: "Statements are not allowed in ambient contexts."} + +var A_declare_modifier_cannot_be_used_in_an_already_ambient_context = &Message{code: 1038, category: CategoryError, key: "A_declare_modifier_cannot_be_used_in_an_already_ambient_context_1038", text: "A 'declare' modifier cannot be used in an already ambient context."} + +var Initializers_are_not_allowed_in_ambient_contexts = &Message{code: 1039, category: CategoryError, key: "Initializers_are_not_allowed_in_ambient_contexts_1039", text: "Initializers are not allowed in ambient contexts."} + +var X_0_modifier_cannot_be_used_in_an_ambient_context = &Message{code: 1040, category: CategoryError, key: "_0_modifier_cannot_be_used_in_an_ambient_context_1040", text: "'{0}' modifier cannot be used in an ambient context."} + +var X_0_modifier_cannot_be_used_here = &Message{code: 1042, category: CategoryError, key: "_0_modifier_cannot_be_used_here_1042", text: "'{0}' modifier cannot be used here."} + +var X_0_modifier_cannot_appear_on_a_module_or_namespace_element = &Message{code: 1044, category: CategoryError, key: "_0_modifier_cannot_appear_on_a_module_or_namespace_element_1044", text: "'{0}' modifier cannot appear on a module or namespace element."} + +var Top_level_declarations_in_d_ts_files_must_start_with_either_a_declare_or_export_modifier = &Message{code: 1046, category: CategoryError, key: "Top_level_declarations_in_d_ts_files_must_start_with_either_a_declare_or_export_modifier_1046", text: "Top-level declarations in .d.ts files must start with either a 'declare' or 'export' modifier."} + +var A_rest_parameter_cannot_be_optional = &Message{code: 1047, category: CategoryError, key: "A_rest_parameter_cannot_be_optional_1047", text: "A rest parameter cannot be optional."} + +var A_rest_parameter_cannot_have_an_initializer = &Message{code: 1048, category: CategoryError, key: "A_rest_parameter_cannot_have_an_initializer_1048", text: "A rest parameter cannot have an initializer."} + +var A_set_accessor_must_have_exactly_one_parameter = &Message{code: 1049, category: CategoryError, key: "A_set_accessor_must_have_exactly_one_parameter_1049", text: "A 'set' accessor must have exactly one parameter."} + +var A_set_accessor_cannot_have_an_optional_parameter = &Message{code: 1051, category: CategoryError, key: "A_set_accessor_cannot_have_an_optional_parameter_1051", text: "A 'set' accessor cannot have an optional parameter."} + +var A_set_accessor_parameter_cannot_have_an_initializer = &Message{code: 1052, category: CategoryError, key: "A_set_accessor_parameter_cannot_have_an_initializer_1052", text: "A 'set' accessor parameter cannot have an initializer."} + +var A_set_accessor_cannot_have_rest_parameter = &Message{code: 1053, category: CategoryError, key: "A_set_accessor_cannot_have_rest_parameter_1053", text: "A 'set' accessor cannot have rest parameter."} + +var A_get_accessor_cannot_have_parameters = &Message{code: 1054, category: CategoryError, key: "A_get_accessor_cannot_have_parameters_1054", text: "A 'get' accessor cannot have parameters."} + +var Type_0_is_not_a_valid_async_function_return_type_in_ES5_because_it_does_not_refer_to_a_Promise_compatible_constructor_value = &Message{code: 1055, category: CategoryError, key: "Type_0_is_not_a_valid_async_function_return_type_in_ES5_because_it_does_not_refer_to_a_Promise_compa_1055", text: "Type '{0}' is not a valid async function return type in ES5 because it does not refer to a Promise-compatible constructor value."} + +var Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher = &Message{code: 1056, category: CategoryError, key: "Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher_1056", text: "Accessors are only available when targeting ECMAScript 5 and higher."} + +var The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member = &Message{code: 1058, category: CategoryError, key: "The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_t_1058", text: "The return type of an async function must either be a valid promise or must not contain a callable 'then' member."} + +var A_promise_must_have_a_then_method = &Message{code: 1059, category: CategoryError, key: "A_promise_must_have_a_then_method_1059", text: "A promise must have a 'then' method."} + +var The_first_parameter_of_the_then_method_of_a_promise_must_be_a_callback = &Message{code: 1060, category: CategoryError, key: "The_first_parameter_of_the_then_method_of_a_promise_must_be_a_callback_1060", text: "The first parameter of the 'then' method of a promise must be a callback."} + +var Enum_member_must_have_initializer = &Message{code: 1061, category: CategoryError, key: "Enum_member_must_have_initializer_1061", text: "Enum member must have initializer."} + +var Type_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method = &Message{code: 1062, category: CategoryError, key: "Type_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method_1062", text: "Type is referenced directly or indirectly in the fulfillment callback of its own 'then' method."} + +var An_export_assignment_cannot_be_used_in_a_namespace = &Message{code: 1063, category: CategoryError, key: "An_export_assignment_cannot_be_used_in_a_namespace_1063", text: "An export assignment cannot be used in a namespace."} + +var The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type_Did_you_mean_to_write_Promise_0 = &Message{code: 1064, category: CategoryError, key: "The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type_Did_you_mean_to_wri_1064", text: "The return type of an async function or method must be the global Promise type. Did you mean to write 'Promise<{0}>'?"} + +var The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type = &Message{code: 1065, category: CategoryError, key: "The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type_1065", text: "The return type of an async function or method must be the global Promise type."} + +var In_ambient_enum_declarations_member_initializer_must_be_constant_expression = &Message{code: 1066, category: CategoryError, key: "In_ambient_enum_declarations_member_initializer_must_be_constant_expression_1066", text: "In ambient enum declarations member initializer must be constant expression."} + +var Unexpected_token_A_constructor_method_accessor_or_property_was_expected = &Message{code: 1068, category: CategoryError, key: "Unexpected_token_A_constructor_method_accessor_or_property_was_expected_1068", text: "Unexpected token. A constructor, method, accessor, or property was expected."} + +var Unexpected_token_A_type_parameter_name_was_expected_without_curly_braces = &Message{code: 1069, category: CategoryError, key: "Unexpected_token_A_type_parameter_name_was_expected_without_curly_braces_1069", text: "Unexpected token. A type parameter name was expected without curly braces."} + +var X_0_modifier_cannot_appear_on_a_type_member = &Message{code: 1070, category: CategoryError, key: "_0_modifier_cannot_appear_on_a_type_member_1070", text: "'{0}' modifier cannot appear on a type member."} + +var X_0_modifier_cannot_appear_on_an_index_signature = &Message{code: 1071, category: CategoryError, key: "_0_modifier_cannot_appear_on_an_index_signature_1071", text: "'{0}' modifier cannot appear on an index signature."} + +var A_0_modifier_cannot_be_used_with_an_import_declaration = &Message{code: 1079, category: CategoryError, key: "A_0_modifier_cannot_be_used_with_an_import_declaration_1079", text: "A '{0}' modifier cannot be used with an import declaration."} + +var Invalid_reference_directive_syntax = &Message{code: 1084, category: CategoryError, key: "Invalid_reference_directive_syntax_1084", text: "Invalid 'reference' directive syntax."} + +var X_0_modifier_cannot_appear_on_a_constructor_declaration = &Message{code: 1089, category: CategoryError, key: "_0_modifier_cannot_appear_on_a_constructor_declaration_1089", text: "'{0}' modifier cannot appear on a constructor declaration."} + +var X_0_modifier_cannot_appear_on_a_parameter = &Message{code: 1090, category: CategoryError, key: "_0_modifier_cannot_appear_on_a_parameter_1090", text: "'{0}' modifier cannot appear on a parameter."} + +var Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement = &Message{code: 1091, category: CategoryError, key: "Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement_1091", text: "Only a single variable declaration is allowed in a 'for...in' statement."} + +var Type_parameters_cannot_appear_on_a_constructor_declaration = &Message{code: 1092, category: CategoryError, key: "Type_parameters_cannot_appear_on_a_constructor_declaration_1092", text: "Type parameters cannot appear on a constructor declaration."} + +var Type_annotation_cannot_appear_on_a_constructor_declaration = &Message{code: 1093, category: CategoryError, key: "Type_annotation_cannot_appear_on_a_constructor_declaration_1093", text: "Type annotation cannot appear on a constructor declaration."} + +var An_accessor_cannot_have_type_parameters = &Message{code: 1094, category: CategoryError, key: "An_accessor_cannot_have_type_parameters_1094", text: "An accessor cannot have type parameters."} + +var A_set_accessor_cannot_have_a_return_type_annotation = &Message{code: 1095, category: CategoryError, key: "A_set_accessor_cannot_have_a_return_type_annotation_1095", text: "A 'set' accessor cannot have a return type annotation."} + +var An_index_signature_must_have_exactly_one_parameter = &Message{code: 1096, category: CategoryError, key: "An_index_signature_must_have_exactly_one_parameter_1096", text: "An index signature must have exactly one parameter."} + +var X_0_list_cannot_be_empty = &Message{code: 1097, category: CategoryError, key: "_0_list_cannot_be_empty_1097", text: "'{0}' list cannot be empty."} + +var Type_parameter_list_cannot_be_empty = &Message{code: 1098, category: CategoryError, key: "Type_parameter_list_cannot_be_empty_1098", text: "Type parameter list cannot be empty."} + +var Type_argument_list_cannot_be_empty = &Message{code: 1099, category: CategoryError, key: "Type_argument_list_cannot_be_empty_1099", text: "Type argument list cannot be empty."} + +var Invalid_use_of_0_in_strict_mode = &Message{code: 1100, category: CategoryError, key: "Invalid_use_of_0_in_strict_mode_1100", text: "Invalid use of '{0}' in strict mode."} + +var X_with_statements_are_not_allowed_in_strict_mode = &Message{code: 1101, category: CategoryError, key: "with_statements_are_not_allowed_in_strict_mode_1101", text: "'with' statements are not allowed in strict mode."} + +var X_delete_cannot_be_called_on_an_identifier_in_strict_mode = &Message{code: 1102, category: CategoryError, key: "delete_cannot_be_called_on_an_identifier_in_strict_mode_1102", text: "'delete' cannot be called on an identifier in strict mode."} + +var X_for_await_loops_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules = &Message{code: 1103, category: CategoryError, key: "for_await_loops_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules_1103", text: "'for await' loops are only allowed within async functions and at the top levels of modules."} + +var A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement = &Message{code: 1104, category: CategoryError, key: "A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement_1104", text: "A 'continue' statement can only be used within an enclosing iteration statement."} + +var A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement = &Message{code: 1105, category: CategoryError, key: "A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement_1105", text: "A 'break' statement can only be used within an enclosing iteration or switch statement."} + +var The_left_hand_side_of_a_for_of_statement_may_not_be_async = &Message{code: 1106, category: CategoryError, key: "The_left_hand_side_of_a_for_of_statement_may_not_be_async_1106", text: "The left-hand side of a 'for...of' statement may not be 'async'."} + +var Jump_target_cannot_cross_function_boundary = &Message{code: 1107, category: CategoryError, key: "Jump_target_cannot_cross_function_boundary_1107", text: "Jump target cannot cross function boundary."} + +var A_return_statement_can_only_be_used_within_a_function_body = &Message{code: 1108, category: CategoryError, key: "A_return_statement_can_only_be_used_within_a_function_body_1108", text: "A 'return' statement can only be used within a function body."} + +var Expression_expected = &Message{code: 1109, category: CategoryError, key: "Expression_expected_1109", text: "Expression expected."} + +var Type_expected = &Message{code: 1110, category: CategoryError, key: "Type_expected_1110", text: "Type expected."} + +var Private_field_0_must_be_declared_in_an_enclosing_class = &Message{code: 1111, category: CategoryError, key: "Private_field_0_must_be_declared_in_an_enclosing_class_1111", text: "Private field '{0}' must be declared in an enclosing class."} + +var A_default_clause_cannot_appear_more_than_once_in_a_switch_statement = &Message{code: 1113, category: CategoryError, key: "A_default_clause_cannot_appear_more_than_once_in_a_switch_statement_1113", text: "A 'default' clause cannot appear more than once in a 'switch' statement."} + +var Duplicate_label_0 = &Message{code: 1114, category: CategoryError, key: "Duplicate_label_0_1114", text: "Duplicate label '{0}'."} + +var A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement = &Message{code: 1115, category: CategoryError, key: "A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement_1115", text: "A 'continue' statement can only jump to a label of an enclosing iteration statement."} + +var A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement = &Message{code: 1116, category: CategoryError, key: "A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement_1116", text: "A 'break' statement can only jump to a label of an enclosing statement."} + +var An_object_literal_cannot_have_multiple_properties_with_the_same_name = &Message{code: 1117, category: CategoryError, key: "An_object_literal_cannot_have_multiple_properties_with_the_same_name_1117", text: "An object literal cannot have multiple properties with the same name."} + +var An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name = &Message{code: 1118, category: CategoryError, key: "An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name_1118", text: "An object literal cannot have multiple get/set accessors with the same name."} + +var An_object_literal_cannot_have_property_and_accessor_with_the_same_name = &Message{code: 1119, category: CategoryError, key: "An_object_literal_cannot_have_property_and_accessor_with_the_same_name_1119", text: "An object literal cannot have property and accessor with the same name."} + +var An_export_assignment_cannot_have_modifiers = &Message{code: 1120, category: CategoryError, key: "An_export_assignment_cannot_have_modifiers_1120", text: "An export assignment cannot have modifiers."} + +var Octal_literals_are_not_allowed_Use_the_syntax_0 = &Message{code: 1121, category: CategoryError, key: "Octal_literals_are_not_allowed_Use_the_syntax_0_1121", text: "Octal literals are not allowed. Use the syntax '{0}'."} + +var Variable_declaration_list_cannot_be_empty = &Message{code: 1123, category: CategoryError, key: "Variable_declaration_list_cannot_be_empty_1123", text: "Variable declaration list cannot be empty."} + +var Digit_expected = &Message{code: 1124, category: CategoryError, key: "Digit_expected_1124", text: "Digit expected."} + +var Hexadecimal_digit_expected = &Message{code: 1125, category: CategoryError, key: "Hexadecimal_digit_expected_1125", text: "Hexadecimal digit expected."} + +var Unexpected_end_of_text = &Message{code: 1126, category: CategoryError, key: "Unexpected_end_of_text_1126", text: "Unexpected end of text."} + +var Invalid_character = &Message{code: 1127, category: CategoryError, key: "Invalid_character_1127", text: "Invalid character."} + +var Declaration_or_statement_expected = &Message{code: 1128, category: CategoryError, key: "Declaration_or_statement_expected_1128", text: "Declaration or statement expected."} + +var Statement_expected = &Message{code: 1129, category: CategoryError, key: "Statement_expected_1129", text: "Statement expected."} + +var X_case_or_default_expected = &Message{code: 1130, category: CategoryError, key: "case_or_default_expected_1130", text: "'case' or 'default' expected."} + +var Property_or_signature_expected = &Message{code: 1131, category: CategoryError, key: "Property_or_signature_expected_1131", text: "Property or signature expected."} + +var Enum_member_expected = &Message{code: 1132, category: CategoryError, key: "Enum_member_expected_1132", text: "Enum member expected."} + +var Variable_declaration_expected = &Message{code: 1134, category: CategoryError, key: "Variable_declaration_expected_1134", text: "Variable declaration expected."} + +var Argument_expression_expected = &Message{code: 1135, category: CategoryError, key: "Argument_expression_expected_1135", text: "Argument expression expected."} + +var Property_assignment_expected = &Message{code: 1136, category: CategoryError, key: "Property_assignment_expected_1136", text: "Property assignment expected."} + +var Expression_or_comma_expected = &Message{code: 1137, category: CategoryError, key: "Expression_or_comma_expected_1137", text: "Expression or comma expected."} + +var Parameter_declaration_expected = &Message{code: 1138, category: CategoryError, key: "Parameter_declaration_expected_1138", text: "Parameter declaration expected."} + +var Type_parameter_declaration_expected = &Message{code: 1139, category: CategoryError, key: "Type_parameter_declaration_expected_1139", text: "Type parameter declaration expected."} + +var Type_argument_expected = &Message{code: 1140, category: CategoryError, key: "Type_argument_expected_1140", text: "Type argument expected."} + +var String_literal_expected = &Message{code: 1141, category: CategoryError, key: "String_literal_expected_1141", text: "String literal expected."} + +var Line_break_not_permitted_here = &Message{code: 1142, category: CategoryError, key: "Line_break_not_permitted_here_1142", text: "Line break not permitted here."} + +var X_or_expected = &Message{code: 1144, category: CategoryError, key: "or_expected_1144", text: "'{' or ';' expected."} + +var X_or_JSX_element_expected = &Message{code: 1145, category: CategoryError, key: "or_JSX_element_expected_1145", text: "'{' or JSX element expected."} + +var Declaration_expected = &Message{code: 1146, category: CategoryError, key: "Declaration_expected_1146", text: "Declaration expected."} + +var Import_declarations_in_a_namespace_cannot_reference_a_module = &Message{code: 1147, category: CategoryError, key: "Import_declarations_in_a_namespace_cannot_reference_a_module_1147", text: "Import declarations in a namespace cannot reference a module."} + +var Cannot_use_imports_exports_or_module_augmentations_when_module_is_none = &Message{code: 1148, category: CategoryError, key: "Cannot_use_imports_exports_or_module_augmentations_when_module_is_none_1148", text: "Cannot use imports, exports, or module augmentations when '--module' is 'none'."} + +var File_name_0_differs_from_already_included_file_name_1_only_in_casing = &Message{code: 1149, category: CategoryError, key: "File_name_0_differs_from_already_included_file_name_1_only_in_casing_1149", text: "File name '{0}' differs from already included file name '{1}' only in casing."} + +var X_0_declarations_must_be_initialized = &Message{code: 1155, category: CategoryError, key: "_0_declarations_must_be_initialized_1155", text: "'{0}' declarations must be initialized."} + +var X_0_declarations_can_only_be_declared_inside_a_block = &Message{code: 1156, category: CategoryError, key: "_0_declarations_can_only_be_declared_inside_a_block_1156", text: "'{0}' declarations can only be declared inside a block."} + +var Unterminated_template_literal = &Message{code: 1160, category: CategoryError, key: "Unterminated_template_literal_1160", text: "Unterminated template literal."} + +var Unterminated_regular_expression_literal = &Message{code: 1161, category: CategoryError, key: "Unterminated_regular_expression_literal_1161", text: "Unterminated regular expression literal."} + +var An_object_member_cannot_be_declared_optional = &Message{code: 1162, category: CategoryError, key: "An_object_member_cannot_be_declared_optional_1162", text: "An object member cannot be declared optional."} + +var A_yield_expression_is_only_allowed_in_a_generator_body = &Message{code: 1163, category: CategoryError, key: "A_yield_expression_is_only_allowed_in_a_generator_body_1163", text: "A 'yield' expression is only allowed in a generator body."} + +var Computed_property_names_are_not_allowed_in_enums = &Message{code: 1164, category: CategoryError, key: "Computed_property_names_are_not_allowed_in_enums_1164", text: "Computed property names are not allowed in enums."} + +var A_computed_property_name_in_an_ambient_context_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type = &Message{code: 1165, category: CategoryError, key: "A_computed_property_name_in_an_ambient_context_must_refer_to_an_expression_whose_type_is_a_literal_t_1165", text: "A computed property name in an ambient context must refer to an expression whose type is a literal type or a 'unique symbol' type."} + +var A_computed_property_name_in_a_class_property_declaration_must_have_a_simple_literal_type_or_a_unique_symbol_type = &Message{code: 1166, category: CategoryError, key: "A_computed_property_name_in_a_class_property_declaration_must_have_a_simple_literal_type_or_a_unique_1166", text: "A computed property name in a class property declaration must have a simple literal type or a 'unique symbol' type."} + +var A_computed_property_name_in_a_method_overload_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type = &Message{code: 1168, category: CategoryError, key: "A_computed_property_name_in_a_method_overload_must_refer_to_an_expression_whose_type_is_a_literal_ty_1168", text: "A computed property name in a method overload must refer to an expression whose type is a literal type or a 'unique symbol' type."} + +var A_computed_property_name_in_an_interface_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type = &Message{code: 1169, category: CategoryError, key: "A_computed_property_name_in_an_interface_must_refer_to_an_expression_whose_type_is_a_literal_type_or_1169", text: "A computed property name in an interface must refer to an expression whose type is a literal type or a 'unique symbol' type."} + +var A_computed_property_name_in_a_type_literal_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type = &Message{code: 1170, category: CategoryError, key: "A_computed_property_name_in_a_type_literal_must_refer_to_an_expression_whose_type_is_a_literal_type__1170", text: "A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type."} + +var A_comma_expression_is_not_allowed_in_a_computed_property_name = &Message{code: 1171, category: CategoryError, key: "A_comma_expression_is_not_allowed_in_a_computed_property_name_1171", text: "A comma expression is not allowed in a computed property name."} + +var X_extends_clause_already_seen = &Message{code: 1172, category: CategoryError, key: "extends_clause_already_seen_1172", text: "'extends' clause already seen."} + +var X_extends_clause_must_precede_implements_clause = &Message{code: 1173, category: CategoryError, key: "extends_clause_must_precede_implements_clause_1173", text: "'extends' clause must precede 'implements' clause."} + +var Classes_can_only_extend_a_single_class = &Message{code: 1174, category: CategoryError, key: "Classes_can_only_extend_a_single_class_1174", text: "Classes can only extend a single class."} + +var X_implements_clause_already_seen = &Message{code: 1175, category: CategoryError, key: "implements_clause_already_seen_1175", text: "'implements' clause already seen."} + +var Interface_declaration_cannot_have_implements_clause = &Message{code: 1176, category: CategoryError, key: "Interface_declaration_cannot_have_implements_clause_1176", text: "Interface declaration cannot have 'implements' clause."} + +var Binary_digit_expected = &Message{code: 1177, category: CategoryError, key: "Binary_digit_expected_1177", text: "Binary digit expected."} + +var Octal_digit_expected = &Message{code: 1178, category: CategoryError, key: "Octal_digit_expected_1178", text: "Octal digit expected."} + +var Unexpected_token_expected = &Message{code: 1179, category: CategoryError, key: "Unexpected_token_expected_1179", text: "Unexpected token. '{' expected."} + +var Property_destructuring_pattern_expected = &Message{code: 1180, category: CategoryError, key: "Property_destructuring_pattern_expected_1180", text: "Property destructuring pattern expected."} + +var Array_element_destructuring_pattern_expected = &Message{code: 1181, category: CategoryError, key: "Array_element_destructuring_pattern_expected_1181", text: "Array element destructuring pattern expected."} + +var A_destructuring_declaration_must_have_an_initializer = &Message{code: 1182, category: CategoryError, key: "A_destructuring_declaration_must_have_an_initializer_1182", text: "A destructuring declaration must have an initializer."} + +var An_implementation_cannot_be_declared_in_ambient_contexts = &Message{code: 1183, category: CategoryError, key: "An_implementation_cannot_be_declared_in_ambient_contexts_1183", text: "An implementation cannot be declared in ambient contexts."} + +var Modifiers_cannot_appear_here = &Message{code: 1184, category: CategoryError, key: "Modifiers_cannot_appear_here_1184", text: "Modifiers cannot appear here."} + +var Merge_conflict_marker_encountered = &Message{code: 1185, category: CategoryError, key: "Merge_conflict_marker_encountered_1185", text: "Merge conflict marker encountered."} + +var A_rest_element_cannot_have_an_initializer = &Message{code: 1186, category: CategoryError, key: "A_rest_element_cannot_have_an_initializer_1186", text: "A rest element cannot have an initializer."} + +var A_parameter_property_may_not_be_declared_using_a_binding_pattern = &Message{code: 1187, category: CategoryError, key: "A_parameter_property_may_not_be_declared_using_a_binding_pattern_1187", text: "A parameter property may not be declared using a binding pattern."} + +var Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement = &Message{code: 1188, category: CategoryError, key: "Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement_1188", text: "Only a single variable declaration is allowed in a 'for...of' statement."} + +var The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer = &Message{code: 1189, category: CategoryError, key: "The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer_1189", text: "The variable declaration of a 'for...in' statement cannot have an initializer."} + +var The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer = &Message{code: 1190, category: CategoryError, key: "The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer_1190", text: "The variable declaration of a 'for...of' statement cannot have an initializer."} + +var An_import_declaration_cannot_have_modifiers = &Message{code: 1191, category: CategoryError, key: "An_import_declaration_cannot_have_modifiers_1191", text: "An import declaration cannot have modifiers."} + +var Module_0_has_no_default_export = &Message{code: 1192, category: CategoryError, key: "Module_0_has_no_default_export_1192", text: "Module '{0}' has no default export."} + +var An_export_declaration_cannot_have_modifiers = &Message{code: 1193, category: CategoryError, key: "An_export_declaration_cannot_have_modifiers_1193", text: "An export declaration cannot have modifiers."} + +var Export_declarations_are_not_permitted_in_a_namespace = &Message{code: 1194, category: CategoryError, key: "Export_declarations_are_not_permitted_in_a_namespace_1194", text: "Export declarations are not permitted in a namespace."} + +var X_export_Asterisk_does_not_re_export_a_default = &Message{code: 1195, category: CategoryError, key: "export_Asterisk_does_not_re_export_a_default_1195", text: "'export *' does not re-export a default."} + +var Catch_clause_variable_type_annotation_must_be_any_or_unknown_if_specified = &Message{code: 1196, category: CategoryError, key: "Catch_clause_variable_type_annotation_must_be_any_or_unknown_if_specified_1196", text: "Catch clause variable type annotation must be 'any' or 'unknown' if specified."} + +var Catch_clause_variable_cannot_have_an_initializer = &Message{code: 1197, category: CategoryError, key: "Catch_clause_variable_cannot_have_an_initializer_1197", text: "Catch clause variable cannot have an initializer."} + +var An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive = &Message{code: 1198, category: CategoryError, key: "An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive_1198", text: "An extended Unicode escape value must be between 0x0 and 0x10FFFF inclusive."} + +var Unterminated_Unicode_escape_sequence = &Message{code: 1199, category: CategoryError, key: "Unterminated_Unicode_escape_sequence_1199", text: "Unterminated Unicode escape sequence."} + +var Line_terminator_not_permitted_before_arrow = &Message{code: 1200, category: CategoryError, key: "Line_terminator_not_permitted_before_arrow_1200", text: "Line terminator not permitted before arrow."} + +var Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_import_d_from_mod_or_another_module_format_instead = &Message{code: 1202, category: CategoryError, key: "Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_1202", text: "Import assignment cannot be used when targeting ECMAScript modules. Consider using 'import * as ns from \"mod\"', 'import {a} from \"mod\"', 'import d from \"mod\"', or another module format instead."} + +var Export_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_export_default_or_another_module_format_instead = &Message{code: 1203, category: CategoryError, key: "Export_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_export_default_or__1203", text: "Export assignment cannot be used when targeting ECMAScript modules. Consider using 'export default' or another module format instead."} + +var Re_exporting_a_type_when_0_is_enabled_requires_using_export_type = &Message{code: 1205, category: CategoryError, key: "Re_exporting_a_type_when_0_is_enabled_requires_using_export_type_1205", text: "Re-exporting a type when '{0}' is enabled requires using 'export type'."} + +var Decorators_are_not_valid_here = &Message{code: 1206, category: CategoryError, key: "Decorators_are_not_valid_here_1206", text: "Decorators are not valid here."} + +var Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name = &Message{code: 1207, category: CategoryError, key: "Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name_1207", text: "Decorators cannot be applied to multiple get/set accessors of the same name."} + +var Invalid_optional_chain_from_new_expression_Did_you_mean_to_call_0 = &Message{code: 1209, category: CategoryError, key: "Invalid_optional_chain_from_new_expression_Did_you_mean_to_call_0_1209", text: "Invalid optional chain from new expression. Did you mean to call '{0}()'?"} + +var 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 = &Message{code: 1210, category: CategoryError, key: "Code_contained_in_a_class_is_evaluated_in_JavaScript_s_strict_mode_which_does_not_allow_this_use_of__1210", text: "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://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode."} + +var A_class_declaration_without_the_default_modifier_must_have_a_name = &Message{code: 1211, category: CategoryError, key: "A_class_declaration_without_the_default_modifier_must_have_a_name_1211", text: "A class declaration without the 'default' modifier must have a name."} + +var Identifier_expected_0_is_a_reserved_word_in_strict_mode = &Message{code: 1212, category: CategoryError, key: "Identifier_expected_0_is_a_reserved_word_in_strict_mode_1212", text: "Identifier expected. '{0}' is a reserved word in strict mode."} + +var Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode = &Message{code: 1213, category: CategoryError, key: "Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_stric_1213", text: "Identifier expected. '{0}' is a reserved word in strict mode. Class definitions are automatically in strict mode."} + +var Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode = &Message{code: 1214, category: CategoryError, key: "Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode_1214", text: "Identifier expected. '{0}' is a reserved word in strict mode. Modules are automatically in strict mode."} + +var Invalid_use_of_0_Modules_are_automatically_in_strict_mode = &Message{code: 1215, category: CategoryError, key: "Invalid_use_of_0_Modules_are_automatically_in_strict_mode_1215", text: "Invalid use of '{0}'. Modules are automatically in strict mode."} + +var Identifier_expected_esModule_is_reserved_as_an_exported_marker_when_transforming_ECMAScript_modules = &Message{code: 1216, category: CategoryError, key: "Identifier_expected_esModule_is_reserved_as_an_exported_marker_when_transforming_ECMAScript_modules_1216", text: "Identifier expected. '__esModule' is reserved as an exported marker when transforming ECMAScript modules."} + +var Export_assignment_is_not_supported_when_module_flag_is_system = &Message{code: 1218, category: CategoryError, key: "Export_assignment_is_not_supported_when_module_flag_is_system_1218", text: "Export assignment is not supported when '--module' flag is 'system'."} + +var Generators_are_not_allowed_in_an_ambient_context = &Message{code: 1221, category: CategoryError, key: "Generators_are_not_allowed_in_an_ambient_context_1221", text: "Generators are not allowed in an ambient context."} + +var An_overload_signature_cannot_be_declared_as_a_generator = &Message{code: 1222, category: CategoryError, key: "An_overload_signature_cannot_be_declared_as_a_generator_1222", text: "An overload signature cannot be declared as a generator."} + +var X_0_tag_already_specified = &Message{code: 1223, category: CategoryError, key: "_0_tag_already_specified_1223", text: "'{0}' tag already specified."} + +var Signature_0_must_be_a_type_predicate = &Message{code: 1224, category: CategoryError, key: "Signature_0_must_be_a_type_predicate_1224", text: "Signature '{0}' must be a type predicate."} + +var Cannot_find_parameter_0 = &Message{code: 1225, category: CategoryError, key: "Cannot_find_parameter_0_1225", text: "Cannot find parameter '{0}'."} + +var Type_predicate_0_is_not_assignable_to_1 = &Message{code: 1226, category: CategoryError, key: "Type_predicate_0_is_not_assignable_to_1_1226", text: "Type predicate '{0}' is not assignable to '{1}'."} + +var Parameter_0_is_not_in_the_same_position_as_parameter_1 = &Message{code: 1227, category: CategoryError, key: "Parameter_0_is_not_in_the_same_position_as_parameter_1_1227", text: "Parameter '{0}' is not in the same position as parameter '{1}'."} + +var A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods = &Message{code: 1228, category: CategoryError, key: "A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods_1228", text: "A type predicate is only allowed in return type position for functions and methods."} + +var A_type_predicate_cannot_reference_a_rest_parameter = &Message{code: 1229, category: CategoryError, key: "A_type_predicate_cannot_reference_a_rest_parameter_1229", text: "A type predicate cannot reference a rest parameter."} + +var A_type_predicate_cannot_reference_element_0_in_a_binding_pattern = &Message{code: 1230, category: CategoryError, key: "A_type_predicate_cannot_reference_element_0_in_a_binding_pattern_1230", text: "A type predicate cannot reference element '{0}' in a binding pattern."} + +var An_export_assignment_must_be_at_the_top_level_of_a_file_or_module_declaration = &Message{code: 1231, category: CategoryError, key: "An_export_assignment_must_be_at_the_top_level_of_a_file_or_module_declaration_1231", text: "An export assignment must be at the top level of a file or module declaration."} + +var An_import_declaration_can_only_be_used_at_the_top_level_of_a_namespace_or_module = &Message{code: 1232, category: CategoryError, key: "An_import_declaration_can_only_be_used_at_the_top_level_of_a_namespace_or_module_1232", text: "An import declaration can only be used at the top level of a namespace or module."} + +var An_export_declaration_can_only_be_used_at_the_top_level_of_a_namespace_or_module = &Message{code: 1233, category: CategoryError, key: "An_export_declaration_can_only_be_used_at_the_top_level_of_a_namespace_or_module_1233", text: "An export declaration can only be used at the top level of a namespace or module."} + +var An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file = &Message{code: 1234, category: CategoryError, key: "An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file_1234", text: "An ambient module declaration is only allowed at the top level in a file."} + +var A_namespace_declaration_is_only_allowed_at_the_top_level_of_a_namespace_or_module = &Message{code: 1235, category: CategoryError, key: "A_namespace_declaration_is_only_allowed_at_the_top_level_of_a_namespace_or_module_1235", text: "A namespace declaration is only allowed at the top level of a namespace or module."} + +var The_return_type_of_a_property_decorator_function_must_be_either_void_or_any = &Message{code: 1236, category: CategoryError, key: "The_return_type_of_a_property_decorator_function_must_be_either_void_or_any_1236", text: "The return type of a property decorator function must be either 'void' or 'any'."} + +var The_return_type_of_a_parameter_decorator_function_must_be_either_void_or_any = &Message{code: 1237, category: CategoryError, key: "The_return_type_of_a_parameter_decorator_function_must_be_either_void_or_any_1237", text: "The return type of a parameter decorator function must be either 'void' or 'any'."} + +var Unable_to_resolve_signature_of_class_decorator_when_called_as_an_expression = &Message{code: 1238, category: CategoryError, key: "Unable_to_resolve_signature_of_class_decorator_when_called_as_an_expression_1238", text: "Unable to resolve signature of class decorator when called as an expression."} + +var Unable_to_resolve_signature_of_parameter_decorator_when_called_as_an_expression = &Message{code: 1239, category: CategoryError, key: "Unable_to_resolve_signature_of_parameter_decorator_when_called_as_an_expression_1239", text: "Unable to resolve signature of parameter decorator when called as an expression."} + +var Unable_to_resolve_signature_of_property_decorator_when_called_as_an_expression = &Message{code: 1240, category: CategoryError, key: "Unable_to_resolve_signature_of_property_decorator_when_called_as_an_expression_1240", text: "Unable to resolve signature of property decorator when called as an expression."} + +var Unable_to_resolve_signature_of_method_decorator_when_called_as_an_expression = &Message{code: 1241, category: CategoryError, key: "Unable_to_resolve_signature_of_method_decorator_when_called_as_an_expression_1241", text: "Unable to resolve signature of method decorator when called as an expression."} + +var X_abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration = &Message{code: 1242, category: CategoryError, key: "abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration_1242", text: "'abstract' modifier can only appear on a class, method, or property declaration."} + +var X_0_modifier_cannot_be_used_with_1_modifier = &Message{code: 1243, category: CategoryError, key: "_0_modifier_cannot_be_used_with_1_modifier_1243", text: "'{0}' modifier cannot be used with '{1}' modifier."} + +var Abstract_methods_can_only_appear_within_an_abstract_class = &Message{code: 1244, category: CategoryError, key: "Abstract_methods_can_only_appear_within_an_abstract_class_1244", text: "Abstract methods can only appear within an abstract class."} + +var Method_0_cannot_have_an_implementation_because_it_is_marked_abstract = &Message{code: 1245, category: CategoryError, key: "Method_0_cannot_have_an_implementation_because_it_is_marked_abstract_1245", text: "Method '{0}' cannot have an implementation because it is marked abstract."} + +var An_interface_property_cannot_have_an_initializer = &Message{code: 1246, category: CategoryError, key: "An_interface_property_cannot_have_an_initializer_1246", text: "An interface property cannot have an initializer."} + +var A_type_literal_property_cannot_have_an_initializer = &Message{code: 1247, category: CategoryError, key: "A_type_literal_property_cannot_have_an_initializer_1247", text: "A type literal property cannot have an initializer."} + +var A_class_member_cannot_have_the_0_keyword = &Message{code: 1248, category: CategoryError, key: "A_class_member_cannot_have_the_0_keyword_1248", text: "A class member cannot have the '{0}' keyword."} + +var A_decorator_can_only_decorate_a_method_implementation_not_an_overload = &Message{code: 1249, category: CategoryError, key: "A_decorator_can_only_decorate_a_method_implementation_not_an_overload_1249", text: "A decorator can only decorate a method implementation, not an overload."} + +var Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES5 = &Message{code: 1250, category: CategoryError, key: "Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES5_1250", text: "Function declarations are not allowed inside blocks in strict mode when targeting 'ES5'."} + +var Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES5_Class_definitions_are_automatically_in_strict_mode = &Message{code: 1251, category: CategoryError, key: "Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES5_Class_definiti_1251", text: "Function declarations are not allowed inside blocks in strict mode when targeting 'ES5'. Class definitions are automatically in strict mode."} + +var Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES5_Modules_are_automatically_in_strict_mode = &Message{code: 1252, category: CategoryError, key: "Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES5_Modules_are_au_1252", text: "Function declarations are not allowed inside blocks in strict mode when targeting 'ES5'. Modules are automatically in strict mode."} + +var Abstract_properties_can_only_appear_within_an_abstract_class = &Message{code: 1253, category: CategoryError, key: "Abstract_properties_can_only_appear_within_an_abstract_class_1253", text: "Abstract properties can only appear within an abstract class."} + +var A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal_or_literal_enum_reference = &Message{code: 1254, category: CategoryError, key: "A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal_or_literal_enum_refere_1254", text: "A 'const' initializer in an ambient context must be a string or numeric literal or literal enum reference."} + +var A_definite_assignment_assertion_is_not_permitted_in_this_context = &Message{code: 1255, category: CategoryError, key: "A_definite_assignment_assertion_is_not_permitted_in_this_context_1255", text: "A definite assignment assertion '!' is not permitted in this context."} + +var A_required_element_cannot_follow_an_optional_element = &Message{code: 1257, category: CategoryError, key: "A_required_element_cannot_follow_an_optional_element_1257", text: "A required element cannot follow an optional element."} + +var A_default_export_must_be_at_the_top_level_of_a_file_or_module_declaration = &Message{code: 1258, category: CategoryError, key: "A_default_export_must_be_at_the_top_level_of_a_file_or_module_declaration_1258", text: "A default export must be at the top level of a file or module declaration."} + +var Module_0_can_only_be_default_imported_using_the_1_flag = &Message{code: 1259, category: CategoryError, key: "Module_0_can_only_be_default_imported_using_the_1_flag_1259", text: "Module '{0}' can only be default-imported using the '{1}' flag"} + +var Keywords_cannot_contain_escape_characters = &Message{code: 1260, category: CategoryError, key: "Keywords_cannot_contain_escape_characters_1260", text: "Keywords cannot contain escape characters."} + +var Already_included_file_name_0_differs_from_file_name_1_only_in_casing = &Message{code: 1261, category: CategoryError, key: "Already_included_file_name_0_differs_from_file_name_1_only_in_casing_1261", text: "Already included file name '{0}' differs from file name '{1}' only in casing."} + +var Identifier_expected_0_is_a_reserved_word_at_the_top_level_of_a_module = &Message{code: 1262, category: CategoryError, key: "Identifier_expected_0_is_a_reserved_word_at_the_top_level_of_a_module_1262", text: "Identifier expected. '{0}' is a reserved word at the top-level of a module."} + +var Declarations_with_initializers_cannot_also_have_definite_assignment_assertions = &Message{code: 1263, category: CategoryError, key: "Declarations_with_initializers_cannot_also_have_definite_assignment_assertions_1263", text: "Declarations with initializers cannot also have definite assignment assertions."} + +var Declarations_with_definite_assignment_assertions_must_also_have_type_annotations = &Message{code: 1264, category: CategoryError, key: "Declarations_with_definite_assignment_assertions_must_also_have_type_annotations_1264", text: "Declarations with definite assignment assertions must also have type annotations."} + +var A_rest_element_cannot_follow_another_rest_element = &Message{code: 1265, category: CategoryError, key: "A_rest_element_cannot_follow_another_rest_element_1265", text: "A rest element cannot follow another rest element."} + +var An_optional_element_cannot_follow_a_rest_element = &Message{code: 1266, category: CategoryError, key: "An_optional_element_cannot_follow_a_rest_element_1266", text: "An optional element cannot follow a rest element."} + +var Property_0_cannot_have_an_initializer_because_it_is_marked_abstract = &Message{code: 1267, category: CategoryError, key: "Property_0_cannot_have_an_initializer_because_it_is_marked_abstract_1267", text: "Property '{0}' cannot have an initializer because it is marked abstract."} + +var An_index_signature_parameter_type_must_be_string_number_symbol_or_a_template_literal_type = &Message{code: 1268, category: CategoryError, key: "An_index_signature_parameter_type_must_be_string_number_symbol_or_a_template_literal_type_1268", text: "An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type."} + +var Cannot_use_export_import_on_a_type_or_type_only_namespace_when_0_is_enabled = &Message{code: 1269, category: CategoryError, key: "Cannot_use_export_import_on_a_type_or_type_only_namespace_when_0_is_enabled_1269", text: "Cannot use 'export import' on a type or type-only namespace when '{0}' is enabled."} + +var Decorator_function_return_type_0_is_not_assignable_to_type_1 = &Message{code: 1270, category: CategoryError, key: "Decorator_function_return_type_0_is_not_assignable_to_type_1_1270", text: "Decorator function return type '{0}' is not assignable to type '{1}'."} + +var Decorator_function_return_type_is_0_but_is_expected_to_be_void_or_any = &Message{code: 1271, category: CategoryError, key: "Decorator_function_return_type_is_0_but_is_expected_to_be_void_or_any_1271", text: "Decorator function return type is '{0}' but is expected to be 'void' or 'any'."} + +var A_type_referenced_in_a_decorated_signature_must_be_imported_with_import_type_or_a_namespace_import_when_isolatedModules_and_emitDecoratorMetadata_are_enabled = &Message{code: 1272, category: CategoryError, key: "A_type_referenced_in_a_decorated_signature_must_be_imported_with_import_type_or_a_namespace_import_w_1272", text: "A type referenced in a decorated signature must be imported with 'import type' or a namespace import when 'isolatedModules' and 'emitDecoratorMetadata' are enabled."} + +var X_0_modifier_cannot_appear_on_a_type_parameter = &Message{code: 1273, category: CategoryError, key: "_0_modifier_cannot_appear_on_a_type_parameter_1273", text: "'{0}' modifier cannot appear on a type parameter"} + +var X_0_modifier_can_only_appear_on_a_type_parameter_of_a_class_interface_or_type_alias = &Message{code: 1274, category: CategoryError, key: "_0_modifier_can_only_appear_on_a_type_parameter_of_a_class_interface_or_type_alias_1274", text: "'{0}' modifier can only appear on a type parameter of a class, interface or type alias"} + +var X_accessor_modifier_can_only_appear_on_a_property_declaration = &Message{code: 1275, category: CategoryError, key: "accessor_modifier_can_only_appear_on_a_property_declaration_1275", text: "'accessor' modifier can only appear on a property declaration."} + +var An_accessor_property_cannot_be_declared_optional = &Message{code: 1276, category: CategoryError, key: "An_accessor_property_cannot_be_declared_optional_1276", text: "An 'accessor' property cannot be declared optional."} + +var X_0_modifier_can_only_appear_on_a_type_parameter_of_a_function_method_or_class = &Message{code: 1277, category: CategoryError, key: "_0_modifier_can_only_appear_on_a_type_parameter_of_a_function_method_or_class_1277", text: "'{0}' modifier can only appear on a type parameter of a function, method or class"} + +var The_runtime_will_invoke_the_decorator_with_1_arguments_but_the_decorator_expects_0 = &Message{code: 1278, category: CategoryError, key: "The_runtime_will_invoke_the_decorator_with_1_arguments_but_the_decorator_expects_0_1278", text: "The runtime will invoke the decorator with {1} arguments, but the decorator expects {0}."} + +var The_runtime_will_invoke_the_decorator_with_1_arguments_but_the_decorator_expects_at_least_0 = &Message{code: 1279, category: CategoryError, key: "The_runtime_will_invoke_the_decorator_with_1_arguments_but_the_decorator_expects_at_least_0_1279", text: "The runtime will invoke the decorator with {1} arguments, but the decorator expects at least {0}."} + +var Namespaces_are_not_allowed_in_global_script_files_when_0_is_enabled_If_this_file_is_not_intended_to_be_a_global_script_set_moduleDetection_to_force_or_add_an_empty_export_statement = &Message{code: 1280, category: CategoryError, key: "Namespaces_are_not_allowed_in_global_script_files_when_0_is_enabled_If_this_file_is_not_intended_to__1280", text: "Namespaces are not allowed in global script files when '{0}' is enabled. If this file is not intended to be a global script, set 'moduleDetection' to 'force' or add an empty 'export {}' statement."} + +var Cannot_access_0_from_another_file_without_qualification_when_1_is_enabled_Use_2_instead = &Message{code: 1281, category: CategoryError, key: "Cannot_access_0_from_another_file_without_qualification_when_1_is_enabled_Use_2_instead_1281", text: "Cannot access '{0}' from another file without qualification when '{1}' is enabled. Use '{2}' instead."} + +var An_export_declaration_must_reference_a_value_when_verbatimModuleSyntax_is_enabled_but_0_only_refers_to_a_type = &Message{code: 1282, category: CategoryError, key: "An_export_declaration_must_reference_a_value_when_verbatimModuleSyntax_is_enabled_but_0_only_refers__1282", text: "An 'export =' declaration must reference a value when 'verbatimModuleSyntax' is enabled, but '{0}' only refers to a type."} + +var An_export_declaration_must_reference_a_real_value_when_verbatimModuleSyntax_is_enabled_but_0_resolves_to_a_type_only_declaration = &Message{code: 1283, category: CategoryError, key: "An_export_declaration_must_reference_a_real_value_when_verbatimModuleSyntax_is_enabled_but_0_resolve_1283", text: "An 'export =' declaration must reference a real value when 'verbatimModuleSyntax' is enabled, but '{0}' resolves to a type-only declaration."} + +var An_export_default_must_reference_a_value_when_verbatimModuleSyntax_is_enabled_but_0_only_refers_to_a_type = &Message{code: 1284, category: CategoryError, key: "An_export_default_must_reference_a_value_when_verbatimModuleSyntax_is_enabled_but_0_only_refers_to_a_1284", text: "An 'export default' must reference a value when 'verbatimModuleSyntax' is enabled, but '{0}' only refers to a type."} + +var An_export_default_must_reference_a_real_value_when_verbatimModuleSyntax_is_enabled_but_0_resolves_to_a_type_only_declaration = &Message{code: 1285, category: CategoryError, key: "An_export_default_must_reference_a_real_value_when_verbatimModuleSyntax_is_enabled_but_0_resolves_to_1285", text: "An 'export default' must reference a real value when 'verbatimModuleSyntax' is enabled, but '{0}' resolves to a type-only declaration."} + +var ECMAScript_imports_and_exports_cannot_be_written_in_a_CommonJS_file_under_verbatimModuleSyntax = &Message{code: 1286, category: CategoryError, key: "ECMAScript_imports_and_exports_cannot_be_written_in_a_CommonJS_file_under_verbatimModuleSyntax_1286", text: "ECMAScript imports and exports cannot be written in a CommonJS file under 'verbatimModuleSyntax'."} + +var A_top_level_export_modifier_cannot_be_used_on_value_declarations_in_a_CommonJS_module_when_verbatimModuleSyntax_is_enabled = &Message{code: 1287, category: CategoryError, key: "A_top_level_export_modifier_cannot_be_used_on_value_declarations_in_a_CommonJS_module_when_verbatimM_1287", text: "A top-level 'export' modifier cannot be used on value declarations in a CommonJS module when 'verbatimModuleSyntax' is enabled."} + +var An_import_alias_cannot_resolve_to_a_type_or_type_only_declaration_when_verbatimModuleSyntax_is_enabled = &Message{code: 1288, category: CategoryError, key: "An_import_alias_cannot_resolve_to_a_type_or_type_only_declaration_when_verbatimModuleSyntax_is_enabl_1288", text: "An import alias cannot resolve to a type or type-only declaration when 'verbatimModuleSyntax' is enabled."} + +var X_0_resolves_to_a_type_only_declaration_and_must_be_marked_type_only_in_this_file_before_re_exporting_when_1_is_enabled_Consider_using_import_type_where_0_is_imported = &Message{code: 1289, category: CategoryError, key: "_0_resolves_to_a_type_only_declaration_and_must_be_marked_type_only_in_this_file_before_re_exporting_1289", text: "'{0}' resolves to a type-only declaration and must be marked type-only in this file before re-exporting when '{1}' is enabled. Consider using 'import type' where '{0}' is imported."} + +var X_0_resolves_to_a_type_only_declaration_and_must_be_marked_type_only_in_this_file_before_re_exporting_when_1_is_enabled_Consider_using_export_type_0_as_default = &Message{code: 1290, category: CategoryError, key: "_0_resolves_to_a_type_only_declaration_and_must_be_marked_type_only_in_this_file_before_re_exporting_1290", text: "'{0}' resolves to a type-only declaration and must be marked type-only in this file before re-exporting when '{1}' is enabled. Consider using 'export type { {0} as default }'."} + +var X_0_resolves_to_a_type_and_must_be_marked_type_only_in_this_file_before_re_exporting_when_1_is_enabled_Consider_using_import_type_where_0_is_imported = &Message{code: 1291, category: CategoryError, key: "_0_resolves_to_a_type_and_must_be_marked_type_only_in_this_file_before_re_exporting_when_1_is_enable_1291", text: "'{0}' resolves to a type and must be marked type-only in this file before re-exporting when '{1}' is enabled. Consider using 'import type' where '{0}' is imported."} + +var X_0_resolves_to_a_type_and_must_be_marked_type_only_in_this_file_before_re_exporting_when_1_is_enabled_Consider_using_export_type_0_as_default = &Message{code: 1292, category: CategoryError, key: "_0_resolves_to_a_type_and_must_be_marked_type_only_in_this_file_before_re_exporting_when_1_is_enable_1292", text: "'{0}' resolves to a type and must be marked type-only in this file before re-exporting when '{1}' is enabled. Consider using 'export type { {0} as default }'."} + +var ECMAScript_module_syntax_is_not_allowed_in_a_CommonJS_module_when_module_is_set_to_preserve = &Message{code: 1293, category: CategoryError, key: "ECMAScript_module_syntax_is_not_allowed_in_a_CommonJS_module_when_module_is_set_to_preserve_1293", text: "ECMAScript module syntax is not allowed in a CommonJS module when 'module' is set to 'preserve'."} + +var This_syntax_is_not_allowed_when_erasableSyntaxOnly_is_enabled = &Message{code: 1294, category: CategoryError, key: "This_syntax_is_not_allowed_when_erasableSyntaxOnly_is_enabled_1294", text: "This syntax is not allowed when 'erasableSyntaxOnly' is enabled."} + +var ECMAScript_imports_and_exports_cannot_be_written_in_a_CommonJS_file_under_verbatimModuleSyntax_Adjust_the_type_field_in_the_nearest_package_json_to_make_this_file_an_ECMAScript_module_or_adjust_your_verbatimModuleSyntax_module_and_moduleResolution_settings_in_TypeScript = &Message{code: 1295, category: CategoryError, key: "ECMAScript_imports_and_exports_cannot_be_written_in_a_CommonJS_file_under_verbatimModuleSyntax_Adjus_1295", text: "ECMAScript imports and exports cannot be written in a CommonJS file under 'verbatimModuleSyntax'. Adjust the 'type' field in the nearest 'package.json' to make this file an ECMAScript module, or adjust your 'verbatimModuleSyntax', 'module', and 'moduleResolution' settings in TypeScript."} + +var X_with_statements_are_not_allowed_in_an_async_function_block = &Message{code: 1300, category: CategoryError, key: "with_statements_are_not_allowed_in_an_async_function_block_1300", text: "'with' statements are not allowed in an async function block."} + +var X_await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules = &Message{code: 1308, category: CategoryError, key: "await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules_1308", text: "'await' expressions are only allowed within async functions and at the top levels of modules."} + +var The_current_file_is_a_CommonJS_module_and_cannot_use_await_at_the_top_level = &Message{code: 1309, category: CategoryError, key: "The_current_file_is_a_CommonJS_module_and_cannot_use_await_at_the_top_level_1309", text: "The current file is a CommonJS module and cannot use 'await' at the top level."} + +var Did_you_mean_to_use_a_Colon_An_can_only_follow_a_property_name_when_the_containing_object_literal_is_part_of_a_destructuring_pattern = &Message{code: 1312, category: CategoryError, key: "Did_you_mean_to_use_a_Colon_An_can_only_follow_a_property_name_when_the_containing_object_literal_is_1312", text: "Did you mean to use a ':'? An '=' can only follow a property name when the containing object literal is part of a destructuring pattern."} + +var The_body_of_an_if_statement_cannot_be_the_empty_statement = &Message{code: 1313, category: CategoryError, key: "The_body_of_an_if_statement_cannot_be_the_empty_statement_1313", text: "The body of an 'if' statement cannot be the empty statement."} + +var Global_module_exports_may_only_appear_in_module_files = &Message{code: 1314, category: CategoryError, key: "Global_module_exports_may_only_appear_in_module_files_1314", text: "Global module exports may only appear in module files."} + +var Global_module_exports_may_only_appear_in_declaration_files = &Message{code: 1315, category: CategoryError, key: "Global_module_exports_may_only_appear_in_declaration_files_1315", text: "Global module exports may only appear in declaration files."} + +var Global_module_exports_may_only_appear_at_top_level = &Message{code: 1316, category: CategoryError, key: "Global_module_exports_may_only_appear_at_top_level_1316", text: "Global module exports may only appear at top level."} + +var A_parameter_property_cannot_be_declared_using_a_rest_parameter = &Message{code: 1317, category: CategoryError, key: "A_parameter_property_cannot_be_declared_using_a_rest_parameter_1317", text: "A parameter property cannot be declared using a rest parameter."} + +var An_abstract_accessor_cannot_have_an_implementation = &Message{code: 1318, category: CategoryError, key: "An_abstract_accessor_cannot_have_an_implementation_1318", text: "An abstract accessor cannot have an implementation."} + +var A_default_export_can_only_be_used_in_an_ECMAScript_style_module = &Message{code: 1319, category: CategoryError, key: "A_default_export_can_only_be_used_in_an_ECMAScript_style_module_1319", text: "A default export can only be used in an ECMAScript-style module."} + +var Type_of_await_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member = &Message{code: 1320, category: CategoryError, key: "Type_of_await_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member_1320", text: "Type of 'await' operand must either be a valid promise or must not contain a callable 'then' member."} + +var Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member = &Message{code: 1321, category: CategoryError, key: "Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_cal_1321", text: "Type of 'yield' operand in an async generator must either be a valid promise or must not contain a callable 'then' member."} + +var Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member = &Message{code: 1322, category: CategoryError, key: "Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_con_1322", text: "Type of iterated elements of a 'yield*' operand must either be a valid promise or must not contain a callable 'then' member."} + +var Dynamic_imports_are_only_supported_when_the_module_flag_is_set_to_es2020_es2022_esnext_commonjs_amd_system_umd_node16_node18_node20_or_nodenext = &Message{code: 1323, category: CategoryError, key: "Dynamic_imports_are_only_supported_when_the_module_flag_is_set_to_es2020_es2022_esnext_commonjs_amd__1323", text: "Dynamic imports are only supported when the '--module' flag is set to 'es2020', 'es2022', 'esnext', 'commonjs', 'amd', 'system', 'umd', 'node16', 'node18', 'node20', or 'nodenext'."} + +var Dynamic_imports_only_support_a_second_argument_when_the_module_option_is_set_to_esnext_node16_node18_node20_nodenext_or_preserve = &Message{code: 1324, category: CategoryError, key: "Dynamic_imports_only_support_a_second_argument_when_the_module_option_is_set_to_esnext_node16_node18_1324", text: "Dynamic imports only support a second argument when the '--module' option is set to 'esnext', 'node16', 'node18', 'node20', 'nodenext', or 'preserve'."} + +var Argument_of_dynamic_import_cannot_be_spread_element = &Message{code: 1325, category: CategoryError, key: "Argument_of_dynamic_import_cannot_be_spread_element_1325", text: "Argument of dynamic import cannot be spread element."} + +var This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot_have_type_arguments = &Message{code: 1326, category: CategoryError, key: "This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot__1326", text: "This use of 'import' is invalid. 'import()' calls can be written, but they must have parentheses and cannot have type arguments."} + +var String_literal_with_double_quotes_expected = &Message{code: 1327, category: CategoryError, key: "String_literal_with_double_quotes_expected_1327", text: "String literal with double quotes expected."} + +var Property_value_can_only_be_string_literal_numeric_literal_true_false_null_object_literal_or_array_literal = &Message{code: 1328, category: CategoryError, key: "Property_value_can_only_be_string_literal_numeric_literal_true_false_null_object_literal_or_array_li_1328", text: "Property value can only be string literal, numeric literal, 'true', 'false', 'null', object literal or array literal."} + +var X_0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write_0 = &Message{code: 1329, category: CategoryError, key: "_0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write__1329", text: "'{0}' accepts too few arguments to be used as a decorator here. Did you mean to call it first and write '@{0}()'?"} + +var A_property_of_an_interface_or_type_literal_whose_type_is_a_unique_symbol_type_must_be_readonly = &Message{code: 1330, category: CategoryError, key: "A_property_of_an_interface_or_type_literal_whose_type_is_a_unique_symbol_type_must_be_readonly_1330", text: "A property of an interface or type literal whose type is a 'unique symbol' type must be 'readonly'."} + +var A_property_of_a_class_whose_type_is_a_unique_symbol_type_must_be_both_static_and_readonly = &Message{code: 1331, category: CategoryError, key: "A_property_of_a_class_whose_type_is_a_unique_symbol_type_must_be_both_static_and_readonly_1331", text: "A property of a class whose type is a 'unique symbol' type must be both 'static' and 'readonly'."} + +var A_variable_whose_type_is_a_unique_symbol_type_must_be_const = &Message{code: 1332, category: CategoryError, key: "A_variable_whose_type_is_a_unique_symbol_type_must_be_const_1332", text: "A variable whose type is a 'unique symbol' type must be 'const'."} + +var X_unique_symbol_types_may_not_be_used_on_a_variable_declaration_with_a_binding_name = &Message{code: 1333, category: CategoryError, key: "unique_symbol_types_may_not_be_used_on_a_variable_declaration_with_a_binding_name_1333", text: "'unique symbol' types may not be used on a variable declaration with a binding name."} + +var X_unique_symbol_types_are_only_allowed_on_variables_in_a_variable_statement = &Message{code: 1334, category: CategoryError, key: "unique_symbol_types_are_only_allowed_on_variables_in_a_variable_statement_1334", text: "'unique symbol' types are only allowed on variables in a variable statement."} + +var X_unique_symbol_types_are_not_allowed_here = &Message{code: 1335, category: CategoryError, key: "unique_symbol_types_are_not_allowed_here_1335", text: "'unique symbol' types are not allowed here."} + +var An_index_signature_parameter_type_cannot_be_a_literal_type_or_generic_type_Consider_using_a_mapped_object_type_instead = &Message{code: 1337, category: CategoryError, key: "An_index_signature_parameter_type_cannot_be_a_literal_type_or_generic_type_Consider_using_a_mapped_o_1337", text: "An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead."} + +var X_infer_declarations_are_only_permitted_in_the_extends_clause_of_a_conditional_type = &Message{code: 1338, category: CategoryError, key: "infer_declarations_are_only_permitted_in_the_extends_clause_of_a_conditional_type_1338", text: "'infer' declarations are only permitted in the 'extends' clause of a conditional type."} + +var Module_0_does_not_refer_to_a_value_but_is_used_as_a_value_here = &Message{code: 1339, category: CategoryError, key: "Module_0_does_not_refer_to_a_value_but_is_used_as_a_value_here_1339", text: "Module '{0}' does not refer to a value, but is used as a value here."} + +var Module_0_does_not_refer_to_a_type_but_is_used_as_a_type_here_Did_you_mean_typeof_import_0 = &Message{code: 1340, category: CategoryError, key: "Module_0_does_not_refer_to_a_type_but_is_used_as_a_type_here_Did_you_mean_typeof_import_0_1340", text: "Module '{0}' does not refer to a type, but is used as a type here. Did you mean 'typeof import('{0}')'?"} + +var Class_constructor_may_not_be_an_accessor = &Message{code: 1341, category: CategoryError, key: "Class_constructor_may_not_be_an_accessor_1341", text: "Class constructor may not be an accessor."} + +var The_import_meta_meta_property_is_only_allowed_when_the_module_option_is_es2020_es2022_esnext_system_node16_node18_node20_or_nodenext = &Message{code: 1343, category: CategoryError, key: "The_import_meta_meta_property_is_only_allowed_when_the_module_option_is_es2020_es2022_esnext_system__1343", text: "The 'import.meta' meta-property is only allowed when the '--module' option is 'es2020', 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', or 'nodenext'."} + +var A_label_is_not_allowed_here = &Message{code: 1344, category: CategoryError, key: "A_label_is_not_allowed_here_1344", text: "'A label is not allowed here."} + +var An_expression_of_type_void_cannot_be_tested_for_truthiness = &Message{code: 1345, category: CategoryError, key: "An_expression_of_type_void_cannot_be_tested_for_truthiness_1345", text: "An expression of type 'void' cannot be tested for truthiness."} + +var This_parameter_is_not_allowed_with_use_strict_directive = &Message{code: 1346, category: CategoryError, key: "This_parameter_is_not_allowed_with_use_strict_directive_1346", text: "This parameter is not allowed with 'use strict' directive."} + +var X_use_strict_directive_cannot_be_used_with_non_simple_parameter_list = &Message{code: 1347, category: CategoryError, key: "use_strict_directive_cannot_be_used_with_non_simple_parameter_list_1347", text: "'use strict' directive cannot be used with non-simple parameter list."} + +var Non_simple_parameter_declared_here = &Message{code: 1348, category: CategoryError, key: "Non_simple_parameter_declared_here_1348", text: "Non-simple parameter declared here."} + +var X_use_strict_directive_used_here = &Message{code: 1349, category: CategoryError, key: "use_strict_directive_used_here_1349", text: "'use strict' directive used here."} + +var Print_the_final_configuration_instead_of_building = &Message{code: 1350, category: CategoryMessage, key: "Print_the_final_configuration_instead_of_building_1350", text: "Print the final configuration instead of building."} + +var An_identifier_or_keyword_cannot_immediately_follow_a_numeric_literal = &Message{code: 1351, category: CategoryError, key: "An_identifier_or_keyword_cannot_immediately_follow_a_numeric_literal_1351", text: "An identifier or keyword cannot immediately follow a numeric literal."} + +var A_bigint_literal_cannot_use_exponential_notation = &Message{code: 1352, category: CategoryError, key: "A_bigint_literal_cannot_use_exponential_notation_1352", text: "A bigint literal cannot use exponential notation."} + +var A_bigint_literal_must_be_an_integer = &Message{code: 1353, category: CategoryError, key: "A_bigint_literal_must_be_an_integer_1353", text: "A bigint literal must be an integer."} + +var X_readonly_type_modifier_is_only_permitted_on_array_and_tuple_literal_types = &Message{code: 1354, category: CategoryError, key: "readonly_type_modifier_is_only_permitted_on_array_and_tuple_literal_types_1354", text: "'readonly' type modifier is only permitted on array and tuple literal types."} + +var A_const_assertions_can_only_be_applied_to_references_to_enum_members_or_string_number_boolean_array_or_object_literals = &Message{code: 1355, category: CategoryError, key: "A_const_assertions_can_only_be_applied_to_references_to_enum_members_or_string_number_boolean_array__1355", text: "A 'const' assertions can only be applied to references to enum members, or string, number, boolean, array, or object literals."} + +var Did_you_mean_to_mark_this_function_as_async = &Message{code: 1356, category: CategoryError, key: "Did_you_mean_to_mark_this_function_as_async_1356", text: "Did you mean to mark this function as 'async'?"} + +var An_enum_member_name_must_be_followed_by_a_or = &Message{code: 1357, category: CategoryError, key: "An_enum_member_name_must_be_followed_by_a_or_1357", text: "An enum member name must be followed by a ',', '=', or '}'."} + +var Tagged_template_expressions_are_not_permitted_in_an_optional_chain = &Message{code: 1358, category: CategoryError, key: "Tagged_template_expressions_are_not_permitted_in_an_optional_chain_1358", text: "Tagged template expressions are not permitted in an optional chain."} + +var Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here = &Message{code: 1359, category: CategoryError, key: "Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here_1359", text: "Identifier expected. '{0}' is a reserved word that cannot be used here."} + +var Type_0_does_not_satisfy_the_expected_type_1 = &Message{code: 1360, category: CategoryError, key: "Type_0_does_not_satisfy_the_expected_type_1_1360", text: "Type '{0}' does not satisfy the expected type '{1}'."} + +var X_0_cannot_be_used_as_a_value_because_it_was_imported_using_import_type = &Message{code: 1361, category: CategoryError, key: "_0_cannot_be_used_as_a_value_because_it_was_imported_using_import_type_1361", text: "'{0}' cannot be used as a value because it was imported using 'import type'."} + +var X_0_cannot_be_used_as_a_value_because_it_was_exported_using_export_type = &Message{code: 1362, category: CategoryError, key: "_0_cannot_be_used_as_a_value_because_it_was_exported_using_export_type_1362", text: "'{0}' cannot be used as a value because it was exported using 'export type'."} + +var A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both = &Message{code: 1363, category: CategoryError, key: "A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both_1363", text: "A type-only import can specify a default import or named bindings, but not both."} + +var Convert_to_type_only_export = &Message{code: 1364, category: CategoryMessage, key: "Convert_to_type_only_export_1364", text: "Convert to type-only export"} + +var Convert_all_re_exported_types_to_type_only_exports = &Message{code: 1365, category: CategoryMessage, key: "Convert_all_re_exported_types_to_type_only_exports_1365", text: "Convert all re-exported types to type-only exports"} + +var Split_into_two_separate_import_declarations = &Message{code: 1366, category: CategoryMessage, key: "Split_into_two_separate_import_declarations_1366", text: "Split into two separate import declarations"} + +var Split_all_invalid_type_only_imports = &Message{code: 1367, category: CategoryMessage, key: "Split_all_invalid_type_only_imports_1367", text: "Split all invalid type-only imports"} + +var Class_constructor_may_not_be_a_generator = &Message{code: 1368, category: CategoryError, key: "Class_constructor_may_not_be_a_generator_1368", text: "Class constructor may not be a generator."} + +var Did_you_mean_0 = &Message{code: 1369, category: CategoryMessage, key: "Did_you_mean_0_1369", text: "Did you mean '{0}'?"} + +var X_await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module = &Message{code: 1375, category: CategoryError, key: "await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_fi_1375", text: "'await' expressions are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module."} + +var X_0_was_imported_here = &Message{code: 1376, category: CategoryMessage, key: "_0_was_imported_here_1376", text: "'{0}' was imported here."} + +var X_0_was_exported_here = &Message{code: 1377, category: CategoryMessage, key: "_0_was_exported_here_1377", text: "'{0}' was exported here."} + +var Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_node16_node18_node20_nodenext_or_preserve_and_the_target_option_is_set_to_es2017_or_higher = &Message{code: 1378, category: CategoryError, key: "Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_n_1378", text: "Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher."} + +var An_import_alias_cannot_reference_a_declaration_that_was_exported_using_export_type = &Message{code: 1379, category: CategoryError, key: "An_import_alias_cannot_reference_a_declaration_that_was_exported_using_export_type_1379", text: "An import alias cannot reference a declaration that was exported using 'export type'."} + +var An_import_alias_cannot_reference_a_declaration_that_was_imported_using_import_type = &Message{code: 1380, category: CategoryError, key: "An_import_alias_cannot_reference_a_declaration_that_was_imported_using_import_type_1380", text: "An import alias cannot reference a declaration that was imported using 'import type'."} + +var Unexpected_token_Did_you_mean_or_rbrace = &Message{code: 1381, category: CategoryError, key: "Unexpected_token_Did_you_mean_or_rbrace_1381", text: "Unexpected token. Did you mean `{'}'}` or `}`?"} + +var Unexpected_token_Did_you_mean_or_gt = &Message{code: 1382, category: CategoryError, key: "Unexpected_token_Did_you_mean_or_gt_1382", text: "Unexpected token. Did you mean `{'>'}` or `>`?"} + +var Function_type_notation_must_be_parenthesized_when_used_in_a_union_type = &Message{code: 1385, category: CategoryError, key: "Function_type_notation_must_be_parenthesized_when_used_in_a_union_type_1385", text: "Function type notation must be parenthesized when used in a union type."} + +var Constructor_type_notation_must_be_parenthesized_when_used_in_a_union_type = &Message{code: 1386, category: CategoryError, key: "Constructor_type_notation_must_be_parenthesized_when_used_in_a_union_type_1386", text: "Constructor type notation must be parenthesized when used in a union type."} + +var Function_type_notation_must_be_parenthesized_when_used_in_an_intersection_type = &Message{code: 1387, category: CategoryError, key: "Function_type_notation_must_be_parenthesized_when_used_in_an_intersection_type_1387", text: "Function type notation must be parenthesized when used in an intersection type."} + +var Constructor_type_notation_must_be_parenthesized_when_used_in_an_intersection_type = &Message{code: 1388, category: CategoryError, key: "Constructor_type_notation_must_be_parenthesized_when_used_in_an_intersection_type_1388", text: "Constructor type notation must be parenthesized when used in an intersection type."} + +var X_0_is_not_allowed_as_a_variable_declaration_name = &Message{code: 1389, category: CategoryError, key: "_0_is_not_allowed_as_a_variable_declaration_name_1389", text: "'{0}' is not allowed as a variable declaration name."} + +var X_0_is_not_allowed_as_a_parameter_name = &Message{code: 1390, category: CategoryError, key: "_0_is_not_allowed_as_a_parameter_name_1390", text: "'{0}' is not allowed as a parameter name."} + +var An_import_alias_cannot_use_import_type = &Message{code: 1392, category: CategoryError, key: "An_import_alias_cannot_use_import_type_1392", text: "An import alias cannot use 'import type'"} + +var Imported_via_0_from_file_1 = &Message{code: 1393, category: CategoryMessage, key: "Imported_via_0_from_file_1_1393", text: "Imported via {0} from file '{1}'"} + +var Imported_via_0_from_file_1_with_packageId_2 = &Message{code: 1394, category: CategoryMessage, key: "Imported_via_0_from_file_1_with_packageId_2_1394", text: "Imported via {0} from file '{1}' with packageId '{2}'"} + +var Imported_via_0_from_file_1_to_import_importHelpers_as_specified_in_compilerOptions = &Message{code: 1395, category: CategoryMessage, key: "Imported_via_0_from_file_1_to_import_importHelpers_as_specified_in_compilerOptions_1395", text: "Imported via {0} from file '{1}' to import 'importHelpers' as specified in compilerOptions"} + +var Imported_via_0_from_file_1_with_packageId_2_to_import_importHelpers_as_specified_in_compilerOptions = &Message{code: 1396, category: CategoryMessage, key: "Imported_via_0_from_file_1_with_packageId_2_to_import_importHelpers_as_specified_in_compilerOptions_1396", text: "Imported via {0} from file '{1}' with packageId '{2}' to import 'importHelpers' as specified in compilerOptions"} + +var Imported_via_0_from_file_1_to_import_jsx_and_jsxs_factory_functions = &Message{code: 1397, category: CategoryMessage, key: "Imported_via_0_from_file_1_to_import_jsx_and_jsxs_factory_functions_1397", text: "Imported via {0} from file '{1}' to import 'jsx' and 'jsxs' factory functions"} + +var Imported_via_0_from_file_1_with_packageId_2_to_import_jsx_and_jsxs_factory_functions = &Message{code: 1398, category: CategoryMessage, key: "Imported_via_0_from_file_1_with_packageId_2_to_import_jsx_and_jsxs_factory_functions_1398", text: "Imported via {0} from file '{1}' with packageId '{2}' to import 'jsx' and 'jsxs' factory functions"} + +var File_is_included_via_import_here = &Message{code: 1399, category: CategoryMessage, key: "File_is_included_via_import_here_1399", text: "File is included via import here."} + +var Referenced_via_0_from_file_1 = &Message{code: 1400, category: CategoryMessage, key: "Referenced_via_0_from_file_1_1400", text: "Referenced via '{0}' from file '{1}'"} + +var File_is_included_via_reference_here = &Message{code: 1401, category: CategoryMessage, key: "File_is_included_via_reference_here_1401", text: "File is included via reference here."} + +var Type_library_referenced_via_0_from_file_1 = &Message{code: 1402, category: CategoryMessage, key: "Type_library_referenced_via_0_from_file_1_1402", text: "Type library referenced via '{0}' from file '{1}'"} + +var Type_library_referenced_via_0_from_file_1_with_packageId_2 = &Message{code: 1403, category: CategoryMessage, key: "Type_library_referenced_via_0_from_file_1_with_packageId_2_1403", text: "Type library referenced via '{0}' from file '{1}' with packageId '{2}'"} + +var File_is_included_via_type_library_reference_here = &Message{code: 1404, category: CategoryMessage, key: "File_is_included_via_type_library_reference_here_1404", text: "File is included via type library reference here."} + +var Library_referenced_via_0_from_file_1 = &Message{code: 1405, category: CategoryMessage, key: "Library_referenced_via_0_from_file_1_1405", text: "Library referenced via '{0}' from file '{1}'"} + +var File_is_included_via_library_reference_here = &Message{code: 1406, category: CategoryMessage, key: "File_is_included_via_library_reference_here_1406", text: "File is included via library reference here."} + +var Matched_by_include_pattern_0_in_1 = &Message{code: 1407, category: CategoryMessage, key: "Matched_by_include_pattern_0_in_1_1407", text: "Matched by include pattern '{0}' in '{1}'"} + +var File_is_matched_by_include_pattern_specified_here = &Message{code: 1408, category: CategoryMessage, key: "File_is_matched_by_include_pattern_specified_here_1408", text: "File is matched by include pattern specified here."} + +var Part_of_files_list_in_tsconfig_json = &Message{code: 1409, category: CategoryMessage, key: "Part_of_files_list_in_tsconfig_json_1409", text: "Part of 'files' list in tsconfig.json"} + +var File_is_matched_by_files_list_specified_here = &Message{code: 1410, category: CategoryMessage, key: "File_is_matched_by_files_list_specified_here_1410", text: "File is matched by 'files' list specified here."} + +var Output_from_referenced_project_0_included_because_1_specified = &Message{code: 1411, category: CategoryMessage, key: "Output_from_referenced_project_0_included_because_1_specified_1411", text: "Output from referenced project '{0}' included because '{1}' specified"} + +var Output_from_referenced_project_0_included_because_module_is_specified_as_none = &Message{code: 1412, category: CategoryMessage, key: "Output_from_referenced_project_0_included_because_module_is_specified_as_none_1412", text: "Output from referenced project '{0}' included because '--module' is specified as 'none'"} + +var File_is_output_from_referenced_project_specified_here = &Message{code: 1413, category: CategoryMessage, key: "File_is_output_from_referenced_project_specified_here_1413", text: "File is output from referenced project specified here."} + +var Source_from_referenced_project_0_included_because_1_specified = &Message{code: 1414, category: CategoryMessage, key: "Source_from_referenced_project_0_included_because_1_specified_1414", text: "Source from referenced project '{0}' included because '{1}' specified"} + +var Source_from_referenced_project_0_included_because_module_is_specified_as_none = &Message{code: 1415, category: CategoryMessage, key: "Source_from_referenced_project_0_included_because_module_is_specified_as_none_1415", text: "Source from referenced project '{0}' included because '--module' is specified as 'none'"} + +var File_is_source_from_referenced_project_specified_here = &Message{code: 1416, category: CategoryMessage, key: "File_is_source_from_referenced_project_specified_here_1416", text: "File is source from referenced project specified here."} + +var Entry_point_of_type_library_0_specified_in_compilerOptions = &Message{code: 1417, category: CategoryMessage, key: "Entry_point_of_type_library_0_specified_in_compilerOptions_1417", text: "Entry point of type library '{0}' specified in compilerOptions"} + +var Entry_point_of_type_library_0_specified_in_compilerOptions_with_packageId_1 = &Message{code: 1418, category: CategoryMessage, key: "Entry_point_of_type_library_0_specified_in_compilerOptions_with_packageId_1_1418", text: "Entry point of type library '{0}' specified in compilerOptions with packageId '{1}'"} + +var File_is_entry_point_of_type_library_specified_here = &Message{code: 1419, category: CategoryMessage, key: "File_is_entry_point_of_type_library_specified_here_1419", text: "File is entry point of type library specified here."} + +var Entry_point_for_implicit_type_library_0 = &Message{code: 1420, category: CategoryMessage, key: "Entry_point_for_implicit_type_library_0_1420", text: "Entry point for implicit type library '{0}'"} + +var Entry_point_for_implicit_type_library_0_with_packageId_1 = &Message{code: 1421, category: CategoryMessage, key: "Entry_point_for_implicit_type_library_0_with_packageId_1_1421", text: "Entry point for implicit type library '{0}' with packageId '{1}'"} + +var Library_0_specified_in_compilerOptions = &Message{code: 1422, category: CategoryMessage, key: "Library_0_specified_in_compilerOptions_1422", text: "Library '{0}' specified in compilerOptions"} + +var File_is_library_specified_here = &Message{code: 1423, category: CategoryMessage, key: "File_is_library_specified_here_1423", text: "File is library specified here."} + +var Default_library = &Message{code: 1424, category: CategoryMessage, key: "Default_library_1424", text: "Default library"} + +var Default_library_for_target_0 = &Message{code: 1425, category: CategoryMessage, key: "Default_library_for_target_0_1425", text: "Default library for target '{0}'"} + +var File_is_default_library_for_target_specified_here = &Message{code: 1426, category: CategoryMessage, key: "File_is_default_library_for_target_specified_here_1426", text: "File is default library for target specified here."} + +var Root_file_specified_for_compilation = &Message{code: 1427, category: CategoryMessage, key: "Root_file_specified_for_compilation_1427", text: "Root file specified for compilation"} + +var File_is_output_of_project_reference_source_0 = &Message{code: 1428, category: CategoryMessage, key: "File_is_output_of_project_reference_source_0_1428", text: "File is output of project reference source '{0}'"} + +var File_redirects_to_file_0 = &Message{code: 1429, category: CategoryMessage, key: "File_redirects_to_file_0_1429", text: "File redirects to file '{0}'"} + +var The_file_is_in_the_program_because_Colon = &Message{code: 1430, category: CategoryMessage, key: "The_file_is_in_the_program_because_Colon_1430", text: "The file is in the program because:"} + +var X_for_await_loops_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module = &Message{code: 1431, category: CategoryError, key: "for_await_loops_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_1431", text: "'for await' loops are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module."} + +var Top_level_for_await_loops_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_node16_node18_node20_nodenext_or_preserve_and_the_target_option_is_set_to_es2017_or_higher = &Message{code: 1432, category: CategoryError, key: "Top_level_for_await_loops_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_nod_1432", text: "Top-level 'for await' loops are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher."} + +var Neither_decorators_nor_modifiers_may_be_applied_to_this_parameters = &Message{code: 1433, category: CategoryError, key: "Neither_decorators_nor_modifiers_may_be_applied_to_this_parameters_1433", text: "Neither decorators nor modifiers may be applied to 'this' parameters."} + +var Unexpected_keyword_or_identifier = &Message{code: 1434, category: CategoryError, key: "Unexpected_keyword_or_identifier_1434", text: "Unexpected keyword or identifier."} + +var Unknown_keyword_or_identifier_Did_you_mean_0 = &Message{code: 1435, category: CategoryError, key: "Unknown_keyword_or_identifier_Did_you_mean_0_1435", text: "Unknown keyword or identifier. Did you mean '{0}'?"} + +var Decorators_must_precede_the_name_and_all_keywords_of_property_declarations = &Message{code: 1436, category: CategoryError, key: "Decorators_must_precede_the_name_and_all_keywords_of_property_declarations_1436", text: "Decorators must precede the name and all keywords of property declarations."} + +var Namespace_must_be_given_a_name = &Message{code: 1437, category: CategoryError, key: "Namespace_must_be_given_a_name_1437", text: "Namespace must be given a name."} + +var Interface_must_be_given_a_name = &Message{code: 1438, category: CategoryError, key: "Interface_must_be_given_a_name_1438", text: "Interface must be given a name."} + +var Type_alias_must_be_given_a_name = &Message{code: 1439, category: CategoryError, key: "Type_alias_must_be_given_a_name_1439", text: "Type alias must be given a name."} + +var Variable_declaration_not_allowed_at_this_location = &Message{code: 1440, category: CategoryError, key: "Variable_declaration_not_allowed_at_this_location_1440", text: "Variable declaration not allowed at this location."} + +var Cannot_start_a_function_call_in_a_type_annotation = &Message{code: 1441, category: CategoryError, key: "Cannot_start_a_function_call_in_a_type_annotation_1441", text: "Cannot start a function call in a type annotation."} + +var Expected_for_property_initializer = &Message{code: 1442, category: CategoryError, key: "Expected_for_property_initializer_1442", text: "Expected '=' for property initializer."} + +var Module_declaration_names_may_only_use_or_quoted_strings = &Message{code: 1443, category: CategoryError, key: "Module_declaration_names_may_only_use_or_quoted_strings_1443", text: "Module declaration names may only use ' or \" quoted strings."} + +var X_0_resolves_to_a_type_only_declaration_and_must_be_re_exported_using_a_type_only_re_export_when_1_is_enabled = &Message{code: 1448, category: CategoryError, key: "_0_resolves_to_a_type_only_declaration_and_must_be_re_exported_using_a_type_only_re_export_when_1_is_1448", text: "'{0}' resolves to a type-only declaration and must be re-exported using a type-only re-export when '{1}' is enabled."} + +var Preserve_unused_imported_values_in_the_JavaScript_output_that_would_otherwise_be_removed = &Message{code: 1449, category: CategoryMessage, key: "Preserve_unused_imported_values_in_the_JavaScript_output_that_would_otherwise_be_removed_1449", text: "Preserve unused imported values in the JavaScript output that would otherwise be removed."} + +var Dynamic_imports_can_only_accept_a_module_specifier_and_an_optional_set_of_attributes_as_arguments = &Message{code: 1450, category: CategoryMessage, key: "Dynamic_imports_can_only_accept_a_module_specifier_and_an_optional_set_of_attributes_as_arguments_1450", text: "Dynamic imports can only accept a module specifier and an optional set of attributes as arguments"} + +var Private_identifiers_are_only_allowed_in_class_bodies_and_may_only_be_used_as_part_of_a_class_member_declaration_property_access_or_on_the_left_hand_side_of_an_in_expression = &Message{code: 1451, category: CategoryError, key: "Private_identifiers_are_only_allowed_in_class_bodies_and_may_only_be_used_as_part_of_a_class_member__1451", text: "Private identifiers are only allowed in class bodies and may only be used as part of a class member declaration, property access, or on the left-hand-side of an 'in' expression"} + +var X_resolution_mode_should_be_either_require_or_import = &Message{code: 1453, category: CategoryError, key: "resolution_mode_should_be_either_require_or_import_1453", text: "`resolution-mode` should be either `require` or `import`."} + +var X_resolution_mode_can_only_be_set_for_type_only_imports = &Message{code: 1454, category: CategoryError, key: "resolution_mode_can_only_be_set_for_type_only_imports_1454", text: "`resolution-mode` can only be set for type-only imports."} + +var X_resolution_mode_is_the_only_valid_key_for_type_import_assertions = &Message{code: 1455, category: CategoryError, key: "resolution_mode_is_the_only_valid_key_for_type_import_assertions_1455", text: "`resolution-mode` is the only valid key for type import assertions."} + +var Type_import_assertions_should_have_exactly_one_key_resolution_mode_with_value_import_or_require = &Message{code: 1456, category: CategoryError, key: "Type_import_assertions_should_have_exactly_one_key_resolution_mode_with_value_import_or_require_1456", text: "Type import assertions should have exactly one key - `resolution-mode` - with value `import` or `require`."} + +var Matched_by_default_include_pattern_Asterisk_Asterisk_Slash_Asterisk = &Message{code: 1457, category: CategoryMessage, key: "Matched_by_default_include_pattern_Asterisk_Asterisk_Slash_Asterisk_1457", text: "Matched by default include pattern '**/*'"} + +var File_is_ECMAScript_module_because_0_has_field_type_with_value_module = &Message{code: 1458, category: CategoryMessage, key: "File_is_ECMAScript_module_because_0_has_field_type_with_value_module_1458", text: "File is ECMAScript module because '{0}' has field \"type\" with value \"module\""} + +var File_is_CommonJS_module_because_0_has_field_type_whose_value_is_not_module = &Message{code: 1459, category: CategoryMessage, key: "File_is_CommonJS_module_because_0_has_field_type_whose_value_is_not_module_1459", text: "File is CommonJS module because '{0}' has field \"type\" whose value is not \"module\""} + +var File_is_CommonJS_module_because_0_does_not_have_field_type = &Message{code: 1460, category: CategoryMessage, key: "File_is_CommonJS_module_because_0_does_not_have_field_type_1460", text: "File is CommonJS module because '{0}' does not have field \"type\""} + +var File_is_CommonJS_module_because_package_json_was_not_found = &Message{code: 1461, category: CategoryMessage, key: "File_is_CommonJS_module_because_package_json_was_not_found_1461", text: "File is CommonJS module because 'package.json' was not found"} + +var X_resolution_mode_is_the_only_valid_key_for_type_import_attributes = &Message{code: 1463, category: CategoryError, key: "resolution_mode_is_the_only_valid_key_for_type_import_attributes_1463", text: "'resolution-mode' is the only valid key for type import attributes."} + +var Type_import_attributes_should_have_exactly_one_key_resolution_mode_with_value_import_or_require = &Message{code: 1464, category: CategoryError, key: "Type_import_attributes_should_have_exactly_one_key_resolution_mode_with_value_import_or_require_1464", text: "Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'."} + +var The_import_meta_meta_property_is_not_allowed_in_files_which_will_build_into_CommonJS_output = &Message{code: 1470, category: CategoryError, key: "The_import_meta_meta_property_is_not_allowed_in_files_which_will_build_into_CommonJS_output_1470", text: "The 'import.meta' meta-property is not allowed in files which will build into CommonJS output."} + +var Module_0_cannot_be_imported_using_this_construct_The_specifier_only_resolves_to_an_ES_module_which_cannot_be_imported_with_require_Use_an_ECMAScript_import_instead = &Message{code: 1471, category: CategoryError, key: "Module_0_cannot_be_imported_using_this_construct_The_specifier_only_resolves_to_an_ES_module_which_c_1471", text: "Module '{0}' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported with 'require'. Use an ECMAScript import instead."} + +var X_catch_or_finally_expected = &Message{code: 1472, category: CategoryError, key: "catch_or_finally_expected_1472", text: "'catch' or 'finally' expected."} + +var An_import_declaration_can_only_be_used_at_the_top_level_of_a_module = &Message{code: 1473, category: CategoryError, key: "An_import_declaration_can_only_be_used_at_the_top_level_of_a_module_1473", text: "An import declaration can only be used at the top level of a module."} + +var An_export_declaration_can_only_be_used_at_the_top_level_of_a_module = &Message{code: 1474, category: CategoryError, key: "An_export_declaration_can_only_be_used_at_the_top_level_of_a_module_1474", text: "An export declaration can only be used at the top level of a module."} + +var Control_what_method_is_used_to_detect_module_format_JS_files = &Message{code: 1475, category: CategoryMessage, key: "Control_what_method_is_used_to_detect_module_format_JS_files_1475", text: "Control what method is used to detect module-format JS files."} + +var X_auto_Colon_Treat_files_with_imports_exports_import_meta_jsx_with_jsx_Colon_react_jsx_or_esm_format_with_module_Colon_node16_as_modules = &Message{code: 1476, category: CategoryMessage, key: "auto_Colon_Treat_files_with_imports_exports_import_meta_jsx_with_jsx_Colon_react_jsx_or_esm_format_w_1476", text: "\"auto\": Treat files with imports, exports, import.meta, jsx (with jsx: react-jsx), or esm format (with module: node16+) as modules."} + +var An_instantiation_expression_cannot_be_followed_by_a_property_access = &Message{code: 1477, category: CategoryError, key: "An_instantiation_expression_cannot_be_followed_by_a_property_access_1477", text: "An instantiation expression cannot be followed by a property access."} + +var Identifier_or_string_literal_expected = &Message{code: 1478, category: CategoryError, key: "Identifier_or_string_literal_expected_1478", text: "Identifier or string literal expected."} + +var The_current_file_is_a_CommonJS_module_whose_imports_will_produce_require_calls_however_the_referenced_file_is_an_ECMAScript_module_and_cannot_be_imported_with_require_Consider_writing_a_dynamic_import_0_call_instead = &Message{code: 1479, category: CategoryError, key: "The_current_file_is_a_CommonJS_module_whose_imports_will_produce_require_calls_however_the_reference_1479", text: "The current file is a CommonJS module whose imports will produce 'require' calls; however, the referenced file is an ECMAScript module and cannot be imported with 'require'. Consider writing a dynamic 'import(\"{0}\")' call instead."} + +var To_convert_this_file_to_an_ECMAScript_module_change_its_file_extension_to_0_or_create_a_local_package_json_file_with_type_Colon_module = &Message{code: 1480, category: CategoryMessage, key: "To_convert_this_file_to_an_ECMAScript_module_change_its_file_extension_to_0_or_create_a_local_packag_1480", text: "To convert this file to an ECMAScript module, change its file extension to '{0}' or create a local package.json file with `{ \"type\": \"module\" }`."} + +var To_convert_this_file_to_an_ECMAScript_module_change_its_file_extension_to_0_or_add_the_field_type_Colon_module_to_1 = &Message{code: 1481, category: CategoryMessage, key: "To_convert_this_file_to_an_ECMAScript_module_change_its_file_extension_to_0_or_add_the_field_type_Co_1481", text: "To convert this file to an ECMAScript module, change its file extension to '{0}', or add the field `\"type\": \"module\"` to '{1}'."} + +var To_convert_this_file_to_an_ECMAScript_module_add_the_field_type_Colon_module_to_0 = &Message{code: 1482, category: CategoryMessage, key: "To_convert_this_file_to_an_ECMAScript_module_add_the_field_type_Colon_module_to_0_1482", text: "To convert this file to an ECMAScript module, add the field `\"type\": \"module\"` to '{0}'."} + +var To_convert_this_file_to_an_ECMAScript_module_create_a_local_package_json_file_with_type_Colon_module = &Message{code: 1483, category: CategoryMessage, key: "To_convert_this_file_to_an_ECMAScript_module_create_a_local_package_json_file_with_type_Colon_module_1483", text: "To convert this file to an ECMAScript module, create a local package.json file with `{ \"type\": \"module\" }`."} + +var X_0_is_a_type_and_must_be_imported_using_a_type_only_import_when_verbatimModuleSyntax_is_enabled = &Message{code: 1484, category: CategoryError, key: "_0_is_a_type_and_must_be_imported_using_a_type_only_import_when_verbatimModuleSyntax_is_enabled_1484", text: "'{0}' is a type and must be imported using a type-only import when 'verbatimModuleSyntax' is enabled."} + +var X_0_resolves_to_a_type_only_declaration_and_must_be_imported_using_a_type_only_import_when_verbatimModuleSyntax_is_enabled = &Message{code: 1485, category: CategoryError, key: "_0_resolves_to_a_type_only_declaration_and_must_be_imported_using_a_type_only_import_when_verbatimMo_1485", text: "'{0}' resolves to a type-only declaration and must be imported using a type-only import when 'verbatimModuleSyntax' is enabled."} + +var Decorator_used_before_export_here = &Message{code: 1486, category: CategoryError, key: "Decorator_used_before_export_here_1486", text: "Decorator used before 'export' here."} + +var Octal_escape_sequences_are_not_allowed_Use_the_syntax_0 = &Message{code: 1487, category: CategoryError, key: "Octal_escape_sequences_are_not_allowed_Use_the_syntax_0_1487", text: "Octal escape sequences are not allowed. Use the syntax '{0}'."} + +var Escape_sequence_0_is_not_allowed = &Message{code: 1488, category: CategoryError, key: "Escape_sequence_0_is_not_allowed_1488", text: "Escape sequence '{0}' is not allowed."} + +var Decimals_with_leading_zeros_are_not_allowed = &Message{code: 1489, category: CategoryError, key: "Decimals_with_leading_zeros_are_not_allowed_1489", text: "Decimals with leading zeros are not allowed."} + +var File_appears_to_be_binary = &Message{code: 1490, category: CategoryError, key: "File_appears_to_be_binary_1490", text: "File appears to be binary."} + +var X_0_modifier_cannot_appear_on_a_using_declaration = &Message{code: 1491, category: CategoryError, key: "_0_modifier_cannot_appear_on_a_using_declaration_1491", text: "'{0}' modifier cannot appear on a 'using' declaration."} + +var X_0_declarations_may_not_have_binding_patterns = &Message{code: 1492, category: CategoryError, key: "_0_declarations_may_not_have_binding_patterns_1492", text: "'{0}' declarations may not have binding patterns."} + +var The_left_hand_side_of_a_for_in_statement_cannot_be_a_using_declaration = &Message{code: 1493, category: CategoryError, key: "The_left_hand_side_of_a_for_in_statement_cannot_be_a_using_declaration_1493", text: "The left-hand side of a 'for...in' statement cannot be a 'using' declaration."} + +var The_left_hand_side_of_a_for_in_statement_cannot_be_an_await_using_declaration = &Message{code: 1494, category: CategoryError, key: "The_left_hand_side_of_a_for_in_statement_cannot_be_an_await_using_declaration_1494", text: "The left-hand side of a 'for...in' statement cannot be an 'await using' declaration."} + +var X_0_modifier_cannot_appear_on_an_await_using_declaration = &Message{code: 1495, category: CategoryError, key: "_0_modifier_cannot_appear_on_an_await_using_declaration_1495", text: "'{0}' modifier cannot appear on an 'await using' declaration."} + +var Identifier_string_literal_or_number_literal_expected = &Message{code: 1496, category: CategoryError, key: "Identifier_string_literal_or_number_literal_expected_1496", text: "Identifier, string literal, or number literal expected."} + +var Expression_must_be_enclosed_in_parentheses_to_be_used_as_a_decorator = &Message{code: 1497, category: CategoryError, key: "Expression_must_be_enclosed_in_parentheses_to_be_used_as_a_decorator_1497", text: "Expression must be enclosed in parentheses to be used as a decorator."} + +var Invalid_syntax_in_decorator = &Message{code: 1498, category: CategoryError, key: "Invalid_syntax_in_decorator_1498", text: "Invalid syntax in decorator."} + +var Unknown_regular_expression_flag = &Message{code: 1499, category: CategoryError, key: "Unknown_regular_expression_flag_1499", text: "Unknown regular expression flag."} + +var Duplicate_regular_expression_flag = &Message{code: 1500, category: CategoryError, key: "Duplicate_regular_expression_flag_1500", text: "Duplicate regular expression flag."} + +var This_regular_expression_flag_is_only_available_when_targeting_0_or_later = &Message{code: 1501, category: CategoryError, key: "This_regular_expression_flag_is_only_available_when_targeting_0_or_later_1501", text: "This regular expression flag is only available when targeting '{0}' or later."} + +var The_Unicode_u_flag_and_the_Unicode_Sets_v_flag_cannot_be_set_simultaneously = &Message{code: 1502, category: CategoryError, key: "The_Unicode_u_flag_and_the_Unicode_Sets_v_flag_cannot_be_set_simultaneously_1502", text: "The Unicode (u) flag and the Unicode Sets (v) flag cannot be set simultaneously."} + +var Named_capturing_groups_are_only_available_when_targeting_ES2018_or_later = &Message{code: 1503, category: CategoryError, key: "Named_capturing_groups_are_only_available_when_targeting_ES2018_or_later_1503", text: "Named capturing groups are only available when targeting 'ES2018' or later."} + +var Subpattern_flags_must_be_present_when_there_is_a_minus_sign = &Message{code: 1504, category: CategoryError, key: "Subpattern_flags_must_be_present_when_there_is_a_minus_sign_1504", text: "Subpattern flags must be present when there is a minus sign."} + +var Incomplete_quantifier_Digit_expected = &Message{code: 1505, category: CategoryError, key: "Incomplete_quantifier_Digit_expected_1505", text: "Incomplete quantifier. Digit expected."} + +var Numbers_out_of_order_in_quantifier = &Message{code: 1506, category: CategoryError, key: "Numbers_out_of_order_in_quantifier_1506", text: "Numbers out of order in quantifier."} + +var There_is_nothing_available_for_repetition = &Message{code: 1507, category: CategoryError, key: "There_is_nothing_available_for_repetition_1507", text: "There is nothing available for repetition."} + +var Unexpected_0_Did_you_mean_to_escape_it_with_backslash = &Message{code: 1508, category: CategoryError, key: "Unexpected_0_Did_you_mean_to_escape_it_with_backslash_1508", text: "Unexpected '{0}'. Did you mean to escape it with backslash?"} + +var This_regular_expression_flag_cannot_be_toggled_within_a_subpattern = &Message{code: 1509, category: CategoryError, key: "This_regular_expression_flag_cannot_be_toggled_within_a_subpattern_1509", text: "This regular expression flag cannot be toggled within a subpattern."} + +var X_k_must_be_followed_by_a_capturing_group_name_enclosed_in_angle_brackets = &Message{code: 1510, category: CategoryError, key: "k_must_be_followed_by_a_capturing_group_name_enclosed_in_angle_brackets_1510", text: "'\\k' must be followed by a capturing group name enclosed in angle brackets."} + +var X_q_is_only_available_inside_character_class = &Message{code: 1511, category: CategoryError, key: "q_is_only_available_inside_character_class_1511", text: "'\\q' is only available inside character class."} + +var X_c_must_be_followed_by_an_ASCII_letter = &Message{code: 1512, category: CategoryError, key: "c_must_be_followed_by_an_ASCII_letter_1512", text: "'\\c' must be followed by an ASCII letter."} + +var Undetermined_character_escape = &Message{code: 1513, category: CategoryError, key: "Undetermined_character_escape_1513", text: "Undetermined character escape."} + +var Expected_a_capturing_group_name = &Message{code: 1514, category: CategoryError, key: "Expected_a_capturing_group_name_1514", text: "Expected a capturing group name."} + +var Named_capturing_groups_with_the_same_name_must_be_mutually_exclusive_to_each_other = &Message{code: 1515, category: CategoryError, key: "Named_capturing_groups_with_the_same_name_must_be_mutually_exclusive_to_each_other_1515", text: "Named capturing groups with the same name must be mutually exclusive to each other."} + +var A_character_class_range_must_not_be_bounded_by_another_character_class = &Message{code: 1516, category: CategoryError, key: "A_character_class_range_must_not_be_bounded_by_another_character_class_1516", text: "A character class range must not be bounded by another character class."} + +var Range_out_of_order_in_character_class = &Message{code: 1517, category: CategoryError, key: "Range_out_of_order_in_character_class_1517", text: "Range out of order in character class."} + +var Anything_that_would_possibly_match_more_than_a_single_character_is_invalid_inside_a_negated_character_class = &Message{code: 1518, category: CategoryError, key: "Anything_that_would_possibly_match_more_than_a_single_character_is_invalid_inside_a_negated_characte_1518", text: "Anything that would possibly match more than a single character is invalid inside a negated character class."} + +var Operators_must_not_be_mixed_within_a_character_class_Wrap_it_in_a_nested_class_instead = &Message{code: 1519, category: CategoryError, key: "Operators_must_not_be_mixed_within_a_character_class_Wrap_it_in_a_nested_class_instead_1519", text: "Operators must not be mixed within a character class. Wrap it in a nested class instead."} + +var Expected_a_class_set_operand = &Message{code: 1520, category: CategoryError, key: "Expected_a_class_set_operand_1520", text: "Expected a class set operand."} + +var X_q_must_be_followed_by_string_alternatives_enclosed_in_braces = &Message{code: 1521, category: CategoryError, key: "q_must_be_followed_by_string_alternatives_enclosed_in_braces_1521", text: "'\\q' must be followed by string alternatives enclosed in braces."} + +var A_character_class_must_not_contain_a_reserved_double_punctuator_Did_you_mean_to_escape_it_with_backslash = &Message{code: 1522, category: CategoryError, key: "A_character_class_must_not_contain_a_reserved_double_punctuator_Did_you_mean_to_escape_it_with_backs_1522", text: "A character class must not contain a reserved double punctuator. Did you mean to escape it with backslash?"} + +var Expected_a_Unicode_property_name = &Message{code: 1523, category: CategoryError, key: "Expected_a_Unicode_property_name_1523", text: "Expected a Unicode property name."} + +var Unknown_Unicode_property_name = &Message{code: 1524, category: CategoryError, key: "Unknown_Unicode_property_name_1524", text: "Unknown Unicode property name."} + +var Expected_a_Unicode_property_value = &Message{code: 1525, category: CategoryError, key: "Expected_a_Unicode_property_value_1525", text: "Expected a Unicode property value."} + +var Unknown_Unicode_property_value = &Message{code: 1526, category: CategoryError, key: "Unknown_Unicode_property_value_1526", text: "Unknown Unicode property value."} + +var Expected_a_Unicode_property_name_or_value = &Message{code: 1527, category: CategoryError, key: "Expected_a_Unicode_property_name_or_value_1527", text: "Expected a Unicode property name or value."} + +var Any_Unicode_property_that_would_possibly_match_more_than_a_single_character_is_only_available_when_the_Unicode_Sets_v_flag_is_set = &Message{code: 1528, category: CategoryError, key: "Any_Unicode_property_that_would_possibly_match_more_than_a_single_character_is_only_available_when_t_1528", text: "Any Unicode property that would possibly match more than a single character is only available when the Unicode Sets (v) flag is set."} + +var Unknown_Unicode_property_name_or_value = &Message{code: 1529, category: CategoryError, key: "Unknown_Unicode_property_name_or_value_1529", text: "Unknown Unicode property name or value."} + +var Unicode_property_value_expressions_are_only_available_when_the_Unicode_u_flag_or_the_Unicode_Sets_v_flag_is_set = &Message{code: 1530, category: CategoryError, key: "Unicode_property_value_expressions_are_only_available_when_the_Unicode_u_flag_or_the_Unicode_Sets_v__1530", text: "Unicode property value expressions are only available when the Unicode (u) flag or the Unicode Sets (v) flag is set."} + +var X_0_must_be_followed_by_a_Unicode_property_value_expression_enclosed_in_braces = &Message{code: 1531, category: CategoryError, key: "_0_must_be_followed_by_a_Unicode_property_value_expression_enclosed_in_braces_1531", text: "'\\{0}' must be followed by a Unicode property value expression enclosed in braces."} + +var There_is_no_capturing_group_named_0_in_this_regular_expression = &Message{code: 1532, category: CategoryError, key: "There_is_no_capturing_group_named_0_in_this_regular_expression_1532", text: "There is no capturing group named '{0}' in this regular expression."} + +var This_backreference_refers_to_a_group_that_does_not_exist_There_are_only_0_capturing_groups_in_this_regular_expression = &Message{code: 1533, category: CategoryError, key: "This_backreference_refers_to_a_group_that_does_not_exist_There_are_only_0_capturing_groups_in_this_r_1533", text: "This backreference refers to a group that does not exist. There are only {0} capturing groups in this regular expression."} + +var This_backreference_refers_to_a_group_that_does_not_exist_There_are_no_capturing_groups_in_this_regular_expression = &Message{code: 1534, category: CategoryError, key: "This_backreference_refers_to_a_group_that_does_not_exist_There_are_no_capturing_groups_in_this_regul_1534", text: "This backreference refers to a group that does not exist. There are no capturing groups in this regular expression."} + +var This_character_cannot_be_escaped_in_a_regular_expression = &Message{code: 1535, category: CategoryError, key: "This_character_cannot_be_escaped_in_a_regular_expression_1535", text: "This character cannot be escaped in a regular expression."} + +var Octal_escape_sequences_and_backreferences_are_not_allowed_in_a_character_class_If_this_was_intended_as_an_escape_sequence_use_the_syntax_0_instead = &Message{code: 1536, category: CategoryError, key: "Octal_escape_sequences_and_backreferences_are_not_allowed_in_a_character_class_If_this_was_intended__1536", text: "Octal escape sequences and backreferences are not allowed in a character class. If this was intended as an escape sequence, use the syntax '{0}' instead."} + +var Decimal_escape_sequences_and_backreferences_are_not_allowed_in_a_character_class = &Message{code: 1537, category: CategoryError, key: "Decimal_escape_sequences_and_backreferences_are_not_allowed_in_a_character_class_1537", text: "Decimal escape sequences and backreferences are not allowed in a character class."} + +var Unicode_escape_sequences_are_only_available_when_the_Unicode_u_flag_or_the_Unicode_Sets_v_flag_is_set = &Message{code: 1538, category: CategoryError, key: "Unicode_escape_sequences_are_only_available_when_the_Unicode_u_flag_or_the_Unicode_Sets_v_flag_is_se_1538", text: "Unicode escape sequences are only available when the Unicode (u) flag or the Unicode Sets (v) flag is set."} + +var A_bigint_literal_cannot_be_used_as_a_property_name = &Message{code: 1539, category: CategoryError, key: "A_bigint_literal_cannot_be_used_as_a_property_name_1539", text: "A 'bigint' literal cannot be used as a property name."} + +var A_namespace_declaration_should_not_be_declared_using_the_module_keyword_Please_use_the_namespace_keyword_instead = &Message{code: 1540, category: CategorySuggestion, key: "A_namespace_declaration_should_not_be_declared_using_the_module_keyword_Please_use_the_namespace_key_1540", text: "A 'namespace' declaration should not be declared using the 'module' keyword. Please use the 'namespace' keyword instead.", reportsDeprecated: true} + +var Type_only_import_of_an_ECMAScript_module_from_a_CommonJS_module_must_have_a_resolution_mode_attribute = &Message{code: 1541, category: CategoryError, key: "Type_only_import_of_an_ECMAScript_module_from_a_CommonJS_module_must_have_a_resolution_mode_attribut_1541", text: "Type-only import of an ECMAScript module from a CommonJS module must have a 'resolution-mode' attribute."} + +var Type_import_of_an_ECMAScript_module_from_a_CommonJS_module_must_have_a_resolution_mode_attribute = &Message{code: 1542, category: CategoryError, key: "Type_import_of_an_ECMAScript_module_from_a_CommonJS_module_must_have_a_resolution_mode_attribute_1542", text: "Type import of an ECMAScript module from a CommonJS module must have a 'resolution-mode' attribute."} + +var Importing_a_JSON_file_into_an_ECMAScript_module_requires_a_type_Colon_json_import_attribute_when_module_is_set_to_0 = &Message{code: 1543, category: CategoryError, key: "Importing_a_JSON_file_into_an_ECMAScript_module_requires_a_type_Colon_json_import_attribute_when_mod_1543", text: "Importing a JSON file into an ECMAScript module requires a 'type: \"json\"' import attribute when 'module' is set to '{0}'."} + +var Named_imports_from_a_JSON_file_into_an_ECMAScript_module_are_not_allowed_when_module_is_set_to_0 = &Message{code: 1544, category: CategoryError, key: "Named_imports_from_a_JSON_file_into_an_ECMAScript_module_are_not_allowed_when_module_is_set_to_0_1544", text: "Named imports from a JSON file into an ECMAScript module are not allowed when 'module' is set to '{0}'."} + +var X_using_declarations_are_not_allowed_in_ambient_contexts = &Message{code: 1545, category: CategoryError, key: "using_declarations_are_not_allowed_in_ambient_contexts_1545", text: "'using' declarations are not allowed in ambient contexts."} + +var X_await_using_declarations_are_not_allowed_in_ambient_contexts = &Message{code: 1546, category: CategoryError, key: "await_using_declarations_are_not_allowed_in_ambient_contexts_1546", text: "'await using' declarations are not allowed in ambient contexts."} + +var The_types_of_0_are_incompatible_between_these_types = &Message{code: 2200, category: CategoryError, key: "The_types_of_0_are_incompatible_between_these_types_2200", text: "The types of '{0}' are incompatible between these types."} + +var The_types_returned_by_0_are_incompatible_between_these_types = &Message{code: 2201, category: CategoryError, key: "The_types_returned_by_0_are_incompatible_between_these_types_2201", text: "The types returned by '{0}' are incompatible between these types."} + +var Call_signature_return_types_0_and_1_are_incompatible = &Message{code: 2202, category: CategoryError, key: "Call_signature_return_types_0_and_1_are_incompatible_2202", text: "Call signature return types '{0}' and '{1}' are incompatible.", elidedInCompatibilityPyramid: true} + +var Construct_signature_return_types_0_and_1_are_incompatible = &Message{code: 2203, category: CategoryError, key: "Construct_signature_return_types_0_and_1_are_incompatible_2203", text: "Construct signature return types '{0}' and '{1}' are incompatible.", elidedInCompatibilityPyramid: true} + +var Call_signatures_with_no_arguments_have_incompatible_return_types_0_and_1 = &Message{code: 2204, category: CategoryError, key: "Call_signatures_with_no_arguments_have_incompatible_return_types_0_and_1_2204", text: "Call signatures with no arguments have incompatible return types '{0}' and '{1}'.", elidedInCompatibilityPyramid: true} + +var Construct_signatures_with_no_arguments_have_incompatible_return_types_0_and_1 = &Message{code: 2205, category: CategoryError, key: "Construct_signatures_with_no_arguments_have_incompatible_return_types_0_and_1_2205", text: "Construct signatures with no arguments have incompatible return types '{0}' and '{1}'.", elidedInCompatibilityPyramid: true} + +var The_type_modifier_cannot_be_used_on_a_named_import_when_import_type_is_used_on_its_import_statement = &Message{code: 2206, category: CategoryError, key: "The_type_modifier_cannot_be_used_on_a_named_import_when_import_type_is_used_on_its_import_statement_2206", text: "The 'type' modifier cannot be used on a named import when 'import type' is used on its import statement."} + +var The_type_modifier_cannot_be_used_on_a_named_export_when_export_type_is_used_on_its_export_statement = &Message{code: 2207, category: CategoryError, key: "The_type_modifier_cannot_be_used_on_a_named_export_when_export_type_is_used_on_its_export_statement_2207", text: "The 'type' modifier cannot be used on a named export when 'export type' is used on its export statement."} + +var This_type_parameter_might_need_an_extends_0_constraint = &Message{code: 2208, category: CategoryError, key: "This_type_parameter_might_need_an_extends_0_constraint_2208", text: "This type parameter might need an `extends {0}` constraint."} + +var The_project_root_is_ambiguous_but_is_required_to_resolve_export_map_entry_0_in_file_1_Supply_the_rootDir_compiler_option_to_disambiguate = &Message{code: 2209, category: CategoryError, key: "The_project_root_is_ambiguous_but_is_required_to_resolve_export_map_entry_0_in_file_1_Supply_the_roo_2209", text: "The project root is ambiguous, but is required to resolve export map entry '{0}' in file '{1}'. Supply the `rootDir` compiler option to disambiguate."} + +var The_project_root_is_ambiguous_but_is_required_to_resolve_import_map_entry_0_in_file_1_Supply_the_rootDir_compiler_option_to_disambiguate = &Message{code: 2210, category: CategoryError, key: "The_project_root_is_ambiguous_but_is_required_to_resolve_import_map_entry_0_in_file_1_Supply_the_roo_2210", text: "The project root is ambiguous, but is required to resolve import map entry '{0}' in file '{1}'. Supply the `rootDir` compiler option to disambiguate."} + +var Add_extends_constraint = &Message{code: 2211, category: CategoryMessage, key: "Add_extends_constraint_2211", text: "Add `extends` constraint."} + +var Add_extends_constraint_to_all_type_parameters = &Message{code: 2212, category: CategoryMessage, key: "Add_extends_constraint_to_all_type_parameters_2212", text: "Add `extends` constraint to all type parameters"} + +var Duplicate_identifier_0 = &Message{code: 2300, category: CategoryError, key: "Duplicate_identifier_0_2300", text: "Duplicate identifier '{0}'."} + +var Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor = &Message{code: 2301, category: CategoryError, key: "Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor_2301", text: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor."} + +var Static_members_cannot_reference_class_type_parameters = &Message{code: 2302, category: CategoryError, key: "Static_members_cannot_reference_class_type_parameters_2302", text: "Static members cannot reference class type parameters."} + +var Circular_definition_of_import_alias_0 = &Message{code: 2303, category: CategoryError, key: "Circular_definition_of_import_alias_0_2303", text: "Circular definition of import alias '{0}'."} + +var Cannot_find_name_0 = &Message{code: 2304, category: CategoryError, key: "Cannot_find_name_0_2304", text: "Cannot find name '{0}'."} + +var Module_0_has_no_exported_member_1 = &Message{code: 2305, category: CategoryError, key: "Module_0_has_no_exported_member_1_2305", text: "Module '{0}' has no exported member '{1}'."} + +var File_0_is_not_a_module = &Message{code: 2306, category: CategoryError, key: "File_0_is_not_a_module_2306", text: "File '{0}' is not a module."} + +var Cannot_find_module_0_or_its_corresponding_type_declarations = &Message{code: 2307, category: CategoryError, key: "Cannot_find_module_0_or_its_corresponding_type_declarations_2307", text: "Cannot find module '{0}' or its corresponding type declarations."} + +var Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambiguity = &Message{code: 2308, category: CategoryError, key: "Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambig_2308", text: "Module {0} has already exported a member named '{1}'. Consider explicitly re-exporting to resolve the ambiguity."} + +var An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements = &Message{code: 2309, category: CategoryError, key: "An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements_2309", text: "An export assignment cannot be used in a module with other exported elements."} + +var Type_0_recursively_references_itself_as_a_base_type = &Message{code: 2310, category: CategoryError, key: "Type_0_recursively_references_itself_as_a_base_type_2310", text: "Type '{0}' recursively references itself as a base type."} + +var Cannot_find_name_0_Did_you_mean_to_write_this_in_an_async_function = &Message{code: 2311, category: CategoryError, key: "Cannot_find_name_0_Did_you_mean_to_write_this_in_an_async_function_2311", text: "Cannot find name '{0}'. Did you mean to write this in an async function?"} + +var An_interface_can_only_extend_an_object_type_or_intersection_of_object_types_with_statically_known_members = &Message{code: 2312, category: CategoryError, key: "An_interface_can_only_extend_an_object_type_or_intersection_of_object_types_with_statically_known_me_2312", text: "An interface can only extend an object type or intersection of object types with statically known members."} + +var Type_parameter_0_has_a_circular_constraint = &Message{code: 2313, category: CategoryError, key: "Type_parameter_0_has_a_circular_constraint_2313", text: "Type parameter '{0}' has a circular constraint."} + +var Generic_type_0_requires_1_type_argument_s = &Message{code: 2314, category: CategoryError, key: "Generic_type_0_requires_1_type_argument_s_2314", text: "Generic type '{0}' requires {1} type argument(s)."} + +var Type_0_is_not_generic = &Message{code: 2315, category: CategoryError, key: "Type_0_is_not_generic_2315", text: "Type '{0}' is not generic."} + +var Global_type_0_must_be_a_class_or_interface_type = &Message{code: 2316, category: CategoryError, key: "Global_type_0_must_be_a_class_or_interface_type_2316", text: "Global type '{0}' must be a class or interface type."} + +var Global_type_0_must_have_1_type_parameter_s = &Message{code: 2317, category: CategoryError, key: "Global_type_0_must_have_1_type_parameter_s_2317", text: "Global type '{0}' must have {1} type parameter(s)."} + +var Cannot_find_global_type_0 = &Message{code: 2318, category: CategoryError, key: "Cannot_find_global_type_0_2318", text: "Cannot find global type '{0}'."} + +var Named_property_0_of_types_1_and_2_are_not_identical = &Message{code: 2319, category: CategoryError, key: "Named_property_0_of_types_1_and_2_are_not_identical_2319", text: "Named property '{0}' of types '{1}' and '{2}' are not identical."} + +var Interface_0_cannot_simultaneously_extend_types_1_and_2 = &Message{code: 2320, category: CategoryError, key: "Interface_0_cannot_simultaneously_extend_types_1_and_2_2320", text: "Interface '{0}' cannot simultaneously extend types '{1}' and '{2}'."} + +var Excessive_stack_depth_comparing_types_0_and_1 = &Message{code: 2321, category: CategoryError, key: "Excessive_stack_depth_comparing_types_0_and_1_2321", text: "Excessive stack depth comparing types '{0}' and '{1}'."} + +var Type_0_is_not_assignable_to_type_1 = &Message{code: 2322, category: CategoryError, key: "Type_0_is_not_assignable_to_type_1_2322", text: "Type '{0}' is not assignable to type '{1}'."} + +var Cannot_redeclare_exported_variable_0 = &Message{code: 2323, category: CategoryError, key: "Cannot_redeclare_exported_variable_0_2323", text: "Cannot redeclare exported variable '{0}'."} + +var Property_0_is_missing_in_type_1 = &Message{code: 2324, category: CategoryError, key: "Property_0_is_missing_in_type_1_2324", text: "Property '{0}' is missing in type '{1}'."} + +var Property_0_is_private_in_type_1_but_not_in_type_2 = &Message{code: 2325, category: CategoryError, key: "Property_0_is_private_in_type_1_but_not_in_type_2_2325", text: "Property '{0}' is private in type '{1}' but not in type '{2}'."} + +var Types_of_property_0_are_incompatible = &Message{code: 2326, category: CategoryError, key: "Types_of_property_0_are_incompatible_2326", text: "Types of property '{0}' are incompatible."} + +var Property_0_is_optional_in_type_1_but_required_in_type_2 = &Message{code: 2327, category: CategoryError, key: "Property_0_is_optional_in_type_1_but_required_in_type_2_2327", text: "Property '{0}' is optional in type '{1}' but required in type '{2}'."} + +var Types_of_parameters_0_and_1_are_incompatible = &Message{code: 2328, category: CategoryError, key: "Types_of_parameters_0_and_1_are_incompatible_2328", text: "Types of parameters '{0}' and '{1}' are incompatible."} + +var Index_signature_for_type_0_is_missing_in_type_1 = &Message{code: 2329, category: CategoryError, key: "Index_signature_for_type_0_is_missing_in_type_1_2329", text: "Index signature for type '{0}' is missing in type '{1}'."} + +var X_0_and_1_index_signatures_are_incompatible = &Message{code: 2330, category: CategoryError, key: "_0_and_1_index_signatures_are_incompatible_2330", text: "'{0}' and '{1}' index signatures are incompatible."} + +var X_this_cannot_be_referenced_in_a_module_or_namespace_body = &Message{code: 2331, category: CategoryError, key: "this_cannot_be_referenced_in_a_module_or_namespace_body_2331", text: "'this' cannot be referenced in a module or namespace body."} + +var X_this_cannot_be_referenced_in_current_location = &Message{code: 2332, category: CategoryError, key: "this_cannot_be_referenced_in_current_location_2332", text: "'this' cannot be referenced in current location."} + +var X_this_cannot_be_referenced_in_a_static_property_initializer = &Message{code: 2334, category: CategoryError, key: "this_cannot_be_referenced_in_a_static_property_initializer_2334", text: "'this' cannot be referenced in a static property initializer."} + +var X_super_can_only_be_referenced_in_a_derived_class = &Message{code: 2335, category: CategoryError, key: "super_can_only_be_referenced_in_a_derived_class_2335", text: "'super' can only be referenced in a derived class."} + +var X_super_cannot_be_referenced_in_constructor_arguments = &Message{code: 2336, category: CategoryError, key: "super_cannot_be_referenced_in_constructor_arguments_2336", text: "'super' cannot be referenced in constructor arguments."} + +var Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors = &Message{code: 2337, category: CategoryError, key: "Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors_2337", text: "Super calls are not permitted outside constructors or in nested functions inside constructors."} + +var X_super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class = &Message{code: 2338, category: CategoryError, key: "super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_der_2338", text: "'super' property access is permitted only in a constructor, member function, or member accessor of a derived class."} + +var Property_0_does_not_exist_on_type_1 = &Message{code: 2339, category: CategoryError, key: "Property_0_does_not_exist_on_type_1_2339", text: "Property '{0}' does not exist on type '{1}'."} + +var Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword = &Message{code: 2340, category: CategoryError, key: "Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword_2340", text: "Only public and protected methods of the base class are accessible via the 'super' keyword."} + +var Property_0_is_private_and_only_accessible_within_class_1 = &Message{code: 2341, category: CategoryError, key: "Property_0_is_private_and_only_accessible_within_class_1_2341", text: "Property '{0}' is private and only accessible within class '{1}'."} + +var This_syntax_requires_an_imported_helper_named_1_which_does_not_exist_in_0_Consider_upgrading_your_version_of_0 = &Message{code: 2343, category: CategoryError, key: "This_syntax_requires_an_imported_helper_named_1_which_does_not_exist_in_0_Consider_upgrading_your_ve_2343", text: "This syntax requires an imported helper named '{1}' which does not exist in '{0}'. Consider upgrading your version of '{0}'."} + +var Type_0_does_not_satisfy_the_constraint_1 = &Message{code: 2344, category: CategoryError, key: "Type_0_does_not_satisfy_the_constraint_1_2344", text: "Type '{0}' does not satisfy the constraint '{1}'."} + +var Argument_of_type_0_is_not_assignable_to_parameter_of_type_1 = &Message{code: 2345, category: CategoryError, key: "Argument_of_type_0_is_not_assignable_to_parameter_of_type_1_2345", text: "Argument of type '{0}' is not assignable to parameter of type '{1}'."} + +var Call_target_does_not_contain_any_signatures = &Message{code: 2346, category: CategoryError, key: "Call_target_does_not_contain_any_signatures_2346", text: "Call target does not contain any signatures."} + +var Untyped_function_calls_may_not_accept_type_arguments = &Message{code: 2347, category: CategoryError, key: "Untyped_function_calls_may_not_accept_type_arguments_2347", text: "Untyped function calls may not accept type arguments."} + +var Value_of_type_0_is_not_callable_Did_you_mean_to_include_new = &Message{code: 2348, category: CategoryError, key: "Value_of_type_0_is_not_callable_Did_you_mean_to_include_new_2348", text: "Value of type '{0}' is not callable. Did you mean to include 'new'?"} + +var This_expression_is_not_callable = &Message{code: 2349, category: CategoryError, key: "This_expression_is_not_callable_2349", text: "This expression is not callable."} + +var Only_a_void_function_can_be_called_with_the_new_keyword = &Message{code: 2350, category: CategoryError, key: "Only_a_void_function_can_be_called_with_the_new_keyword_2350", text: "Only a void function can be called with the 'new' keyword."} + +var This_expression_is_not_constructable = &Message{code: 2351, category: CategoryError, key: "This_expression_is_not_constructable_2351", text: "This expression is not constructable."} + +var Conversion_of_type_0_to_type_1_may_be_a_mistake_because_neither_type_sufficiently_overlaps_with_the_other_If_this_was_intentional_convert_the_expression_to_unknown_first = &Message{code: 2352, category: CategoryError, key: "Conversion_of_type_0_to_type_1_may_be_a_mistake_because_neither_type_sufficiently_overlaps_with_the__2352", text: "Conversion of type '{0}' to type '{1}' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first."} + +var Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1 = &Message{code: 2353, category: CategoryError, key: "Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1_2353", text: "Object literal may only specify known properties, and '{0}' does not exist in type '{1}'."} + +var This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found = &Message{code: 2354, category: CategoryError, key: "This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found_2354", text: "This syntax requires an imported helper but module '{0}' cannot be found."} + +var A_function_whose_declared_type_is_neither_undefined_void_nor_any_must_return_a_value = &Message{code: 2355, category: CategoryError, key: "A_function_whose_declared_type_is_neither_undefined_void_nor_any_must_return_a_value_2355", text: "A function whose declared type is neither 'undefined', 'void', nor 'any' must return a value."} + +var An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type = &Message{code: 2356, category: CategoryError, key: "An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type_2356", text: "An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type."} + +var The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access = &Message{code: 2357, category: CategoryError, key: "The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access_2357", text: "The operand of an increment or decrement operator must be a variable or a property access."} + +var The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter = &Message{code: 2358, category: CategoryError, key: "The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_paramete_2358", text: "The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter."} + +var The_right_hand_side_of_an_instanceof_expression_must_be_either_of_type_any_a_class_function_or_other_type_assignable_to_the_Function_interface_type_or_an_object_type_with_a_Symbol_hasInstance_method = &Message{code: 2359, category: CategoryError, key: "The_right_hand_side_of_an_instanceof_expression_must_be_either_of_type_any_a_class_function_or_other_2359", text: "The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method."} + +var The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type = &Message{code: 2362, category: CategoryError, key: "The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type_2362", text: "The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type."} + +var The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type = &Message{code: 2363, category: CategoryError, key: "The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type_2363", text: "The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type."} + +var The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access = &Message{code: 2364, category: CategoryError, key: "The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access_2364", text: "The left-hand side of an assignment expression must be a variable or a property access."} + +var Operator_0_cannot_be_applied_to_types_1_and_2 = &Message{code: 2365, category: CategoryError, key: "Operator_0_cannot_be_applied_to_types_1_and_2_2365", text: "Operator '{0}' cannot be applied to types '{1}' and '{2}'."} + +var Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined = &Message{code: 2366, category: CategoryError, key: "Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined_2366", text: "Function lacks ending return statement and return type does not include 'undefined'."} + +var This_comparison_appears_to_be_unintentional_because_the_types_0_and_1_have_no_overlap = &Message{code: 2367, category: CategoryError, key: "This_comparison_appears_to_be_unintentional_because_the_types_0_and_1_have_no_overlap_2367", text: "This comparison appears to be unintentional because the types '{0}' and '{1}' have no overlap."} + +var Type_parameter_name_cannot_be_0 = &Message{code: 2368, category: CategoryError, key: "Type_parameter_name_cannot_be_0_2368", text: "Type parameter name cannot be '{0}'."} + +var A_parameter_property_is_only_allowed_in_a_constructor_implementation = &Message{code: 2369, category: CategoryError, key: "A_parameter_property_is_only_allowed_in_a_constructor_implementation_2369", text: "A parameter property is only allowed in a constructor implementation."} + +var A_rest_parameter_must_be_of_an_array_type = &Message{code: 2370, category: CategoryError, key: "A_rest_parameter_must_be_of_an_array_type_2370", text: "A rest parameter must be of an array type."} + +var A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation = &Message{code: 2371, category: CategoryError, key: "A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation_2371", text: "A parameter initializer is only allowed in a function or constructor implementation."} + +var Parameter_0_cannot_reference_itself = &Message{code: 2372, category: CategoryError, key: "Parameter_0_cannot_reference_itself_2372", text: "Parameter '{0}' cannot reference itself."} + +var Parameter_0_cannot_reference_identifier_1_declared_after_it = &Message{code: 2373, category: CategoryError, key: "Parameter_0_cannot_reference_identifier_1_declared_after_it_2373", text: "Parameter '{0}' cannot reference identifier '{1}' declared after it."} + +var Duplicate_index_signature_for_type_0 = &Message{code: 2374, category: CategoryError, key: "Duplicate_index_signature_for_type_0_2374", text: "Duplicate index signature for type '{0}'."} + +var Type_0_is_not_assignable_to_type_1_with_exactOptionalPropertyTypes_Colon_true_Consider_adding_undefined_to_the_types_of_the_target_s_properties = &Message{code: 2375, category: CategoryError, key: "Type_0_is_not_assignable_to_type_1_with_exactOptionalPropertyTypes_Colon_true_Consider_adding_undefi_2375", text: "Type '{0}' is not assignable to type '{1}' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties."} + +var A_super_call_must_be_the_first_statement_in_the_constructor_to_refer_to_super_or_this_when_a_derived_class_contains_initialized_properties_parameter_properties_or_private_identifiers = &Message{code: 2376, category: CategoryError, key: "A_super_call_must_be_the_first_statement_in_the_constructor_to_refer_to_super_or_this_when_a_derived_2376", text: "A 'super' call must be the first statement in the constructor to refer to 'super' or 'this' when a derived class contains initialized properties, parameter properties, or private identifiers."} + +var Constructors_for_derived_classes_must_contain_a_super_call = &Message{code: 2377, category: CategoryError, key: "Constructors_for_derived_classes_must_contain_a_super_call_2377", text: "Constructors for derived classes must contain a 'super' call."} + +var A_get_accessor_must_return_a_value = &Message{code: 2378, category: CategoryError, key: "A_get_accessor_must_return_a_value_2378", text: "A 'get' accessor must return a value."} + +var Argument_of_type_0_is_not_assignable_to_parameter_of_type_1_with_exactOptionalPropertyTypes_Colon_true_Consider_adding_undefined_to_the_types_of_the_target_s_properties = &Message{code: 2379, category: CategoryError, key: "Argument_of_type_0_is_not_assignable_to_parameter_of_type_1_with_exactOptionalPropertyTypes_Colon_tr_2379", text: "Argument of type '{0}' is not assignable to parameter of type '{1}' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties."} + +var Overload_signatures_must_all_be_exported_or_non_exported = &Message{code: 2383, category: CategoryError, key: "Overload_signatures_must_all_be_exported_or_non_exported_2383", text: "Overload signatures must all be exported or non-exported."} + +var Overload_signatures_must_all_be_ambient_or_non_ambient = &Message{code: 2384, category: CategoryError, key: "Overload_signatures_must_all_be_ambient_or_non_ambient_2384", text: "Overload signatures must all be ambient or non-ambient."} + +var Overload_signatures_must_all_be_public_private_or_protected = &Message{code: 2385, category: CategoryError, key: "Overload_signatures_must_all_be_public_private_or_protected_2385", text: "Overload signatures must all be public, private or protected."} + +var Overload_signatures_must_all_be_optional_or_required = &Message{code: 2386, category: CategoryError, key: "Overload_signatures_must_all_be_optional_or_required_2386", text: "Overload signatures must all be optional or required."} + +var Function_overload_must_be_static = &Message{code: 2387, category: CategoryError, key: "Function_overload_must_be_static_2387", text: "Function overload must be static."} + +var Function_overload_must_not_be_static = &Message{code: 2388, category: CategoryError, key: "Function_overload_must_not_be_static_2388", text: "Function overload must not be static."} + +var Function_implementation_name_must_be_0 = &Message{code: 2389, category: CategoryError, key: "Function_implementation_name_must_be_0_2389", text: "Function implementation name must be '{0}'."} + +var Constructor_implementation_is_missing = &Message{code: 2390, category: CategoryError, key: "Constructor_implementation_is_missing_2390", text: "Constructor implementation is missing."} + +var Function_implementation_is_missing_or_not_immediately_following_the_declaration = &Message{code: 2391, category: CategoryError, key: "Function_implementation_is_missing_or_not_immediately_following_the_declaration_2391", text: "Function implementation is missing or not immediately following the declaration."} + +var Multiple_constructor_implementations_are_not_allowed = &Message{code: 2392, category: CategoryError, key: "Multiple_constructor_implementations_are_not_allowed_2392", text: "Multiple constructor implementations are not allowed."} + +var Duplicate_function_implementation = &Message{code: 2393, category: CategoryError, key: "Duplicate_function_implementation_2393", text: "Duplicate function implementation."} + +var This_overload_signature_is_not_compatible_with_its_implementation_signature = &Message{code: 2394, category: CategoryError, key: "This_overload_signature_is_not_compatible_with_its_implementation_signature_2394", text: "This overload signature is not compatible with its implementation signature."} + +var Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local = &Message{code: 2395, category: CategoryError, key: "Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local_2395", text: "Individual declarations in merged declaration '{0}' must be all exported or all local."} + +var Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters = &Message{code: 2396, category: CategoryError, key: "Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters_2396", text: "Duplicate identifier 'arguments'. Compiler uses 'arguments' to initialize rest parameters."} + +var Declaration_name_conflicts_with_built_in_global_identifier_0 = &Message{code: 2397, category: CategoryError, key: "Declaration_name_conflicts_with_built_in_global_identifier_0_2397", text: "Declaration name conflicts with built-in global identifier '{0}'."} + +var X_constructor_cannot_be_used_as_a_parameter_property_name = &Message{code: 2398, category: CategoryError, key: "constructor_cannot_be_used_as_a_parameter_property_name_2398", text: "'constructor' cannot be used as a parameter property name."} + +var Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference = &Message{code: 2399, category: CategoryError, key: "Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference_2399", text: "Duplicate identifier '_this'. Compiler uses variable declaration '_this' to capture 'this' reference."} + +var Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference = &Message{code: 2400, category: CategoryError, key: "Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference_2400", text: "Expression resolves to variable declaration '_this' that compiler uses to capture 'this' reference."} + +var A_super_call_must_be_a_root_level_statement_within_a_constructor_of_a_derived_class_that_contains_initialized_properties_parameter_properties_or_private_identifiers = &Message{code: 2401, category: CategoryError, key: "A_super_call_must_be_a_root_level_statement_within_a_constructor_of_a_derived_class_that_contains_in_2401", text: "A 'super' call must be a root-level statement within a constructor of a derived class that contains initialized properties, parameter properties, or private identifiers."} + +var Expression_resolves_to_super_that_compiler_uses_to_capture_base_class_reference = &Message{code: 2402, category: CategoryError, key: "Expression_resolves_to_super_that_compiler_uses_to_capture_base_class_reference_2402", text: "Expression resolves to '_super' that compiler uses to capture base class reference."} + +var Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2 = &Message{code: 2403, category: CategoryError, key: "Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403", text: "Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'."} + +var The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation = &Message{code: 2404, category: CategoryError, key: "The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation_2404", text: "The left-hand side of a 'for...in' statement cannot use a type annotation."} + +var The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any = &Message{code: 2405, category: CategoryError, key: "The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any_2405", text: "The left-hand side of a 'for...in' statement must be of type 'string' or 'any'."} + +var The_left_hand_side_of_a_for_in_statement_must_be_a_variable_or_a_property_access = &Message{code: 2406, category: CategoryError, key: "The_left_hand_side_of_a_for_in_statement_must_be_a_variable_or_a_property_access_2406", text: "The left-hand side of a 'for...in' statement must be a variable or a property access."} + +var The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter_but_here_has_type_0 = &Message{code: 2407, category: CategoryError, key: "The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter_but_2407", text: "The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter, but here has type '{0}'."} + +var Setters_cannot_return_a_value = &Message{code: 2408, category: CategoryError, key: "Setters_cannot_return_a_value_2408", text: "Setters cannot return a value."} + +var Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class = &Message{code: 2409, category: CategoryError, key: "Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class_2409", text: "Return type of constructor signature must be assignable to the instance type of the class."} + +var The_with_statement_is_not_supported_All_symbols_in_a_with_block_will_have_type_any = &Message{code: 2410, category: CategoryError, key: "The_with_statement_is_not_supported_All_symbols_in_a_with_block_will_have_type_any_2410", text: "The 'with' statement is not supported. All symbols in a 'with' block will have type 'any'."} + +var Property_0_of_type_1_is_not_assignable_to_2_index_type_3 = &Message{code: 2411, category: CategoryError, key: "Property_0_of_type_1_is_not_assignable_to_2_index_type_3_2411", text: "Property '{0}' of type '{1}' is not assignable to '{2}' index type '{3}'."} + +var Type_0_is_not_assignable_to_type_1_with_exactOptionalPropertyTypes_Colon_true_Consider_adding_undefined_to_the_type_of_the_target = &Message{code: 2412, category: CategoryError, key: "Type_0_is_not_assignable_to_type_1_with_exactOptionalPropertyTypes_Colon_true_Consider_adding_undefi_2412", text: "Type '{0}' is not assignable to type '{1}' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the type of the target."} + +var X_0_index_type_1_is_not_assignable_to_2_index_type_3 = &Message{code: 2413, category: CategoryError, key: "_0_index_type_1_is_not_assignable_to_2_index_type_3_2413", text: "'{0}' index type '{1}' is not assignable to '{2}' index type '{3}'."} + +var Class_name_cannot_be_0 = &Message{code: 2414, category: CategoryError, key: "Class_name_cannot_be_0_2414", text: "Class name cannot be '{0}'."} + +var Class_0_incorrectly_extends_base_class_1 = &Message{code: 2415, category: CategoryError, key: "Class_0_incorrectly_extends_base_class_1_2415", text: "Class '{0}' incorrectly extends base class '{1}'."} + +var Property_0_in_type_1_is_not_assignable_to_the_same_property_in_base_type_2 = &Message{code: 2416, category: CategoryError, key: "Property_0_in_type_1_is_not_assignable_to_the_same_property_in_base_type_2_2416", text: "Property '{0}' in type '{1}' is not assignable to the same property in base type '{2}'."} + +var Class_static_side_0_incorrectly_extends_base_class_static_side_1 = &Message{code: 2417, category: CategoryError, key: "Class_static_side_0_incorrectly_extends_base_class_static_side_1_2417", text: "Class static side '{0}' incorrectly extends base class static side '{1}'."} + +var Type_of_computed_property_s_value_is_0_which_is_not_assignable_to_type_1 = &Message{code: 2418, category: CategoryError, key: "Type_of_computed_property_s_value_is_0_which_is_not_assignable_to_type_1_2418", text: "Type of computed property's value is '{0}', which is not assignable to type '{1}'."} + +var Types_of_construct_signatures_are_incompatible = &Message{code: 2419, category: CategoryError, key: "Types_of_construct_signatures_are_incompatible_2419", text: "Types of construct signatures are incompatible."} + +var Class_0_incorrectly_implements_interface_1 = &Message{code: 2420, category: CategoryError, key: "Class_0_incorrectly_implements_interface_1_2420", text: "Class '{0}' incorrectly implements interface '{1}'."} + +var A_class_can_only_implement_an_object_type_or_intersection_of_object_types_with_statically_known_members = &Message{code: 2422, category: CategoryError, key: "A_class_can_only_implement_an_object_type_or_intersection_of_object_types_with_statically_known_memb_2422", text: "A class can only implement an object type or intersection of object types with statically known members."} + +var Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_accessor = &Message{code: 2423, category: CategoryError, key: "Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_access_2423", text: "Class '{0}' defines instance member function '{1}', but extended class '{2}' defines it as instance member accessor."} + +var Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_function = &Message{code: 2425, category: CategoryError, key: "Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_functi_2425", text: "Class '{0}' defines instance member property '{1}', but extended class '{2}' defines it as instance member function."} + +var Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_function = &Message{code: 2426, category: CategoryError, key: "Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_functi_2426", text: "Class '{0}' defines instance member accessor '{1}', but extended class '{2}' defines it as instance member function."} + +var Interface_name_cannot_be_0 = &Message{code: 2427, category: CategoryError, key: "Interface_name_cannot_be_0_2427", text: "Interface name cannot be '{0}'."} + +var All_declarations_of_0_must_have_identical_type_parameters = &Message{code: 2428, category: CategoryError, key: "All_declarations_of_0_must_have_identical_type_parameters_2428", text: "All declarations of '{0}' must have identical type parameters."} + +var Interface_0_incorrectly_extends_interface_1 = &Message{code: 2430, category: CategoryError, key: "Interface_0_incorrectly_extends_interface_1_2430", text: "Interface '{0}' incorrectly extends interface '{1}'."} + +var Enum_name_cannot_be_0 = &Message{code: 2431, category: CategoryError, key: "Enum_name_cannot_be_0_2431", text: "Enum name cannot be '{0}'."} + +var In_an_enum_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_its_first_enum_element = &Message{code: 2432, category: CategoryError, key: "In_an_enum_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_its_first_enu_2432", text: "In an enum with multiple declarations, only one declaration can omit an initializer for its first enum element."} + +var A_namespace_declaration_cannot_be_in_a_different_file_from_a_class_or_function_with_which_it_is_merged = &Message{code: 2433, category: CategoryError, key: "A_namespace_declaration_cannot_be_in_a_different_file_from_a_class_or_function_with_which_it_is_merg_2433", text: "A namespace declaration cannot be in a different file from a class or function with which it is merged."} + +var A_namespace_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged = &Message{code: 2434, category: CategoryError, key: "A_namespace_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged_2434", text: "A namespace declaration cannot be located prior to a class or function with which it is merged."} + +var Ambient_modules_cannot_be_nested_in_other_modules_or_namespaces = &Message{code: 2435, category: CategoryError, key: "Ambient_modules_cannot_be_nested_in_other_modules_or_namespaces_2435", text: "Ambient modules cannot be nested in other modules or namespaces."} + +var Ambient_module_declaration_cannot_specify_relative_module_name = &Message{code: 2436, category: CategoryError, key: "Ambient_module_declaration_cannot_specify_relative_module_name_2436", text: "Ambient module declaration cannot specify relative module name."} + +var Module_0_is_hidden_by_a_local_declaration_with_the_same_name = &Message{code: 2437, category: CategoryError, key: "Module_0_is_hidden_by_a_local_declaration_with_the_same_name_2437", text: "Module '{0}' is hidden by a local declaration with the same name."} + +var Import_name_cannot_be_0 = &Message{code: 2438, category: CategoryError, key: "Import_name_cannot_be_0_2438", text: "Import name cannot be '{0}'."} + +var Import_or_export_declaration_in_an_ambient_module_declaration_cannot_reference_module_through_relative_module_name = &Message{code: 2439, category: CategoryError, key: "Import_or_export_declaration_in_an_ambient_module_declaration_cannot_reference_module_through_relati_2439", text: "Import or export declaration in an ambient module declaration cannot reference module through relative module name."} + +var Import_declaration_conflicts_with_local_declaration_of_0 = &Message{code: 2440, category: CategoryError, key: "Import_declaration_conflicts_with_local_declaration_of_0_2440", text: "Import declaration conflicts with local declaration of '{0}'."} + +var Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module = &Message{code: 2441, category: CategoryError, key: "Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_2441", text: "Duplicate identifier '{0}'. Compiler reserves name '{1}' in top level scope of a module."} + +var Types_have_separate_declarations_of_a_private_property_0 = &Message{code: 2442, category: CategoryError, key: "Types_have_separate_declarations_of_a_private_property_0_2442", text: "Types have separate declarations of a private property '{0}'."} + +var Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2 = &Message{code: 2443, category: CategoryError, key: "Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2_2443", text: "Property '{0}' is protected but type '{1}' is not a class derived from '{2}'."} + +var Property_0_is_protected_in_type_1_but_public_in_type_2 = &Message{code: 2444, category: CategoryError, key: "Property_0_is_protected_in_type_1_but_public_in_type_2_2444", text: "Property '{0}' is protected in type '{1}' but public in type '{2}'."} + +var Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses = &Message{code: 2445, category: CategoryError, key: "Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses_2445", text: "Property '{0}' is protected and only accessible within class '{1}' and its subclasses."} + +var Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1_This_is_an_instance_of_class_2 = &Message{code: 2446, category: CategoryError, key: "Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1_This_is_an_instance_of_cl_2446", text: "Property '{0}' is protected and only accessible through an instance of class '{1}'. This is an instance of class '{2}'."} + +var The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead = &Message{code: 2447, category: CategoryError, key: "The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead_2447", text: "The '{0}' operator is not allowed for boolean types. Consider using '{1}' instead."} + +var Block_scoped_variable_0_used_before_its_declaration = &Message{code: 2448, category: CategoryError, key: "Block_scoped_variable_0_used_before_its_declaration_2448", text: "Block-scoped variable '{0}' used before its declaration."} + +var Class_0_used_before_its_declaration = &Message{code: 2449, category: CategoryError, key: "Class_0_used_before_its_declaration_2449", text: "Class '{0}' used before its declaration."} + +var Enum_0_used_before_its_declaration = &Message{code: 2450, category: CategoryError, key: "Enum_0_used_before_its_declaration_2450", text: "Enum '{0}' used before its declaration."} + +var Cannot_redeclare_block_scoped_variable_0 = &Message{code: 2451, category: CategoryError, key: "Cannot_redeclare_block_scoped_variable_0_2451", text: "Cannot redeclare block-scoped variable '{0}'."} + +var An_enum_member_cannot_have_a_numeric_name = &Message{code: 2452, category: CategoryError, key: "An_enum_member_cannot_have_a_numeric_name_2452", text: "An enum member cannot have a numeric name."} + +var Variable_0_is_used_before_being_assigned = &Message{code: 2454, category: CategoryError, key: "Variable_0_is_used_before_being_assigned_2454", text: "Variable '{0}' is used before being assigned."} + +var Type_alias_0_circularly_references_itself = &Message{code: 2456, category: CategoryError, key: "Type_alias_0_circularly_references_itself_2456", text: "Type alias '{0}' circularly references itself."} + +var Type_alias_name_cannot_be_0 = &Message{code: 2457, category: CategoryError, key: "Type_alias_name_cannot_be_0_2457", text: "Type alias name cannot be '{0}'."} + +var An_AMD_module_cannot_have_multiple_name_assignments = &Message{code: 2458, category: CategoryError, key: "An_AMD_module_cannot_have_multiple_name_assignments_2458", text: "An AMD module cannot have multiple name assignments."} + +var Module_0_declares_1_locally_but_it_is_not_exported = &Message{code: 2459, category: CategoryError, key: "Module_0_declares_1_locally_but_it_is_not_exported_2459", text: "Module '{0}' declares '{1}' locally, but it is not exported."} + +var Module_0_declares_1_locally_but_it_is_exported_as_2 = &Message{code: 2460, category: CategoryError, key: "Module_0_declares_1_locally_but_it_is_exported_as_2_2460", text: "Module '{0}' declares '{1}' locally, but it is exported as '{2}'."} + +var Type_0_is_not_an_array_type = &Message{code: 2461, category: CategoryError, key: "Type_0_is_not_an_array_type_2461", text: "Type '{0}' is not an array type."} + +var A_rest_element_must_be_last_in_a_destructuring_pattern = &Message{code: 2462, category: CategoryError, key: "A_rest_element_must_be_last_in_a_destructuring_pattern_2462", text: "A rest element must be last in a destructuring pattern."} + +var A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature = &Message{code: 2463, category: CategoryError, key: "A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature_2463", text: "A binding pattern parameter cannot be optional in an implementation signature."} + +var A_computed_property_name_must_be_of_type_string_number_symbol_or_any = &Message{code: 2464, category: CategoryError, key: "A_computed_property_name_must_be_of_type_string_number_symbol_or_any_2464", text: "A computed property name must be of type 'string', 'number', 'symbol', or 'any'."} + +var X_this_cannot_be_referenced_in_a_computed_property_name = &Message{code: 2465, category: CategoryError, key: "this_cannot_be_referenced_in_a_computed_property_name_2465", text: "'this' cannot be referenced in a computed property name."} + +var X_super_cannot_be_referenced_in_a_computed_property_name = &Message{code: 2466, category: CategoryError, key: "super_cannot_be_referenced_in_a_computed_property_name_2466", text: "'super' cannot be referenced in a computed property name."} + +var A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type = &Message{code: 2467, category: CategoryError, key: "A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type_2467", text: "A computed property name cannot reference a type parameter from its containing type."} + +var Cannot_find_global_value_0 = &Message{code: 2468, category: CategoryError, key: "Cannot_find_global_value_0_2468", text: "Cannot find global value '{0}'."} + +var The_0_operator_cannot_be_applied_to_type_symbol = &Message{code: 2469, category: CategoryError, key: "The_0_operator_cannot_be_applied_to_type_symbol_2469", text: "The '{0}' operator cannot be applied to type 'symbol'."} + +var Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher = &Message{code: 2472, category: CategoryError, key: "Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher_2472", text: "Spread operator in 'new' expressions is only available when targeting ECMAScript 5 and higher."} + +var Enum_declarations_must_all_be_const_or_non_const = &Message{code: 2473, category: CategoryError, key: "Enum_declarations_must_all_be_const_or_non_const_2473", text: "Enum declarations must all be const or non-const."} + +var X_const_enum_member_initializers_must_be_constant_expressions = &Message{code: 2474, category: CategoryError, key: "const_enum_member_initializers_must_be_constant_expressions_2474", text: "const enum member initializers must be constant expressions."} + +var X_const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment_or_type_query = &Message{code: 2475, category: CategoryError, key: "const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_im_2475", text: "'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query."} + +var A_const_enum_member_can_only_be_accessed_using_a_string_literal = &Message{code: 2476, category: CategoryError, key: "A_const_enum_member_can_only_be_accessed_using_a_string_literal_2476", text: "A const enum member can only be accessed using a string literal."} + +var X_const_enum_member_initializer_was_evaluated_to_a_non_finite_value = &Message{code: 2477, category: CategoryError, key: "const_enum_member_initializer_was_evaluated_to_a_non_finite_value_2477", text: "'const' enum member initializer was evaluated to a non-finite value."} + +var X_const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN = &Message{code: 2478, category: CategoryError, key: "const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN_2478", text: "'const' enum member initializer was evaluated to disallowed value 'NaN'."} + +var X_let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations = &Message{code: 2480, category: CategoryError, key: "let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations_2480", text: "'let' is not allowed to be used as a name in 'let' or 'const' declarations."} + +var Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1 = &Message{code: 2481, category: CategoryError, key: "Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1_2481", text: "Cannot initialize outer scoped variable '{0}' in the same scope as block scoped declaration '{1}'."} + +var The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation = &Message{code: 2483, category: CategoryError, key: "The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation_2483", text: "The left-hand side of a 'for...of' statement cannot use a type annotation."} + +var Export_declaration_conflicts_with_exported_declaration_of_0 = &Message{code: 2484, category: CategoryError, key: "Export_declaration_conflicts_with_exported_declaration_of_0_2484", text: "Export declaration conflicts with exported declaration of '{0}'."} + +var The_left_hand_side_of_a_for_of_statement_must_be_a_variable_or_a_property_access = &Message{code: 2487, category: CategoryError, key: "The_left_hand_side_of_a_for_of_statement_must_be_a_variable_or_a_property_access_2487", text: "The left-hand side of a 'for...of' statement must be a variable or a property access."} + +var Type_0_must_have_a_Symbol_iterator_method_that_returns_an_iterator = &Message{code: 2488, category: CategoryError, key: "Type_0_must_have_a_Symbol_iterator_method_that_returns_an_iterator_2488", text: "Type '{0}' must have a '[Symbol.iterator]()' method that returns an iterator."} + +var An_iterator_must_have_a_next_method = &Message{code: 2489, category: CategoryError, key: "An_iterator_must_have_a_next_method_2489", text: "An iterator must have a 'next()' method."} + +var The_type_returned_by_the_0_method_of_an_iterator_must_have_a_value_property = &Message{code: 2490, category: CategoryError, key: "The_type_returned_by_the_0_method_of_an_iterator_must_have_a_value_property_2490", text: "The type returned by the '{0}()' method of an iterator must have a 'value' property."} + +var The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern = &Message{code: 2491, category: CategoryError, key: "The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern_2491", text: "The left-hand side of a 'for...in' statement cannot be a destructuring pattern."} + +var Cannot_redeclare_identifier_0_in_catch_clause = &Message{code: 2492, category: CategoryError, key: "Cannot_redeclare_identifier_0_in_catch_clause_2492", text: "Cannot redeclare identifier '{0}' in catch clause."} + +var Tuple_type_0_of_length_1_has_no_element_at_index_2 = &Message{code: 2493, category: CategoryError, key: "Tuple_type_0_of_length_1_has_no_element_at_index_2_2493", text: "Tuple type '{0}' of length '{1}' has no element at index '{2}'."} + +var Using_a_string_in_a_for_of_statement_is_only_supported_in_ECMAScript_5_and_higher = &Message{code: 2494, category: CategoryError, key: "Using_a_string_in_a_for_of_statement_is_only_supported_in_ECMAScript_5_and_higher_2494", text: "Using a string in a 'for...of' statement is only supported in ECMAScript 5 and higher."} + +var Type_0_is_not_an_array_type_or_a_string_type = &Message{code: 2495, category: CategoryError, key: "Type_0_is_not_an_array_type_or_a_string_type_2495", text: "Type '{0}' is not an array type or a string type."} + +var The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES5_Consider_using_a_standard_function_expression = &Message{code: 2496, category: CategoryError, key: "The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES5_Consider_using_a_standard_func_2496", text: "The 'arguments' object cannot be referenced in an arrow function in ES5. Consider using a standard function expression."} + +var This_module_can_only_be_referenced_with_ECMAScript_imports_Slashexports_by_turning_on_the_0_flag_and_referencing_its_default_export = &Message{code: 2497, category: CategoryError, key: "This_module_can_only_be_referenced_with_ECMAScript_imports_Slashexports_by_turning_on_the_0_flag_and_2497", text: "This module can only be referenced with ECMAScript imports/exports by turning on the '{0}' flag and referencing its default export."} + +var Module_0_uses_export_and_cannot_be_used_with_export_Asterisk = &Message{code: 2498, category: CategoryError, key: "Module_0_uses_export_and_cannot_be_used_with_export_Asterisk_2498", text: "Module '{0}' uses 'export =' and cannot be used with 'export *'."} + +var An_interface_can_only_extend_an_identifier_Slashqualified_name_with_optional_type_arguments = &Message{code: 2499, category: CategoryError, key: "An_interface_can_only_extend_an_identifier_Slashqualified_name_with_optional_type_arguments_2499", text: "An interface can only extend an identifier/qualified-name with optional type arguments."} + +var A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments = &Message{code: 2500, category: CategoryError, key: "A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments_2500", text: "A class can only implement an identifier/qualified-name with optional type arguments."} + +var A_rest_element_cannot_contain_a_binding_pattern = &Message{code: 2501, category: CategoryError, key: "A_rest_element_cannot_contain_a_binding_pattern_2501", text: "A rest element cannot contain a binding pattern."} + +var X_0_is_referenced_directly_or_indirectly_in_its_own_type_annotation = &Message{code: 2502, category: CategoryError, key: "_0_is_referenced_directly_or_indirectly_in_its_own_type_annotation_2502", text: "'{0}' is referenced directly or indirectly in its own type annotation."} + +var Cannot_find_namespace_0 = &Message{code: 2503, category: CategoryError, key: "Cannot_find_namespace_0_2503", text: "Cannot find namespace '{0}'."} + +var Type_0_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator = &Message{code: 2504, category: CategoryError, key: "Type_0_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator_2504", text: "Type '{0}' must have a '[Symbol.asyncIterator]()' method that returns an async iterator."} + +var A_generator_cannot_have_a_void_type_annotation = &Message{code: 2505, category: CategoryError, key: "A_generator_cannot_have_a_void_type_annotation_2505", text: "A generator cannot have a 'void' type annotation."} + +var X_0_is_referenced_directly_or_indirectly_in_its_own_base_expression = &Message{code: 2506, category: CategoryError, key: "_0_is_referenced_directly_or_indirectly_in_its_own_base_expression_2506", text: "'{0}' is referenced directly or indirectly in its own base expression."} + +var Type_0_is_not_a_constructor_function_type = &Message{code: 2507, category: CategoryError, key: "Type_0_is_not_a_constructor_function_type_2507", text: "Type '{0}' is not a constructor function type."} + +var No_base_constructor_has_the_specified_number_of_type_arguments = &Message{code: 2508, category: CategoryError, key: "No_base_constructor_has_the_specified_number_of_type_arguments_2508", text: "No base constructor has the specified number of type arguments."} + +var Base_constructor_return_type_0_is_not_an_object_type_or_intersection_of_object_types_with_statically_known_members = &Message{code: 2509, category: CategoryError, key: "Base_constructor_return_type_0_is_not_an_object_type_or_intersection_of_object_types_with_statically_2509", text: "Base constructor return type '{0}' is not an object type or intersection of object types with statically known members."} + +var Base_constructors_must_all_have_the_same_return_type = &Message{code: 2510, category: CategoryError, key: "Base_constructors_must_all_have_the_same_return_type_2510", text: "Base constructors must all have the same return type."} + +var Cannot_create_an_instance_of_an_abstract_class = &Message{code: 2511, category: CategoryError, key: "Cannot_create_an_instance_of_an_abstract_class_2511", text: "Cannot create an instance of an abstract class."} + +var Overload_signatures_must_all_be_abstract_or_non_abstract = &Message{code: 2512, category: CategoryError, key: "Overload_signatures_must_all_be_abstract_or_non_abstract_2512", text: "Overload signatures must all be abstract or non-abstract."} + +var Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression = &Message{code: 2513, category: CategoryError, key: "Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression_2513", text: "Abstract method '{0}' in class '{1}' cannot be accessed via super expression."} + +var A_tuple_type_cannot_be_indexed_with_a_negative_value = &Message{code: 2514, category: CategoryError, key: "A_tuple_type_cannot_be_indexed_with_a_negative_value_2514", text: "A tuple type cannot be indexed with a negative value."} + +var Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2 = &Message{code: 2515, category: CategoryError, key: "Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2_2515", text: "Non-abstract class '{0}' does not implement inherited abstract member {1} from class '{2}'."} + +var All_declarations_of_an_abstract_method_must_be_consecutive = &Message{code: 2516, category: CategoryError, key: "All_declarations_of_an_abstract_method_must_be_consecutive_2516", text: "All declarations of an abstract method must be consecutive."} + +var Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type = &Message{code: 2517, category: CategoryError, key: "Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type_2517", text: "Cannot assign an abstract constructor type to a non-abstract constructor type."} + +var A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard = &Message{code: 2518, category: CategoryError, key: "A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard_2518", text: "A 'this'-based type guard is not compatible with a parameter-based type guard."} + +var An_async_iterator_must_have_a_next_method = &Message{code: 2519, category: CategoryError, key: "An_async_iterator_must_have_a_next_method_2519", text: "An async iterator must have a 'next()' method."} + +var Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions = &Message{code: 2520, category: CategoryError, key: "Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions_2520", text: "Duplicate identifier '{0}'. Compiler uses declaration '{1}' to support async functions."} + +var The_arguments_object_cannot_be_referenced_in_an_async_function_or_method_in_ES5_Consider_using_a_standard_function_or_method = &Message{code: 2522, category: CategoryError, key: "The_arguments_object_cannot_be_referenced_in_an_async_function_or_method_in_ES5_Consider_using_a_sta_2522", text: "The 'arguments' object cannot be referenced in an async function or method in ES5. Consider using a standard function or method."} + +var X_yield_expressions_cannot_be_used_in_a_parameter_initializer = &Message{code: 2523, category: CategoryError, key: "yield_expressions_cannot_be_used_in_a_parameter_initializer_2523", text: "'yield' expressions cannot be used in a parameter initializer."} + +var X_await_expressions_cannot_be_used_in_a_parameter_initializer = &Message{code: 2524, category: CategoryError, key: "await_expressions_cannot_be_used_in_a_parameter_initializer_2524", text: "'await' expressions cannot be used in a parameter initializer."} + +var A_this_type_is_available_only_in_a_non_static_member_of_a_class_or_interface = &Message{code: 2526, category: CategoryError, key: "A_this_type_is_available_only_in_a_non_static_member_of_a_class_or_interface_2526", text: "A 'this' type is available only in a non-static member of a class or interface."} + +var The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary = &Message{code: 2527, category: CategoryError, key: "The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary_2527", text: "The inferred type of '{0}' references an inaccessible '{1}' type. A type annotation is necessary."} + +var A_module_cannot_have_multiple_default_exports = &Message{code: 2528, category: CategoryError, key: "A_module_cannot_have_multiple_default_exports_2528", text: "A module cannot have multiple default exports."} + +var Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_containing_async_functions = &Message{code: 2529, category: CategoryError, key: "Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_containing_async_func_2529", text: "Duplicate identifier '{0}'. Compiler reserves name '{1}' in top level scope of a module containing async functions."} + +var Property_0_is_incompatible_with_index_signature = &Message{code: 2530, category: CategoryError, key: "Property_0_is_incompatible_with_index_signature_2530", text: "Property '{0}' is incompatible with index signature."} + +var Object_is_possibly_null = &Message{code: 2531, category: CategoryError, key: "Object_is_possibly_null_2531", text: "Object is possibly 'null'."} + +var Object_is_possibly_undefined = &Message{code: 2532, category: CategoryError, key: "Object_is_possibly_undefined_2532", text: "Object is possibly 'undefined'."} + +var Object_is_possibly_null_or_undefined = &Message{code: 2533, category: CategoryError, key: "Object_is_possibly_null_or_undefined_2533", text: "Object is possibly 'null' or 'undefined'."} + +var A_function_returning_never_cannot_have_a_reachable_end_point = &Message{code: 2534, category: CategoryError, key: "A_function_returning_never_cannot_have_a_reachable_end_point_2534", text: "A function returning 'never' cannot have a reachable end point."} + +var Type_0_cannot_be_used_to_index_type_1 = &Message{code: 2536, category: CategoryError, key: "Type_0_cannot_be_used_to_index_type_1_2536", text: "Type '{0}' cannot be used to index type '{1}'."} + +var Type_0_has_no_matching_index_signature_for_type_1 = &Message{code: 2537, category: CategoryError, key: "Type_0_has_no_matching_index_signature_for_type_1_2537", text: "Type '{0}' has no matching index signature for type '{1}'."} + +var Type_0_cannot_be_used_as_an_index_type = &Message{code: 2538, category: CategoryError, key: "Type_0_cannot_be_used_as_an_index_type_2538", text: "Type '{0}' cannot be used as an index type."} + +var Cannot_assign_to_0_because_it_is_not_a_variable = &Message{code: 2539, category: CategoryError, key: "Cannot_assign_to_0_because_it_is_not_a_variable_2539", text: "Cannot assign to '{0}' because it is not a variable."} + +var Cannot_assign_to_0_because_it_is_a_read_only_property = &Message{code: 2540, category: CategoryError, key: "Cannot_assign_to_0_because_it_is_a_read_only_property_2540", text: "Cannot assign to '{0}' because it is a read-only property."} + +var Index_signature_in_type_0_only_permits_reading = &Message{code: 2542, category: CategoryError, key: "Index_signature_in_type_0_only_permits_reading_2542", text: "Index signature in type '{0}' only permits reading."} + +var Duplicate_identifier_newTarget_Compiler_uses_variable_declaration_newTarget_to_capture_new_target_meta_property_reference = &Message{code: 2543, category: CategoryError, key: "Duplicate_identifier_newTarget_Compiler_uses_variable_declaration_newTarget_to_capture_new_target_me_2543", text: "Duplicate identifier '_newTarget'. Compiler uses variable declaration '_newTarget' to capture 'new.target' meta-property reference."} + +var Expression_resolves_to_variable_declaration_newTarget_that_compiler_uses_to_capture_new_target_meta_property_reference = &Message{code: 2544, category: CategoryError, key: "Expression_resolves_to_variable_declaration_newTarget_that_compiler_uses_to_capture_new_target_meta__2544", text: "Expression resolves to variable declaration '_newTarget' that compiler uses to capture 'new.target' meta-property reference."} + +var A_mixin_class_must_have_a_constructor_with_a_single_rest_parameter_of_type_any = &Message{code: 2545, category: CategoryError, key: "A_mixin_class_must_have_a_constructor_with_a_single_rest_parameter_of_type_any_2545", text: "A mixin class must have a constructor with a single rest parameter of type 'any[]'."} + +var The_type_returned_by_the_0_method_of_an_async_iterator_must_be_a_promise_for_a_type_with_a_value_property = &Message{code: 2547, category: CategoryError, key: "The_type_returned_by_the_0_method_of_an_async_iterator_must_be_a_promise_for_a_type_with_a_value_pro_2547", text: "The type returned by the '{0}()' method of an async iterator must be a promise for a type with a 'value' property."} + +var Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator = &Message{code: 2548, category: CategoryError, key: "Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator_2548", text: "Type '{0}' is not an array type or does not have a '[Symbol.iterator]()' method that returns an iterator."} + +var Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator = &Message{code: 2549, category: CategoryError, key: "Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns__2549", text: "Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]()' method that returns an iterator."} + +var Property_0_does_not_exist_on_type_1_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_2_or_later = &Message{code: 2550, category: CategoryError, key: "Property_0_does_not_exist_on_type_1_Do_you_need_to_change_your_target_library_Try_changing_the_lib_c_2550", text: "Property '{0}' does not exist on type '{1}'. Do you need to change your target library? Try changing the 'lib' compiler option to '{2}' or later."} + +var Property_0_does_not_exist_on_type_1_Did_you_mean_2 = &Message{code: 2551, category: CategoryError, key: "Property_0_does_not_exist_on_type_1_Did_you_mean_2_2551", text: "Property '{0}' does not exist on type '{1}'. Did you mean '{2}'?"} + +var Cannot_find_name_0_Did_you_mean_1 = &Message{code: 2552, category: CategoryError, key: "Cannot_find_name_0_Did_you_mean_1_2552", text: "Cannot find name '{0}'. Did you mean '{1}'?"} + +var Computed_values_are_not_permitted_in_an_enum_with_string_valued_members = &Message{code: 2553, category: CategoryError, key: "Computed_values_are_not_permitted_in_an_enum_with_string_valued_members_2553", text: "Computed values are not permitted in an enum with string valued members."} + +var Expected_0_arguments_but_got_1 = &Message{code: 2554, category: CategoryError, key: "Expected_0_arguments_but_got_1_2554", text: "Expected {0} arguments, but got {1}."} + +var Expected_at_least_0_arguments_but_got_1 = &Message{code: 2555, category: CategoryError, key: "Expected_at_least_0_arguments_but_got_1_2555", text: "Expected at least {0} arguments, but got {1}."} + +var A_spread_argument_must_either_have_a_tuple_type_or_be_passed_to_a_rest_parameter = &Message{code: 2556, category: CategoryError, key: "A_spread_argument_must_either_have_a_tuple_type_or_be_passed_to_a_rest_parameter_2556", text: "A spread argument must either have a tuple type or be passed to a rest parameter."} + +var Expected_0_type_arguments_but_got_1 = &Message{code: 2558, category: CategoryError, key: "Expected_0_type_arguments_but_got_1_2558", text: "Expected {0} type arguments, but got {1}."} + +var Type_0_has_no_properties_in_common_with_type_1 = &Message{code: 2559, category: CategoryError, key: "Type_0_has_no_properties_in_common_with_type_1_2559", text: "Type '{0}' has no properties in common with type '{1}'."} + +var Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it = &Message{code: 2560, category: CategoryError, key: "Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it_2560", text: "Value of type '{0}' has no properties in common with type '{1}'. Did you mean to call it?"} + +var Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_write_2 = &Message{code: 2561, category: CategoryError, key: "Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_writ_2561", text: "Object literal may only specify known properties, but '{0}' does not exist in type '{1}'. Did you mean to write '{2}'?"} + +var Base_class_expressions_cannot_reference_class_type_parameters = &Message{code: 2562, category: CategoryError, key: "Base_class_expressions_cannot_reference_class_type_parameters_2562", text: "Base class expressions cannot reference class type parameters."} + +var The_containing_function_or_module_body_is_too_large_for_control_flow_analysis = &Message{code: 2563, category: CategoryError, key: "The_containing_function_or_module_body_is_too_large_for_control_flow_analysis_2563", text: "The containing function or module body is too large for control flow analysis."} + +var Property_0_has_no_initializer_and_is_not_definitely_assigned_in_the_constructor = &Message{code: 2564, category: CategoryError, key: "Property_0_has_no_initializer_and_is_not_definitely_assigned_in_the_constructor_2564", text: "Property '{0}' has no initializer and is not definitely assigned in the constructor."} + +var Property_0_is_used_before_being_assigned = &Message{code: 2565, category: CategoryError, key: "Property_0_is_used_before_being_assigned_2565", text: "Property '{0}' is used before being assigned."} + +var A_rest_element_cannot_have_a_property_name = &Message{code: 2566, category: CategoryError, key: "A_rest_element_cannot_have_a_property_name_2566", text: "A rest element cannot have a property name."} + +var Enum_declarations_can_only_merge_with_namespace_or_other_enum_declarations = &Message{code: 2567, category: CategoryError, key: "Enum_declarations_can_only_merge_with_namespace_or_other_enum_declarations_2567", text: "Enum declarations can only merge with namespace or other enum declarations."} + +var Property_0_may_not_exist_on_type_1_Did_you_mean_2 = &Message{code: 2568, category: CategoryError, key: "Property_0_may_not_exist_on_type_1_Did_you_mean_2_2568", text: "Property '{0}' may not exist on type '{1}'. Did you mean '{2}'?"} + +var Could_not_find_name_0_Did_you_mean_1 = &Message{code: 2570, category: CategoryError, key: "Could_not_find_name_0_Did_you_mean_1_2570", text: "Could not find name '{0}'. Did you mean '{1}'?"} + +var Object_is_of_type_unknown = &Message{code: 2571, category: CategoryError, key: "Object_is_of_type_unknown_2571", text: "Object is of type 'unknown'."} + +var A_rest_element_type_must_be_an_array_type = &Message{code: 2574, category: CategoryError, key: "A_rest_element_type_must_be_an_array_type_2574", text: "A rest element type must be an array type."} + +var No_overload_expects_0_arguments_but_overloads_do_exist_that_expect_either_1_or_2_arguments = &Message{code: 2575, category: CategoryError, key: "No_overload_expects_0_arguments_but_overloads_do_exist_that_expect_either_1_or_2_arguments_2575", text: "No overload expects {0} arguments, but overloads do exist that expect either {1} or {2} arguments."} + +var Property_0_does_not_exist_on_type_1_Did_you_mean_to_access_the_static_member_2_instead = &Message{code: 2576, category: CategoryError, key: "Property_0_does_not_exist_on_type_1_Did_you_mean_to_access_the_static_member_2_instead_2576", text: "Property '{0}' does not exist on type '{1}'. Did you mean to access the static member '{2}' instead?"} + +var Return_type_annotation_circularly_references_itself = &Message{code: 2577, category: CategoryError, key: "Return_type_annotation_circularly_references_itself_2577", text: "Return type annotation circularly references itself."} + +var Unused_ts_expect_error_directive = &Message{code: 2578, category: CategoryError, key: "Unused_ts_expect_error_directive_2578", text: "Unused '@ts-expect-error' directive."} + +var Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_save_dev_types_Slashnode = &Message{code: 2580, category: CategoryError, key: "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_save_dev_types_Slashno_2580", text: "Cannot find name '{0}'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`."} + +var Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_save_dev_types_Slashjquery = &Message{code: 2581, category: CategoryError, key: "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_save_dev_types_Slash_2581", text: "Cannot find name '{0}'. Do you need to install type definitions for jQuery? Try `npm i --save-dev @types/jquery`."} + +var Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_save_dev_types_Slashjest_or_npm_i_save_dev_types_Slashmocha = &Message{code: 2582, category: CategoryError, key: "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_save_dev_type_2582", text: "Cannot find name '{0}'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`."} + +var Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_1_or_later = &Message{code: 2583, category: CategoryError, key: "Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_2583", text: "Cannot find name '{0}'. Do you need to change your target library? Try changing the 'lib' compiler option to '{1}' or later."} + +var Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_include_dom = &Message{code: 2584, category: CategoryError, key: "Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_2584", text: "Cannot find name '{0}'. Do you need to change your target library? Try changing the 'lib' compiler option to include 'dom'."} + +var X_0_only_refers_to_a_type_but_is_being_used_as_a_value_here_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_es2015_or_later = &Message{code: 2585, category: CategoryError, key: "_0_only_refers_to_a_type_but_is_being_used_as_a_value_here_Do_you_need_to_change_your_target_library_2585", text: "'{0}' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the 'lib' compiler option to es2015 or later."} + +var Cannot_assign_to_0_because_it_is_a_constant = &Message{code: 2588, category: CategoryError, key: "Cannot_assign_to_0_because_it_is_a_constant_2588", text: "Cannot assign to '{0}' because it is a constant."} + +var Type_instantiation_is_excessively_deep_and_possibly_infinite = &Message{code: 2589, category: CategoryError, key: "Type_instantiation_is_excessively_deep_and_possibly_infinite_2589", text: "Type instantiation is excessively deep and possibly infinite."} + +var Expression_produces_a_union_type_that_is_too_complex_to_represent = &Message{code: 2590, category: CategoryError, key: "Expression_produces_a_union_type_that_is_too_complex_to_represent_2590", text: "Expression produces a union type that is too complex to represent."} + +var Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_save_dev_types_Slashnode_and_then_add_node_to_the_types_field_in_your_tsconfig = &Message{code: 2591, category: CategoryError, key: "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_save_dev_types_Slashno_2591", text: "Cannot find name '{0}'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node` and then add 'node' to the types field in your tsconfig."} + +var Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_save_dev_types_Slashjquery_and_then_add_jquery_to_the_types_field_in_your_tsconfig = &Message{code: 2592, category: CategoryError, key: "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_save_dev_types_Slash_2592", text: "Cannot find name '{0}'. Do you need to install type definitions for jQuery? Try `npm i --save-dev @types/jquery` and then add 'jquery' to the types field in your tsconfig."} + +var Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_save_dev_types_Slashjest_or_npm_i_save_dev_types_Slashmocha_and_then_add_jest_or_mocha_to_the_types_field_in_your_tsconfig = &Message{code: 2593, category: CategoryError, key: "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_save_dev_type_2593", text: "Cannot find name '{0}'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha` and then add 'jest' or 'mocha' to the types field in your tsconfig."} + +var This_module_is_declared_with_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag = &Message{code: 2594, category: CategoryError, key: "This_module_is_declared_with_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag_2594", text: "This module is declared with 'export =', and can only be used with a default import when using the '{0}' flag."} + +var X_0_can_only_be_imported_by_using_a_default_import = &Message{code: 2595, category: CategoryError, key: "_0_can_only_be_imported_by_using_a_default_import_2595", text: "'{0}' can only be imported by using a default import."} + +var X_0_can_only_be_imported_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import = &Message{code: 2596, category: CategoryError, key: "_0_can_only_be_imported_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import_2596", text: "'{0}' can only be imported by turning on the 'esModuleInterop' flag and using a default import."} + +var X_0_can_only_be_imported_by_using_a_require_call_or_by_using_a_default_import = &Message{code: 2597, category: CategoryError, key: "_0_can_only_be_imported_by_using_a_require_call_or_by_using_a_default_import_2597", text: "'{0}' can only be imported by using a 'require' call or by using a default import."} + +var X_0_can_only_be_imported_by_using_a_require_call_or_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import = &Message{code: 2598, category: CategoryError, key: "_0_can_only_be_imported_by_using_a_require_call_or_by_turning_on_the_esModuleInterop_flag_and_using__2598", text: "'{0}' can only be imported by using a 'require' call or by turning on the 'esModuleInterop' flag and using a default import."} + +var JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist = &Message{code: 2602, category: CategoryError, key: "JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist_2602", text: "JSX element implicitly has type 'any' because the global type 'JSX.Element' does not exist."} + +var Property_0_in_type_1_is_not_assignable_to_type_2 = &Message{code: 2603, category: CategoryError, key: "Property_0_in_type_1_is_not_assignable_to_type_2_2603", text: "Property '{0}' in type '{1}' is not assignable to type '{2}'."} + +var JSX_element_type_0_does_not_have_any_construct_or_call_signatures = &Message{code: 2604, category: CategoryError, key: "JSX_element_type_0_does_not_have_any_construct_or_call_signatures_2604", text: "JSX element type '{0}' does not have any construct or call signatures."} + +var Property_0_of_JSX_spread_attribute_is_not_assignable_to_target_property = &Message{code: 2606, category: CategoryError, key: "Property_0_of_JSX_spread_attribute_is_not_assignable_to_target_property_2606", text: "Property '{0}' of JSX spread attribute is not assignable to target property."} + +var JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property = &Message{code: 2607, category: CategoryError, key: "JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property_2607", text: "JSX element class does not support attributes because it does not have a '{0}' property."} + +var The_global_type_JSX_0_may_not_have_more_than_one_property = &Message{code: 2608, category: CategoryError, key: "The_global_type_JSX_0_may_not_have_more_than_one_property_2608", text: "The global type 'JSX.{0}' may not have more than one property."} + +var JSX_spread_child_must_be_an_array_type = &Message{code: 2609, category: CategoryError, key: "JSX_spread_child_must_be_an_array_type_2609", text: "JSX spread child must be an array type."} + +var X_0_is_defined_as_an_accessor_in_class_1_but_is_overridden_here_in_2_as_an_instance_property = &Message{code: 2610, category: CategoryError, key: "_0_is_defined_as_an_accessor_in_class_1_but_is_overridden_here_in_2_as_an_instance_property_2610", text: "'{0}' is defined as an accessor in class '{1}', but is overridden here in '{2}' as an instance property."} + +var X_0_is_defined_as_a_property_in_class_1_but_is_overridden_here_in_2_as_an_accessor = &Message{code: 2611, category: CategoryError, key: "_0_is_defined_as_a_property_in_class_1_but_is_overridden_here_in_2_as_an_accessor_2611", text: "'{0}' is defined as a property in class '{1}', but is overridden here in '{2}' as an accessor."} + +var Property_0_will_overwrite_the_base_property_in_1_If_this_is_intentional_add_an_initializer_Otherwise_add_a_declare_modifier_or_remove_the_redundant_declaration = &Message{code: 2612, category: CategoryError, key: "Property_0_will_overwrite_the_base_property_in_1_If_this_is_intentional_add_an_initializer_Otherwise_2612", text: "Property '{0}' will overwrite the base property in '{1}'. If this is intentional, add an initializer. Otherwise, add a 'declare' modifier or remove the redundant declaration."} + +var Module_0_has_no_default_export_Did_you_mean_to_use_import_1_from_0_instead = &Message{code: 2613, category: CategoryError, key: "Module_0_has_no_default_export_Did_you_mean_to_use_import_1_from_0_instead_2613", text: "Module '{0}' has no default export. Did you mean to use 'import { {1} } from {0}' instead?"} + +var Module_0_has_no_exported_member_1_Did_you_mean_to_use_import_1_from_0_instead = &Message{code: 2614, category: CategoryError, key: "Module_0_has_no_exported_member_1_Did_you_mean_to_use_import_1_from_0_instead_2614", text: "Module '{0}' has no exported member '{1}'. Did you mean to use 'import {1} from {0}' instead?"} + +var Type_of_property_0_circularly_references_itself_in_mapped_type_1 = &Message{code: 2615, category: CategoryError, key: "Type_of_property_0_circularly_references_itself_in_mapped_type_1_2615", text: "Type of property '{0}' circularly references itself in mapped type '{1}'."} + +var X_0_can_only_be_imported_by_using_import_1_require_2_or_a_default_import = &Message{code: 2616, category: CategoryError, key: "_0_can_only_be_imported_by_using_import_1_require_2_or_a_default_import_2616", text: "'{0}' can only be imported by using 'import {1} = require({2})' or a default import."} + +var X_0_can_only_be_imported_by_using_import_1_require_2_or_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import = &Message{code: 2617, category: CategoryError, key: "_0_can_only_be_imported_by_using_import_1_require_2_or_by_turning_on_the_esModuleInterop_flag_and_us_2617", text: "'{0}' can only be imported by using 'import {1} = require({2})' or by turning on the 'esModuleInterop' flag and using a default import."} + +var Source_has_0_element_s_but_target_requires_1 = &Message{code: 2618, category: CategoryError, key: "Source_has_0_element_s_but_target_requires_1_2618", text: "Source has {0} element(s) but target requires {1}."} + +var Source_has_0_element_s_but_target_allows_only_1 = &Message{code: 2619, category: CategoryError, key: "Source_has_0_element_s_but_target_allows_only_1_2619", text: "Source has {0} element(s) but target allows only {1}."} + +var Target_requires_0_element_s_but_source_may_have_fewer = &Message{code: 2620, category: CategoryError, key: "Target_requires_0_element_s_but_source_may_have_fewer_2620", text: "Target requires {0} element(s) but source may have fewer."} + +var Target_allows_only_0_element_s_but_source_may_have_more = &Message{code: 2621, category: CategoryError, key: "Target_allows_only_0_element_s_but_source_may_have_more_2621", text: "Target allows only {0} element(s) but source may have more."} + +var Source_provides_no_match_for_required_element_at_position_0_in_target = &Message{code: 2623, category: CategoryError, key: "Source_provides_no_match_for_required_element_at_position_0_in_target_2623", text: "Source provides no match for required element at position {0} in target."} + +var Source_provides_no_match_for_variadic_element_at_position_0_in_target = &Message{code: 2624, category: CategoryError, key: "Source_provides_no_match_for_variadic_element_at_position_0_in_target_2624", text: "Source provides no match for variadic element at position {0} in target."} + +var Variadic_element_at_position_0_in_source_does_not_match_element_at_position_1_in_target = &Message{code: 2625, category: CategoryError, key: "Variadic_element_at_position_0_in_source_does_not_match_element_at_position_1_in_target_2625", text: "Variadic element at position {0} in source does not match element at position {1} in target."} + +var Type_at_position_0_in_source_is_not_compatible_with_type_at_position_1_in_target = &Message{code: 2626, category: CategoryError, key: "Type_at_position_0_in_source_is_not_compatible_with_type_at_position_1_in_target_2626", text: "Type at position {0} in source is not compatible with type at position {1} in target."} + +var Type_at_positions_0_through_1_in_source_is_not_compatible_with_type_at_position_2_in_target = &Message{code: 2627, category: CategoryError, key: "Type_at_positions_0_through_1_in_source_is_not_compatible_with_type_at_position_2_in_target_2627", text: "Type at positions {0} through {1} in source is not compatible with type at position {2} in target."} + +var Cannot_assign_to_0_because_it_is_an_enum = &Message{code: 2628, category: CategoryError, key: "Cannot_assign_to_0_because_it_is_an_enum_2628", text: "Cannot assign to '{0}' because it is an enum."} + +var Cannot_assign_to_0_because_it_is_a_class = &Message{code: 2629, category: CategoryError, key: "Cannot_assign_to_0_because_it_is_a_class_2629", text: "Cannot assign to '{0}' because it is a class."} + +var Cannot_assign_to_0_because_it_is_a_function = &Message{code: 2630, category: CategoryError, key: "Cannot_assign_to_0_because_it_is_a_function_2630", text: "Cannot assign to '{0}' because it is a function."} + +var Cannot_assign_to_0_because_it_is_a_namespace = &Message{code: 2631, category: CategoryError, key: "Cannot_assign_to_0_because_it_is_a_namespace_2631", text: "Cannot assign to '{0}' because it is a namespace."} + +var Cannot_assign_to_0_because_it_is_an_import = &Message{code: 2632, category: CategoryError, key: "Cannot_assign_to_0_because_it_is_an_import_2632", text: "Cannot assign to '{0}' because it is an import."} + +var JSX_property_access_expressions_cannot_include_JSX_namespace_names = &Message{code: 2633, category: CategoryError, key: "JSX_property_access_expressions_cannot_include_JSX_namespace_names_2633", text: "JSX property access expressions cannot include JSX namespace names"} + +var X_0_index_signatures_are_incompatible = &Message{code: 2634, category: CategoryError, key: "_0_index_signatures_are_incompatible_2634", text: "'{0}' index signatures are incompatible."} + +var Type_0_has_no_signatures_for_which_the_type_argument_list_is_applicable = &Message{code: 2635, category: CategoryError, key: "Type_0_has_no_signatures_for_which_the_type_argument_list_is_applicable_2635", text: "Type '{0}' has no signatures for which the type argument list is applicable."} + +var Type_0_is_not_assignable_to_type_1_as_implied_by_variance_annotation = &Message{code: 2636, category: CategoryError, key: "Type_0_is_not_assignable_to_type_1_as_implied_by_variance_annotation_2636", text: "Type '{0}' is not assignable to type '{1}' as implied by variance annotation."} + +var Variance_annotations_are_only_supported_in_type_aliases_for_object_function_constructor_and_mapped_types = &Message{code: 2637, category: CategoryError, key: "Variance_annotations_are_only_supported_in_type_aliases_for_object_function_constructor_and_mapped_t_2637", text: "Variance annotations are only supported in type aliases for object, function, constructor, and mapped types."} + +var Type_0_may_represent_a_primitive_value_which_is_not_permitted_as_the_right_operand_of_the_in_operator = &Message{code: 2638, category: CategoryError, key: "Type_0_may_represent_a_primitive_value_which_is_not_permitted_as_the_right_operand_of_the_in_operato_2638", text: "Type '{0}' may represent a primitive value, which is not permitted as the right operand of the 'in' operator."} + +var React_components_cannot_include_JSX_namespace_names = &Message{code: 2639, category: CategoryError, key: "React_components_cannot_include_JSX_namespace_names_2639", text: "React components cannot include JSX namespace names"} + +var Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity = &Message{code: 2649, category: CategoryError, key: "Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity_2649", text: "Cannot augment module '{0}' with value exports because it resolves to a non-module entity."} + +var Non_abstract_class_expression_is_missing_implementations_for_the_following_members_of_0_Colon_1_and_2_more = &Message{code: 2650, category: CategoryError, key: "Non_abstract_class_expression_is_missing_implementations_for_the_following_members_of_0_Colon_1_and__2650", text: "Non-abstract class expression is missing implementations for the following members of '{0}': {1} and {2} more."} + +var A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums = &Message{code: 2651, category: CategoryError, key: "A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_memb_2651", text: "A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums."} + +var Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration_instead = &Message{code: 2652, category: CategoryError, key: "Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_d_2652", text: "Merged declaration '{0}' cannot include a default export declaration. Consider adding a separate 'export default {0}' declaration instead."} + +var Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1 = &Message{code: 2653, category: CategoryError, key: "Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1_2653", text: "Non-abstract class expression does not implement inherited abstract member '{0}' from class '{1}'."} + +var Non_abstract_class_0_is_missing_implementations_for_the_following_members_of_1_Colon_2 = &Message{code: 2654, category: CategoryError, key: "Non_abstract_class_0_is_missing_implementations_for_the_following_members_of_1_Colon_2_2654", text: "Non-abstract class '{0}' is missing implementations for the following members of '{1}': {2}."} + +var Non_abstract_class_0_is_missing_implementations_for_the_following_members_of_1_Colon_2_and_3_more = &Message{code: 2655, category: CategoryError, key: "Non_abstract_class_0_is_missing_implementations_for_the_following_members_of_1_Colon_2_and_3_more_2655", text: "Non-abstract class '{0}' is missing implementations for the following members of '{1}': {2} and {3} more."} + +var Non_abstract_class_expression_is_missing_implementations_for_the_following_members_of_0_Colon_1 = &Message{code: 2656, category: CategoryError, key: "Non_abstract_class_expression_is_missing_implementations_for_the_following_members_of_0_Colon_1_2656", text: "Non-abstract class expression is missing implementations for the following members of '{0}': {1}."} + +var JSX_expressions_must_have_one_parent_element = &Message{code: 2657, category: CategoryError, key: "JSX_expressions_must_have_one_parent_element_2657", text: "JSX expressions must have one parent element."} + +var Type_0_provides_no_match_for_the_signature_1 = &Message{code: 2658, category: CategoryError, key: "Type_0_provides_no_match_for_the_signature_1_2658", text: "Type '{0}' provides no match for the signature '{1}'."} + +var X_super_is_only_allowed_in_members_of_object_literal_expressions_when_option_target_is_ES2015_or_higher = &Message{code: 2659, category: CategoryError, key: "super_is_only_allowed_in_members_of_object_literal_expressions_when_option_target_is_ES2015_or_highe_2659", text: "'super' is only allowed in members of object literal expressions when option 'target' is 'ES2015' or higher."} + +var X_super_can_only_be_referenced_in_members_of_derived_classes_or_object_literal_expressions = &Message{code: 2660, category: CategoryError, key: "super_can_only_be_referenced_in_members_of_derived_classes_or_object_literal_expressions_2660", text: "'super' can only be referenced in members of derived classes or object literal expressions."} + +var Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module = &Message{code: 2661, category: CategoryError, key: "Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module_2661", text: "Cannot export '{0}'. Only local declarations can be exported from a module."} + +var Cannot_find_name_0_Did_you_mean_the_static_member_1_0 = &Message{code: 2662, category: CategoryError, key: "Cannot_find_name_0_Did_you_mean_the_static_member_1_0_2662", text: "Cannot find name '{0}'. Did you mean the static member '{1}.{0}'?"} + +var Cannot_find_name_0_Did_you_mean_the_instance_member_this_0 = &Message{code: 2663, category: CategoryError, key: "Cannot_find_name_0_Did_you_mean_the_instance_member_this_0_2663", text: "Cannot find name '{0}'. Did you mean the instance member 'this.{0}'?"} + +var Invalid_module_name_in_augmentation_module_0_cannot_be_found = &Message{code: 2664, category: CategoryError, key: "Invalid_module_name_in_augmentation_module_0_cannot_be_found_2664", text: "Invalid module name in augmentation, module '{0}' cannot be found."} + +var Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augmented = &Message{code: 2665, category: CategoryError, key: "Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augm_2665", text: "Invalid module name in augmentation. Module '{0}' resolves to an untyped module at '{1}', which cannot be augmented."} + +var Exports_and_export_assignments_are_not_permitted_in_module_augmentations = &Message{code: 2666, category: CategoryError, key: "Exports_and_export_assignments_are_not_permitted_in_module_augmentations_2666", text: "Exports and export assignments are not permitted in module augmentations."} + +var Imports_are_not_permitted_in_module_augmentations_Consider_moving_them_to_the_enclosing_external_module = &Message{code: 2667, category: CategoryError, key: "Imports_are_not_permitted_in_module_augmentations_Consider_moving_them_to_the_enclosing_external_mod_2667", text: "Imports are not permitted in module augmentations. Consider moving them to the enclosing external module."} + +var X_export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always_visible = &Message{code: 2668, category: CategoryError, key: "export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always__2668", text: "'export' modifier cannot be applied to ambient modules and module augmentations since they are always visible."} + +var Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_declarations = &Message{code: 2669, category: CategoryError, key: "Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_2669", text: "Augmentations for the global scope can only be directly nested in external modules or ambient module declarations."} + +var Augmentations_for_the_global_scope_should_have_declare_modifier_unless_they_appear_in_already_ambient_context = &Message{code: 2670, category: CategoryError, key: "Augmentations_for_the_global_scope_should_have_declare_modifier_unless_they_appear_in_already_ambien_2670", text: "Augmentations for the global scope should have 'declare' modifier unless they appear in already ambient context."} + +var Cannot_augment_module_0_because_it_resolves_to_a_non_module_entity = &Message{code: 2671, category: CategoryError, key: "Cannot_augment_module_0_because_it_resolves_to_a_non_module_entity_2671", text: "Cannot augment module '{0}' because it resolves to a non-module entity."} + +var Cannot_assign_a_0_constructor_type_to_a_1_constructor_type = &Message{code: 2672, category: CategoryError, key: "Cannot_assign_a_0_constructor_type_to_a_1_constructor_type_2672", text: "Cannot assign a '{0}' constructor type to a '{1}' constructor type."} + +var Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration = &Message{code: 2673, category: CategoryError, key: "Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration_2673", text: "Constructor of class '{0}' is private and only accessible within the class declaration."} + +var Constructor_of_class_0_is_protected_and_only_accessible_within_the_class_declaration = &Message{code: 2674, category: CategoryError, key: "Constructor_of_class_0_is_protected_and_only_accessible_within_the_class_declaration_2674", text: "Constructor of class '{0}' is protected and only accessible within the class declaration."} + +var Cannot_extend_a_class_0_Class_constructor_is_marked_as_private = &Message{code: 2675, category: CategoryError, key: "Cannot_extend_a_class_0_Class_constructor_is_marked_as_private_2675", text: "Cannot extend a class '{0}'. Class constructor is marked as private."} + +var Accessors_must_both_be_abstract_or_non_abstract = &Message{code: 2676, category: CategoryError, key: "Accessors_must_both_be_abstract_or_non_abstract_2676", text: "Accessors must both be abstract or non-abstract."} + +var A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type = &Message{code: 2677, category: CategoryError, key: "A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type_2677", text: "A type predicate's type must be assignable to its parameter's type."} + +var Type_0_is_not_comparable_to_type_1 = &Message{code: 2678, category: CategoryError, key: "Type_0_is_not_comparable_to_type_1_2678", text: "Type '{0}' is not comparable to type '{1}'."} + +var A_function_that_is_called_with_the_new_keyword_cannot_have_a_this_type_that_is_void = &Message{code: 2679, category: CategoryError, key: "A_function_that_is_called_with_the_new_keyword_cannot_have_a_this_type_that_is_void_2679", text: "A function that is called with the 'new' keyword cannot have a 'this' type that is 'void'."} + +var A_0_parameter_must_be_the_first_parameter = &Message{code: 2680, category: CategoryError, key: "A_0_parameter_must_be_the_first_parameter_2680", text: "A '{0}' parameter must be the first parameter."} + +var A_constructor_cannot_have_a_this_parameter = &Message{code: 2681, category: CategoryError, key: "A_constructor_cannot_have_a_this_parameter_2681", text: "A constructor cannot have a 'this' parameter."} + +var X_this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation = &Message{code: 2683, category: CategoryError, key: "this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_2683", text: "'this' implicitly has type 'any' because it does not have a type annotation."} + +var The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1 = &Message{code: 2684, category: CategoryError, key: "The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1_2684", text: "The 'this' context of type '{0}' is not assignable to method's 'this' of type '{1}'."} + +var The_this_types_of_each_signature_are_incompatible = &Message{code: 2685, category: CategoryError, key: "The_this_types_of_each_signature_are_incompatible_2685", text: "The 'this' types of each signature are incompatible."} + +var X_0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead = &Message{code: 2686, category: CategoryError, key: "_0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead_2686", text: "'{0}' refers to a UMD global, but the current file is a module. Consider adding an import instead."} + +var All_declarations_of_0_must_have_identical_modifiers = &Message{code: 2687, category: CategoryError, key: "All_declarations_of_0_must_have_identical_modifiers_2687", text: "All declarations of '{0}' must have identical modifiers."} + +var Cannot_find_type_definition_file_for_0 = &Message{code: 2688, category: CategoryError, key: "Cannot_find_type_definition_file_for_0_2688", text: "Cannot find type definition file for '{0}'."} + +var Cannot_extend_an_interface_0_Did_you_mean_implements = &Message{code: 2689, category: CategoryError, key: "Cannot_extend_an_interface_0_Did_you_mean_implements_2689", text: "Cannot extend an interface '{0}'. Did you mean 'implements'?"} + +var X_0_only_refers_to_a_type_but_is_being_used_as_a_value_here_Did_you_mean_to_use_1_in_0 = &Message{code: 2690, category: CategoryError, key: "_0_only_refers_to_a_type_but_is_being_used_as_a_value_here_Did_you_mean_to_use_1_in_0_2690", text: "'{0}' only refers to a type, but is being used as a value here. Did you mean to use '{1} in {0}'?"} + +var X_0_is_a_primitive_but_1_is_a_wrapper_object_Prefer_using_0_when_possible = &Message{code: 2692, category: CategoryError, key: "_0_is_a_primitive_but_1_is_a_wrapper_object_Prefer_using_0_when_possible_2692", text: "'{0}' is a primitive, but '{1}' is a wrapper object. Prefer using '{0}' when possible."} + +var X_0_only_refers_to_a_type_but_is_being_used_as_a_value_here = &Message{code: 2693, category: CategoryError, key: "_0_only_refers_to_a_type_but_is_being_used_as_a_value_here_2693", text: "'{0}' only refers to a type, but is being used as a value here."} + +var Namespace_0_has_no_exported_member_1 = &Message{code: 2694, category: CategoryError, key: "Namespace_0_has_no_exported_member_1_2694", text: "Namespace '{0}' has no exported member '{1}'."} + +var Left_side_of_comma_operator_is_unused_and_has_no_side_effects = &Message{code: 2695, category: CategoryError, key: "Left_side_of_comma_operator_is_unused_and_has_no_side_effects_2695", text: "Left side of comma operator is unused and has no side effects.", reportsUnnecessary: true} + +var The_Object_type_is_assignable_to_very_few_other_types_Did_you_mean_to_use_the_any_type_instead = &Message{code: 2696, category: CategoryError, key: "The_Object_type_is_assignable_to_very_few_other_types_Did_you_mean_to_use_the_any_type_instead_2696", text: "The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead?"} + +var An_async_function_or_method_must_return_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option = &Message{code: 2697, category: CategoryError, key: "An_async_function_or_method_must_return_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_in_2697", text: "An async function or method must return a 'Promise'. Make sure you have a declaration for 'Promise' or include 'ES2015' in your '--lib' option."} + +var Spread_types_may_only_be_created_from_object_types = &Message{code: 2698, category: CategoryError, key: "Spread_types_may_only_be_created_from_object_types_2698", text: "Spread types may only be created from object types."} + +var Static_property_0_conflicts_with_built_in_property_Function_0_of_constructor_function_1 = &Message{code: 2699, category: CategoryError, key: "Static_property_0_conflicts_with_built_in_property_Function_0_of_constructor_function_1_2699", text: "Static property '{0}' conflicts with built-in property 'Function.{0}' of constructor function '{1}'."} + +var Rest_types_may_only_be_created_from_object_types = &Message{code: 2700, category: CategoryError, key: "Rest_types_may_only_be_created_from_object_types_2700", text: "Rest types may only be created from object types."} + +var The_target_of_an_object_rest_assignment_must_be_a_variable_or_a_property_access = &Message{code: 2701, category: CategoryError, key: "The_target_of_an_object_rest_assignment_must_be_a_variable_or_a_property_access_2701", text: "The target of an object rest assignment must be a variable or a property access."} + +var X_0_only_refers_to_a_type_but_is_being_used_as_a_namespace_here = &Message{code: 2702, category: CategoryError, key: "_0_only_refers_to_a_type_but_is_being_used_as_a_namespace_here_2702", text: "'{0}' only refers to a type, but is being used as a namespace here."} + +var The_operand_of_a_delete_operator_must_be_a_property_reference = &Message{code: 2703, category: CategoryError, key: "The_operand_of_a_delete_operator_must_be_a_property_reference_2703", text: "The operand of a 'delete' operator must be a property reference."} + +var The_operand_of_a_delete_operator_cannot_be_a_read_only_property = &Message{code: 2704, category: CategoryError, key: "The_operand_of_a_delete_operator_cannot_be_a_read_only_property_2704", text: "The operand of a 'delete' operator cannot be a read-only property."} + +var An_async_function_or_method_in_ES5_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option = &Message{code: 2705, category: CategoryError, key: "An_async_function_or_method_in_ES5_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_2705", text: "An async function or method in ES5 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your '--lib' option."} + +var Required_type_parameters_may_not_follow_optional_type_parameters = &Message{code: 2706, category: CategoryError, key: "Required_type_parameters_may_not_follow_optional_type_parameters_2706", text: "Required type parameters may not follow optional type parameters."} + +var Generic_type_0_requires_between_1_and_2_type_arguments = &Message{code: 2707, category: CategoryError, key: "Generic_type_0_requires_between_1_and_2_type_arguments_2707", text: "Generic type '{0}' requires between {1} and {2} type arguments."} + +var Cannot_use_namespace_0_as_a_value = &Message{code: 2708, category: CategoryError, key: "Cannot_use_namespace_0_as_a_value_2708", text: "Cannot use namespace '{0}' as a value."} + +var Cannot_use_namespace_0_as_a_type = &Message{code: 2709, category: CategoryError, key: "Cannot_use_namespace_0_as_a_type_2709", text: "Cannot use namespace '{0}' as a type."} + +var X_0_are_specified_twice_The_attribute_named_0_will_be_overwritten = &Message{code: 2710, category: CategoryError, key: "_0_are_specified_twice_The_attribute_named_0_will_be_overwritten_2710", text: "'{0}' are specified twice. The attribute named '{0}' will be overwritten."} + +var A_dynamic_import_call_returns_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option = &Message{code: 2711, category: CategoryError, key: "A_dynamic_import_call_returns_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES20_2711", text: "A dynamic import call returns a 'Promise'. Make sure you have a declaration for 'Promise' or include 'ES2015' in your '--lib' option."} + +var A_dynamic_import_call_in_ES5_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option = &Message{code: 2712, category: CategoryError, key: "A_dynamic_import_call_in_ES5_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_t_2712", text: "A dynamic import call in ES5 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your '--lib' option."} + +var Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1 = &Message{code: 2713, category: CategoryError, key: "Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_p_2713", text: "Cannot access '{0}.{1}' because '{0}' is a type, but not a namespace. Did you mean to retrieve the type of the property '{1}' in '{0}' with '{0}[\"{1}\"]'?"} + +var The_expression_of_an_export_assignment_must_be_an_identifier_or_qualified_name_in_an_ambient_context = &Message{code: 2714, category: CategoryError, key: "The_expression_of_an_export_assignment_must_be_an_identifier_or_qualified_name_in_an_ambient_context_2714", text: "The expression of an export assignment must be an identifier or qualified name in an ambient context."} + +var Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor = &Message{code: 2715, category: CategoryError, key: "Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor_2715", text: "Abstract property '{0}' in class '{1}' cannot be accessed in the constructor."} + +var Type_parameter_0_has_a_circular_default = &Message{code: 2716, category: CategoryError, key: "Type_parameter_0_has_a_circular_default_2716", text: "Type parameter '{0}' has a circular default."} + +var Subsequent_property_declarations_must_have_the_same_type_Property_0_must_be_of_type_1_but_here_has_type_2 = &Message{code: 2717, category: CategoryError, key: "Subsequent_property_declarations_must_have_the_same_type_Property_0_must_be_of_type_1_but_here_has_t_2717", text: "Subsequent property declarations must have the same type. Property '{0}' must be of type '{1}', but here has type '{2}'."} + +var Duplicate_property_0 = &Message{code: 2718, category: CategoryError, key: "Duplicate_property_0_2718", text: "Duplicate property '{0}'."} + +var Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated = &Message{code: 2719, category: CategoryError, key: "Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated_2719", text: "Type '{0}' is not assignable to type '{1}'. Two different types with this name exist, but they are unrelated."} + +var Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclass = &Message{code: 2720, category: CategoryError, key: "Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclas_2720", text: "Class '{0}' incorrectly implements class '{1}'. Did you mean to extend '{1}' and inherit its members as a subclass?"} + +var Cannot_invoke_an_object_which_is_possibly_null = &Message{code: 2721, category: CategoryError, key: "Cannot_invoke_an_object_which_is_possibly_null_2721", text: "Cannot invoke an object which is possibly 'null'."} + +var Cannot_invoke_an_object_which_is_possibly_undefined = &Message{code: 2722, category: CategoryError, key: "Cannot_invoke_an_object_which_is_possibly_undefined_2722", text: "Cannot invoke an object which is possibly 'undefined'."} + +var Cannot_invoke_an_object_which_is_possibly_null_or_undefined = &Message{code: 2723, category: CategoryError, key: "Cannot_invoke_an_object_which_is_possibly_null_or_undefined_2723", text: "Cannot invoke an object which is possibly 'null' or 'undefined'."} + +var X_0_has_no_exported_member_named_1_Did_you_mean_2 = &Message{code: 2724, category: CategoryError, key: "_0_has_no_exported_member_named_1_Did_you_mean_2_2724", text: "'{0}' has no exported member named '{1}'. Did you mean '{2}'?"} + +var Class_name_cannot_be_Object_when_targeting_ES5_and_above_with_module_0 = &Message{code: 2725, category: CategoryError, key: "Class_name_cannot_be_Object_when_targeting_ES5_and_above_with_module_0_2725", text: "Class name cannot be 'Object' when targeting ES5 and above with module {0}."} + +var Cannot_find_lib_definition_for_0 = &Message{code: 2726, category: CategoryError, key: "Cannot_find_lib_definition_for_0_2726", text: "Cannot find lib definition for '{0}'."} + +var Cannot_find_lib_definition_for_0_Did_you_mean_1 = &Message{code: 2727, category: CategoryError, key: "Cannot_find_lib_definition_for_0_Did_you_mean_1_2727", text: "Cannot find lib definition for '{0}'. Did you mean '{1}'?"} + +var X_0_is_declared_here = &Message{code: 2728, category: CategoryMessage, key: "_0_is_declared_here_2728", text: "'{0}' is declared here."} + +var Property_0_is_used_before_its_initialization = &Message{code: 2729, category: CategoryError, key: "Property_0_is_used_before_its_initialization_2729", text: "Property '{0}' is used before its initialization."} + +var An_arrow_function_cannot_have_a_this_parameter = &Message{code: 2730, category: CategoryError, key: "An_arrow_function_cannot_have_a_this_parameter_2730", text: "An arrow function cannot have a 'this' parameter."} + +var Implicit_conversion_of_a_symbol_to_a_string_will_fail_at_runtime_Consider_wrapping_this_expression_in_String = &Message{code: 2731, category: CategoryError, key: "Implicit_conversion_of_a_symbol_to_a_string_will_fail_at_runtime_Consider_wrapping_this_expression_i_2731", text: "Implicit conversion of a 'symbol' to a 'string' will fail at runtime. Consider wrapping this expression in 'String(...)'."} + +var Cannot_find_module_0_Consider_using_resolveJsonModule_to_import_module_with_json_extension = &Message{code: 2732, category: CategoryError, key: "Cannot_find_module_0_Consider_using_resolveJsonModule_to_import_module_with_json_extension_2732", text: "Cannot find module '{0}'. Consider using '--resolveJsonModule' to import module with '.json' extension."} + +var Property_0_was_also_declared_here = &Message{code: 2733, category: CategoryError, key: "Property_0_was_also_declared_here_2733", text: "Property '{0}' was also declared here."} + +var Are_you_missing_a_semicolon = &Message{code: 2734, category: CategoryError, key: "Are_you_missing_a_semicolon_2734", text: "Are you missing a semicolon?"} + +var Did_you_mean_for_0_to_be_constrained_to_type_new_args_Colon_any_1 = &Message{code: 2735, category: CategoryError, key: "Did_you_mean_for_0_to_be_constrained_to_type_new_args_Colon_any_1_2735", text: "Did you mean for '{0}' to be constrained to type 'new (...args: any[]) => {1}'?"} + +var Operator_0_cannot_be_applied_to_type_1 = &Message{code: 2736, category: CategoryError, key: "Operator_0_cannot_be_applied_to_type_1_2736", text: "Operator '{0}' cannot be applied to type '{1}'."} + +var BigInt_literals_are_not_available_when_targeting_lower_than_ES2020 = &Message{code: 2737, category: CategoryError, key: "BigInt_literals_are_not_available_when_targeting_lower_than_ES2020_2737", text: "BigInt literals are not available when targeting lower than ES2020."} + +var An_outer_value_of_this_is_shadowed_by_this_container = &Message{code: 2738, category: CategoryMessage, key: "An_outer_value_of_this_is_shadowed_by_this_container_2738", text: "An outer value of 'this' is shadowed by this container."} + +var Type_0_is_missing_the_following_properties_from_type_1_Colon_2 = &Message{code: 2739, category: CategoryError, key: "Type_0_is_missing_the_following_properties_from_type_1_Colon_2_2739", text: "Type '{0}' is missing the following properties from type '{1}': {2}"} + +var Type_0_is_missing_the_following_properties_from_type_1_Colon_2_and_3_more = &Message{code: 2740, category: CategoryError, key: "Type_0_is_missing_the_following_properties_from_type_1_Colon_2_and_3_more_2740", text: "Type '{0}' is missing the following properties from type '{1}': {2}, and {3} more."} + +var Property_0_is_missing_in_type_1_but_required_in_type_2 = &Message{code: 2741, category: CategoryError, key: "Property_0_is_missing_in_type_1_but_required_in_type_2_2741", text: "Property '{0}' is missing in type '{1}' but required in type '{2}'."} + +var The_inferred_type_of_0_cannot_be_named_without_a_reference_to_1_This_is_likely_not_portable_A_type_annotation_is_necessary = &Message{code: 2742, category: CategoryError, key: "The_inferred_type_of_0_cannot_be_named_without_a_reference_to_1_This_is_likely_not_portable_A_type_a_2742", text: "The inferred type of '{0}' cannot be named without a reference to '{1}'. This is likely not portable. A type annotation is necessary."} + +var No_overload_expects_0_type_arguments_but_overloads_do_exist_that_expect_either_1_or_2_type_arguments = &Message{code: 2743, category: CategoryError, key: "No_overload_expects_0_type_arguments_but_overloads_do_exist_that_expect_either_1_or_2_type_arguments_2743", text: "No overload expects {0} type arguments, but overloads do exist that expect either {1} or {2} type arguments."} + +var Type_parameter_defaults_can_only_reference_previously_declared_type_parameters = &Message{code: 2744, category: CategoryError, key: "Type_parameter_defaults_can_only_reference_previously_declared_type_parameters_2744", text: "Type parameter defaults can only reference previously declared type parameters."} + +var This_JSX_tag_s_0_prop_expects_type_1_which_requires_multiple_children_but_only_a_single_child_was_provided = &Message{code: 2745, category: CategoryError, key: "This_JSX_tag_s_0_prop_expects_type_1_which_requires_multiple_children_but_only_a_single_child_was_pr_2745", text: "This JSX tag's '{0}' prop expects type '{1}' which requires multiple children, but only a single child was provided."} + +var This_JSX_tag_s_0_prop_expects_a_single_child_of_type_1_but_multiple_children_were_provided = &Message{code: 2746, category: CategoryError, key: "This_JSX_tag_s_0_prop_expects_a_single_child_of_type_1_but_multiple_children_were_provided_2746", text: "This JSX tag's '{0}' prop expects a single child of type '{1}', but multiple children were provided."} + +var X_0_components_don_t_accept_text_as_child_elements_Text_in_JSX_has_the_type_string_but_the_expected_type_of_1_is_2 = &Message{code: 2747, category: CategoryError, key: "_0_components_don_t_accept_text_as_child_elements_Text_in_JSX_has_the_type_string_but_the_expected_t_2747", text: "'{0}' components don't accept text as child elements. Text in JSX has the type 'string', but the expected type of '{1}' is '{2}'."} + +var Cannot_access_ambient_const_enums_when_0_is_enabled = &Message{code: 2748, category: CategoryError, key: "Cannot_access_ambient_const_enums_when_0_is_enabled_2748", text: "Cannot access ambient const enums when '{0}' is enabled."} + +var X_0_refers_to_a_value_but_is_being_used_as_a_type_here_Did_you_mean_typeof_0 = &Message{code: 2749, category: CategoryError, key: "_0_refers_to_a_value_but_is_being_used_as_a_type_here_Did_you_mean_typeof_0_2749", text: "'{0}' refers to a value, but is being used as a type here. Did you mean 'typeof {0}'?"} + +var The_implementation_signature_is_declared_here = &Message{code: 2750, category: CategoryError, key: "The_implementation_signature_is_declared_here_2750", text: "The implementation signature is declared here."} + +var Circularity_originates_in_type_at_this_location = &Message{code: 2751, category: CategoryError, key: "Circularity_originates_in_type_at_this_location_2751", text: "Circularity originates in type at this location."} + +var The_first_export_default_is_here = &Message{code: 2752, category: CategoryError, key: "The_first_export_default_is_here_2752", text: "The first export default is here."} + +var Another_export_default_is_here = &Message{code: 2753, category: CategoryError, key: "Another_export_default_is_here_2753", text: "Another export default is here."} + +var X_super_may_not_use_type_arguments = &Message{code: 2754, category: CategoryError, key: "super_may_not_use_type_arguments_2754", text: "'super' may not use type arguments."} + +var No_constituent_of_type_0_is_callable = &Message{code: 2755, category: CategoryError, key: "No_constituent_of_type_0_is_callable_2755", text: "No constituent of type '{0}' is callable."} + +var Not_all_constituents_of_type_0_are_callable = &Message{code: 2756, category: CategoryError, key: "Not_all_constituents_of_type_0_are_callable_2756", text: "Not all constituents of type '{0}' are callable."} + +var Type_0_has_no_call_signatures = &Message{code: 2757, category: CategoryError, key: "Type_0_has_no_call_signatures_2757", text: "Type '{0}' has no call signatures."} + +var Each_member_of_the_union_type_0_has_signatures_but_none_of_those_signatures_are_compatible_with_each_other = &Message{code: 2758, category: CategoryError, key: "Each_member_of_the_union_type_0_has_signatures_but_none_of_those_signatures_are_compatible_with_each_2758", text: "Each member of the union type '{0}' has signatures, but none of those signatures are compatible with each other."} + +var No_constituent_of_type_0_is_constructable = &Message{code: 2759, category: CategoryError, key: "No_constituent_of_type_0_is_constructable_2759", text: "No constituent of type '{0}' is constructable."} + +var Not_all_constituents_of_type_0_are_constructable = &Message{code: 2760, category: CategoryError, key: "Not_all_constituents_of_type_0_are_constructable_2760", text: "Not all constituents of type '{0}' are constructable."} + +var Type_0_has_no_construct_signatures = &Message{code: 2761, category: CategoryError, key: "Type_0_has_no_construct_signatures_2761", text: "Type '{0}' has no construct signatures."} + +var Each_member_of_the_union_type_0_has_construct_signatures_but_none_of_those_signatures_are_compatible_with_each_other = &Message{code: 2762, category: CategoryError, key: "Each_member_of_the_union_type_0_has_construct_signatures_but_none_of_those_signatures_are_compatible_2762", text: "Each member of the union type '{0}' has construct signatures, but none of those signatures are compatible with each other."} + +var Cannot_iterate_value_because_the_next_method_of_its_iterator_expects_type_1_but_for_of_will_always_send_0 = &Message{code: 2763, category: CategoryError, key: "Cannot_iterate_value_because_the_next_method_of_its_iterator_expects_type_1_but_for_of_will_always_s_2763", text: "Cannot iterate value because the 'next' method of its iterator expects type '{1}', but for-of will always send '{0}'."} + +var Cannot_iterate_value_because_the_next_method_of_its_iterator_expects_type_1_but_array_spread_will_always_send_0 = &Message{code: 2764, category: CategoryError, key: "Cannot_iterate_value_because_the_next_method_of_its_iterator_expects_type_1_but_array_spread_will_al_2764", text: "Cannot iterate value because the 'next' method of its iterator expects type '{1}', but array spread will always send '{0}'."} + +var Cannot_iterate_value_because_the_next_method_of_its_iterator_expects_type_1_but_array_destructuring_will_always_send_0 = &Message{code: 2765, category: CategoryError, key: "Cannot_iterate_value_because_the_next_method_of_its_iterator_expects_type_1_but_array_destructuring__2765", text: "Cannot iterate value because the 'next' method of its iterator expects type '{1}', but array destructuring will always send '{0}'."} + +var Cannot_delegate_iteration_to_value_because_the_next_method_of_its_iterator_expects_type_1_but_the_containing_generator_will_always_send_0 = &Message{code: 2766, category: CategoryError, key: "Cannot_delegate_iteration_to_value_because_the_next_method_of_its_iterator_expects_type_1_but_the_co_2766", text: "Cannot delegate iteration to value because the 'next' method of its iterator expects type '{1}', but the containing generator will always send '{0}'."} + +var The_0_property_of_an_iterator_must_be_a_method = &Message{code: 2767, category: CategoryError, key: "The_0_property_of_an_iterator_must_be_a_method_2767", text: "The '{0}' property of an iterator must be a method."} + +var The_0_property_of_an_async_iterator_must_be_a_method = &Message{code: 2768, category: CategoryError, key: "The_0_property_of_an_async_iterator_must_be_a_method_2768", text: "The '{0}' property of an async iterator must be a method."} + +var No_overload_matches_this_call = &Message{code: 2769, category: CategoryError, key: "No_overload_matches_this_call_2769", text: "No overload matches this call."} + +var The_last_overload_gave_the_following_error = &Message{code: 2770, category: CategoryError, key: "The_last_overload_gave_the_following_error_2770", text: "The last overload gave the following error."} + +var The_last_overload_is_declared_here = &Message{code: 2771, category: CategoryError, key: "The_last_overload_is_declared_here_2771", text: "The last overload is declared here."} + +var Overload_0_of_1_2_gave_the_following_error = &Message{code: 2772, category: CategoryError, key: "Overload_0_of_1_2_gave_the_following_error_2772", text: "Overload {0} of {1}, '{2}', gave the following error."} + +var Did_you_forget_to_use_await = &Message{code: 2773, category: CategoryError, key: "Did_you_forget_to_use_await_2773", text: "Did you forget to use 'await'?"} + +var This_condition_will_always_return_true_since_this_function_is_always_defined_Did_you_mean_to_call_it_instead = &Message{code: 2774, category: CategoryError, key: "This_condition_will_always_return_true_since_this_function_is_always_defined_Did_you_mean_to_call_it_2774", text: "This condition will always return true since this function is always defined. Did you mean to call it instead?"} + +var Assertions_require_every_name_in_the_call_target_to_be_declared_with_an_explicit_type_annotation = &Message{code: 2775, category: CategoryError, key: "Assertions_require_every_name_in_the_call_target_to_be_declared_with_an_explicit_type_annotation_2775", text: "Assertions require every name in the call target to be declared with an explicit type annotation."} + +var Assertions_require_the_call_target_to_be_an_identifier_or_qualified_name = &Message{code: 2776, category: CategoryError, key: "Assertions_require_the_call_target_to_be_an_identifier_or_qualified_name_2776", text: "Assertions require the call target to be an identifier or qualified name."} + +var The_operand_of_an_increment_or_decrement_operator_may_not_be_an_optional_property_access = &Message{code: 2777, category: CategoryError, key: "The_operand_of_an_increment_or_decrement_operator_may_not_be_an_optional_property_access_2777", text: "The operand of an increment or decrement operator may not be an optional property access."} + +var The_target_of_an_object_rest_assignment_may_not_be_an_optional_property_access = &Message{code: 2778, category: CategoryError, key: "The_target_of_an_object_rest_assignment_may_not_be_an_optional_property_access_2778", text: "The target of an object rest assignment may not be an optional property access."} + +var The_left_hand_side_of_an_assignment_expression_may_not_be_an_optional_property_access = &Message{code: 2779, category: CategoryError, key: "The_left_hand_side_of_an_assignment_expression_may_not_be_an_optional_property_access_2779", text: "The left-hand side of an assignment expression may not be an optional property access."} + +var The_left_hand_side_of_a_for_in_statement_may_not_be_an_optional_property_access = &Message{code: 2780, category: CategoryError, key: "The_left_hand_side_of_a_for_in_statement_may_not_be_an_optional_property_access_2780", text: "The left-hand side of a 'for...in' statement may not be an optional property access."} + +var The_left_hand_side_of_a_for_of_statement_may_not_be_an_optional_property_access = &Message{code: 2781, category: CategoryError, key: "The_left_hand_side_of_a_for_of_statement_may_not_be_an_optional_property_access_2781", text: "The left-hand side of a 'for...of' statement may not be an optional property access."} + +var X_0_needs_an_explicit_type_annotation = &Message{code: 2782, category: CategoryMessage, key: "_0_needs_an_explicit_type_annotation_2782", text: "'{0}' needs an explicit type annotation."} + +var X_0_is_specified_more_than_once_so_this_usage_will_be_overwritten = &Message{code: 2783, category: CategoryError, key: "_0_is_specified_more_than_once_so_this_usage_will_be_overwritten_2783", text: "'{0}' is specified more than once, so this usage will be overwritten."} + +var X_get_and_set_accessors_cannot_declare_this_parameters = &Message{code: 2784, category: CategoryError, key: "get_and_set_accessors_cannot_declare_this_parameters_2784", text: "'get' and 'set' accessors cannot declare 'this' parameters."} + +var This_spread_always_overwrites_this_property = &Message{code: 2785, category: CategoryError, key: "This_spread_always_overwrites_this_property_2785", text: "This spread always overwrites this property."} + +var X_0_cannot_be_used_as_a_JSX_component = &Message{code: 2786, category: CategoryError, key: "_0_cannot_be_used_as_a_JSX_component_2786", text: "'{0}' cannot be used as a JSX component."} + +var Its_return_type_0_is_not_a_valid_JSX_element = &Message{code: 2787, category: CategoryError, key: "Its_return_type_0_is_not_a_valid_JSX_element_2787", text: "Its return type '{0}' is not a valid JSX element."} + +var Its_instance_type_0_is_not_a_valid_JSX_element = &Message{code: 2788, category: CategoryError, key: "Its_instance_type_0_is_not_a_valid_JSX_element_2788", text: "Its instance type '{0}' is not a valid JSX element."} + +var Its_element_type_0_is_not_a_valid_JSX_element = &Message{code: 2789, category: CategoryError, key: "Its_element_type_0_is_not_a_valid_JSX_element_2789", text: "Its element type '{0}' is not a valid JSX element."} + +var The_operand_of_a_delete_operator_must_be_optional = &Message{code: 2790, category: CategoryError, key: "The_operand_of_a_delete_operator_must_be_optional_2790", text: "The operand of a 'delete' operator must be optional."} + +var Exponentiation_cannot_be_performed_on_bigint_values_unless_the_target_option_is_set_to_es2016_or_later = &Message{code: 2791, category: CategoryError, key: "Exponentiation_cannot_be_performed_on_bigint_values_unless_the_target_option_is_set_to_es2016_or_lat_2791", text: "Exponentiation cannot be performed on 'bigint' values unless the 'target' option is set to 'es2016' or later."} + +var Cannot_find_module_0_Did_you_mean_to_set_the_moduleResolution_option_to_nodenext_or_to_add_aliases_to_the_paths_option = &Message{code: 2792, category: CategoryError, key: "Cannot_find_module_0_Did_you_mean_to_set_the_moduleResolution_option_to_nodenext_or_to_add_aliases_t_2792", text: "Cannot find module '{0}'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option?"} + +var The_call_would_have_succeeded_against_this_implementation_but_implementation_signatures_of_overloads_are_not_externally_visible = &Message{code: 2793, category: CategoryError, key: "The_call_would_have_succeeded_against_this_implementation_but_implementation_signatures_of_overloads_2793", text: "The call would have succeeded against this implementation, but implementation signatures of overloads are not externally visible."} + +var Expected_0_arguments_but_got_1_Did_you_forget_to_include_void_in_your_type_argument_to_Promise = &Message{code: 2794, category: CategoryError, key: "Expected_0_arguments_but_got_1_Did_you_forget_to_include_void_in_your_type_argument_to_Promise_2794", text: "Expected {0} arguments, but got {1}. Did you forget to include 'void' in your type argument to 'Promise'?"} + +var The_intrinsic_keyword_can_only_be_used_to_declare_compiler_provided_intrinsic_types = &Message{code: 2795, category: CategoryError, key: "The_intrinsic_keyword_can_only_be_used_to_declare_compiler_provided_intrinsic_types_2795", text: "The 'intrinsic' keyword can only be used to declare compiler provided intrinsic types."} + +var It_is_likely_that_you_are_missing_a_comma_to_separate_these_two_template_expressions_They_form_a_tagged_template_expression_which_cannot_be_invoked = &Message{code: 2796, category: CategoryError, key: "It_is_likely_that_you_are_missing_a_comma_to_separate_these_two_template_expressions_They_form_a_tag_2796", text: "It is likely that you are missing a comma to separate these two template expressions. They form a tagged template expression which cannot be invoked."} + +var A_mixin_class_that_extends_from_a_type_variable_containing_an_abstract_construct_signature_must_also_be_declared_abstract = &Message{code: 2797, category: CategoryError, key: "A_mixin_class_that_extends_from_a_type_variable_containing_an_abstract_construct_signature_must_also_2797", text: "A mixin class that extends from a type variable containing an abstract construct signature must also be declared 'abstract'."} + +var The_declaration_was_marked_as_deprecated_here = &Message{code: 2798, category: CategoryError, key: "The_declaration_was_marked_as_deprecated_here_2798", text: "The declaration was marked as deprecated here."} + +var Type_produces_a_tuple_type_that_is_too_large_to_represent = &Message{code: 2799, category: CategoryError, key: "Type_produces_a_tuple_type_that_is_too_large_to_represent_2799", text: "Type produces a tuple type that is too large to represent."} + +var Expression_produces_a_tuple_type_that_is_too_large_to_represent = &Message{code: 2800, category: CategoryError, key: "Expression_produces_a_tuple_type_that_is_too_large_to_represent_2800", text: "Expression produces a tuple type that is too large to represent."} + +var This_condition_will_always_return_true_since_this_0_is_always_defined = &Message{code: 2801, category: CategoryError, key: "This_condition_will_always_return_true_since_this_0_is_always_defined_2801", text: "This condition will always return true since this '{0}' is always defined."} + +var Type_0_can_only_be_iterated_through_when_using_the_downlevelIteration_flag_or_with_a_target_of_es2015_or_higher = &Message{code: 2802, category: CategoryError, key: "Type_0_can_only_be_iterated_through_when_using_the_downlevelIteration_flag_or_with_a_target_of_es201_2802", text: "Type '{0}' can only be iterated through when using the '--downlevelIteration' flag or with a '--target' of 'es2015' or higher."} + +var Cannot_assign_to_private_method_0_Private_methods_are_not_writable = &Message{code: 2803, category: CategoryError, key: "Cannot_assign_to_private_method_0_Private_methods_are_not_writable_2803", text: "Cannot assign to private method '{0}'. Private methods are not writable."} + +var Duplicate_identifier_0_Static_and_instance_elements_cannot_share_the_same_private_name = &Message{code: 2804, category: CategoryError, key: "Duplicate_identifier_0_Static_and_instance_elements_cannot_share_the_same_private_name_2804", text: "Duplicate identifier '{0}'. Static and instance elements cannot share the same private name."} + +var Private_accessor_was_defined_without_a_getter = &Message{code: 2806, category: CategoryError, key: "Private_accessor_was_defined_without_a_getter_2806", text: "Private accessor was defined without a getter."} + +var This_syntax_requires_an_imported_helper_named_1_with_2_parameters_which_is_not_compatible_with_the_one_in_0_Consider_upgrading_your_version_of_0 = &Message{code: 2807, category: CategoryError, key: "This_syntax_requires_an_imported_helper_named_1_with_2_parameters_which_is_not_compatible_with_the_o_2807", text: "This syntax requires an imported helper named '{1}' with {2} parameters, which is not compatible with the one in '{0}'. Consider upgrading your version of '{0}'."} + +var A_get_accessor_must_be_at_least_as_accessible_as_the_setter = &Message{code: 2808, category: CategoryError, key: "A_get_accessor_must_be_at_least_as_accessible_as_the_setter_2808", text: "A get accessor must be at least as accessible as the setter"} + +var Declaration_or_statement_expected_This_follows_a_block_of_statements_so_if_you_intended_to_write_a_destructuring_assignment_you_might_need_to_wrap_the_whole_assignment_in_parentheses = &Message{code: 2809, category: CategoryError, key: "Declaration_or_statement_expected_This_follows_a_block_of_statements_so_if_you_intended_to_write_a_d_2809", text: "Declaration or statement expected. This '=' follows a block of statements, so if you intended to write a destructuring assignment, you might need to wrap the whole assignment in parentheses."} + +var Expected_1_argument_but_got_0_new_Promise_needs_a_JSDoc_hint_to_produce_a_resolve_that_can_be_called_without_arguments = &Message{code: 2810, category: CategoryError, key: "Expected_1_argument_but_got_0_new_Promise_needs_a_JSDoc_hint_to_produce_a_resolve_that_can_be_called_2810", text: "Expected 1 argument, but got 0. 'new Promise()' needs a JSDoc hint to produce a 'resolve' that can be called without arguments."} + +var Initializer_for_property_0 = &Message{code: 2811, category: CategoryError, key: "Initializer_for_property_0_2811", text: "Initializer for property '{0}'"} + +var Property_0_does_not_exist_on_type_1_Try_changing_the_lib_compiler_option_to_include_dom = &Message{code: 2812, category: CategoryError, key: "Property_0_does_not_exist_on_type_1_Try_changing_the_lib_compiler_option_to_include_dom_2812", text: "Property '{0}' does not exist on type '{1}'. Try changing the 'lib' compiler option to include 'dom'."} + +var Class_declaration_cannot_implement_overload_list_for_0 = &Message{code: 2813, category: CategoryError, key: "Class_declaration_cannot_implement_overload_list_for_0_2813", text: "Class declaration cannot implement overload list for '{0}'."} + +var Function_with_bodies_can_only_merge_with_classes_that_are_ambient = &Message{code: 2814, category: CategoryError, key: "Function_with_bodies_can_only_merge_with_classes_that_are_ambient_2814", text: "Function with bodies can only merge with classes that are ambient."} + +var X_arguments_cannot_be_referenced_in_property_initializers_or_class_static_initialization_blocks = &Message{code: 2815, category: CategoryError, key: "arguments_cannot_be_referenced_in_property_initializers_or_class_static_initialization_blocks_2815", text: "'arguments' cannot be referenced in property initializers or class static initialization blocks."} + +var Cannot_use_this_in_a_static_property_initializer_of_a_decorated_class = &Message{code: 2816, category: CategoryError, key: "Cannot_use_this_in_a_static_property_initializer_of_a_decorated_class_2816", text: "Cannot use 'this' in a static property initializer of a decorated class."} + +var Property_0_has_no_initializer_and_is_not_definitely_assigned_in_a_class_static_block = &Message{code: 2817, category: CategoryError, key: "Property_0_has_no_initializer_and_is_not_definitely_assigned_in_a_class_static_block_2817", text: "Property '{0}' has no initializer and is not definitely assigned in a class static block."} + +var Duplicate_identifier_0_Compiler_reserves_name_1_when_emitting_super_references_in_static_initializers = &Message{code: 2818, category: CategoryError, key: "Duplicate_identifier_0_Compiler_reserves_name_1_when_emitting_super_references_in_static_initializer_2818", text: "Duplicate identifier '{0}'. Compiler reserves name '{1}' when emitting 'super' references in static initializers."} + +var Namespace_name_cannot_be_0 = &Message{code: 2819, category: CategoryError, key: "Namespace_name_cannot_be_0_2819", text: "Namespace name cannot be '{0}'."} + +var Type_0_is_not_assignable_to_type_1_Did_you_mean_2 = &Message{code: 2820, category: CategoryError, key: "Type_0_is_not_assignable_to_type_1_Did_you_mean_2_2820", text: "Type '{0}' is not assignable to type '{1}'. Did you mean '{2}'?"} + +var Import_assertions_are_only_supported_when_the_module_option_is_set_to_esnext_node18_node20_nodenext_or_preserve = &Message{code: 2821, category: CategoryError, key: "Import_assertions_are_only_supported_when_the_module_option_is_set_to_esnext_node18_node20_nodenext__2821", text: "Import assertions are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'."} + +var Import_assertions_cannot_be_used_with_type_only_imports_or_exports = &Message{code: 2822, category: CategoryError, key: "Import_assertions_cannot_be_used_with_type_only_imports_or_exports_2822", text: "Import assertions cannot be used with type-only imports or exports."} + +var Import_attributes_are_only_supported_when_the_module_option_is_set_to_esnext_node18_node20_nodenext_or_preserve = &Message{code: 2823, category: CategoryError, key: "Import_attributes_are_only_supported_when_the_module_option_is_set_to_esnext_node18_node20_nodenext__2823", text: "Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'."} + +var Cannot_find_namespace_0_Did_you_mean_1 = &Message{code: 2833, category: CategoryError, key: "Cannot_find_namespace_0_Did_you_mean_1_2833", text: "Cannot find namespace '{0}'. Did you mean '{1}'?"} + +var Relative_import_paths_need_explicit_file_extensions_in_ECMAScript_imports_when_moduleResolution_is_node16_or_nodenext_Consider_adding_an_extension_to_the_import_path = &Message{code: 2834, category: CategoryError, key: "Relative_import_paths_need_explicit_file_extensions_in_ECMAScript_imports_when_moduleResolution_is_n_2834", text: "Relative import paths need explicit file extensions in ECMAScript imports when '--moduleResolution' is 'node16' or 'nodenext'. Consider adding an extension to the import path."} + +var Relative_import_paths_need_explicit_file_extensions_in_ECMAScript_imports_when_moduleResolution_is_node16_or_nodenext_Did_you_mean_0 = &Message{code: 2835, category: CategoryError, key: "Relative_import_paths_need_explicit_file_extensions_in_ECMAScript_imports_when_moduleResolution_is_n_2835", text: "Relative import paths need explicit file extensions in ECMAScript imports when '--moduleResolution' is 'node16' or 'nodenext'. Did you mean '{0}'?"} + +var Import_assertions_are_not_allowed_on_statements_that_compile_to_CommonJS_require_calls = &Message{code: 2836, category: CategoryError, key: "Import_assertions_are_not_allowed_on_statements_that_compile_to_CommonJS_require_calls_2836", text: "Import assertions are not allowed on statements that compile to CommonJS 'require' calls."} + +var Import_assertion_values_must_be_string_literal_expressions = &Message{code: 2837, category: CategoryError, key: "Import_assertion_values_must_be_string_literal_expressions_2837", text: "Import assertion values must be string literal expressions."} + +var All_declarations_of_0_must_have_identical_constraints = &Message{code: 2838, category: CategoryError, key: "All_declarations_of_0_must_have_identical_constraints_2838", text: "All declarations of '{0}' must have identical constraints."} + +var This_condition_will_always_return_0_since_JavaScript_compares_objects_by_reference_not_value = &Message{code: 2839, category: CategoryError, key: "This_condition_will_always_return_0_since_JavaScript_compares_objects_by_reference_not_value_2839", text: "This condition will always return '{0}' since JavaScript compares objects by reference, not value."} + +var An_interface_cannot_extend_a_primitive_type_like_0_It_can_only_extend_other_named_object_types = &Message{code: 2840, category: CategoryError, key: "An_interface_cannot_extend_a_primitive_type_like_0_It_can_only_extend_other_named_object_types_2840", text: "An interface cannot extend a primitive type like '{0}'. It can only extend other named object types."} + +var X_0_is_an_unused_renaming_of_1_Did_you_intend_to_use_it_as_a_type_annotation = &Message{code: 2842, category: CategoryError, key: "_0_is_an_unused_renaming_of_1_Did_you_intend_to_use_it_as_a_type_annotation_2842", text: "'{0}' is an unused renaming of '{1}'. Did you intend to use it as a type annotation?"} + +var We_can_only_write_a_type_for_0_by_adding_a_type_for_the_entire_parameter_here = &Message{code: 2843, category: CategoryError, key: "We_can_only_write_a_type_for_0_by_adding_a_type_for_the_entire_parameter_here_2843", text: "We can only write a type for '{0}' by adding a type for the entire parameter here."} + +var Type_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor = &Message{code: 2844, category: CategoryError, key: "Type_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor_2844", text: "Type of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor."} + +var This_condition_will_always_return_0 = &Message{code: 2845, category: CategoryError, key: "This_condition_will_always_return_0_2845", text: "This condition will always return '{0}'."} + +var A_declaration_file_cannot_be_imported_without_import_type_Did_you_mean_to_import_an_implementation_file_0_instead = &Message{code: 2846, category: CategoryError, key: "A_declaration_file_cannot_be_imported_without_import_type_Did_you_mean_to_import_an_implementation_f_2846", text: "A declaration file cannot be imported without 'import type'. Did you mean to import an implementation file '{0}' instead?"} + +var The_right_hand_side_of_an_instanceof_expression_must_not_be_an_instantiation_expression = &Message{code: 2848, category: CategoryError, key: "The_right_hand_side_of_an_instanceof_expression_must_not_be_an_instantiation_expression_2848", text: "The right-hand side of an 'instanceof' expression must not be an instantiation expression."} + +var Target_signature_provides_too_few_arguments_Expected_0_or_more_but_got_1 = &Message{code: 2849, category: CategoryError, key: "Target_signature_provides_too_few_arguments_Expected_0_or_more_but_got_1_2849", text: "Target signature provides too few arguments. Expected {0} or more, but got {1}."} + +var The_initializer_of_a_using_declaration_must_be_either_an_object_with_a_Symbol_dispose_method_or_be_null_or_undefined = &Message{code: 2850, category: CategoryError, key: "The_initializer_of_a_using_declaration_must_be_either_an_object_with_a_Symbol_dispose_method_or_be_n_2850", text: "The initializer of a 'using' declaration must be either an object with a '[Symbol.dispose]()' method, or be 'null' or 'undefined'."} + +var The_initializer_of_an_await_using_declaration_must_be_either_an_object_with_a_Symbol_asyncDispose_or_Symbol_dispose_method_or_be_null_or_undefined = &Message{code: 2851, category: CategoryError, key: "The_initializer_of_an_await_using_declaration_must_be_either_an_object_with_a_Symbol_asyncDispose_or_2851", text: "The initializer of an 'await using' declaration must be either an object with a '[Symbol.asyncDispose]()' or '[Symbol.dispose]()' method, or be 'null' or 'undefined'."} + +var X_await_using_statements_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules = &Message{code: 2852, category: CategoryError, key: "await_using_statements_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules_2852", text: "'await using' statements are only allowed within async functions and at the top levels of modules."} + +var X_await_using_statements_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module = &Message{code: 2853, category: CategoryError, key: "await_using_statements_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_th_2853", text: "'await using' statements are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module."} + +var Top_level_await_using_statements_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_node16_node18_node20_nodenext_or_preserve_and_the_target_option_is_set_to_es2017_or_higher = &Message{code: 2854, category: CategoryError, key: "Top_level_await_using_statements_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_sys_2854", text: "Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher."} + +var Class_field_0_defined_by_the_parent_class_is_not_accessible_in_the_child_class_via_super = &Message{code: 2855, category: CategoryError, key: "Class_field_0_defined_by_the_parent_class_is_not_accessible_in_the_child_class_via_super_2855", text: "Class field '{0}' defined by the parent class is not accessible in the child class via super."} + +var Import_attributes_are_not_allowed_on_statements_that_compile_to_CommonJS_require_calls = &Message{code: 2856, category: CategoryError, key: "Import_attributes_are_not_allowed_on_statements_that_compile_to_CommonJS_require_calls_2856", text: "Import attributes are not allowed on statements that compile to CommonJS 'require' calls."} + +var Import_attributes_cannot_be_used_with_type_only_imports_or_exports = &Message{code: 2857, category: CategoryError, key: "Import_attributes_cannot_be_used_with_type_only_imports_or_exports_2857", text: "Import attributes cannot be used with type-only imports or exports."} + +var Import_attribute_values_must_be_string_literal_expressions = &Message{code: 2858, category: CategoryError, key: "Import_attribute_values_must_be_string_literal_expressions_2858", text: "Import attribute values must be string literal expressions."} + +var Excessive_complexity_comparing_types_0_and_1 = &Message{code: 2859, category: CategoryError, key: "Excessive_complexity_comparing_types_0_and_1_2859", text: "Excessive complexity comparing types '{0}' and '{1}'."} + +var The_left_hand_side_of_an_instanceof_expression_must_be_assignable_to_the_first_argument_of_the_right_hand_side_s_Symbol_hasInstance_method = &Message{code: 2860, category: CategoryError, key: "The_left_hand_side_of_an_instanceof_expression_must_be_assignable_to_the_first_argument_of_the_right_2860", text: "The left-hand side of an 'instanceof' expression must be assignable to the first argument of the right-hand side's '[Symbol.hasInstance]' method."} + +var An_object_s_Symbol_hasInstance_method_must_return_a_boolean_value_for_it_to_be_used_on_the_right_hand_side_of_an_instanceof_expression = &Message{code: 2861, category: CategoryError, key: "An_object_s_Symbol_hasInstance_method_must_return_a_boolean_value_for_it_to_be_used_on_the_right_han_2861", text: "An object's '[Symbol.hasInstance]' method must return a boolean value for it to be used on the right-hand side of an 'instanceof' expression."} + +var Type_0_is_generic_and_can_only_be_indexed_for_reading = &Message{code: 2862, category: CategoryError, key: "Type_0_is_generic_and_can_only_be_indexed_for_reading_2862", text: "Type '{0}' is generic and can only be indexed for reading."} + +var A_class_cannot_extend_a_primitive_type_like_0_Classes_can_only_extend_constructable_values = &Message{code: 2863, category: CategoryError, key: "A_class_cannot_extend_a_primitive_type_like_0_Classes_can_only_extend_constructable_values_2863", text: "A class cannot extend a primitive type like '{0}'. Classes can only extend constructable values."} + +var A_class_cannot_implement_a_primitive_type_like_0_It_can_only_implement_other_named_object_types = &Message{code: 2864, category: CategoryError, key: "A_class_cannot_implement_a_primitive_type_like_0_It_can_only_implement_other_named_object_types_2864", text: "A class cannot implement a primitive type like '{0}'. It can only implement other named object types."} + +var Import_0_conflicts_with_local_value_so_must_be_declared_with_a_type_only_import_when_isolatedModules_is_enabled = &Message{code: 2865, category: CategoryError, key: "Import_0_conflicts_with_local_value_so_must_be_declared_with_a_type_only_import_when_isolatedModules_2865", text: "Import '{0}' conflicts with local value, so must be declared with a type-only import when 'isolatedModules' is enabled."} + +var Import_0_conflicts_with_global_value_used_in_this_file_so_must_be_declared_with_a_type_only_import_when_isolatedModules_is_enabled = &Message{code: 2866, category: CategoryError, key: "Import_0_conflicts_with_global_value_used_in_this_file_so_must_be_declared_with_a_type_only_import_w_2866", text: "Import '{0}' conflicts with global value used in this file, so must be declared with a type-only import when 'isolatedModules' is enabled."} + +var Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_Bun_Try_npm_i_save_dev_types_Slashbun = &Message{code: 2867, category: CategoryError, key: "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_Bun_Try_npm_i_save_dev_types_Slashbun_2867", text: "Cannot find name '{0}'. Do you need to install type definitions for Bun? Try `npm i --save-dev @types/bun`."} + +var Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_Bun_Try_npm_i_save_dev_types_Slashbun_and_then_add_bun_to_the_types_field_in_your_tsconfig = &Message{code: 2868, category: CategoryError, key: "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_Bun_Try_npm_i_save_dev_types_Slashbun_2868", text: "Cannot find name '{0}'. Do you need to install type definitions for Bun? Try `npm i --save-dev @types/bun` and then add 'bun' to the types field in your tsconfig."} + +var Right_operand_of_is_unreachable_because_the_left_operand_is_never_nullish = &Message{code: 2869, category: CategoryError, key: "Right_operand_of_is_unreachable_because_the_left_operand_is_never_nullish_2869", text: "Right operand of ?? is unreachable because the left operand is never nullish."} + +var This_binary_expression_is_never_nullish_Are_you_missing_parentheses = &Message{code: 2870, category: CategoryError, key: "This_binary_expression_is_never_nullish_Are_you_missing_parentheses_2870", text: "This binary expression is never nullish. Are you missing parentheses?"} + +var This_expression_is_always_nullish = &Message{code: 2871, category: CategoryError, key: "This_expression_is_always_nullish_2871", text: "This expression is always nullish."} + +var This_kind_of_expression_is_always_truthy = &Message{code: 2872, category: CategoryError, key: "This_kind_of_expression_is_always_truthy_2872", text: "This kind of expression is always truthy."} + +var This_kind_of_expression_is_always_falsy = &Message{code: 2873, category: CategoryError, key: "This_kind_of_expression_is_always_falsy_2873", text: "This kind of expression is always falsy."} + +var This_JSX_tag_requires_0_to_be_in_scope_but_it_could_not_be_found = &Message{code: 2874, category: CategoryError, key: "This_JSX_tag_requires_0_to_be_in_scope_but_it_could_not_be_found_2874", text: "This JSX tag requires '{0}' to be in scope, but it could not be found."} + +var This_JSX_tag_requires_the_module_path_0_to_exist_but_none_could_be_found_Make_sure_you_have_types_for_the_appropriate_package_installed = &Message{code: 2875, category: CategoryError, key: "This_JSX_tag_requires_the_module_path_0_to_exist_but_none_could_be_found_Make_sure_you_have_types_fo_2875", text: "This JSX tag requires the module path '{0}' to exist, but none could be found. Make sure you have types for the appropriate package installed."} + +var This_relative_import_path_is_unsafe_to_rewrite_because_it_looks_like_a_file_name_but_actually_resolves_to_0 = &Message{code: 2876, category: CategoryError, key: "This_relative_import_path_is_unsafe_to_rewrite_because_it_looks_like_a_file_name_but_actually_resolv_2876", text: "This relative import path is unsafe to rewrite because it looks like a file name, but actually resolves to \"{0}\"."} + +var This_import_uses_a_0_extension_to_resolve_to_an_input_TypeScript_file_but_will_not_be_rewritten_during_emit_because_it_is_not_a_relative_path = &Message{code: 2877, category: CategoryError, key: "This_import_uses_a_0_extension_to_resolve_to_an_input_TypeScript_file_but_will_not_be_rewritten_duri_2877", text: "This import uses a '{0}' extension to resolve to an input TypeScript file, but will not be rewritten during emit because it is not a relative path."} + +var This_import_path_is_unsafe_to_rewrite_because_it_resolves_to_another_project_and_the_relative_path_between_the_projects_output_files_is_not_the_same_as_the_relative_path_between_its_input_files = &Message{code: 2878, category: CategoryError, key: "This_import_path_is_unsafe_to_rewrite_because_it_resolves_to_another_project_and_the_relative_path_b_2878", text: "This import path is unsafe to rewrite because it resolves to another project, and the relative path between the projects' output files is not the same as the relative path between its input files."} + +var Using_JSX_fragments_requires_fragment_factory_0_to_be_in_scope_but_it_could_not_be_found = &Message{code: 2879, category: CategoryError, key: "Using_JSX_fragments_requires_fragment_factory_0_to_be_in_scope_but_it_could_not_be_found_2879", text: "Using JSX fragments requires fragment factory '{0}' to be in scope, but it could not be found."} + +var Import_assertions_have_been_replaced_by_import_attributes_Use_with_instead_of_assert = &Message{code: 2880, category: CategoryError, key: "Import_assertions_have_been_replaced_by_import_attributes_Use_with_instead_of_assert_2880", text: "Import assertions have been replaced by import attributes. Use 'with' instead of 'assert'."} + +var This_expression_is_never_nullish = &Message{code: 2881, category: CategoryError, key: "This_expression_is_never_nullish_2881", text: "This expression is never nullish."} + +var Import_declaration_0_is_using_private_name_1 = &Message{code: 4000, category: CategoryError, key: "Import_declaration_0_is_using_private_name_1_4000", text: "Import declaration '{0}' is using private name '{1}'."} + +var Type_parameter_0_of_exported_class_has_or_is_using_private_name_1 = &Message{code: 4002, category: CategoryError, key: "Type_parameter_0_of_exported_class_has_or_is_using_private_name_1_4002", text: "Type parameter '{0}' of exported class has or is using private name '{1}'."} + +var Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1 = &Message{code: 4004, category: CategoryError, key: "Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1_4004", text: "Type parameter '{0}' of exported interface has or is using private name '{1}'."} + +var Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1 = &Message{code: 4006, category: CategoryError, key: "Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1_4006", text: "Type parameter '{0}' of constructor signature from exported interface has or is using private name '{1}'."} + +var Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1 = &Message{code: 4008, category: CategoryError, key: "Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4008", text: "Type parameter '{0}' of call signature from exported interface has or is using private name '{1}'."} + +var Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1 = &Message{code: 4010, category: CategoryError, key: "Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1_4010", text: "Type parameter '{0}' of public static method from exported class has or is using private name '{1}'."} + +var Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1 = &Message{code: 4012, category: CategoryError, key: "Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1_4012", text: "Type parameter '{0}' of public method from exported class has or is using private name '{1}'."} + +var Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1 = &Message{code: 4014, category: CategoryError, key: "Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1_4014", text: "Type parameter '{0}' of method from exported interface has or is using private name '{1}'."} + +var Type_parameter_0_of_exported_function_has_or_is_using_private_name_1 = &Message{code: 4016, category: CategoryError, key: "Type_parameter_0_of_exported_function_has_or_is_using_private_name_1_4016", text: "Type parameter '{0}' of exported function has or is using private name '{1}'."} + +var Implements_clause_of_exported_class_0_has_or_is_using_private_name_1 = &Message{code: 4019, category: CategoryError, key: "Implements_clause_of_exported_class_0_has_or_is_using_private_name_1_4019", text: "Implements clause of exported class '{0}' has or is using private name '{1}'."} + +var X_extends_clause_of_exported_class_0_has_or_is_using_private_name_1 = &Message{code: 4020, category: CategoryError, key: "extends_clause_of_exported_class_0_has_or_is_using_private_name_1_4020", text: "'extends' clause of exported class '{0}' has or is using private name '{1}'."} + +var X_extends_clause_of_exported_class_has_or_is_using_private_name_0 = &Message{code: 4021, category: CategoryError, key: "extends_clause_of_exported_class_has_or_is_using_private_name_0_4021", text: "'extends' clause of exported class has or is using private name '{0}'."} + +var X_extends_clause_of_exported_interface_0_has_or_is_using_private_name_1 = &Message{code: 4022, category: CategoryError, key: "extends_clause_of_exported_interface_0_has_or_is_using_private_name_1_4022", text: "'extends' clause of exported interface '{0}' has or is using private name '{1}'."} + +var Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named = &Message{code: 4023, category: CategoryError, key: "Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4023", text: "Exported variable '{0}' has or is using name '{1}' from external module {2} but cannot be named."} + +var Exported_variable_0_has_or_is_using_name_1_from_private_module_2 = &Message{code: 4024, category: CategoryError, key: "Exported_variable_0_has_or_is_using_name_1_from_private_module_2_4024", text: "Exported variable '{0}' has or is using name '{1}' from private module '{2}'."} + +var Exported_variable_0_has_or_is_using_private_name_1 = &Message{code: 4025, category: CategoryError, key: "Exported_variable_0_has_or_is_using_private_name_1_4025", text: "Exported variable '{0}' has or is using private name '{1}'."} + +var Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named = &Message{code: 4026, category: CategoryError, key: "Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot__4026", text: "Public static property '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named."} + +var Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 = &Message{code: 4027, category: CategoryError, key: "Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4027", text: "Public static property '{0}' of exported class has or is using name '{1}' from private module '{2}'."} + +var Public_static_property_0_of_exported_class_has_or_is_using_private_name_1 = &Message{code: 4028, category: CategoryError, key: "Public_static_property_0_of_exported_class_has_or_is_using_private_name_1_4028", text: "Public static property '{0}' of exported class has or is using private name '{1}'."} + +var Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named = &Message{code: 4029, category: CategoryError, key: "Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_name_4029", text: "Public property '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named."} + +var Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 = &Message{code: 4030, category: CategoryError, key: "Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4030", text: "Public property '{0}' of exported class has or is using name '{1}' from private module '{2}'."} + +var Public_property_0_of_exported_class_has_or_is_using_private_name_1 = &Message{code: 4031, category: CategoryError, key: "Public_property_0_of_exported_class_has_or_is_using_private_name_1_4031", text: "Public property '{0}' of exported class has or is using private name '{1}'."} + +var Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2 = &Message{code: 4032, category: CategoryError, key: "Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2_4032", text: "Property '{0}' of exported interface has or is using name '{1}' from private module '{2}'."} + +var Property_0_of_exported_interface_has_or_is_using_private_name_1 = &Message{code: 4033, category: CategoryError, key: "Property_0_of_exported_interface_has_or_is_using_private_name_1_4033", text: "Property '{0}' of exported interface has or is using private name '{1}'."} + +var Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 = &Message{code: 4034, category: CategoryError, key: "Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_name_1_from_private_mod_4034", text: "Parameter type of public static setter '{0}' from exported class has or is using name '{1}' from private module '{2}'."} + +var Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_private_name_1 = &Message{code: 4035, category: CategoryError, key: "Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_private_name_1_4035", text: "Parameter type of public static setter '{0}' from exported class has or is using private name '{1}'."} + +var Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 = &Message{code: 4036, category: CategoryError, key: "Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2_4036", text: "Parameter type of public setter '{0}' from exported class has or is using name '{1}' from private module '{2}'."} + +var Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_private_name_1 = &Message{code: 4037, category: CategoryError, key: "Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_private_name_1_4037", text: "Parameter type of public setter '{0}' from exported class has or is using private name '{1}'."} + +var Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named = &Message{code: 4038, category: CategoryError, key: "Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_external_modul_4038", text: "Return type of public static getter '{0}' from exported class has or is using name '{1}' from external module {2} but cannot be named."} + +var Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 = &Message{code: 4039, category: CategoryError, key: "Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_4039", text: "Return type of public static getter '{0}' from exported class has or is using name '{1}' from private module '{2}'."} + +var Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_private_name_1 = &Message{code: 4040, category: CategoryError, key: "Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_private_name_1_4040", text: "Return type of public static getter '{0}' from exported class has or is using private name '{1}'."} + +var Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named = &Message{code: 4041, category: CategoryError, key: "Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_4041", text: "Return type of public getter '{0}' from exported class has or is using name '{1}' from external module {2} but cannot be named."} + +var Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 = &Message{code: 4042, category: CategoryError, key: "Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2_4042", text: "Return type of public getter '{0}' from exported class has or is using name '{1}' from private module '{2}'."} + +var Return_type_of_public_getter_0_from_exported_class_has_or_is_using_private_name_1 = &Message{code: 4043, category: CategoryError, key: "Return_type_of_public_getter_0_from_exported_class_has_or_is_using_private_name_1_4043", text: "Return type of public getter '{0}' from exported class has or is using private name '{1}'."} + +var Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 = &Message{code: 4044, category: CategoryError, key: "Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_mod_4044", text: "Return type of constructor signature from exported interface has or is using name '{0}' from private module '{1}'."} + +var Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0 = &Message{code: 4045, category: CategoryError, key: "Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0_4045", text: "Return type of constructor signature from exported interface has or is using private name '{0}'."} + +var Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 = &Message{code: 4046, category: CategoryError, key: "Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4046", text: "Return type of call signature from exported interface has or is using name '{0}' from private module '{1}'."} + +var Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0 = &Message{code: 4047, category: CategoryError, key: "Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0_4047", text: "Return type of call signature from exported interface has or is using private name '{0}'."} + +var Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 = &Message{code: 4048, category: CategoryError, key: "Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4048", text: "Return type of index signature from exported interface has or is using name '{0}' from private module '{1}'."} + +var Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_name_0 = &Message{code: 4049, category: CategoryError, key: "Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_name_0_4049", text: "Return type of index signature from exported interface has or is using private name '{0}'."} + +var Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named = &Message{code: 4050, category: CategoryError, key: "Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module__4050", text: "Return type of public static method from exported class has or is using name '{0}' from external module {1} but cannot be named."} + +var Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1 = &Message{code: 4051, category: CategoryError, key: "Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1_4051", text: "Return type of public static method from exported class has or is using name '{0}' from private module '{1}'."} + +var Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0 = &Message{code: 4052, category: CategoryError, key: "Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0_4052", text: "Return type of public static method from exported class has or is using private name '{0}'."} + +var Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named = &Message{code: 4053, category: CategoryError, key: "Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_c_4053", text: "Return type of public method from exported class has or is using name '{0}' from external module {1} but cannot be named."} + +var Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_private_module_1 = &Message{code: 4054, category: CategoryError, key: "Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_private_module_1_4054", text: "Return type of public method from exported class has or is using name '{0}' from private module '{1}'."} + +var Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0 = &Message{code: 4055, category: CategoryError, key: "Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0_4055", text: "Return type of public method from exported class has or is using private name '{0}'."} + +var Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1 = &Message{code: 4056, category: CategoryError, key: "Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4056", text: "Return type of method from exported interface has or is using name '{0}' from private module '{1}'."} + +var Return_type_of_method_from_exported_interface_has_or_is_using_private_name_0 = &Message{code: 4057, category: CategoryError, key: "Return_type_of_method_from_exported_interface_has_or_is_using_private_name_0_4057", text: "Return type of method from exported interface has or is using private name '{0}'."} + +var Return_type_of_exported_function_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named = &Message{code: 4058, category: CategoryError, key: "Return_type_of_exported_function_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named_4058", text: "Return type of exported function has or is using name '{0}' from external module {1} but cannot be named."} + +var Return_type_of_exported_function_has_or_is_using_name_0_from_private_module_1 = &Message{code: 4059, category: CategoryError, key: "Return_type_of_exported_function_has_or_is_using_name_0_from_private_module_1_4059", text: "Return type of exported function has or is using name '{0}' from private module '{1}'."} + +var Return_type_of_exported_function_has_or_is_using_private_name_0 = &Message{code: 4060, category: CategoryError, key: "Return_type_of_exported_function_has_or_is_using_private_name_0_4060", text: "Return type of exported function has or is using private name '{0}'."} + +var Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named = &Message{code: 4061, category: CategoryError, key: "Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_can_4061", text: "Parameter '{0}' of constructor from exported class has or is using name '{1}' from external module {2} but cannot be named."} + +var Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2 = &Message{code: 4062, category: CategoryError, key: "Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2_4062", text: "Parameter '{0}' of constructor from exported class has or is using name '{1}' from private module '{2}'."} + +var Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1 = &Message{code: 4063, category: CategoryError, key: "Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1_4063", text: "Parameter '{0}' of constructor from exported class has or is using private name '{1}'."} + +var Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 = &Message{code: 4064, category: CategoryError, key: "Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_mod_4064", text: "Parameter '{0}' of constructor signature from exported interface has or is using name '{1}' from private module '{2}'."} + +var Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1 = &Message{code: 4065, category: CategoryError, key: "Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1_4065", text: "Parameter '{0}' of constructor signature from exported interface has or is using private name '{1}'."} + +var Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 = &Message{code: 4066, category: CategoryError, key: "Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4066", text: "Parameter '{0}' of call signature from exported interface has or is using name '{1}' from private module '{2}'."} + +var Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1 = &Message{code: 4067, category: CategoryError, key: "Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4067", text: "Parameter '{0}' of call signature from exported interface has or is using private name '{1}'."} + +var Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named = &Message{code: 4068, category: CategoryError, key: "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module__4068", text: "Parameter '{0}' of public static method from exported class has or is using name '{1}' from external module {2} but cannot be named."} + +var Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 = &Message{code: 4069, category: CategoryError, key: "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2_4069", text: "Parameter '{0}' of public static method from exported class has or is using name '{1}' from private module '{2}'."} + +var Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1 = &Message{code: 4070, category: CategoryError, key: "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1_4070", text: "Parameter '{0}' of public static method from exported class has or is using private name '{1}'."} + +var Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named = &Message{code: 4071, category: CategoryError, key: "Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_c_4071", text: "Parameter '{0}' of public method from exported class has or is using name '{1}' from external module {2} but cannot be named."} + +var Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 = &Message{code: 4072, category: CategoryError, key: "Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2_4072", text: "Parameter '{0}' of public method from exported class has or is using name '{1}' from private module '{2}'."} + +var Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1 = &Message{code: 4073, category: CategoryError, key: "Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1_4073", text: "Parameter '{0}' of public method from exported class has or is using private name '{1}'."} + +var Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2 = &Message{code: 4074, category: CategoryError, key: "Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4074", text: "Parameter '{0}' of method from exported interface has or is using name '{1}' from private module '{2}'."} + +var Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1 = &Message{code: 4075, category: CategoryError, key: "Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1_4075", text: "Parameter '{0}' of method from exported interface has or is using private name '{1}'."} + +var Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named = &Message{code: 4076, category: CategoryError, key: "Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4076", text: "Parameter '{0}' of exported function has or is using name '{1}' from external module {2} but cannot be named."} + +var Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2 = &Message{code: 4077, category: CategoryError, key: "Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2_4077", text: "Parameter '{0}' of exported function has or is using name '{1}' from private module '{2}'."} + +var Parameter_0_of_exported_function_has_or_is_using_private_name_1 = &Message{code: 4078, category: CategoryError, key: "Parameter_0_of_exported_function_has_or_is_using_private_name_1_4078", text: "Parameter '{0}' of exported function has or is using private name '{1}'."} + +var Exported_type_alias_0_has_or_is_using_private_name_1 = &Message{code: 4081, category: CategoryError, key: "Exported_type_alias_0_has_or_is_using_private_name_1_4081", text: "Exported type alias '{0}' has or is using private name '{1}'."} + +var Default_export_of_the_module_has_or_is_using_private_name_0 = &Message{code: 4082, category: CategoryError, key: "Default_export_of_the_module_has_or_is_using_private_name_0_4082", text: "Default export of the module has or is using private name '{0}'."} + +var Type_parameter_0_of_exported_type_alias_has_or_is_using_private_name_1 = &Message{code: 4083, category: CategoryError, key: "Type_parameter_0_of_exported_type_alias_has_or_is_using_private_name_1_4083", text: "Type parameter '{0}' of exported type alias has or is using private name '{1}'."} + +var Exported_type_alias_0_has_or_is_using_private_name_1_from_module_2 = &Message{code: 4084, category: CategoryError, key: "Exported_type_alias_0_has_or_is_using_private_name_1_from_module_2_4084", text: "Exported type alias '{0}' has or is using private name '{1}' from module {2}."} + +var Extends_clause_for_inferred_type_0_has_or_is_using_private_name_1 = &Message{code: 4085, category: CategoryError, key: "Extends_clause_for_inferred_type_0_has_or_is_using_private_name_1_4085", text: "Extends clause for inferred type '{0}' has or is using private name '{1}'."} + +var Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 = &Message{code: 4091, category: CategoryError, key: "Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4091", text: "Parameter '{0}' of index signature from exported interface has or is using name '{1}' from private module '{2}'."} + +var Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_private_name_1 = &Message{code: 4092, category: CategoryError, key: "Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_private_name_1_4092", text: "Parameter '{0}' of index signature from exported interface has or is using private name '{1}'."} + +var Property_0_of_exported_anonymous_class_type_may_not_be_private_or_protected = &Message{code: 4094, category: CategoryError, key: "Property_0_of_exported_anonymous_class_type_may_not_be_private_or_protected_4094", text: "Property '{0}' of exported anonymous class type may not be private or protected."} + +var Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named = &Message{code: 4095, category: CategoryError, key: "Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_4095", text: "Public static method '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named."} + +var Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 = &Message{code: 4096, category: CategoryError, key: "Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4096", text: "Public static method '{0}' of exported class has or is using name '{1}' from private module '{2}'."} + +var Public_static_method_0_of_exported_class_has_or_is_using_private_name_1 = &Message{code: 4097, category: CategoryError, key: "Public_static_method_0_of_exported_class_has_or_is_using_private_name_1_4097", text: "Public static method '{0}' of exported class has or is using private name '{1}'."} + +var Public_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named = &Message{code: 4098, category: CategoryError, key: "Public_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4098", text: "Public method '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named."} + +var Public_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 = &Message{code: 4099, category: CategoryError, key: "Public_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4099", text: "Public method '{0}' of exported class has or is using name '{1}' from private module '{2}'."} + +var Public_method_0_of_exported_class_has_or_is_using_private_name_1 = &Message{code: 4100, category: CategoryError, key: "Public_method_0_of_exported_class_has_or_is_using_private_name_1_4100", text: "Public method '{0}' of exported class has or is using private name '{1}'."} + +var Method_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2 = &Message{code: 4101, category: CategoryError, key: "Method_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2_4101", text: "Method '{0}' of exported interface has or is using name '{1}' from private module '{2}'."} + +var Method_0_of_exported_interface_has_or_is_using_private_name_1 = &Message{code: 4102, category: CategoryError, key: "Method_0_of_exported_interface_has_or_is_using_private_name_1_4102", text: "Method '{0}' of exported interface has or is using private name '{1}'."} + +var Type_parameter_0_of_exported_mapped_object_type_is_using_private_name_1 = &Message{code: 4103, category: CategoryError, key: "Type_parameter_0_of_exported_mapped_object_type_is_using_private_name_1_4103", text: "Type parameter '{0}' of exported mapped object type is using private name '{1}'."} + +var The_type_0_is_readonly_and_cannot_be_assigned_to_the_mutable_type_1 = &Message{code: 4104, category: CategoryError, key: "The_type_0_is_readonly_and_cannot_be_assigned_to_the_mutable_type_1_4104", text: "The type '{0}' is 'readonly' and cannot be assigned to the mutable type '{1}'."} + +var Private_or_protected_member_0_cannot_be_accessed_on_a_type_parameter = &Message{code: 4105, category: CategoryError, key: "Private_or_protected_member_0_cannot_be_accessed_on_a_type_parameter_4105", text: "Private or protected member '{0}' cannot be accessed on a type parameter."} + +var Parameter_0_of_accessor_has_or_is_using_private_name_1 = &Message{code: 4106, category: CategoryError, key: "Parameter_0_of_accessor_has_or_is_using_private_name_1_4106", text: "Parameter '{0}' of accessor has or is using private name '{1}'."} + +var Parameter_0_of_accessor_has_or_is_using_name_1_from_private_module_2 = &Message{code: 4107, category: CategoryError, key: "Parameter_0_of_accessor_has_or_is_using_name_1_from_private_module_2_4107", text: "Parameter '{0}' of accessor has or is using name '{1}' from private module '{2}'."} + +var Parameter_0_of_accessor_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named = &Message{code: 4108, category: CategoryError, key: "Parameter_0_of_accessor_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4108", text: "Parameter '{0}' of accessor has or is using name '{1}' from external module '{2}' but cannot be named."} + +var Type_arguments_for_0_circularly_reference_themselves = &Message{code: 4109, category: CategoryError, key: "Type_arguments_for_0_circularly_reference_themselves_4109", text: "Type arguments for '{0}' circularly reference themselves."} + +var Tuple_type_arguments_circularly_reference_themselves = &Message{code: 4110, category: CategoryError, key: "Tuple_type_arguments_circularly_reference_themselves_4110", text: "Tuple type arguments circularly reference themselves."} + +var Property_0_comes_from_an_index_signature_so_it_must_be_accessed_with_0 = &Message{code: 4111, category: CategoryError, key: "Property_0_comes_from_an_index_signature_so_it_must_be_accessed_with_0_4111", text: "Property '{0}' comes from an index signature, so it must be accessed with ['{0}']."} + +var This_member_cannot_have_an_override_modifier_because_its_containing_class_0_does_not_extend_another_class = &Message{code: 4112, category: CategoryError, key: "This_member_cannot_have_an_override_modifier_because_its_containing_class_0_does_not_extend_another__4112", text: "This member cannot have an 'override' modifier because its containing class '{0}' does not extend another class."} + +var This_member_cannot_have_an_override_modifier_because_it_is_not_declared_in_the_base_class_0 = &Message{code: 4113, category: CategoryError, key: "This_member_cannot_have_an_override_modifier_because_it_is_not_declared_in_the_base_class_0_4113", text: "This member cannot have an 'override' modifier because it is not declared in the base class '{0}'."} + +var This_member_must_have_an_override_modifier_because_it_overrides_a_member_in_the_base_class_0 = &Message{code: 4114, category: CategoryError, key: "This_member_must_have_an_override_modifier_because_it_overrides_a_member_in_the_base_class_0_4114", text: "This member must have an 'override' modifier because it overrides a member in the base class '{0}'."} + +var This_parameter_property_must_have_an_override_modifier_because_it_overrides_a_member_in_base_class_0 = &Message{code: 4115, category: CategoryError, key: "This_parameter_property_must_have_an_override_modifier_because_it_overrides_a_member_in_base_class_0_4115", text: "This parameter property must have an 'override' modifier because it overrides a member in base class '{0}'."} + +var This_member_must_have_an_override_modifier_because_it_overrides_an_abstract_method_that_is_declared_in_the_base_class_0 = &Message{code: 4116, category: CategoryError, key: "This_member_must_have_an_override_modifier_because_it_overrides_an_abstract_method_that_is_declared__4116", text: "This member must have an 'override' modifier because it overrides an abstract method that is declared in the base class '{0}'."} + +var This_member_cannot_have_an_override_modifier_because_it_is_not_declared_in_the_base_class_0_Did_you_mean_1 = &Message{code: 4117, category: CategoryError, key: "This_member_cannot_have_an_override_modifier_because_it_is_not_declared_in_the_base_class_0_Did_you__4117", text: "This member cannot have an 'override' modifier because it is not declared in the base class '{0}'. Did you mean '{1}'?"} + +var The_type_of_this_node_cannot_be_serialized_because_its_property_0_cannot_be_serialized = &Message{code: 4118, category: CategoryError, key: "The_type_of_this_node_cannot_be_serialized_because_its_property_0_cannot_be_serialized_4118", text: "The type of this node cannot be serialized because its property '{0}' cannot be serialized."} + +var This_member_must_have_a_JSDoc_comment_with_an_override_tag_because_it_overrides_a_member_in_the_base_class_0 = &Message{code: 4119, category: CategoryError, key: "This_member_must_have_a_JSDoc_comment_with_an_override_tag_because_it_overrides_a_member_in_the_base_4119", text: "This member must have a JSDoc comment with an '@override' tag because it overrides a member in the base class '{0}'."} + +var This_parameter_property_must_have_a_JSDoc_comment_with_an_override_tag_because_it_overrides_a_member_in_the_base_class_0 = &Message{code: 4120, category: CategoryError, key: "This_parameter_property_must_have_a_JSDoc_comment_with_an_override_tag_because_it_overrides_a_member_4120", text: "This parameter property must have a JSDoc comment with an '@override' tag because it overrides a member in the base class '{0}'."} + +var This_member_cannot_have_a_JSDoc_comment_with_an_override_tag_because_its_containing_class_0_does_not_extend_another_class = &Message{code: 4121, category: CategoryError, key: "This_member_cannot_have_a_JSDoc_comment_with_an_override_tag_because_its_containing_class_0_does_not_4121", text: "This member cannot have a JSDoc comment with an '@override' tag because its containing class '{0}' does not extend another class."} + +var This_member_cannot_have_a_JSDoc_comment_with_an_override_tag_because_it_is_not_declared_in_the_base_class_0 = &Message{code: 4122, category: CategoryError, key: "This_member_cannot_have_a_JSDoc_comment_with_an_override_tag_because_it_is_not_declared_in_the_base__4122", text: "This member cannot have a JSDoc comment with an '@override' tag because it is not declared in the base class '{0}'."} + +var This_member_cannot_have_a_JSDoc_comment_with_an_override_tag_because_it_is_not_declared_in_the_base_class_0_Did_you_mean_1 = &Message{code: 4123, category: CategoryError, key: "This_member_cannot_have_a_JSDoc_comment_with_an_override_tag_because_it_is_not_declared_in_the_base__4123", text: "This member cannot have a JSDoc comment with an 'override' tag because it is not declared in the base class '{0}'. Did you mean '{1}'?"} + +var Compiler_option_0_of_value_1_is_unstable_Use_nightly_TypeScript_to_silence_this_error_Try_updating_with_npm_install_D_typescript_next = &Message{code: 4124, category: CategoryError, key: "Compiler_option_0_of_value_1_is_unstable_Use_nightly_TypeScript_to_silence_this_error_Try_updating_w_4124", text: "Compiler option '{0}' of value '{1}' is unstable. Use nightly TypeScript to silence this error. Try updating with 'npm install -D typescript@next'."} + +var Each_declaration_of_0_1_differs_in_its_value_where_2_was_expected_but_3_was_given = &Message{code: 4125, category: CategoryError, key: "Each_declaration_of_0_1_differs_in_its_value_where_2_was_expected_but_3_was_given_4125", text: "Each declaration of '{0}.{1}' differs in its value, where '{2}' was expected but '{3}' was given."} + +var One_value_of_0_1_is_the_string_2_and_the_other_is_assumed_to_be_an_unknown_numeric_value = &Message{code: 4126, category: CategoryError, key: "One_value_of_0_1_is_the_string_2_and_the_other_is_assumed_to_be_an_unknown_numeric_value_4126", text: "One value of '{0}.{1}' is the string '{2}', and the other is assumed to be an unknown numeric value."} + +var This_member_cannot_have_an_override_modifier_because_its_name_is_dynamic = &Message{code: 4127, category: CategoryError, key: "This_member_cannot_have_an_override_modifier_because_its_name_is_dynamic_4127", text: "This member cannot have an 'override' modifier because its name is dynamic."} + +var This_member_cannot_have_a_JSDoc_comment_with_an_override_tag_because_its_name_is_dynamic = &Message{code: 4128, category: CategoryError, key: "This_member_cannot_have_a_JSDoc_comment_with_an_override_tag_because_its_name_is_dynamic_4128", text: "This member cannot have a JSDoc comment with an '@override' tag because its name is dynamic."} + +var The_current_host_does_not_support_the_0_option = &Message{code: 5001, category: CategoryError, key: "The_current_host_does_not_support_the_0_option_5001", text: "The current host does not support the '{0}' option."} + +var Cannot_find_the_common_subdirectory_path_for_the_input_files = &Message{code: 5009, category: CategoryError, key: "Cannot_find_the_common_subdirectory_path_for_the_input_files_5009", text: "Cannot find the common subdirectory path for the input files."} + +var File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0 = &Message{code: 5010, category: CategoryError, key: "File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0_5010", text: "File specification cannot end in a recursive directory wildcard ('**'): '{0}'."} + +var Cannot_read_file_0_Colon_1 = &Message{code: 5012, category: CategoryError, key: "Cannot_read_file_0_Colon_1_5012", text: "Cannot read file '{0}': {1}."} + +var Unknown_compiler_option_0 = &Message{code: 5023, category: CategoryError, key: "Unknown_compiler_option_0_5023", text: "Unknown compiler option '{0}'."} + +var Compiler_option_0_requires_a_value_of_type_1 = &Message{code: 5024, category: CategoryError, key: "Compiler_option_0_requires_a_value_of_type_1_5024", text: "Compiler option '{0}' requires a value of type {1}."} + +var Unknown_compiler_option_0_Did_you_mean_1 = &Message{code: 5025, category: CategoryError, key: "Unknown_compiler_option_0_Did_you_mean_1_5025", text: "Unknown compiler option '{0}'. Did you mean '{1}'?"} + +var Could_not_write_file_0_Colon_1 = &Message{code: 5033, category: CategoryError, key: "Could_not_write_file_0_Colon_1_5033", text: "Could not write file '{0}': {1}."} + +var Option_project_cannot_be_mixed_with_source_files_on_a_command_line = &Message{code: 5042, category: CategoryError, key: "Option_project_cannot_be_mixed_with_source_files_on_a_command_line_5042", text: "Option 'project' cannot be mixed with source files on a command line."} + +var Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES2015_or_higher = &Message{code: 5047, category: CategoryError, key: "Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES_5047", text: "Option 'isolatedModules' can only be used when either option '--module' is provided or option 'target' is 'ES2015' or higher."} + +var Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided = &Message{code: 5051, category: CategoryError, key: "Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided_5051", text: "Option '{0} can only be used when either option '--inlineSourceMap' or option '--sourceMap' is provided."} + +var Option_0_cannot_be_specified_without_specifying_option_1 = &Message{code: 5052, category: CategoryError, key: "Option_0_cannot_be_specified_without_specifying_option_1_5052", text: "Option '{0}' cannot be specified without specifying option '{1}'."} + +var Option_0_cannot_be_specified_with_option_1 = &Message{code: 5053, category: CategoryError, key: "Option_0_cannot_be_specified_with_option_1_5053", text: "Option '{0}' cannot be specified with option '{1}'."} + +var A_tsconfig_json_file_is_already_defined_at_Colon_0 = &Message{code: 5054, category: CategoryError, key: "A_tsconfig_json_file_is_already_defined_at_Colon_0_5054", text: "A 'tsconfig.json' file is already defined at: '{0}'."} + +var Cannot_write_file_0_because_it_would_overwrite_input_file = &Message{code: 5055, category: CategoryError, key: "Cannot_write_file_0_because_it_would_overwrite_input_file_5055", text: "Cannot write file '{0}' because it would overwrite input file."} + +var Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files = &Message{code: 5056, category: CategoryError, key: "Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files_5056", text: "Cannot write file '{0}' because it would be overwritten by multiple input files."} + +var Cannot_find_a_tsconfig_json_file_at_the_specified_directory_Colon_0 = &Message{code: 5057, category: CategoryError, key: "Cannot_find_a_tsconfig_json_file_at_the_specified_directory_Colon_0_5057", text: "Cannot find a tsconfig.json file at the specified directory: '{0}'."} + +var The_specified_path_does_not_exist_Colon_0 = &Message{code: 5058, category: CategoryError, key: "The_specified_path_does_not_exist_Colon_0_5058", text: "The specified path does not exist: '{0}'."} + +var Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier = &Message{code: 5059, category: CategoryError, key: "Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier_5059", text: "Invalid value for '--reactNamespace'. '{0}' is not a valid identifier."} + +var Pattern_0_can_have_at_most_one_Asterisk_character = &Message{code: 5061, category: CategoryError, key: "Pattern_0_can_have_at_most_one_Asterisk_character_5061", text: "Pattern '{0}' can have at most one '*' character."} + +var Substitution_0_in_pattern_1_can_have_at_most_one_Asterisk_character = &Message{code: 5062, category: CategoryError, key: "Substitution_0_in_pattern_1_can_have_at_most_one_Asterisk_character_5062", text: "Substitution '{0}' in pattern '{1}' can have at most one '*' character."} + +var Substitutions_for_pattern_0_should_be_an_array = &Message{code: 5063, category: CategoryError, key: "Substitutions_for_pattern_0_should_be_an_array_5063", text: "Substitutions for pattern '{0}' should be an array."} + +var Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2 = &Message{code: 5064, category: CategoryError, key: "Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2_5064", text: "Substitution '{0}' for pattern '{1}' has incorrect type, expected 'string', got '{2}'."} + +var File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0 = &Message{code: 5065, category: CategoryError, key: "File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildca_5065", text: "File specification cannot contain a parent directory ('..') that appears after a recursive directory wildcard ('**'): '{0}'."} + +var Substitutions_for_pattern_0_shouldn_t_be_an_empty_array = &Message{code: 5066, category: CategoryError, key: "Substitutions_for_pattern_0_shouldn_t_be_an_empty_array_5066", text: "Substitutions for pattern '{0}' shouldn't be an empty array."} + +var Invalid_value_for_jsxFactory_0_is_not_a_valid_identifier_or_qualified_name = &Message{code: 5067, category: CategoryError, key: "Invalid_value_for_jsxFactory_0_is_not_a_valid_identifier_or_qualified_name_5067", text: "Invalid value for 'jsxFactory'. '{0}' is not a valid identifier or qualified-name."} + +var Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript_files_Learn_more_at_https_Colon_Slash_Slashaka_ms_Slashtsconfig = &Message{code: 5068, category: CategoryError, key: "Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript__5068", text: "Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig."} + +var Option_0_cannot_be_specified_without_specifying_option_1_or_option_2 = &Message{code: 5069, category: CategoryError, key: "Option_0_cannot_be_specified_without_specifying_option_1_or_option_2_5069", text: "Option '{0}' cannot be specified without specifying option '{1}' or option '{2}'."} + +var Option_resolveJsonModule_cannot_be_specified_when_moduleResolution_is_set_to_classic = &Message{code: 5070, category: CategoryError, key: "Option_resolveJsonModule_cannot_be_specified_when_moduleResolution_is_set_to_classic_5070", text: "Option '--resolveJsonModule' cannot be specified when 'moduleResolution' is set to 'classic'."} + +var Option_resolveJsonModule_cannot_be_specified_when_module_is_set_to_none_system_or_umd = &Message{code: 5071, category: CategoryError, key: "Option_resolveJsonModule_cannot_be_specified_when_module_is_set_to_none_system_or_umd_5071", text: "Option '--resolveJsonModule' cannot be specified when 'module' is set to 'none', 'system', or 'umd'."} + +var Unknown_build_option_0 = &Message{code: 5072, category: CategoryError, key: "Unknown_build_option_0_5072", text: "Unknown build option '{0}'."} + +var Build_option_0_requires_a_value_of_type_1 = &Message{code: 5073, category: CategoryError, key: "Build_option_0_requires_a_value_of_type_1_5073", text: "Build option '{0}' requires a value of type {1}."} + +var Option_incremental_can_only_be_specified_using_tsconfig_emitting_to_single_file_or_when_option_tsBuildInfoFile_is_specified = &Message{code: 5074, category: CategoryError, key: "Option_incremental_can_only_be_specified_using_tsconfig_emitting_to_single_file_or_when_option_tsBui_5074", text: "Option '--incremental' can only be specified using tsconfig, emitting to single file or when option '--tsBuildInfoFile' is specified."} + +var X_0_is_assignable_to_the_constraint_of_type_1_but_1_could_be_instantiated_with_a_different_subtype_of_constraint_2 = &Message{code: 5075, category: CategoryError, key: "_0_is_assignable_to_the_constraint_of_type_1_but_1_could_be_instantiated_with_a_different_subtype_of_5075", text: "'{0}' is assignable to the constraint of type '{1}', but '{1}' could be instantiated with a different subtype of constraint '{2}'."} + +var X_0_and_1_operations_cannot_be_mixed_without_parentheses = &Message{code: 5076, category: CategoryError, key: "_0_and_1_operations_cannot_be_mixed_without_parentheses_5076", text: "'{0}' and '{1}' operations cannot be mixed without parentheses."} + +var Unknown_build_option_0_Did_you_mean_1 = &Message{code: 5077, category: CategoryError, key: "Unknown_build_option_0_Did_you_mean_1_5077", text: "Unknown build option '{0}'. Did you mean '{1}'?"} + +var Unknown_watch_option_0 = &Message{code: 5078, category: CategoryError, key: "Unknown_watch_option_0_5078", text: "Unknown watch option '{0}'."} + +var Unknown_watch_option_0_Did_you_mean_1 = &Message{code: 5079, category: CategoryError, key: "Unknown_watch_option_0_Did_you_mean_1_5079", text: "Unknown watch option '{0}'. Did you mean '{1}'?"} + +var Watch_option_0_requires_a_value_of_type_1 = &Message{code: 5080, category: CategoryError, key: "Watch_option_0_requires_a_value_of_type_1_5080", text: "Watch option '{0}' requires a value of type {1}."} + +var Cannot_find_a_tsconfig_json_file_at_the_current_directory_Colon_0 = &Message{code: 5081, category: CategoryError, key: "Cannot_find_a_tsconfig_json_file_at_the_current_directory_Colon_0_5081", text: "Cannot find a tsconfig.json file at the current directory: {0}."} + +var X_0_could_be_instantiated_with_an_arbitrary_type_which_could_be_unrelated_to_1 = &Message{code: 5082, category: CategoryError, key: "_0_could_be_instantiated_with_an_arbitrary_type_which_could_be_unrelated_to_1_5082", text: "'{0}' could be instantiated with an arbitrary type which could be unrelated to '{1}'."} + +var Cannot_read_file_0 = &Message{code: 5083, category: CategoryError, key: "Cannot_read_file_0_5083", text: "Cannot read file '{0}'."} + +var A_tuple_member_cannot_be_both_optional_and_rest = &Message{code: 5085, category: CategoryError, key: "A_tuple_member_cannot_be_both_optional_and_rest_5085", text: "A tuple member cannot be both optional and rest."} + +var A_labeled_tuple_element_is_declared_as_optional_with_a_question_mark_after_the_name_and_before_the_colon_rather_than_after_the_type = &Message{code: 5086, category: CategoryError, key: "A_labeled_tuple_element_is_declared_as_optional_with_a_question_mark_after_the_name_and_before_the_c_5086", text: "A labeled tuple element is declared as optional with a question mark after the name and before the colon, rather than after the type."} + +var A_labeled_tuple_element_is_declared_as_rest_with_a_before_the_name_rather_than_before_the_type = &Message{code: 5087, category: CategoryError, key: "A_labeled_tuple_element_is_declared_as_rest_with_a_before_the_name_rather_than_before_the_type_5087", text: "A labeled tuple element is declared as rest with a '...' before the name, rather than before the type."} + +var The_inferred_type_of_0_references_a_type_with_a_cyclic_structure_which_cannot_be_trivially_serialized_A_type_annotation_is_necessary = &Message{code: 5088, category: CategoryError, key: "The_inferred_type_of_0_references_a_type_with_a_cyclic_structure_which_cannot_be_trivially_serialize_5088", text: "The inferred type of '{0}' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary."} + +var Option_0_cannot_be_specified_when_option_jsx_is_1 = &Message{code: 5089, category: CategoryError, key: "Option_0_cannot_be_specified_when_option_jsx_is_1_5089", text: "Option '{0}' cannot be specified when option 'jsx' is '{1}'."} + +var Non_relative_paths_are_not_allowed_Did_you_forget_a_leading_Slash = &Message{code: 5090, category: CategoryError, key: "Non_relative_paths_are_not_allowed_Did_you_forget_a_leading_Slash_5090", text: "Non-relative paths are not allowed. Did you forget a leading './'?"} + +var Option_preserveConstEnums_cannot_be_disabled_when_0_is_enabled = &Message{code: 5091, category: CategoryError, key: "Option_preserveConstEnums_cannot_be_disabled_when_0_is_enabled_5091", text: "Option 'preserveConstEnums' cannot be disabled when '{0}' is enabled."} + +var The_root_value_of_a_0_file_must_be_an_object = &Message{code: 5092, category: CategoryError, key: "The_root_value_of_a_0_file_must_be_an_object_5092", text: "The root value of a '{0}' file must be an object."} + +var Compiler_option_0_may_only_be_used_with_build = &Message{code: 5093, category: CategoryError, key: "Compiler_option_0_may_only_be_used_with_build_5093", text: "Compiler option '--{0}' may only be used with '--build'."} + +var Compiler_option_0_may_not_be_used_with_build = &Message{code: 5094, category: CategoryError, key: "Compiler_option_0_may_not_be_used_with_build_5094", text: "Compiler option '--{0}' may not be used with '--build'."} + +var Option_0_can_only_be_used_when_module_is_set_to_preserve_commonjs_or_es2015_or_later = &Message{code: 5095, category: CategoryError, key: "Option_0_can_only_be_used_when_module_is_set_to_preserve_commonjs_or_es2015_or_later_5095", text: "Option '{0}' can only be used when 'module' is set to 'preserve', 'commonjs', or 'es2015' or later."} + +var Option_allowImportingTsExtensions_can_only_be_used_when_either_noEmit_or_emitDeclarationOnly_is_set = &Message{code: 5096, category: CategoryError, key: "Option_allowImportingTsExtensions_can_only_be_used_when_either_noEmit_or_emitDeclarationOnly_is_set_5096", text: "Option 'allowImportingTsExtensions' can only be used when either 'noEmit' or 'emitDeclarationOnly' is set."} + +var An_import_path_can_only_end_with_a_0_extension_when_allowImportingTsExtensions_is_enabled = &Message{code: 5097, category: CategoryError, key: "An_import_path_can_only_end_with_a_0_extension_when_allowImportingTsExtensions_is_enabled_5097", text: "An import path can only end with a '{0}' extension when 'allowImportingTsExtensions' is enabled."} + +var Option_0_can_only_be_used_when_moduleResolution_is_set_to_node16_nodenext_or_bundler = &Message{code: 5098, category: CategoryError, key: "Option_0_can_only_be_used_when_moduleResolution_is_set_to_node16_nodenext_or_bundler_5098", text: "Option '{0}' can only be used when 'moduleResolution' is set to 'node16', 'nodenext', or 'bundler'."} + +var Option_0_is_deprecated_and_will_stop_functioning_in_TypeScript_1_Specify_compilerOption_ignoreDeprecations_Colon_2_to_silence_this_error = &Message{code: 5101, category: CategoryError, key: "Option_0_is_deprecated_and_will_stop_functioning_in_TypeScript_1_Specify_compilerOption_ignoreDeprec_5101", text: "Option '{0}' is deprecated and will stop functioning in TypeScript {1}. Specify compilerOption '\"ignoreDeprecations\": \"{2}\"' to silence this error."} + +var Option_0_has_been_removed_Please_remove_it_from_your_configuration = &Message{code: 5102, category: CategoryError, key: "Option_0_has_been_removed_Please_remove_it_from_your_configuration_5102", text: "Option '{0}' has been removed. Please remove it from your configuration."} + +var Invalid_value_for_ignoreDeprecations = &Message{code: 5103, category: CategoryError, key: "Invalid_value_for_ignoreDeprecations_5103", text: "Invalid value for '--ignoreDeprecations'."} + +var Option_0_is_redundant_and_cannot_be_specified_with_option_1 = &Message{code: 5104, category: CategoryError, key: "Option_0_is_redundant_and_cannot_be_specified_with_option_1_5104", text: "Option '{0}' is redundant and cannot be specified with option '{1}'."} + +var Option_verbatimModuleSyntax_cannot_be_used_when_module_is_set_to_UMD_AMD_or_System = &Message{code: 5105, category: CategoryError, key: "Option_verbatimModuleSyntax_cannot_be_used_when_module_is_set_to_UMD_AMD_or_System_5105", text: "Option 'verbatimModuleSyntax' cannot be used when 'module' is set to 'UMD', 'AMD', or 'System'."} + +var Use_0_instead = &Message{code: 5106, category: CategoryMessage, key: "Use_0_instead_5106", text: "Use '{0}' instead."} + +var Option_0_1_is_deprecated_and_will_stop_functioning_in_TypeScript_2_Specify_compilerOption_ignoreDeprecations_Colon_3_to_silence_this_error = &Message{code: 5107, category: CategoryError, key: "Option_0_1_is_deprecated_and_will_stop_functioning_in_TypeScript_2_Specify_compilerOption_ignoreDepr_5107", text: "Option '{0}={1}' is deprecated and will stop functioning in TypeScript {2}. Specify compilerOption '\"ignoreDeprecations\": \"{3}\"' to silence this error."} + +var Option_0_1_has_been_removed_Please_remove_it_from_your_configuration = &Message{code: 5108, category: CategoryError, key: "Option_0_1_has_been_removed_Please_remove_it_from_your_configuration_5108", text: "Option '{0}={1}' has been removed. Please remove it from your configuration."} + +var Option_moduleResolution_must_be_set_to_0_or_left_unspecified_when_option_module_is_set_to_1 = &Message{code: 5109, category: CategoryError, key: "Option_moduleResolution_must_be_set_to_0_or_left_unspecified_when_option_module_is_set_to_1_5109", text: "Option 'moduleResolution' must be set to '{0}' (or left unspecified) when option 'module' is set to '{1}'."} + +var Option_module_must_be_set_to_0_when_option_moduleResolution_is_set_to_1 = &Message{code: 5110, category: CategoryError, key: "Option_module_must_be_set_to_0_when_option_moduleResolution_is_set_to_1_5110", text: "Option 'module' must be set to '{0}' when option 'moduleResolution' is set to '{1}'."} + +var Generates_a_sourcemap_for_each_corresponding_d_ts_file = &Message{code: 6000, category: CategoryMessage, key: "Generates_a_sourcemap_for_each_corresponding_d_ts_file_6000", text: "Generates a sourcemap for each corresponding '.d.ts' file."} + +var Concatenate_and_emit_output_to_single_file = &Message{code: 6001, category: CategoryMessage, key: "Concatenate_and_emit_output_to_single_file_6001", text: "Concatenate and emit output to single file."} + +var Generates_corresponding_d_ts_file = &Message{code: 6002, category: CategoryMessage, key: "Generates_corresponding_d_ts_file_6002", text: "Generates corresponding '.d.ts' file."} + +var Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations = &Message{code: 6004, category: CategoryMessage, key: "Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations_6004", text: "Specify the location where debugger should locate TypeScript files instead of source locations."} + +var Watch_input_files = &Message{code: 6005, category: CategoryMessage, key: "Watch_input_files_6005", text: "Watch input files."} + +var Redirect_output_structure_to_the_directory = &Message{code: 6006, category: CategoryMessage, key: "Redirect_output_structure_to_the_directory_6006", text: "Redirect output structure to the directory."} + +var Do_not_erase_const_enum_declarations_in_generated_code = &Message{code: 6007, category: CategoryMessage, key: "Do_not_erase_const_enum_declarations_in_generated_code_6007", text: "Do not erase const enum declarations in generated code."} + +var Do_not_emit_outputs_if_any_errors_were_reported = &Message{code: 6008, category: CategoryMessage, key: "Do_not_emit_outputs_if_any_errors_were_reported_6008", text: "Do not emit outputs if any errors were reported."} + +var Do_not_emit_comments_to_output = &Message{code: 6009, category: CategoryMessage, key: "Do_not_emit_comments_to_output_6009", text: "Do not emit comments to output."} + +var Do_not_emit_outputs = &Message{code: 6010, category: CategoryMessage, key: "Do_not_emit_outputs_6010", text: "Do not emit outputs."} + +var Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking = &Message{code: 6011, category: CategoryMessage, key: "Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typech_6011", text: "Allow default imports from modules with no default export. This does not affect code emit, just typechecking."} + +var Skip_type_checking_of_declaration_files = &Message{code: 6012, category: CategoryMessage, key: "Skip_type_checking_of_declaration_files_6012", text: "Skip type checking of declaration files."} + +var Do_not_resolve_the_real_path_of_symlinks = &Message{code: 6013, category: CategoryMessage, key: "Do_not_resolve_the_real_path_of_symlinks_6013", text: "Do not resolve the real path of symlinks."} + +var Only_emit_d_ts_declaration_files = &Message{code: 6014, category: CategoryMessage, key: "Only_emit_d_ts_declaration_files_6014", text: "Only emit '.d.ts' declaration files."} + +var Specify_ECMAScript_target_version = &Message{code: 6015, category: CategoryMessage, key: "Specify_ECMAScript_target_version_6015", text: "Specify ECMAScript target version."} + +var Specify_module_code_generation = &Message{code: 6016, category: CategoryMessage, key: "Specify_module_code_generation_6016", text: "Specify module code generation."} + +var Print_this_message = &Message{code: 6017, category: CategoryMessage, key: "Print_this_message_6017", text: "Print this message."} + +var Print_the_compiler_s_version = &Message{code: 6019, category: CategoryMessage, key: "Print_the_compiler_s_version_6019", text: "Print the compiler's version."} + +var Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json = &Message{code: 6020, category: CategoryMessage, key: "Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json_6020", text: "Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'."} + +var Syntax_Colon_0 = &Message{code: 6023, category: CategoryMessage, key: "Syntax_Colon_0_6023", text: "Syntax: {0}"} + +var X_options = &Message{code: 6024, category: CategoryMessage, key: "options_6024", text: "options"} + +var X_file = &Message{code: 6025, category: CategoryMessage, key: "file_6025", text: "file"} + +var Examples_Colon_0 = &Message{code: 6026, category: CategoryMessage, key: "Examples_Colon_0_6026", text: "Examples: {0}"} + +var Options_Colon = &Message{code: 6027, category: CategoryMessage, key: "Options_Colon_6027", text: "Options:"} + +var Version_0 = &Message{code: 6029, category: CategoryMessage, key: "Version_0_6029", text: "Version {0}"} + +var Insert_command_line_options_and_files_from_a_file = &Message{code: 6030, category: CategoryMessage, key: "Insert_command_line_options_and_files_from_a_file_6030", text: "Insert command line options and files from a file."} + +var Starting_compilation_in_watch_mode = &Message{code: 6031, category: CategoryMessage, key: "Starting_compilation_in_watch_mode_6031", text: "Starting compilation in watch mode..."} + +var File_change_detected_Starting_incremental_compilation = &Message{code: 6032, category: CategoryMessage, key: "File_change_detected_Starting_incremental_compilation_6032", text: "File change detected. Starting incremental compilation..."} + +var KIND = &Message{code: 6034, category: CategoryMessage, key: "KIND_6034", text: "KIND"} + +var FILE = &Message{code: 6035, category: CategoryMessage, key: "FILE_6035", text: "FILE"} + +var VERSION = &Message{code: 6036, category: CategoryMessage, key: "VERSION_6036", text: "VERSION"} + +var LOCATION = &Message{code: 6037, category: CategoryMessage, key: "LOCATION_6037", text: "LOCATION"} + +var DIRECTORY = &Message{code: 6038, category: CategoryMessage, key: "DIRECTORY_6038", text: "DIRECTORY"} + +var STRATEGY = &Message{code: 6039, category: CategoryMessage, key: "STRATEGY_6039", text: "STRATEGY"} + +var FILE_OR_DIRECTORY = &Message{code: 6040, category: CategoryMessage, key: "FILE_OR_DIRECTORY_6040", text: "FILE OR DIRECTORY"} + +var Errors_Files = &Message{code: 6041, category: CategoryMessage, key: "Errors_Files_6041", text: "Errors Files"} + +var Generates_corresponding_map_file = &Message{code: 6043, category: CategoryMessage, key: "Generates_corresponding_map_file_6043", text: "Generates corresponding '.map' file."} + +var Compiler_option_0_expects_an_argument = &Message{code: 6044, category: CategoryError, key: "Compiler_option_0_expects_an_argument_6044", text: "Compiler option '{0}' expects an argument."} + +var Unterminated_quoted_string_in_response_file_0 = &Message{code: 6045, category: CategoryError, key: "Unterminated_quoted_string_in_response_file_0_6045", text: "Unterminated quoted string in response file '{0}'."} + +var Argument_for_0_option_must_be_Colon_1 = &Message{code: 6046, category: CategoryError, key: "Argument_for_0_option_must_be_Colon_1_6046", text: "Argument for '{0}' option must be: {1}."} + +var Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1 = &Message{code: 6048, category: CategoryError, key: "Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1_6048", text: "Locale must be of the form or -. For example '{0}' or '{1}'."} + +var Unable_to_open_file_0 = &Message{code: 6050, category: CategoryError, key: "Unable_to_open_file_0_6050", text: "Unable to open file '{0}'."} + +var Corrupted_locale_file_0 = &Message{code: 6051, category: CategoryError, key: "Corrupted_locale_file_0_6051", text: "Corrupted locale file {0}."} + +var Raise_error_on_expressions_and_declarations_with_an_implied_any_type = &Message{code: 6052, category: CategoryMessage, key: "Raise_error_on_expressions_and_declarations_with_an_implied_any_type_6052", text: "Raise error on expressions and declarations with an implied 'any' type."} + +var File_0_not_found = &Message{code: 6053, category: CategoryError, key: "File_0_not_found_6053", text: "File '{0}' not found."} + +var File_0_has_an_unsupported_extension_The_only_supported_extensions_are_1 = &Message{code: 6054, category: CategoryError, key: "File_0_has_an_unsupported_extension_The_only_supported_extensions_are_1_6054", text: "File '{0}' has an unsupported extension. The only supported extensions are {1}."} + +var Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures = &Message{code: 6055, category: CategoryMessage, key: "Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures_6055", text: "Suppress noImplicitAny errors for indexing objects lacking index signatures."} + +var Do_not_emit_declarations_for_code_that_has_an_internal_annotation = &Message{code: 6056, category: CategoryMessage, key: "Do_not_emit_declarations_for_code_that_has_an_internal_annotation_6056", text: "Do not emit declarations for code that has an '@internal' annotation."} + +var Specify_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir = &Message{code: 6058, category: CategoryMessage, key: "Specify_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir_6058", text: "Specify the root directory of input files. Use to control the output directory structure with --outDir."} + +var File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files = &Message{code: 6059, category: CategoryError, key: "File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files_6059", text: "File '{0}' is not under 'rootDir' '{1}'. 'rootDir' is expected to contain all source files."} + +var Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix = &Message{code: 6060, category: CategoryMessage, key: "Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix_6060", text: "Specify the end of line sequence to be used when emitting files: 'CRLF' (dos) or 'LF' (unix)."} + +var NEWLINE = &Message{code: 6061, category: CategoryMessage, key: "NEWLINE_6061", text: "NEWLINE"} + +var Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_null_on_command_line = &Message{code: 6064, category: CategoryError, key: "Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_null_on_command_line_6064", text: "Option '{0}' can only be specified in 'tsconfig.json' file or set to 'null' on command line."} + +var Enables_experimental_support_for_ES7_decorators = &Message{code: 6065, category: CategoryMessage, key: "Enables_experimental_support_for_ES7_decorators_6065", text: "Enables experimental support for ES7 decorators."} + +var Enables_experimental_support_for_emitting_type_metadata_for_decorators = &Message{code: 6066, category: CategoryMessage, key: "Enables_experimental_support_for_emitting_type_metadata_for_decorators_6066", text: "Enables experimental support for emitting type metadata for decorators."} + +var Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file = &Message{code: 6070, category: CategoryMessage, key: "Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file_6070", text: "Initializes a TypeScript project and creates a tsconfig.json file."} + +var Successfully_created_a_tsconfig_json_file = &Message{code: 6071, category: CategoryMessage, key: "Successfully_created_a_tsconfig_json_file_6071", text: "Successfully created a tsconfig.json file."} + +var Suppress_excess_property_checks_for_object_literals = &Message{code: 6072, category: CategoryMessage, key: "Suppress_excess_property_checks_for_object_literals_6072", text: "Suppress excess property checks for object literals."} + +var Stylize_errors_and_messages_using_color_and_context_experimental = &Message{code: 6073, category: CategoryMessage, key: "Stylize_errors_and_messages_using_color_and_context_experimental_6073", text: "Stylize errors and messages using color and context (experimental)."} + +var Do_not_report_errors_on_unused_labels = &Message{code: 6074, category: CategoryMessage, key: "Do_not_report_errors_on_unused_labels_6074", text: "Do not report errors on unused labels."} + +var Report_error_when_not_all_code_paths_in_function_return_a_value = &Message{code: 6075, category: CategoryMessage, key: "Report_error_when_not_all_code_paths_in_function_return_a_value_6075", text: "Report error when not all code paths in function return a value."} + +var Report_errors_for_fallthrough_cases_in_switch_statement = &Message{code: 6076, category: CategoryMessage, key: "Report_errors_for_fallthrough_cases_in_switch_statement_6076", text: "Report errors for fallthrough cases in switch statement."} + +var Do_not_report_errors_on_unreachable_code = &Message{code: 6077, category: CategoryMessage, key: "Do_not_report_errors_on_unreachable_code_6077", text: "Do not report errors on unreachable code."} + +var Disallow_inconsistently_cased_references_to_the_same_file = &Message{code: 6078, category: CategoryMessage, key: "Disallow_inconsistently_cased_references_to_the_same_file_6078", text: "Disallow inconsistently-cased references to the same file."} + +var Specify_library_files_to_be_included_in_the_compilation = &Message{code: 6079, category: CategoryMessage, key: "Specify_library_files_to_be_included_in_the_compilation_6079", text: "Specify library files to be included in the compilation."} + +var Specify_JSX_code_generation = &Message{code: 6080, category: CategoryMessage, key: "Specify_JSX_code_generation_6080", text: "Specify JSX code generation."} + +var Only_amd_and_system_modules_are_supported_alongside_0 = &Message{code: 6082, category: CategoryError, key: "Only_amd_and_system_modules_are_supported_alongside_0_6082", text: "Only 'amd' and 'system' modules are supported alongside --{0}."} + +var Base_directory_to_resolve_non_absolute_module_names = &Message{code: 6083, category: CategoryMessage, key: "Base_directory_to_resolve_non_absolute_module_names_6083", text: "Base directory to resolve non-absolute module names."} + +var Deprecated_Use_jsxFactory_instead_Specify_the_object_invoked_for_createElement_when_targeting_react_JSX_emit = &Message{code: 6084, category: CategoryMessage, key: "Deprecated_Use_jsxFactory_instead_Specify_the_object_invoked_for_createElement_when_targeting_react__6084", text: "[Deprecated] Use '--jsxFactory' instead. Specify the object invoked for createElement when targeting 'react' JSX emit"} + +var Enable_tracing_of_the_name_resolution_process = &Message{code: 6085, category: CategoryMessage, key: "Enable_tracing_of_the_name_resolution_process_6085", text: "Enable tracing of the name resolution process."} + +var Resolving_module_0_from_1 = &Message{code: 6086, category: CategoryMessage, key: "Resolving_module_0_from_1_6086", text: "======== Resolving module '{0}' from '{1}'. ========"} + +var Explicitly_specified_module_resolution_kind_Colon_0 = &Message{code: 6087, category: CategoryMessage, key: "Explicitly_specified_module_resolution_kind_Colon_0_6087", text: "Explicitly specified module resolution kind: '{0}'."} + +var Module_resolution_kind_is_not_specified_using_0 = &Message{code: 6088, category: CategoryMessage, key: "Module_resolution_kind_is_not_specified_using_0_6088", text: "Module resolution kind is not specified, using '{0}'."} + +var Module_name_0_was_successfully_resolved_to_1 = &Message{code: 6089, category: CategoryMessage, key: "Module_name_0_was_successfully_resolved_to_1_6089", text: "======== Module name '{0}' was successfully resolved to '{1}'. ========"} + +var Module_name_0_was_not_resolved = &Message{code: 6090, category: CategoryMessage, key: "Module_name_0_was_not_resolved_6090", text: "======== Module name '{0}' was not resolved. ========"} + +var X_paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0 = &Message{code: 6091, category: CategoryMessage, key: "paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0_6091", text: "'paths' option is specified, looking for a pattern to match module name '{0}'."} + +var Module_name_0_matched_pattern_1 = &Message{code: 6092, category: CategoryMessage, key: "Module_name_0_matched_pattern_1_6092", text: "Module name '{0}', matched pattern '{1}'."} + +var Trying_substitution_0_candidate_module_location_Colon_1 = &Message{code: 6093, category: CategoryMessage, key: "Trying_substitution_0_candidate_module_location_Colon_1_6093", text: "Trying substitution '{0}', candidate module location: '{1}'."} + +var Resolving_module_name_0_relative_to_base_url_1_2 = &Message{code: 6094, category: CategoryMessage, key: "Resolving_module_name_0_relative_to_base_url_1_2_6094", text: "Resolving module name '{0}' relative to base url '{1}' - '{2}'."} + +var Loading_module_as_file_Slash_folder_candidate_module_location_0_target_file_types_Colon_1 = &Message{code: 6095, category: CategoryMessage, key: "Loading_module_as_file_Slash_folder_candidate_module_location_0_target_file_types_Colon_1_6095", text: "Loading module as file / folder, candidate module location '{0}', target file types: {1}."} + +var File_0_does_not_exist = &Message{code: 6096, category: CategoryMessage, key: "File_0_does_not_exist_6096", text: "File '{0}' does not exist."} + +var File_0_exists_use_it_as_a_name_resolution_result = &Message{code: 6097, category: CategoryMessage, key: "File_0_exists_use_it_as_a_name_resolution_result_6097", text: "File '{0}' exists - use it as a name resolution result."} + +var Loading_module_0_from_node_modules_folder_target_file_types_Colon_1 = &Message{code: 6098, category: CategoryMessage, key: "Loading_module_0_from_node_modules_folder_target_file_types_Colon_1_6098", text: "Loading module '{0}' from 'node_modules' folder, target file types: {1}."} + +var Found_package_json_at_0 = &Message{code: 6099, category: CategoryMessage, key: "Found_package_json_at_0_6099", text: "Found 'package.json' at '{0}'."} + +var X_package_json_does_not_have_a_0_field = &Message{code: 6100, category: CategoryMessage, key: "package_json_does_not_have_a_0_field_6100", text: "'package.json' does not have a '{0}' field."} + +var X_package_json_has_0_field_1_that_references_2 = &Message{code: 6101, category: CategoryMessage, key: "package_json_has_0_field_1_that_references_2_6101", text: "'package.json' has '{0}' field '{1}' that references '{2}'."} + +var Allow_javascript_files_to_be_compiled = &Message{code: 6102, category: CategoryMessage, key: "Allow_javascript_files_to_be_compiled_6102", text: "Allow javascript files to be compiled."} + +var Checking_if_0_is_the_longest_matching_prefix_for_1_2 = &Message{code: 6104, category: CategoryMessage, key: "Checking_if_0_is_the_longest_matching_prefix_for_1_2_6104", text: "Checking if '{0}' is the longest matching prefix for '{1}' - '{2}'."} + +var Expected_type_of_0_field_in_package_json_to_be_1_got_2 = &Message{code: 6105, category: CategoryMessage, key: "Expected_type_of_0_field_in_package_json_to_be_1_got_2_6105", text: "Expected type of '{0}' field in 'package.json' to be '{1}', got '{2}'."} + +var X_baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1 = &Message{code: 6106, category: CategoryMessage, key: "baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1_6106", text: "'baseUrl' option is set to '{0}', using this value to resolve non-relative module name '{1}'."} + +var X_rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0 = &Message{code: 6107, category: CategoryMessage, key: "rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0_6107", text: "'rootDirs' option is set, using it to resolve relative module name '{0}'."} + +var Longest_matching_prefix_for_0_is_1 = &Message{code: 6108, category: CategoryMessage, key: "Longest_matching_prefix_for_0_is_1_6108", text: "Longest matching prefix for '{0}' is '{1}'."} + +var Loading_0_from_the_root_dir_1_candidate_location_2 = &Message{code: 6109, category: CategoryMessage, key: "Loading_0_from_the_root_dir_1_candidate_location_2_6109", text: "Loading '{0}' from the root dir '{1}', candidate location '{2}'."} + +var Trying_other_entries_in_rootDirs = &Message{code: 6110, category: CategoryMessage, key: "Trying_other_entries_in_rootDirs_6110", text: "Trying other entries in 'rootDirs'."} + +var Module_resolution_using_rootDirs_has_failed = &Message{code: 6111, category: CategoryMessage, key: "Module_resolution_using_rootDirs_has_failed_6111", text: "Module resolution using 'rootDirs' has failed."} + +var Do_not_emit_use_strict_directives_in_module_output = &Message{code: 6112, category: CategoryMessage, key: "Do_not_emit_use_strict_directives_in_module_output_6112", text: "Do not emit 'use strict' directives in module output."} + +var Enable_strict_null_checks = &Message{code: 6113, category: CategoryMessage, key: "Enable_strict_null_checks_6113", text: "Enable strict null checks."} + +var Unknown_option_excludes_Did_you_mean_exclude = &Message{code: 6114, category: CategoryError, key: "Unknown_option_excludes_Did_you_mean_exclude_6114", text: "Unknown option 'excludes'. Did you mean 'exclude'?"} + +var Raise_error_on_this_expressions_with_an_implied_any_type = &Message{code: 6115, category: CategoryMessage, key: "Raise_error_on_this_expressions_with_an_implied_any_type_6115", text: "Raise error on 'this' expressions with an implied 'any' type."} + +var Resolving_type_reference_directive_0_containing_file_1_root_directory_2 = &Message{code: 6116, category: CategoryMessage, key: "Resolving_type_reference_directive_0_containing_file_1_root_directory_2_6116", text: "======== Resolving type reference directive '{0}', containing file '{1}', root directory '{2}'. ========"} + +var Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2 = &Message{code: 6119, category: CategoryMessage, key: "Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2_6119", text: "======== Type reference directive '{0}' was successfully resolved to '{1}', primary: {2}. ========"} + +var Type_reference_directive_0_was_not_resolved = &Message{code: 6120, category: CategoryMessage, key: "Type_reference_directive_0_was_not_resolved_6120", text: "======== Type reference directive '{0}' was not resolved. ========"} + +var Resolving_with_primary_search_path_0 = &Message{code: 6121, category: CategoryMessage, key: "Resolving_with_primary_search_path_0_6121", text: "Resolving with primary search path '{0}'."} + +var Root_directory_cannot_be_determined_skipping_primary_search_paths = &Message{code: 6122, category: CategoryMessage, key: "Root_directory_cannot_be_determined_skipping_primary_search_paths_6122", text: "Root directory cannot be determined, skipping primary search paths."} + +var Resolving_type_reference_directive_0_containing_file_1_root_directory_not_set = &Message{code: 6123, category: CategoryMessage, key: "Resolving_type_reference_directive_0_containing_file_1_root_directory_not_set_6123", text: "======== Resolving type reference directive '{0}', containing file '{1}', root directory not set. ========"} + +var Type_declaration_files_to_be_included_in_compilation = &Message{code: 6124, category: CategoryMessage, key: "Type_declaration_files_to_be_included_in_compilation_6124", text: "Type declaration files to be included in compilation."} + +var Looking_up_in_node_modules_folder_initial_location_0 = &Message{code: 6125, category: CategoryMessage, key: "Looking_up_in_node_modules_folder_initial_location_0_6125", text: "Looking up in 'node_modules' folder, initial location '{0}'."} + +var Containing_file_is_not_specified_and_root_directory_cannot_be_determined_skipping_lookup_in_node_modules_folder = &Message{code: 6126, category: CategoryMessage, key: "Containing_file_is_not_specified_and_root_directory_cannot_be_determined_skipping_lookup_in_node_mod_6126", text: "Containing file is not specified and root directory cannot be determined, skipping lookup in 'node_modules' folder."} + +var Resolving_type_reference_directive_0_containing_file_not_set_root_directory_1 = &Message{code: 6127, category: CategoryMessage, key: "Resolving_type_reference_directive_0_containing_file_not_set_root_directory_1_6127", text: "======== Resolving type reference directive '{0}', containing file not set, root directory '{1}'. ========"} + +var Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set = &Message{code: 6128, category: CategoryMessage, key: "Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set_6128", text: "======== Resolving type reference directive '{0}', containing file not set, root directory not set. ========"} + +var Resolving_real_path_for_0_result_1 = &Message{code: 6130, category: CategoryMessage, key: "Resolving_real_path_for_0_result_1_6130", text: "Resolving real path for '{0}', result '{1}'."} + +var Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system = &Message{code: 6131, category: CategoryError, key: "Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system_6131", text: "Cannot compile modules using option '{0}' unless the '--module' flag is 'amd' or 'system'."} + +var File_name_0_has_a_1_extension_stripping_it = &Message{code: 6132, category: CategoryMessage, key: "File_name_0_has_a_1_extension_stripping_it_6132", text: "File name '{0}' has a '{1}' extension - stripping it."} + +var X_0_is_declared_but_its_value_is_never_read = &Message{code: 6133, category: CategoryError, key: "_0_is_declared_but_its_value_is_never_read_6133", text: "'{0}' is declared but its value is never read.", reportsUnnecessary: true} + +var Report_errors_on_unused_locals = &Message{code: 6134, category: CategoryMessage, key: "Report_errors_on_unused_locals_6134", text: "Report errors on unused locals."} + +var Report_errors_on_unused_parameters = &Message{code: 6135, category: CategoryMessage, key: "Report_errors_on_unused_parameters_6135", text: "Report errors on unused parameters."} + +var The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files = &Message{code: 6136, category: CategoryMessage, key: "The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files_6136", text: "The maximum dependency depth to search under node_modules and load JavaScript files."} + +var Cannot_import_type_declaration_files_Consider_importing_0_instead_of_1 = &Message{code: 6137, category: CategoryError, key: "Cannot_import_type_declaration_files_Consider_importing_0_instead_of_1_6137", text: "Cannot import type declaration files. Consider importing '{0}' instead of '{1}'."} + +var Property_0_is_declared_but_its_value_is_never_read = &Message{code: 6138, category: CategoryError, key: "Property_0_is_declared_but_its_value_is_never_read_6138", text: "Property '{0}' is declared but its value is never read.", reportsUnnecessary: true} + +var Import_emit_helpers_from_tslib = &Message{code: 6139, category: CategoryMessage, key: "Import_emit_helpers_from_tslib_6139", text: "Import emit helpers from 'tslib'."} + +var Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using_cache_location_2 = &Message{code: 6140, category: CategoryError, key: "Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using__6140", text: "Auto discovery for typings is enabled in project '{0}'. Running extra resolution pass for module '{1}' using cache location '{2}'."} + +var Parse_in_strict_mode_and_emit_use_strict_for_each_source_file = &Message{code: 6141, category: CategoryMessage, key: "Parse_in_strict_mode_and_emit_use_strict_for_each_source_file_6141", text: "Parse in strict mode and emit \"use strict\" for each source file."} + +var Module_0_was_resolved_to_1_but_jsx_is_not_set = &Message{code: 6142, category: CategoryError, key: "Module_0_was_resolved_to_1_but_jsx_is_not_set_6142", text: "Module '{0}' was resolved to '{1}', but '--jsx' is not set."} + +var Module_0_was_resolved_as_locally_declared_ambient_module_in_file_1 = &Message{code: 6144, category: CategoryMessage, key: "Module_0_was_resolved_as_locally_declared_ambient_module_in_file_1_6144", text: "Module '{0}' was resolved as locally declared ambient module in file '{1}'."} + +var Specify_the_JSX_factory_function_to_use_when_targeting_react_JSX_emit_e_g_React_createElement_or_h = &Message{code: 6146, category: CategoryMessage, key: "Specify_the_JSX_factory_function_to_use_when_targeting_react_JSX_emit_e_g_React_createElement_or_h_6146", text: "Specify the JSX factory function to use when targeting 'react' JSX emit, e.g. 'React.createElement' or 'h'."} + +var Resolution_for_module_0_was_found_in_cache_from_location_1 = &Message{code: 6147, category: CategoryMessage, key: "Resolution_for_module_0_was_found_in_cache_from_location_1_6147", text: "Resolution for module '{0}' was found in cache from location '{1}'."} + +var Directory_0_does_not_exist_skipping_all_lookups_in_it = &Message{code: 6148, category: CategoryMessage, key: "Directory_0_does_not_exist_skipping_all_lookups_in_it_6148", text: "Directory '{0}' does not exist, skipping all lookups in it."} + +var Show_diagnostic_information = &Message{code: 6149, category: CategoryMessage, key: "Show_diagnostic_information_6149", text: "Show diagnostic information."} + +var Show_verbose_diagnostic_information = &Message{code: 6150, category: CategoryMessage, key: "Show_verbose_diagnostic_information_6150", text: "Show verbose diagnostic information."} + +var Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file = &Message{code: 6151, category: CategoryMessage, key: "Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file_6151", text: "Emit a single file with source maps instead of having a separate file."} + +var Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap_to_be_set = &Message{code: 6152, category: CategoryMessage, key: "Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap__6152", text: "Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set."} + +var Transpile_each_file_as_a_separate_module_similar_to_ts_transpileModule = &Message{code: 6153, category: CategoryMessage, key: "Transpile_each_file_as_a_separate_module_similar_to_ts_transpileModule_6153", text: "Transpile each file as a separate module (similar to 'ts.transpileModule')."} + +var Print_names_of_generated_files_part_of_the_compilation = &Message{code: 6154, category: CategoryMessage, key: "Print_names_of_generated_files_part_of_the_compilation_6154", text: "Print names of generated files part of the compilation."} + +var Print_names_of_files_part_of_the_compilation = &Message{code: 6155, category: CategoryMessage, key: "Print_names_of_files_part_of_the_compilation_6155", text: "Print names of files part of the compilation."} + +var The_locale_used_when_displaying_messages_to_the_user_e_g_en_us = &Message{code: 6156, category: CategoryMessage, key: "The_locale_used_when_displaying_messages_to_the_user_e_g_en_us_6156", text: "The locale used when displaying messages to the user (e.g. 'en-us')"} + +var Do_not_generate_custom_helper_functions_like_extends_in_compiled_output = &Message{code: 6157, category: CategoryMessage, key: "Do_not_generate_custom_helper_functions_like_extends_in_compiled_output_6157", text: "Do not generate custom helper functions like '__extends' in compiled output."} + +var Do_not_include_the_default_library_file_lib_d_ts = &Message{code: 6158, category: CategoryMessage, key: "Do_not_include_the_default_library_file_lib_d_ts_6158", text: "Do not include the default library file (lib.d.ts)."} + +var Do_not_add_triple_slash_references_or_imported_modules_to_the_list_of_compiled_files = &Message{code: 6159, category: CategoryMessage, key: "Do_not_add_triple_slash_references_or_imported_modules_to_the_list_of_compiled_files_6159", text: "Do not add triple-slash references or imported modules to the list of compiled files."} + +var Deprecated_Use_skipLibCheck_instead_Skip_type_checking_of_default_library_declaration_files = &Message{code: 6160, category: CategoryMessage, key: "Deprecated_Use_skipLibCheck_instead_Skip_type_checking_of_default_library_declaration_files_6160", text: "[Deprecated] Use '--skipLibCheck' instead. Skip type checking of default library declaration files."} + +var List_of_folders_to_include_type_definitions_from = &Message{code: 6161, category: CategoryMessage, key: "List_of_folders_to_include_type_definitions_from_6161", text: "List of folders to include type definitions from."} + +var Disable_size_limitations_on_JavaScript_projects = &Message{code: 6162, category: CategoryMessage, key: "Disable_size_limitations_on_JavaScript_projects_6162", text: "Disable size limitations on JavaScript projects."} + +var The_character_set_of_the_input_files = &Message{code: 6163, category: CategoryMessage, key: "The_character_set_of_the_input_files_6163", text: "The character set of the input files."} + +var Skipping_module_0_that_looks_like_an_absolute_URI_target_file_types_Colon_1 = &Message{code: 6164, category: CategoryMessage, key: "Skipping_module_0_that_looks_like_an_absolute_URI_target_file_types_Colon_1_6164", text: "Skipping module '{0}' that looks like an absolute URI, target file types: {1}."} + +var Do_not_truncate_error_messages = &Message{code: 6165, category: CategoryMessage, key: "Do_not_truncate_error_messages_6165", text: "Do not truncate error messages."} + +var Output_directory_for_generated_declaration_files = &Message{code: 6166, category: CategoryMessage, key: "Output_directory_for_generated_declaration_files_6166", text: "Output directory for generated declaration files."} + +var A_series_of_entries_which_re_map_imports_to_lookup_locations_relative_to_the_baseUrl = &Message{code: 6167, category: CategoryMessage, key: "A_series_of_entries_which_re_map_imports_to_lookup_locations_relative_to_the_baseUrl_6167", text: "A series of entries which re-map imports to lookup locations relative to the 'baseUrl'."} + +var List_of_root_folders_whose_combined_content_represents_the_structure_of_the_project_at_runtime = &Message{code: 6168, category: CategoryMessage, key: "List_of_root_folders_whose_combined_content_represents_the_structure_of_the_project_at_runtime_6168", text: "List of root folders whose combined content represents the structure of the project at runtime."} + +var Show_all_compiler_options = &Message{code: 6169, category: CategoryMessage, key: "Show_all_compiler_options_6169", text: "Show all compiler options."} + +var Deprecated_Use_outFile_instead_Concatenate_and_emit_output_to_single_file = &Message{code: 6170, category: CategoryMessage, key: "Deprecated_Use_outFile_instead_Concatenate_and_emit_output_to_single_file_6170", text: "[Deprecated] Use '--outFile' instead. Concatenate and emit output to single file"} + +var Command_line_Options = &Message{code: 6171, category: CategoryMessage, key: "Command_line_Options_6171", text: "Command-line Options"} + +var Provide_full_support_for_iterables_in_for_of_spread_and_destructuring_when_targeting_ES5 = &Message{code: 6179, category: CategoryMessage, key: "Provide_full_support_for_iterables_in_for_of_spread_and_destructuring_when_targeting_ES5_6179", text: "Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5'."} + +var Enable_all_strict_type_checking_options = &Message{code: 6180, category: CategoryMessage, key: "Enable_all_strict_type_checking_options_6180", text: "Enable all strict type-checking options."} + +var Scoped_package_detected_looking_in_0 = &Message{code: 6182, category: CategoryMessage, key: "Scoped_package_detected_looking_in_0_6182", text: "Scoped package detected, looking in '{0}'"} + +var Reusing_resolution_of_module_0_from_1_of_old_program_it_was_successfully_resolved_to_2 = &Message{code: 6183, category: CategoryMessage, key: "Reusing_resolution_of_module_0_from_1_of_old_program_it_was_successfully_resolved_to_2_6183", text: "Reusing resolution of module '{0}' from '{1}' of old program, it was successfully resolved to '{2}'."} + +var Reusing_resolution_of_module_0_from_1_of_old_program_it_was_successfully_resolved_to_2_with_Package_ID_3 = &Message{code: 6184, category: CategoryMessage, key: "Reusing_resolution_of_module_0_from_1_of_old_program_it_was_successfully_resolved_to_2_with_Package__6184", text: "Reusing resolution of module '{0}' from '{1}' of old program, it was successfully resolved to '{2}' with Package ID '{3}'."} + +var Enable_strict_checking_of_function_types = &Message{code: 6186, category: CategoryMessage, key: "Enable_strict_checking_of_function_types_6186", text: "Enable strict checking of function types."} + +var Enable_strict_checking_of_property_initialization_in_classes = &Message{code: 6187, category: CategoryMessage, key: "Enable_strict_checking_of_property_initialization_in_classes_6187", text: "Enable strict checking of property initialization in classes."} + +var Numeric_separators_are_not_allowed_here = &Message{code: 6188, category: CategoryError, key: "Numeric_separators_are_not_allowed_here_6188", text: "Numeric separators are not allowed here."} + +var Multiple_consecutive_numeric_separators_are_not_permitted = &Message{code: 6189, category: CategoryError, key: "Multiple_consecutive_numeric_separators_are_not_permitted_6189", text: "Multiple consecutive numeric separators are not permitted."} + +var Whether_to_keep_outdated_console_output_in_watch_mode_instead_of_clearing_the_screen = &Message{code: 6191, category: CategoryMessage, key: "Whether_to_keep_outdated_console_output_in_watch_mode_instead_of_clearing_the_screen_6191", text: "Whether to keep outdated console output in watch mode instead of clearing the screen."} + +var All_imports_in_import_declaration_are_unused = &Message{code: 6192, category: CategoryError, key: "All_imports_in_import_declaration_are_unused_6192", text: "All imports in import declaration are unused.", reportsUnnecessary: true} + +var Found_1_error_Watching_for_file_changes = &Message{code: 6193, category: CategoryMessage, key: "Found_1_error_Watching_for_file_changes_6193", text: "Found 1 error. Watching for file changes."} + +var Found_0_errors_Watching_for_file_changes = &Message{code: 6194, category: CategoryMessage, key: "Found_0_errors_Watching_for_file_changes_6194", text: "Found {0} errors. Watching for file changes."} + +var Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols = &Message{code: 6195, category: CategoryMessage, key: "Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195", text: "Resolve 'keyof' to string valued property names only (no numbers or symbols)."} + +var X_0_is_declared_but_never_used = &Message{code: 6196, category: CategoryError, key: "_0_is_declared_but_never_used_6196", text: "'{0}' is declared but never used.", reportsUnnecessary: true} + +var Include_modules_imported_with_json_extension = &Message{code: 6197, category: CategoryMessage, key: "Include_modules_imported_with_json_extension_6197", text: "Include modules imported with '.json' extension"} + +var All_destructured_elements_are_unused = &Message{code: 6198, category: CategoryError, key: "All_destructured_elements_are_unused_6198", text: "All destructured elements are unused.", reportsUnnecessary: true} + +var All_variables_are_unused = &Message{code: 6199, category: CategoryError, key: "All_variables_are_unused_6199", text: "All variables are unused.", reportsUnnecessary: true} + +var Definitions_of_the_following_identifiers_conflict_with_those_in_another_file_Colon_0 = &Message{code: 6200, category: CategoryError, key: "Definitions_of_the_following_identifiers_conflict_with_those_in_another_file_Colon_0_6200", text: "Definitions of the following identifiers conflict with those in another file: {0}"} + +var Conflicts_are_in_this_file = &Message{code: 6201, category: CategoryMessage, key: "Conflicts_are_in_this_file_6201", text: "Conflicts are in this file."} + +var Project_references_may_not_form_a_circular_graph_Cycle_detected_Colon_0 = &Message{code: 6202, category: CategoryError, key: "Project_references_may_not_form_a_circular_graph_Cycle_detected_Colon_0_6202", text: "Project references may not form a circular graph. Cycle detected: {0}"} + +var X_0_was_also_declared_here = &Message{code: 6203, category: CategoryMessage, key: "_0_was_also_declared_here_6203", text: "'{0}' was also declared here."} + +var X_and_here = &Message{code: 6204, category: CategoryMessage, key: "and_here_6204", text: "and here."} + +var All_type_parameters_are_unused = &Message{code: 6205, category: CategoryError, key: "All_type_parameters_are_unused_6205", text: "All type parameters are unused."} + +var X_package_json_has_a_typesVersions_field_with_version_specific_path_mappings = &Message{code: 6206, category: CategoryMessage, key: "package_json_has_a_typesVersions_field_with_version_specific_path_mappings_6206", text: "'package.json' has a 'typesVersions' field with version-specific path mappings."} + +var X_package_json_does_not_have_a_typesVersions_entry_that_matches_version_0 = &Message{code: 6207, category: CategoryMessage, key: "package_json_does_not_have_a_typesVersions_entry_that_matches_version_0_6207", text: "'package.json' does not have a 'typesVersions' entry that matches version '{0}'."} + +var X_package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_match_module_name_2 = &Message{code: 6208, category: CategoryMessage, key: "package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_ma_6208", text: "'package.json' has a 'typesVersions' entry '{0}' that matches compiler version '{1}', looking for a pattern to match module name '{2}'."} + +var X_package_json_has_a_typesVersions_entry_0_that_is_not_a_valid_semver_range = &Message{code: 6209, category: CategoryMessage, key: "package_json_has_a_typesVersions_entry_0_that_is_not_a_valid_semver_range_6209", text: "'package.json' has a 'typesVersions' entry '{0}' that is not a valid semver range."} + +var An_argument_for_0_was_not_provided = &Message{code: 6210, category: CategoryMessage, key: "An_argument_for_0_was_not_provided_6210", text: "An argument for '{0}' was not provided."} + +var An_argument_matching_this_binding_pattern_was_not_provided = &Message{code: 6211, category: CategoryMessage, key: "An_argument_matching_this_binding_pattern_was_not_provided_6211", text: "An argument matching this binding pattern was not provided."} + +var Did_you_mean_to_call_this_expression = &Message{code: 6212, category: CategoryMessage, key: "Did_you_mean_to_call_this_expression_6212", text: "Did you mean to call this expression?"} + +var Did_you_mean_to_use_new_with_this_expression = &Message{code: 6213, category: CategoryMessage, key: "Did_you_mean_to_use_new_with_this_expression_6213", text: "Did you mean to use 'new' with this expression?"} + +var Enable_strict_bind_call_and_apply_methods_on_functions = &Message{code: 6214, category: CategoryMessage, key: "Enable_strict_bind_call_and_apply_methods_on_functions_6214", text: "Enable strict 'bind', 'call', and 'apply' methods on functions."} + +var Using_compiler_options_of_project_reference_redirect_0 = &Message{code: 6215, category: CategoryMessage, key: "Using_compiler_options_of_project_reference_redirect_0_6215", text: "Using compiler options of project reference redirect '{0}'."} + +var Found_1_error = &Message{code: 6216, category: CategoryMessage, key: "Found_1_error_6216", text: "Found 1 error."} + +var Found_0_errors = &Message{code: 6217, category: CategoryMessage, key: "Found_0_errors_6217", text: "Found {0} errors."} + +var Module_name_0_was_successfully_resolved_to_1_with_Package_ID_2 = &Message{code: 6218, category: CategoryMessage, key: "Module_name_0_was_successfully_resolved_to_1_with_Package_ID_2_6218", text: "======== Module name '{0}' was successfully resolved to '{1}' with Package ID '{2}'. ========"} + +var Type_reference_directive_0_was_successfully_resolved_to_1_with_Package_ID_2_primary_Colon_3 = &Message{code: 6219, category: CategoryMessage, key: "Type_reference_directive_0_was_successfully_resolved_to_1_with_Package_ID_2_primary_Colon_3_6219", text: "======== Type reference directive '{0}' was successfully resolved to '{1}' with Package ID '{2}', primary: {3}. ========"} + +var X_package_json_had_a_falsy_0_field = &Message{code: 6220, category: CategoryMessage, key: "package_json_had_a_falsy_0_field_6220", text: "'package.json' had a falsy '{0}' field."} + +var Disable_use_of_source_files_instead_of_declaration_files_from_referenced_projects = &Message{code: 6221, category: CategoryMessage, key: "Disable_use_of_source_files_instead_of_declaration_files_from_referenced_projects_6221", text: "Disable use of source files instead of declaration files from referenced projects."} + +var Emit_class_fields_with_Define_instead_of_Set = &Message{code: 6222, category: CategoryMessage, key: "Emit_class_fields_with_Define_instead_of_Set_6222", text: "Emit class fields with Define instead of Set."} + +var Generates_a_CPU_profile = &Message{code: 6223, category: CategoryMessage, key: "Generates_a_CPU_profile_6223", text: "Generates a CPU profile."} + +var Disable_solution_searching_for_this_project = &Message{code: 6224, category: CategoryMessage, key: "Disable_solution_searching_for_this_project_6224", text: "Disable solution searching for this project."} + +var Specify_strategy_for_watching_file_Colon_FixedPollingInterval_default_PriorityPollingInterval_DynamicPriorityPolling_FixedChunkSizePolling_UseFsEvents_UseFsEventsOnParentDirectory = &Message{code: 6225, category: CategoryMessage, key: "Specify_strategy_for_watching_file_Colon_FixedPollingInterval_default_PriorityPollingInterval_Dynami_6225", text: "Specify strategy for watching file: 'FixedPollingInterval' (default), 'PriorityPollingInterval', 'DynamicPriorityPolling', 'FixedChunkSizePolling', 'UseFsEvents', 'UseFsEventsOnParentDirectory'."} + +var Specify_strategy_for_watching_directory_on_platforms_that_don_t_support_recursive_watching_natively_Colon_UseFsEvents_default_FixedPollingInterval_DynamicPriorityPolling_FixedChunkSizePolling = &Message{code: 6226, category: CategoryMessage, key: "Specify_strategy_for_watching_directory_on_platforms_that_don_t_support_recursive_watching_natively__6226", text: "Specify strategy for watching directory on platforms that don't support recursive watching natively: 'UseFsEvents' (default), 'FixedPollingInterval', 'DynamicPriorityPolling', 'FixedChunkSizePolling'."} + +var Specify_strategy_for_creating_a_polling_watch_when_it_fails_to_create_using_file_system_events_Colon_FixedInterval_default_PriorityInterval_DynamicPriority_FixedChunkSize = &Message{code: 6227, category: CategoryMessage, key: "Specify_strategy_for_creating_a_polling_watch_when_it_fails_to_create_using_file_system_events_Colon_6227", text: "Specify strategy for creating a polling watch when it fails to create using file system events: 'FixedInterval' (default), 'PriorityInterval', 'DynamicPriority', 'FixedChunkSize'."} + +var Tag_0_expects_at_least_1_arguments_but_the_JSX_factory_2_provides_at_most_3 = &Message{code: 6229, category: CategoryError, key: "Tag_0_expects_at_least_1_arguments_but_the_JSX_factory_2_provides_at_most_3_6229", text: "Tag '{0}' expects at least '{1}' arguments, but the JSX factory '{2}' provides at most '{3}'."} + +var Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_false_or_null_on_command_line = &Message{code: 6230, category: CategoryError, key: "Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_false_or_null_on_command_line_6230", text: "Option '{0}' can only be specified in 'tsconfig.json' file or set to 'false' or 'null' on command line."} + +var Could_not_resolve_the_path_0_with_the_extensions_Colon_1 = &Message{code: 6231, category: CategoryError, key: "Could_not_resolve_the_path_0_with_the_extensions_Colon_1_6231", text: "Could not resolve the path '{0}' with the extensions: {1}."} + +var Declaration_augments_declaration_in_another_file_This_cannot_be_serialized = &Message{code: 6232, category: CategoryError, key: "Declaration_augments_declaration_in_another_file_This_cannot_be_serialized_6232", text: "Declaration augments declaration in another file. This cannot be serialized."} + +var This_is_the_declaration_being_augmented_Consider_moving_the_augmenting_declaration_into_the_same_file = &Message{code: 6233, category: CategoryError, key: "This_is_the_declaration_being_augmented_Consider_moving_the_augmenting_declaration_into_the_same_fil_6233", text: "This is the declaration being augmented. Consider moving the augmenting declaration into the same file."} + +var This_expression_is_not_callable_because_it_is_a_get_accessor_Did_you_mean_to_use_it_without = &Message{code: 6234, category: CategoryError, key: "This_expression_is_not_callable_because_it_is_a_get_accessor_Did_you_mean_to_use_it_without_6234", text: "This expression is not callable because it is a 'get' accessor. Did you mean to use it without '()'?"} + +var Disable_loading_referenced_projects = &Message{code: 6235, category: CategoryMessage, key: "Disable_loading_referenced_projects_6235", text: "Disable loading referenced projects."} + +var Arguments_for_the_rest_parameter_0_were_not_provided = &Message{code: 6236, category: CategoryError, key: "Arguments_for_the_rest_parameter_0_were_not_provided_6236", text: "Arguments for the rest parameter '{0}' were not provided."} + +var Generates_an_event_trace_and_a_list_of_types = &Message{code: 6237, category: CategoryMessage, key: "Generates_an_event_trace_and_a_list_of_types_6237", text: "Generates an event trace and a list of types."} + +var Specify_the_module_specifier_to_be_used_to_import_the_jsx_and_jsxs_factory_functions_from_eg_react = &Message{code: 6238, category: CategoryError, key: "Specify_the_module_specifier_to_be_used_to_import_the_jsx_and_jsxs_factory_functions_from_eg_react_6238", text: "Specify the module specifier to be used to import the 'jsx' and 'jsxs' factory functions from. eg, react"} + +var File_0_exists_according_to_earlier_cached_lookups = &Message{code: 6239, category: CategoryMessage, key: "File_0_exists_according_to_earlier_cached_lookups_6239", text: "File '{0}' exists according to earlier cached lookups."} + +var File_0_does_not_exist_according_to_earlier_cached_lookups = &Message{code: 6240, category: CategoryMessage, key: "File_0_does_not_exist_according_to_earlier_cached_lookups_6240", text: "File '{0}' does not exist according to earlier cached lookups."} + +var Resolution_for_type_reference_directive_0_was_found_in_cache_from_location_1 = &Message{code: 6241, category: CategoryMessage, key: "Resolution_for_type_reference_directive_0_was_found_in_cache_from_location_1_6241", text: "Resolution for type reference directive '{0}' was found in cache from location '{1}'."} + +var Resolving_type_reference_directive_0_containing_file_1 = &Message{code: 6242, category: CategoryMessage, key: "Resolving_type_reference_directive_0_containing_file_1_6242", text: "======== Resolving type reference directive '{0}', containing file '{1}'. ========"} + +var Interpret_optional_property_types_as_written_rather_than_adding_undefined = &Message{code: 6243, category: CategoryMessage, key: "Interpret_optional_property_types_as_written_rather_than_adding_undefined_6243", text: "Interpret optional property types as written, rather than adding 'undefined'."} + +var Modules = &Message{code: 6244, category: CategoryMessage, key: "Modules_6244", text: "Modules"} + +var File_Management = &Message{code: 6245, category: CategoryMessage, key: "File_Management_6245", text: "File Management"} + +var Emit = &Message{code: 6246, category: CategoryMessage, key: "Emit_6246", text: "Emit"} + +var JavaScript_Support = &Message{code: 6247, category: CategoryMessage, key: "JavaScript_Support_6247", text: "JavaScript Support"} + +var Type_Checking = &Message{code: 6248, category: CategoryMessage, key: "Type_Checking_6248", text: "Type Checking"} + +var Editor_Support = &Message{code: 6249, category: CategoryMessage, key: "Editor_Support_6249", text: "Editor Support"} + +var Watch_and_Build_Modes = &Message{code: 6250, category: CategoryMessage, key: "Watch_and_Build_Modes_6250", text: "Watch and Build Modes"} + +var Compiler_Diagnostics = &Message{code: 6251, category: CategoryMessage, key: "Compiler_Diagnostics_6251", text: "Compiler Diagnostics"} + +var Interop_Constraints = &Message{code: 6252, category: CategoryMessage, key: "Interop_Constraints_6252", text: "Interop Constraints"} + +var Backwards_Compatibility = &Message{code: 6253, category: CategoryMessage, key: "Backwards_Compatibility_6253", text: "Backwards Compatibility"} + +var Language_and_Environment = &Message{code: 6254, category: CategoryMessage, key: "Language_and_Environment_6254", text: "Language and Environment"} + +var Projects = &Message{code: 6255, category: CategoryMessage, key: "Projects_6255", text: "Projects"} + +var Output_Formatting = &Message{code: 6256, category: CategoryMessage, key: "Output_Formatting_6256", text: "Output Formatting"} + +var Completeness = &Message{code: 6257, category: CategoryMessage, key: "Completeness_6257", text: "Completeness"} + +var X_0_should_be_set_inside_the_compilerOptions_object_of_the_config_json_file = &Message{code: 6258, category: CategoryError, key: "_0_should_be_set_inside_the_compilerOptions_object_of_the_config_json_file_6258", text: "'{0}' should be set inside the 'compilerOptions' object of the config json file"} + +var Found_1_error_in_0 = &Message{code: 6259, category: CategoryMessage, key: "Found_1_error_in_0_6259", text: "Found 1 error in {0}"} + +var Found_0_errors_in_the_same_file_starting_at_Colon_1 = &Message{code: 6260, category: CategoryMessage, key: "Found_0_errors_in_the_same_file_starting_at_Colon_1_6260", text: "Found {0} errors in the same file, starting at: {1}"} + +var Found_0_errors_in_1_files = &Message{code: 6261, category: CategoryMessage, key: "Found_0_errors_in_1_files_6261", text: "Found {0} errors in {1} files."} + +var File_name_0_has_a_1_extension_looking_up_2_instead = &Message{code: 6262, category: CategoryMessage, key: "File_name_0_has_a_1_extension_looking_up_2_instead_6262", text: "File name '{0}' has a '{1}' extension - looking up '{2}' instead."} + +var Module_0_was_resolved_to_1_but_allowArbitraryExtensions_is_not_set = &Message{code: 6263, category: CategoryError, key: "Module_0_was_resolved_to_1_but_allowArbitraryExtensions_is_not_set_6263", text: "Module '{0}' was resolved to '{1}', but '--allowArbitraryExtensions' is not set."} + +var Enable_importing_files_with_any_extension_provided_a_declaration_file_is_present = &Message{code: 6264, category: CategoryMessage, key: "Enable_importing_files_with_any_extension_provided_a_declaration_file_is_present_6264", text: "Enable importing files with any extension, provided a declaration file is present."} + +var Resolving_type_reference_directive_for_program_that_specifies_custom_typeRoots_skipping_lookup_in_node_modules_folder = &Message{code: 6265, category: CategoryMessage, key: "Resolving_type_reference_directive_for_program_that_specifies_custom_typeRoots_skipping_lookup_in_no_6265", text: "Resolving type reference directive for program that specifies custom typeRoots, skipping lookup in 'node_modules' folder."} + +var Option_0_can_only_be_specified_on_command_line = &Message{code: 6266, category: CategoryError, key: "Option_0_can_only_be_specified_on_command_line_6266", text: "Option '{0}' can only be specified on command line."} + +var Directory_0_has_no_containing_package_json_scope_Imports_will_not_resolve = &Message{code: 6270, category: CategoryMessage, key: "Directory_0_has_no_containing_package_json_scope_Imports_will_not_resolve_6270", text: "Directory '{0}' has no containing package.json scope. Imports will not resolve."} + +var Import_specifier_0_does_not_exist_in_package_json_scope_at_path_1 = &Message{code: 6271, category: CategoryMessage, key: "Import_specifier_0_does_not_exist_in_package_json_scope_at_path_1_6271", text: "Import specifier '{0}' does not exist in package.json scope at path '{1}'."} + +var Invalid_import_specifier_0_has_no_possible_resolutions = &Message{code: 6272, category: CategoryMessage, key: "Invalid_import_specifier_0_has_no_possible_resolutions_6272", text: "Invalid import specifier '{0}' has no possible resolutions."} + +var X_package_json_scope_0_has_no_imports_defined = &Message{code: 6273, category: CategoryMessage, key: "package_json_scope_0_has_no_imports_defined_6273", text: "package.json scope '{0}' has no imports defined."} + +var X_package_json_scope_0_explicitly_maps_specifier_1_to_null = &Message{code: 6274, category: CategoryMessage, key: "package_json_scope_0_explicitly_maps_specifier_1_to_null_6274", text: "package.json scope '{0}' explicitly maps specifier '{1}' to null."} + +var X_package_json_scope_0_has_invalid_type_for_target_of_specifier_1 = &Message{code: 6275, category: CategoryMessage, key: "package_json_scope_0_has_invalid_type_for_target_of_specifier_1_6275", text: "package.json scope '{0}' has invalid type for target of specifier '{1}'"} + +var Export_specifier_0_does_not_exist_in_package_json_scope_at_path_1 = &Message{code: 6276, category: CategoryMessage, key: "Export_specifier_0_does_not_exist_in_package_json_scope_at_path_1_6276", text: "Export specifier '{0}' does not exist in package.json scope at path '{1}'."} + +var Resolution_of_non_relative_name_failed_trying_with_modern_Node_resolution_features_disabled_to_see_if_npm_library_needs_configuration_update = &Message{code: 6277, category: CategoryMessage, key: "Resolution_of_non_relative_name_failed_trying_with_modern_Node_resolution_features_disabled_to_see_i_6277", text: "Resolution of non-relative name failed; trying with modern Node resolution features disabled to see if npm library needs configuration update."} + +var There_are_types_at_0_but_this_result_could_not_be_resolved_when_respecting_package_json_exports_The_1_library_may_need_to_update_its_package_json_or_typings = &Message{code: 6278, category: CategoryMessage, key: "There_are_types_at_0_but_this_result_could_not_be_resolved_when_respecting_package_json_exports_The__6278", text: "There are types at '{0}', but this result could not be resolved when respecting package.json \"exports\". The '{1}' library may need to update its package.json or typings."} + +var Resolution_of_non_relative_name_failed_trying_with_moduleResolution_bundler_to_see_if_project_may_need_configuration_update = &Message{code: 6279, category: CategoryMessage, key: "Resolution_of_non_relative_name_failed_trying_with_moduleResolution_bundler_to_see_if_project_may_ne_6279", text: "Resolution of non-relative name failed; trying with '--moduleResolution bundler' to see if project may need configuration update."} + +var There_are_types_at_0_but_this_result_could_not_be_resolved_under_your_current_moduleResolution_setting_Consider_updating_to_node16_nodenext_or_bundler = &Message{code: 6280, category: CategoryMessage, key: "There_are_types_at_0_but_this_result_could_not_be_resolved_under_your_current_moduleResolution_setti_6280", text: "There are types at '{0}', but this result could not be resolved under your current 'moduleResolution' setting. Consider updating to 'node16', 'nodenext', or 'bundler'."} + +var X_package_json_has_a_peerDependencies_field = &Message{code: 6281, category: CategoryMessage, key: "package_json_has_a_peerDependencies_field_6281", text: "'package.json' has a 'peerDependencies' field."} + +var Found_peerDependency_0_with_1_version = &Message{code: 6282, category: CategoryMessage, key: "Found_peerDependency_0_with_1_version_6282", text: "Found peerDependency '{0}' with '{1}' version."} + +var Failed_to_find_peerDependency_0 = &Message{code: 6283, category: CategoryMessage, key: "Failed_to_find_peerDependency_0_6283", text: "Failed to find peerDependency '{0}'."} + +var File_Layout = &Message{code: 6284, category: CategoryMessage, key: "File_Layout_6284", text: "File Layout"} + +var Environment_Settings = &Message{code: 6285, category: CategoryMessage, key: "Environment_Settings_6285", text: "Environment Settings"} + +var See_also_https_Colon_Slash_Slashaka_ms_Slashtsconfig_Slashmodule = &Message{code: 6286, category: CategoryMessage, key: "See_also_https_Colon_Slash_Slashaka_ms_Slashtsconfig_Slashmodule_6286", text: "See also https://aka.ms/tsconfig/module"} + +var For_nodejs_Colon = &Message{code: 6287, category: CategoryMessage, key: "For_nodejs_Colon_6287", text: "For nodejs:"} + +var X_and_npm_install_D_types_Slashnode = &Message{code: 6290, category: CategoryMessage, key: "and_npm_install_D_types_Slashnode_6290", text: "and npm install -D @types/node"} + +var Other_Outputs = &Message{code: 6291, category: CategoryMessage, key: "Other_Outputs_6291", text: "Other Outputs"} + +var Stricter_Typechecking_Options = &Message{code: 6292, category: CategoryMessage, key: "Stricter_Typechecking_Options_6292", text: "Stricter Typechecking Options"} + +var Style_Options = &Message{code: 6293, category: CategoryMessage, key: "Style_Options_6293", text: "Style Options"} + +var Recommended_Options = &Message{code: 6294, category: CategoryMessage, key: "Recommended_Options_6294", text: "Recommended Options"} + +var Enable_project_compilation = &Message{code: 6302, category: CategoryMessage, key: "Enable_project_compilation_6302", text: "Enable project compilation"} + +var Composite_projects_may_not_disable_declaration_emit = &Message{code: 6304, category: CategoryError, key: "Composite_projects_may_not_disable_declaration_emit_6304", text: "Composite projects may not disable declaration emit."} + +var Output_file_0_has_not_been_built_from_source_file_1 = &Message{code: 6305, category: CategoryError, key: "Output_file_0_has_not_been_built_from_source_file_1_6305", text: "Output file '{0}' has not been built from source file '{1}'."} + +var Referenced_project_0_must_have_setting_composite_Colon_true = &Message{code: 6306, category: CategoryError, key: "Referenced_project_0_must_have_setting_composite_Colon_true_6306", text: "Referenced project '{0}' must have setting \"composite\": true."} + +var File_0_is_not_listed_within_the_file_list_of_project_1_Projects_must_list_all_files_or_use_an_include_pattern = &Message{code: 6307, category: CategoryError, key: "File_0_is_not_listed_within_the_file_list_of_project_1_Projects_must_list_all_files_or_use_an_includ_6307", text: "File '{0}' is not listed within the file list of project '{1}'. Projects must list all files or use an 'include' pattern."} + +var Referenced_project_0_may_not_disable_emit = &Message{code: 6310, category: CategoryError, key: "Referenced_project_0_may_not_disable_emit_6310", text: "Referenced project '{0}' may not disable emit."} + +var Project_0_is_out_of_date_because_output_1_is_older_than_input_2 = &Message{code: 6350, category: CategoryMessage, key: "Project_0_is_out_of_date_because_output_1_is_older_than_input_2_6350", text: "Project '{0}' is out of date because output '{1}' is older than input '{2}'"} + +var Project_0_is_up_to_date_because_newest_input_1_is_older_than_output_2 = &Message{code: 6351, category: CategoryMessage, key: "Project_0_is_up_to_date_because_newest_input_1_is_older_than_output_2_6351", text: "Project '{0}' is up to date because newest input '{1}' is older than output '{2}'"} + +var Project_0_is_out_of_date_because_output_file_1_does_not_exist = &Message{code: 6352, category: CategoryMessage, key: "Project_0_is_out_of_date_because_output_file_1_does_not_exist_6352", text: "Project '{0}' is out of date because output file '{1}' does not exist"} + +var Failed_to_delete_file_0 = &Message{code: 6353, category: CategoryMessage, key: "Failed_to_delete_file_0_6353", text: "Failed to delete file '{0}'."} + +var Project_0_is_up_to_date_with_d_ts_files_from_its_dependencies = &Message{code: 6354, category: CategoryMessage, key: "Project_0_is_up_to_date_with_d_ts_files_from_its_dependencies_6354", text: "Project '{0}' is up to date with .d.ts files from its dependencies"} + +var Projects_in_this_build_Colon_0 = &Message{code: 6355, category: CategoryMessage, key: "Projects_in_this_build_Colon_0_6355", text: "Projects in this build: {0}"} + +var A_non_dry_build_would_delete_the_following_files_Colon_0 = &Message{code: 6356, category: CategoryMessage, key: "A_non_dry_build_would_delete_the_following_files_Colon_0_6356", text: "A non-dry build would delete the following files: {0}"} + +var A_non_dry_build_would_build_project_0 = &Message{code: 6357, category: CategoryMessage, key: "A_non_dry_build_would_build_project_0_6357", text: "A non-dry build would build project '{0}'"} + +var Building_project_0 = &Message{code: 6358, category: CategoryMessage, key: "Building_project_0_6358", text: "Building project '{0}'..."} + +var Updating_output_timestamps_of_project_0 = &Message{code: 6359, category: CategoryMessage, key: "Updating_output_timestamps_of_project_0_6359", text: "Updating output timestamps of project '{0}'..."} + +var Project_0_is_up_to_date = &Message{code: 6361, category: CategoryMessage, key: "Project_0_is_up_to_date_6361", text: "Project '{0}' is up to date"} + +var Skipping_build_of_project_0_because_its_dependency_1_has_errors = &Message{code: 6362, category: CategoryMessage, key: "Skipping_build_of_project_0_because_its_dependency_1_has_errors_6362", text: "Skipping build of project '{0}' because its dependency '{1}' has errors"} + +var Project_0_can_t_be_built_because_its_dependency_1_has_errors = &Message{code: 6363, category: CategoryMessage, key: "Project_0_can_t_be_built_because_its_dependency_1_has_errors_6363", text: "Project '{0}' can't be built because its dependency '{1}' has errors"} + +var Build_one_or_more_projects_and_their_dependencies_if_out_of_date = &Message{code: 6364, category: CategoryMessage, key: "Build_one_or_more_projects_and_their_dependencies_if_out_of_date_6364", text: "Build one or more projects and their dependencies, if out of date"} + +var Delete_the_outputs_of_all_projects = &Message{code: 6365, category: CategoryMessage, key: "Delete_the_outputs_of_all_projects_6365", text: "Delete the outputs of all projects."} + +var Show_what_would_be_built_or_deleted_if_specified_with_clean = &Message{code: 6367, category: CategoryMessage, key: "Show_what_would_be_built_or_deleted_if_specified_with_clean_6367", text: "Show what would be built (or deleted, if specified with '--clean')"} + +var Option_build_must_be_the_first_command_line_argument = &Message{code: 6369, category: CategoryError, key: "Option_build_must_be_the_first_command_line_argument_6369", text: "Option '--build' must be the first command line argument."} + +var Options_0_and_1_cannot_be_combined = &Message{code: 6370, category: CategoryError, key: "Options_0_and_1_cannot_be_combined_6370", text: "Options '{0}' and '{1}' cannot be combined."} + +var Updating_unchanged_output_timestamps_of_project_0 = &Message{code: 6371, category: CategoryMessage, key: "Updating_unchanged_output_timestamps_of_project_0_6371", text: "Updating unchanged output timestamps of project '{0}'..."} + +var A_non_dry_build_would_update_timestamps_for_output_of_project_0 = &Message{code: 6374, category: CategoryMessage, key: "A_non_dry_build_would_update_timestamps_for_output_of_project_0_6374", text: "A non-dry build would update timestamps for output of project '{0}'"} + +var Cannot_write_file_0_because_it_will_overwrite_tsbuildinfo_file_generated_by_referenced_project_1 = &Message{code: 6377, category: CategoryError, key: "Cannot_write_file_0_because_it_will_overwrite_tsbuildinfo_file_generated_by_referenced_project_1_6377", text: "Cannot write file '{0}' because it will overwrite '.tsbuildinfo' file generated by referenced project '{1}'"} + +var Composite_projects_may_not_disable_incremental_compilation = &Message{code: 6379, category: CategoryError, key: "Composite_projects_may_not_disable_incremental_compilation_6379", text: "Composite projects may not disable incremental compilation."} + +var Specify_file_to_store_incremental_compilation_information = &Message{code: 6380, category: CategoryMessage, key: "Specify_file_to_store_incremental_compilation_information_6380", text: "Specify file to store incremental compilation information"} + +var Project_0_is_out_of_date_because_output_for_it_was_generated_with_version_1_that_differs_with_current_version_2 = &Message{code: 6381, category: CategoryMessage, key: "Project_0_is_out_of_date_because_output_for_it_was_generated_with_version_1_that_differs_with_curren_6381", text: "Project '{0}' is out of date because output for it was generated with version '{1}' that differs with current version '{2}'"} + +var Skipping_build_of_project_0_because_its_dependency_1_was_not_built = &Message{code: 6382, category: CategoryMessage, key: "Skipping_build_of_project_0_because_its_dependency_1_was_not_built_6382", text: "Skipping build of project '{0}' because its dependency '{1}' was not built"} + +var Project_0_can_t_be_built_because_its_dependency_1_was_not_built = &Message{code: 6383, category: CategoryMessage, key: "Project_0_can_t_be_built_because_its_dependency_1_was_not_built_6383", text: "Project '{0}' can't be built because its dependency '{1}' was not built"} + +var Have_recompiles_in_incremental_and_watch_assume_that_changes_within_a_file_will_only_affect_files_directly_depending_on_it = &Message{code: 6384, category: CategoryMessage, key: "Have_recompiles_in_incremental_and_watch_assume_that_changes_within_a_file_will_only_affect_files_di_6384", text: "Have recompiles in '--incremental' and '--watch' assume that changes within a file will only affect files directly depending on it."} + +var X_0_is_deprecated = &Message{code: 6385, category: CategorySuggestion, key: "_0_is_deprecated_6385", text: "'{0}' is deprecated.", reportsDeprecated: true} + +var Performance_timings_for_diagnostics_or_extendedDiagnostics_are_not_available_in_this_session_A_native_implementation_of_the_Web_Performance_API_could_not_be_found = &Message{code: 6386, category: CategoryMessage, key: "Performance_timings_for_diagnostics_or_extendedDiagnostics_are_not_available_in_this_session_A_nativ_6386", text: "Performance timings for '--diagnostics' or '--extendedDiagnostics' are not available in this session. A native implementation of the Web Performance API could not be found."} + +var The_signature_0_of_1_is_deprecated = &Message{code: 6387, category: CategorySuggestion, key: "The_signature_0_of_1_is_deprecated_6387", text: "The signature '{0}' of '{1}' is deprecated.", reportsDeprecated: true} + +var Project_0_is_being_forcibly_rebuilt = &Message{code: 6388, category: CategoryMessage, key: "Project_0_is_being_forcibly_rebuilt_6388", text: "Project '{0}' is being forcibly rebuilt"} + +var Reusing_resolution_of_module_0_from_1_of_old_program_it_was_not_resolved = &Message{code: 6389, category: CategoryMessage, key: "Reusing_resolution_of_module_0_from_1_of_old_program_it_was_not_resolved_6389", text: "Reusing resolution of module '{0}' from '{1}' of old program, it was not resolved."} + +var Reusing_resolution_of_type_reference_directive_0_from_1_of_old_program_it_was_successfully_resolved_to_2 = &Message{code: 6390, category: CategoryMessage, key: "Reusing_resolution_of_type_reference_directive_0_from_1_of_old_program_it_was_successfully_resolved__6390", text: "Reusing resolution of type reference directive '{0}' from '{1}' of old program, it was successfully resolved to '{2}'."} + +var Reusing_resolution_of_type_reference_directive_0_from_1_of_old_program_it_was_successfully_resolved_to_2_with_Package_ID_3 = &Message{code: 6391, category: CategoryMessage, key: "Reusing_resolution_of_type_reference_directive_0_from_1_of_old_program_it_was_successfully_resolved__6391", text: "Reusing resolution of type reference directive '{0}' from '{1}' of old program, it was successfully resolved to '{2}' with Package ID '{3}'."} + +var Reusing_resolution_of_type_reference_directive_0_from_1_of_old_program_it_was_not_resolved = &Message{code: 6392, category: CategoryMessage, key: "Reusing_resolution_of_type_reference_directive_0_from_1_of_old_program_it_was_not_resolved_6392", text: "Reusing resolution of type reference directive '{0}' from '{1}' of old program, it was not resolved."} + +var Reusing_resolution_of_module_0_from_1_found_in_cache_from_location_2_it_was_successfully_resolved_to_3 = &Message{code: 6393, category: CategoryMessage, key: "Reusing_resolution_of_module_0_from_1_found_in_cache_from_location_2_it_was_successfully_resolved_to_6393", text: "Reusing resolution of module '{0}' from '{1}' found in cache from location '{2}', it was successfully resolved to '{3}'."} + +var Reusing_resolution_of_module_0_from_1_found_in_cache_from_location_2_it_was_successfully_resolved_to_3_with_Package_ID_4 = &Message{code: 6394, category: CategoryMessage, key: "Reusing_resolution_of_module_0_from_1_found_in_cache_from_location_2_it_was_successfully_resolved_to_6394", text: "Reusing resolution of module '{0}' from '{1}' found in cache from location '{2}', it was successfully resolved to '{3}' with Package ID '{4}'."} + +var Reusing_resolution_of_module_0_from_1_found_in_cache_from_location_2_it_was_not_resolved = &Message{code: 6395, category: CategoryMessage, key: "Reusing_resolution_of_module_0_from_1_found_in_cache_from_location_2_it_was_not_resolved_6395", text: "Reusing resolution of module '{0}' from '{1}' found in cache from location '{2}', it was not resolved."} + +var Reusing_resolution_of_type_reference_directive_0_from_1_found_in_cache_from_location_2_it_was_successfully_resolved_to_3 = &Message{code: 6396, category: CategoryMessage, key: "Reusing_resolution_of_type_reference_directive_0_from_1_found_in_cache_from_location_2_it_was_succes_6396", text: "Reusing resolution of type reference directive '{0}' from '{1}' found in cache from location '{2}', it was successfully resolved to '{3}'."} + +var Reusing_resolution_of_type_reference_directive_0_from_1_found_in_cache_from_location_2_it_was_successfully_resolved_to_3_with_Package_ID_4 = &Message{code: 6397, category: CategoryMessage, key: "Reusing_resolution_of_type_reference_directive_0_from_1_found_in_cache_from_location_2_it_was_succes_6397", text: "Reusing resolution of type reference directive '{0}' from '{1}' found in cache from location '{2}', it was successfully resolved to '{3}' with Package ID '{4}'."} + +var Reusing_resolution_of_type_reference_directive_0_from_1_found_in_cache_from_location_2_it_was_not_resolved = &Message{code: 6398, category: CategoryMessage, key: "Reusing_resolution_of_type_reference_directive_0_from_1_found_in_cache_from_location_2_it_was_not_re_6398", text: "Reusing resolution of type reference directive '{0}' from '{1}' found in cache from location '{2}', it was not resolved."} + +var Project_0_is_out_of_date_because_buildinfo_file_1_indicates_that_some_of_the_changes_were_not_emitted = &Message{code: 6399, category: CategoryMessage, key: "Project_0_is_out_of_date_because_buildinfo_file_1_indicates_that_some_of_the_changes_were_not_emitte_6399", text: "Project '{0}' is out of date because buildinfo file '{1}' indicates that some of the changes were not emitted"} + +var Project_0_is_up_to_date_but_needs_to_update_timestamps_of_output_files_that_are_older_than_input_files = &Message{code: 6400, category: CategoryMessage, key: "Project_0_is_up_to_date_but_needs_to_update_timestamps_of_output_files_that_are_older_than_input_fil_6400", text: "Project '{0}' is up to date but needs to update timestamps of output files that are older than input files"} + +var Project_0_is_out_of_date_because_config_file_does_not_exist = &Message{code: 6401, category: CategoryMessage, key: "Project_0_is_out_of_date_because_config_file_does_not_exist_6401", text: "Project '{0}' is out of date because config file does not exist."} + +var Resolving_in_0_mode_with_conditions_1 = &Message{code: 6402, category: CategoryMessage, key: "Resolving_in_0_mode_with_conditions_1_6402", text: "Resolving in {0} mode with conditions {1}."} + +var Matched_0_condition_1 = &Message{code: 6403, category: CategoryMessage, key: "Matched_0_condition_1_6403", text: "Matched '{0}' condition '{1}'."} + +var Using_0_subpath_1_with_target_2 = &Message{code: 6404, category: CategoryMessage, key: "Using_0_subpath_1_with_target_2_6404", text: "Using '{0}' subpath '{1}' with target '{2}'."} + +var Saw_non_matching_condition_0 = &Message{code: 6405, category: CategoryMessage, key: "Saw_non_matching_condition_0_6405", text: "Saw non-matching condition '{0}'."} + +var Project_0_is_out_of_date_because_buildinfo_file_1_indicates_there_is_change_in_compilerOptions = &Message{code: 6406, category: CategoryMessage, key: "Project_0_is_out_of_date_because_buildinfo_file_1_indicates_there_is_change_in_compilerOptions_6406", text: "Project '{0}' is out of date because buildinfo file '{1}' indicates there is change in compilerOptions"} + +var Allow_imports_to_include_TypeScript_file_extensions_Requires_moduleResolution_bundler_and_either_noEmit_or_emitDeclarationOnly_to_be_set = &Message{code: 6407, category: CategoryMessage, key: "Allow_imports_to_include_TypeScript_file_extensions_Requires_moduleResolution_bundler_and_either_noE_6407", text: "Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set."} + +var Use_the_package_json_exports_field_when_resolving_package_imports = &Message{code: 6408, category: CategoryMessage, key: "Use_the_package_json_exports_field_when_resolving_package_imports_6408", text: "Use the package.json 'exports' field when resolving package imports."} + +var Use_the_package_json_imports_field_when_resolving_imports = &Message{code: 6409, category: CategoryMessage, key: "Use_the_package_json_imports_field_when_resolving_imports_6409", text: "Use the package.json 'imports' field when resolving imports."} + +var Conditions_to_set_in_addition_to_the_resolver_specific_defaults_when_resolving_imports = &Message{code: 6410, category: CategoryMessage, key: "Conditions_to_set_in_addition_to_the_resolver_specific_defaults_when_resolving_imports_6410", text: "Conditions to set in addition to the resolver-specific defaults when resolving imports."} + +var X_true_when_moduleResolution_is_node16_nodenext_or_bundler_otherwise_false = &Message{code: 6411, category: CategoryMessage, key: "true_when_moduleResolution_is_node16_nodenext_or_bundler_otherwise_false_6411", text: "`true` when 'moduleResolution' is 'node16', 'nodenext', or 'bundler'; otherwise `false`."} + +var Project_0_is_out_of_date_because_buildinfo_file_1_indicates_that_file_2_was_root_file_of_compilation_but_not_any_more = &Message{code: 6412, category: CategoryMessage, key: "Project_0_is_out_of_date_because_buildinfo_file_1_indicates_that_file_2_was_root_file_of_compilation_6412", text: "Project '{0}' is out of date because buildinfo file '{1}' indicates that file '{2}' was root file of compilation but not any more."} + +var Entering_conditional_exports = &Message{code: 6413, category: CategoryMessage, key: "Entering_conditional_exports_6413", text: "Entering conditional exports."} + +var Resolved_under_condition_0 = &Message{code: 6414, category: CategoryMessage, key: "Resolved_under_condition_0_6414", text: "Resolved under condition '{0}'."} + +var Failed_to_resolve_under_condition_0 = &Message{code: 6415, category: CategoryMessage, key: "Failed_to_resolve_under_condition_0_6415", text: "Failed to resolve under condition '{0}'."} + +var Exiting_conditional_exports = &Message{code: 6416, category: CategoryMessage, key: "Exiting_conditional_exports_6416", text: "Exiting conditional exports."} + +var Searching_all_ancestor_node_modules_directories_for_preferred_extensions_Colon_0 = &Message{code: 6417, category: CategoryMessage, key: "Searching_all_ancestor_node_modules_directories_for_preferred_extensions_Colon_0_6417", text: "Searching all ancestor node_modules directories for preferred extensions: {0}."} + +var Searching_all_ancestor_node_modules_directories_for_fallback_extensions_Colon_0 = &Message{code: 6418, category: CategoryMessage, key: "Searching_all_ancestor_node_modules_directories_for_fallback_extensions_Colon_0_6418", text: "Searching all ancestor node_modules directories for fallback extensions: {0}."} + +var Project_0_is_out_of_date_because_buildinfo_file_1_indicates_that_program_needs_to_report_errors = &Message{code: 6419, category: CategoryMessage, key: "Project_0_is_out_of_date_because_buildinfo_file_1_indicates_that_program_needs_to_report_errors_6419", text: "Project '{0}' is out of date because buildinfo file '{1}' indicates that program needs to report errors."} + +var Project_0_is_out_of_date_because_input_1_does_not_exist = &Message{code: 6420, category: CategoryMessage, key: "Project_0_is_out_of_date_because_input_1_does_not_exist_6420", text: "Project '{0}' is out of date because input '{1}' does not exist."} + +var Rewrite_ts_tsx_mts_and_cts_file_extensions_in_relative_import_paths_to_their_JavaScript_equivalent_in_output_files = &Message{code: 6421, category: CategoryMessage, key: "Rewrite_ts_tsx_mts_and_cts_file_extensions_in_relative_import_paths_to_their_JavaScript_equivalent_i_6421", text: "Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files."} + +var Project_0_is_out_of_date_because_it_has_errors = &Message{code: 6423, category: CategoryMessage, key: "Project_0_is_out_of_date_because_it_has_errors_6423", text: "Project '{0}' is out of date because it has errors."} + +var The_expected_type_comes_from_property_0_which_is_declared_here_on_type_1 = &Message{code: 6500, category: CategoryMessage, key: "The_expected_type_comes_from_property_0_which_is_declared_here_on_type_1_6500", text: "The expected type comes from property '{0}' which is declared here on type '{1}'"} + +var The_expected_type_comes_from_this_index_signature = &Message{code: 6501, category: CategoryMessage, key: "The_expected_type_comes_from_this_index_signature_6501", text: "The expected type comes from this index signature."} + +var The_expected_type_comes_from_the_return_type_of_this_signature = &Message{code: 6502, category: CategoryMessage, key: "The_expected_type_comes_from_the_return_type_of_this_signature_6502", text: "The expected type comes from the return type of this signature."} + +var Print_names_of_files_that_are_part_of_the_compilation_and_then_stop_processing = &Message{code: 6503, category: CategoryMessage, key: "Print_names_of_files_that_are_part_of_the_compilation_and_then_stop_processing_6503", text: "Print names of files that are part of the compilation and then stop processing."} + +var File_0_is_a_JavaScript_file_Did_you_mean_to_enable_the_allowJs_option = &Message{code: 6504, category: CategoryError, key: "File_0_is_a_JavaScript_file_Did_you_mean_to_enable_the_allowJs_option_6504", text: "File '{0}' is a JavaScript file. Did you mean to enable the 'allowJs' option?"} + +var Print_names_of_files_and_the_reason_they_are_part_of_the_compilation = &Message{code: 6505, category: CategoryMessage, key: "Print_names_of_files_and_the_reason_they_are_part_of_the_compilation_6505", text: "Print names of files and the reason they are part of the compilation."} + +var Consider_adding_a_declare_modifier_to_this_class = &Message{code: 6506, category: CategoryMessage, key: "Consider_adding_a_declare_modifier_to_this_class_6506", text: "Consider adding a 'declare' modifier to this class."} + +var Allow_JavaScript_files_to_be_a_part_of_your_program_Use_the_checkJs_option_to_get_errors_from_these_files = &Message{code: 6600, category: CategoryMessage, key: "Allow_JavaScript_files_to_be_a_part_of_your_program_Use_the_checkJs_option_to_get_errors_from_these__6600", text: "Allow JavaScript files to be a part of your program. Use the 'checkJs' option to get errors from these files."} + +var Allow_import_x_from_y_when_a_module_doesn_t_have_a_default_export = &Message{code: 6601, category: CategoryMessage, key: "Allow_import_x_from_y_when_a_module_doesn_t_have_a_default_export_6601", text: "Allow 'import x from y' when a module doesn't have a default export."} + +var Allow_accessing_UMD_globals_from_modules = &Message{code: 6602, category: CategoryMessage, key: "Allow_accessing_UMD_globals_from_modules_6602", text: "Allow accessing UMD globals from modules."} + +var Disable_error_reporting_for_unreachable_code = &Message{code: 6603, category: CategoryMessage, key: "Disable_error_reporting_for_unreachable_code_6603", text: "Disable error reporting for unreachable code."} + +var Disable_error_reporting_for_unused_labels = &Message{code: 6604, category: CategoryMessage, key: "Disable_error_reporting_for_unused_labels_6604", text: "Disable error reporting for unused labels."} + +var Ensure_use_strict_is_always_emitted = &Message{code: 6605, category: CategoryMessage, key: "Ensure_use_strict_is_always_emitted_6605", text: "Ensure 'use strict' is always emitted."} + +var Have_recompiles_in_projects_that_use_incremental_and_watch_mode_assume_that_changes_within_a_file_will_only_affect_files_directly_depending_on_it = &Message{code: 6606, category: CategoryMessage, key: "Have_recompiles_in_projects_that_use_incremental_and_watch_mode_assume_that_changes_within_a_file_wi_6606", text: "Have recompiles in projects that use 'incremental' and 'watch' mode assume that changes within a file will only affect files directly depending on it."} + +var Specify_the_base_directory_to_resolve_non_relative_module_names = &Message{code: 6607, category: CategoryMessage, key: "Specify_the_base_directory_to_resolve_non_relative_module_names_6607", text: "Specify the base directory to resolve non-relative module names."} + +var No_longer_supported_In_early_versions_manually_set_the_text_encoding_for_reading_files = &Message{code: 6608, category: CategoryMessage, key: "No_longer_supported_In_early_versions_manually_set_the_text_encoding_for_reading_files_6608", text: "No longer supported. In early versions, manually set the text encoding for reading files."} + +var Enable_error_reporting_in_type_checked_JavaScript_files = &Message{code: 6609, category: CategoryMessage, key: "Enable_error_reporting_in_type_checked_JavaScript_files_6609", text: "Enable error reporting in type-checked JavaScript files."} + +var Enable_constraints_that_allow_a_TypeScript_project_to_be_used_with_project_references = &Message{code: 6611, category: CategoryMessage, key: "Enable_constraints_that_allow_a_TypeScript_project_to_be_used_with_project_references_6611", text: "Enable constraints that allow a TypeScript project to be used with project references."} + +var Generate_d_ts_files_from_TypeScript_and_JavaScript_files_in_your_project = &Message{code: 6612, category: CategoryMessage, key: "Generate_d_ts_files_from_TypeScript_and_JavaScript_files_in_your_project_6612", text: "Generate .d.ts files from TypeScript and JavaScript files in your project."} + +var Specify_the_output_directory_for_generated_declaration_files = &Message{code: 6613, category: CategoryMessage, key: "Specify_the_output_directory_for_generated_declaration_files_6613", text: "Specify the output directory for generated declaration files."} + +var Create_sourcemaps_for_d_ts_files = &Message{code: 6614, category: CategoryMessage, key: "Create_sourcemaps_for_d_ts_files_6614", text: "Create sourcemaps for d.ts files."} + +var Output_compiler_performance_information_after_building = &Message{code: 6615, category: CategoryMessage, key: "Output_compiler_performance_information_after_building_6615", text: "Output compiler performance information after building."} + +var Disables_inference_for_type_acquisition_by_looking_at_filenames_in_a_project = &Message{code: 6616, category: CategoryMessage, key: "Disables_inference_for_type_acquisition_by_looking_at_filenames_in_a_project_6616", text: "Disables inference for type acquisition by looking at filenames in a project."} + +var Reduce_the_number_of_projects_loaded_automatically_by_TypeScript = &Message{code: 6617, category: CategoryMessage, key: "Reduce_the_number_of_projects_loaded_automatically_by_TypeScript_6617", text: "Reduce the number of projects loaded automatically by TypeScript."} + +var Remove_the_20mb_cap_on_total_source_code_size_for_JavaScript_files_in_the_TypeScript_language_server = &Message{code: 6618, category: CategoryMessage, key: "Remove_the_20mb_cap_on_total_source_code_size_for_JavaScript_files_in_the_TypeScript_language_server_6618", text: "Remove the 20mb cap on total source code size for JavaScript files in the TypeScript language server."} + +var Opt_a_project_out_of_multi_project_reference_checking_when_editing = &Message{code: 6619, category: CategoryMessage, key: "Opt_a_project_out_of_multi_project_reference_checking_when_editing_6619", text: "Opt a project out of multi-project reference checking when editing."} + +var Disable_preferring_source_files_instead_of_declaration_files_when_referencing_composite_projects = &Message{code: 6620, category: CategoryMessage, key: "Disable_preferring_source_files_instead_of_declaration_files_when_referencing_composite_projects_6620", text: "Disable preferring source files instead of declaration files when referencing composite projects."} + +var Emit_more_compliant_but_verbose_and_less_performant_JavaScript_for_iteration = &Message{code: 6621, category: CategoryMessage, key: "Emit_more_compliant_but_verbose_and_less_performant_JavaScript_for_iteration_6621", text: "Emit more compliant, but verbose and less performant JavaScript for iteration."} + +var Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files = &Message{code: 6622, category: CategoryMessage, key: "Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files_6622", text: "Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files."} + +var Only_output_d_ts_files_and_not_JavaScript_files = &Message{code: 6623, category: CategoryMessage, key: "Only_output_d_ts_files_and_not_JavaScript_files_6623", text: "Only output d.ts files and not JavaScript files."} + +var Emit_design_type_metadata_for_decorated_declarations_in_source_files = &Message{code: 6624, category: CategoryMessage, key: "Emit_design_type_metadata_for_decorated_declarations_in_source_files_6624", text: "Emit design-type metadata for decorated declarations in source files."} + +var Disable_the_type_acquisition_for_JavaScript_projects = &Message{code: 6625, category: CategoryMessage, key: "Disable_the_type_acquisition_for_JavaScript_projects_6625", text: "Disable the type acquisition for JavaScript projects"} + +var Emit_additional_JavaScript_to_ease_support_for_importing_CommonJS_modules_This_enables_allowSyntheticDefaultImports_for_type_compatibility = &Message{code: 6626, category: CategoryMessage, key: "Emit_additional_JavaScript_to_ease_support_for_importing_CommonJS_modules_This_enables_allowSyntheti_6626", text: "Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility."} + +var Filters_results_from_the_include_option = &Message{code: 6627, category: CategoryMessage, key: "Filters_results_from_the_include_option_6627", text: "Filters results from the `include` option."} + +var Remove_a_list_of_directories_from_the_watch_process = &Message{code: 6628, category: CategoryMessage, key: "Remove_a_list_of_directories_from_the_watch_process_6628", text: "Remove a list of directories from the watch process."} + +var Remove_a_list_of_files_from_the_watch_mode_s_processing = &Message{code: 6629, category: CategoryMessage, key: "Remove_a_list_of_files_from_the_watch_mode_s_processing_6629", text: "Remove a list of files from the watch mode's processing."} + +var Enable_experimental_support_for_legacy_experimental_decorators = &Message{code: 6630, category: CategoryMessage, key: "Enable_experimental_support_for_legacy_experimental_decorators_6630", text: "Enable experimental support for legacy experimental decorators."} + +var Print_files_read_during_the_compilation_including_why_it_was_included = &Message{code: 6631, category: CategoryMessage, key: "Print_files_read_during_the_compilation_including_why_it_was_included_6631", text: "Print files read during the compilation including why it was included."} + +var Output_more_detailed_compiler_performance_information_after_building = &Message{code: 6632, category: CategoryMessage, key: "Output_more_detailed_compiler_performance_information_after_building_6632", text: "Output more detailed compiler performance information after building."} + +var Specify_one_or_more_path_or_node_module_references_to_base_configuration_files_from_which_settings_are_inherited = &Message{code: 6633, category: CategoryMessage, key: "Specify_one_or_more_path_or_node_module_references_to_base_configuration_files_from_which_settings_a_6633", text: "Specify one or more path or node module references to base configuration files from which settings are inherited."} + +var Specify_what_approach_the_watcher_should_use_if_the_system_runs_out_of_native_file_watchers = &Message{code: 6634, category: CategoryMessage, key: "Specify_what_approach_the_watcher_should_use_if_the_system_runs_out_of_native_file_watchers_6634", text: "Specify what approach the watcher should use if the system runs out of native file watchers."} + +var Include_a_list_of_files_This_does_not_support_glob_patterns_as_opposed_to_include = &Message{code: 6635, category: CategoryMessage, key: "Include_a_list_of_files_This_does_not_support_glob_patterns_as_opposed_to_include_6635", text: "Include a list of files. This does not support glob patterns, as opposed to `include`."} + +var Build_all_projects_including_those_that_appear_to_be_up_to_date = &Message{code: 6636, category: CategoryMessage, key: "Build_all_projects_including_those_that_appear_to_be_up_to_date_6636", text: "Build all projects, including those that appear to be up to date."} + +var Ensure_that_casing_is_correct_in_imports = &Message{code: 6637, category: CategoryMessage, key: "Ensure_that_casing_is_correct_in_imports_6637", text: "Ensure that casing is correct in imports."} + +var Emit_a_v8_CPU_profile_of_the_compiler_run_for_debugging = &Message{code: 6638, category: CategoryMessage, key: "Emit_a_v8_CPU_profile_of_the_compiler_run_for_debugging_6638", text: "Emit a v8 CPU profile of the compiler run for debugging."} + +var Allow_importing_helper_functions_from_tslib_once_per_project_instead_of_including_them_per_file = &Message{code: 6639, category: CategoryMessage, key: "Allow_importing_helper_functions_from_tslib_once_per_project_instead_of_including_them_per_file_6639", text: "Allow importing helper functions from tslib once per project, instead of including them per-file."} + +var Skip_building_downstream_projects_on_error_in_upstream_project = &Message{code: 6640, category: CategoryMessage, key: "Skip_building_downstream_projects_on_error_in_upstream_project_6640", text: "Skip building downstream projects on error in upstream project."} + +var Specify_a_list_of_glob_patterns_that_match_files_to_be_included_in_compilation = &Message{code: 6641, category: CategoryMessage, key: "Specify_a_list_of_glob_patterns_that_match_files_to_be_included_in_compilation_6641", text: "Specify a list of glob patterns that match files to be included in compilation."} + +var Save_tsbuildinfo_files_to_allow_for_incremental_compilation_of_projects = &Message{code: 6642, category: CategoryMessage, key: "Save_tsbuildinfo_files_to_allow_for_incremental_compilation_of_projects_6642", text: "Save .tsbuildinfo files to allow for incremental compilation of projects."} + +var Include_sourcemap_files_inside_the_emitted_JavaScript = &Message{code: 6643, category: CategoryMessage, key: "Include_sourcemap_files_inside_the_emitted_JavaScript_6643", text: "Include sourcemap files inside the emitted JavaScript."} + +var Include_source_code_in_the_sourcemaps_inside_the_emitted_JavaScript = &Message{code: 6644, category: CategoryMessage, key: "Include_source_code_in_the_sourcemaps_inside_the_emitted_JavaScript_6644", text: "Include source code in the sourcemaps inside the emitted JavaScript."} + +var Ensure_that_each_file_can_be_safely_transpiled_without_relying_on_other_imports = &Message{code: 6645, category: CategoryMessage, key: "Ensure_that_each_file_can_be_safely_transpiled_without_relying_on_other_imports_6645", text: "Ensure that each file can be safely transpiled without relying on other imports."} + +var Specify_what_JSX_code_is_generated = &Message{code: 6646, category: CategoryMessage, key: "Specify_what_JSX_code_is_generated_6646", text: "Specify what JSX code is generated."} + +var Specify_the_JSX_factory_function_used_when_targeting_React_JSX_emit_e_g_React_createElement_or_h = &Message{code: 6647, category: CategoryMessage, key: "Specify_the_JSX_factory_function_used_when_targeting_React_JSX_emit_e_g_React_createElement_or_h_6647", text: "Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'."} + +var Specify_the_JSX_Fragment_reference_used_for_fragments_when_targeting_React_JSX_emit_e_g_React_Fragment_or_Fragment = &Message{code: 6648, category: CategoryMessage, key: "Specify_the_JSX_Fragment_reference_used_for_fragments_when_targeting_React_JSX_emit_e_g_React_Fragme_6648", text: "Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'."} + +var Specify_module_specifier_used_to_import_the_JSX_factory_functions_when_using_jsx_Colon_react_jsx_Asterisk = &Message{code: 6649, category: CategoryMessage, key: "Specify_module_specifier_used_to_import_the_JSX_factory_functions_when_using_jsx_Colon_react_jsx_Ast_6649", text: "Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'."} + +var Make_keyof_only_return_strings_instead_of_string_numbers_or_symbols_Legacy_option = &Message{code: 6650, category: CategoryMessage, key: "Make_keyof_only_return_strings_instead_of_string_numbers_or_symbols_Legacy_option_6650", text: "Make keyof only return strings instead of string, numbers or symbols. Legacy option."} + +var Specify_a_set_of_bundled_library_declaration_files_that_describe_the_target_runtime_environment = &Message{code: 6651, category: CategoryMessage, key: "Specify_a_set_of_bundled_library_declaration_files_that_describe_the_target_runtime_environment_6651", text: "Specify a set of bundled library declaration files that describe the target runtime environment."} + +var Print_the_names_of_emitted_files_after_a_compilation = &Message{code: 6652, category: CategoryMessage, key: "Print_the_names_of_emitted_files_after_a_compilation_6652", text: "Print the names of emitted files after a compilation."} + +var Print_all_of_the_files_read_during_the_compilation = &Message{code: 6653, category: CategoryMessage, key: "Print_all_of_the_files_read_during_the_compilation_6653", text: "Print all of the files read during the compilation."} + +var Set_the_language_of_the_messaging_from_TypeScript_This_does_not_affect_emit = &Message{code: 6654, category: CategoryMessage, key: "Set_the_language_of_the_messaging_from_TypeScript_This_does_not_affect_emit_6654", text: "Set the language of the messaging from TypeScript. This does not affect emit."} + +var Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations = &Message{code: 6655, category: CategoryMessage, key: "Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations_6655", text: "Specify the location where debugger should locate map files instead of generated locations."} + +var Specify_the_maximum_folder_depth_used_for_checking_JavaScript_files_from_node_modules_Only_applicable_with_allowJs = &Message{code: 6656, category: CategoryMessage, key: "Specify_the_maximum_folder_depth_used_for_checking_JavaScript_files_from_node_modules_Only_applicabl_6656", text: "Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'."} + +var Specify_what_module_code_is_generated = &Message{code: 6657, category: CategoryMessage, key: "Specify_what_module_code_is_generated_6657", text: "Specify what module code is generated."} + +var Specify_how_TypeScript_looks_up_a_file_from_a_given_module_specifier = &Message{code: 6658, category: CategoryMessage, key: "Specify_how_TypeScript_looks_up_a_file_from_a_given_module_specifier_6658", text: "Specify how TypeScript looks up a file from a given module specifier."} + +var Set_the_newline_character_for_emitting_files = &Message{code: 6659, category: CategoryMessage, key: "Set_the_newline_character_for_emitting_files_6659", text: "Set the newline character for emitting files."} + +var Disable_emitting_files_from_a_compilation = &Message{code: 6660, category: CategoryMessage, key: "Disable_emitting_files_from_a_compilation_6660", text: "Disable emitting files from a compilation."} + +var Disable_generating_custom_helper_functions_like_extends_in_compiled_output = &Message{code: 6661, category: CategoryMessage, key: "Disable_generating_custom_helper_functions_like_extends_in_compiled_output_6661", text: "Disable generating custom helper functions like '__extends' in compiled output."} + +var Disable_emitting_files_if_any_type_checking_errors_are_reported = &Message{code: 6662, category: CategoryMessage, key: "Disable_emitting_files_if_any_type_checking_errors_are_reported_6662", text: "Disable emitting files if any type checking errors are reported."} + +var Disable_truncating_types_in_error_messages = &Message{code: 6663, category: CategoryMessage, key: "Disable_truncating_types_in_error_messages_6663", text: "Disable truncating types in error messages."} + +var Enable_error_reporting_for_fallthrough_cases_in_switch_statements = &Message{code: 6664, category: CategoryMessage, key: "Enable_error_reporting_for_fallthrough_cases_in_switch_statements_6664", text: "Enable error reporting for fallthrough cases in switch statements."} + +var Enable_error_reporting_for_expressions_and_declarations_with_an_implied_any_type = &Message{code: 6665, category: CategoryMessage, key: "Enable_error_reporting_for_expressions_and_declarations_with_an_implied_any_type_6665", text: "Enable error reporting for expressions and declarations with an implied 'any' type."} + +var Ensure_overriding_members_in_derived_classes_are_marked_with_an_override_modifier = &Message{code: 6666, category: CategoryMessage, key: "Ensure_overriding_members_in_derived_classes_are_marked_with_an_override_modifier_6666", text: "Ensure overriding members in derived classes are marked with an override modifier."} + +var Enable_error_reporting_for_codepaths_that_do_not_explicitly_return_in_a_function = &Message{code: 6667, category: CategoryMessage, key: "Enable_error_reporting_for_codepaths_that_do_not_explicitly_return_in_a_function_6667", text: "Enable error reporting for codepaths that do not explicitly return in a function."} + +var Enable_error_reporting_when_this_is_given_the_type_any = &Message{code: 6668, category: CategoryMessage, key: "Enable_error_reporting_when_this_is_given_the_type_any_6668", text: "Enable error reporting when 'this' is given the type 'any'."} + +var Disable_adding_use_strict_directives_in_emitted_JavaScript_files = &Message{code: 6669, category: CategoryMessage, key: "Disable_adding_use_strict_directives_in_emitted_JavaScript_files_6669", text: "Disable adding 'use strict' directives in emitted JavaScript files."} + +var Disable_including_any_library_files_including_the_default_lib_d_ts = &Message{code: 6670, category: CategoryMessage, key: "Disable_including_any_library_files_including_the_default_lib_d_ts_6670", text: "Disable including any library files, including the default lib.d.ts."} + +var Enforces_using_indexed_accessors_for_keys_declared_using_an_indexed_type = &Message{code: 6671, category: CategoryMessage, key: "Enforces_using_indexed_accessors_for_keys_declared_using_an_indexed_type_6671", text: "Enforces using indexed accessors for keys declared using an indexed type."} + +var Disallow_import_s_require_s_or_reference_s_from_expanding_the_number_of_files_TypeScript_should_add_to_a_project = &Message{code: 6672, category: CategoryMessage, key: "Disallow_import_s_require_s_or_reference_s_from_expanding_the_number_of_files_TypeScript_should_add__6672", text: "Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project."} + +var Disable_strict_checking_of_generic_signatures_in_function_types = &Message{code: 6673, category: CategoryMessage, key: "Disable_strict_checking_of_generic_signatures_in_function_types_6673", text: "Disable strict checking of generic signatures in function types."} + +var Add_undefined_to_a_type_when_accessed_using_an_index = &Message{code: 6674, category: CategoryMessage, key: "Add_undefined_to_a_type_when_accessed_using_an_index_6674", text: "Add 'undefined' to a type when accessed using an index."} + +var Enable_error_reporting_when_local_variables_aren_t_read = &Message{code: 6675, category: CategoryMessage, key: "Enable_error_reporting_when_local_variables_aren_t_read_6675", text: "Enable error reporting when local variables aren't read."} + +var Raise_an_error_when_a_function_parameter_isn_t_read = &Message{code: 6676, category: CategoryMessage, key: "Raise_an_error_when_a_function_parameter_isn_t_read_6676", text: "Raise an error when a function parameter isn't read."} + +var Deprecated_setting_Use_outFile_instead = &Message{code: 6677, category: CategoryMessage, key: "Deprecated_setting_Use_outFile_instead_6677", text: "Deprecated setting. Use 'outFile' instead."} + +var Specify_an_output_folder_for_all_emitted_files = &Message{code: 6678, category: CategoryMessage, key: "Specify_an_output_folder_for_all_emitted_files_6678", text: "Specify an output folder for all emitted files."} + +var Specify_a_file_that_bundles_all_outputs_into_one_JavaScript_file_If_declaration_is_true_also_designates_a_file_that_bundles_all_d_ts_output = &Message{code: 6679, category: CategoryMessage, key: "Specify_a_file_that_bundles_all_outputs_into_one_JavaScript_file_If_declaration_is_true_also_designa_6679", text: "Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output."} + +var Specify_a_set_of_entries_that_re_map_imports_to_additional_lookup_locations = &Message{code: 6680, category: CategoryMessage, key: "Specify_a_set_of_entries_that_re_map_imports_to_additional_lookup_locations_6680", text: "Specify a set of entries that re-map imports to additional lookup locations."} + +var Specify_a_list_of_language_service_plugins_to_include = &Message{code: 6681, category: CategoryMessage, key: "Specify_a_list_of_language_service_plugins_to_include_6681", text: "Specify a list of language service plugins to include."} + +var Disable_erasing_const_enum_declarations_in_generated_code = &Message{code: 6682, category: CategoryMessage, key: "Disable_erasing_const_enum_declarations_in_generated_code_6682", text: "Disable erasing 'const enum' declarations in generated code."} + +var Disable_resolving_symlinks_to_their_realpath_This_correlates_to_the_same_flag_in_node = &Message{code: 6683, category: CategoryMessage, key: "Disable_resolving_symlinks_to_their_realpath_This_correlates_to_the_same_flag_in_node_6683", text: "Disable resolving symlinks to their realpath. This correlates to the same flag in node."} + +var Disable_wiping_the_console_in_watch_mode = &Message{code: 6684, category: CategoryMessage, key: "Disable_wiping_the_console_in_watch_mode_6684", text: "Disable wiping the console in watch mode."} + +var Enable_color_and_formatting_in_TypeScript_s_output_to_make_compiler_errors_easier_to_read = &Message{code: 6685, category: CategoryMessage, key: "Enable_color_and_formatting_in_TypeScript_s_output_to_make_compiler_errors_easier_to_read_6685", text: "Enable color and formatting in TypeScript's output to make compiler errors easier to read."} + +var Specify_the_object_invoked_for_createElement_This_only_applies_when_targeting_react_JSX_emit = &Message{code: 6686, category: CategoryMessage, key: "Specify_the_object_invoked_for_createElement_This_only_applies_when_targeting_react_JSX_emit_6686", text: "Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit."} + +var Specify_an_array_of_objects_that_specify_paths_for_projects_Used_in_project_references = &Message{code: 6687, category: CategoryMessage, key: "Specify_an_array_of_objects_that_specify_paths_for_projects_Used_in_project_references_6687", text: "Specify an array of objects that specify paths for projects. Used in project references."} + +var Disable_emitting_comments = &Message{code: 6688, category: CategoryMessage, key: "Disable_emitting_comments_6688", text: "Disable emitting comments."} + +var Enable_importing_json_files = &Message{code: 6689, category: CategoryMessage, key: "Enable_importing_json_files_6689", text: "Enable importing .json files."} + +var Specify_the_root_folder_within_your_source_files = &Message{code: 6690, category: CategoryMessage, key: "Specify_the_root_folder_within_your_source_files_6690", text: "Specify the root folder within your source files."} + +var Allow_multiple_folders_to_be_treated_as_one_when_resolving_modules = &Message{code: 6691, category: CategoryMessage, key: "Allow_multiple_folders_to_be_treated_as_one_when_resolving_modules_6691", text: "Allow multiple folders to be treated as one when resolving modules."} + +var Skip_type_checking_d_ts_files_that_are_included_with_TypeScript = &Message{code: 6692, category: CategoryMessage, key: "Skip_type_checking_d_ts_files_that_are_included_with_TypeScript_6692", text: "Skip type checking .d.ts files that are included with TypeScript."} + +var Skip_type_checking_all_d_ts_files = &Message{code: 6693, category: CategoryMessage, key: "Skip_type_checking_all_d_ts_files_6693", text: "Skip type checking all .d.ts files."} + +var Create_source_map_files_for_emitted_JavaScript_files = &Message{code: 6694, category: CategoryMessage, key: "Create_source_map_files_for_emitted_JavaScript_files_6694", text: "Create source map files for emitted JavaScript files."} + +var Specify_the_root_path_for_debuggers_to_find_the_reference_source_code = &Message{code: 6695, category: CategoryMessage, key: "Specify_the_root_path_for_debuggers_to_find_the_reference_source_code_6695", text: "Specify the root path for debuggers to find the reference source code."} + +var Check_that_the_arguments_for_bind_call_and_apply_methods_match_the_original_function = &Message{code: 6697, category: CategoryMessage, key: "Check_that_the_arguments_for_bind_call_and_apply_methods_match_the_original_function_6697", text: "Check that the arguments for 'bind', 'call', and 'apply' methods match the original function."} + +var When_assigning_functions_check_to_ensure_parameters_and_the_return_values_are_subtype_compatible = &Message{code: 6698, category: CategoryMessage, key: "When_assigning_functions_check_to_ensure_parameters_and_the_return_values_are_subtype_compatible_6698", text: "When assigning functions, check to ensure parameters and the return values are subtype-compatible."} + +var When_type_checking_take_into_account_null_and_undefined = &Message{code: 6699, category: CategoryMessage, key: "When_type_checking_take_into_account_null_and_undefined_6699", text: "When type checking, take into account 'null' and 'undefined'."} + +var Check_for_class_properties_that_are_declared_but_not_set_in_the_constructor = &Message{code: 6700, category: CategoryMessage, key: "Check_for_class_properties_that_are_declared_but_not_set_in_the_constructor_6700", text: "Check for class properties that are declared but not set in the constructor."} + +var Disable_emitting_declarations_that_have_internal_in_their_JSDoc_comments = &Message{code: 6701, category: CategoryMessage, key: "Disable_emitting_declarations_that_have_internal_in_their_JSDoc_comments_6701", text: "Disable emitting declarations that have '@internal' in their JSDoc comments."} + +var Disable_reporting_of_excess_property_errors_during_the_creation_of_object_literals = &Message{code: 6702, category: CategoryMessage, key: "Disable_reporting_of_excess_property_errors_during_the_creation_of_object_literals_6702", text: "Disable reporting of excess property errors during the creation of object literals."} + +var Suppress_noImplicitAny_errors_when_indexing_objects_that_lack_index_signatures = &Message{code: 6703, category: CategoryMessage, key: "Suppress_noImplicitAny_errors_when_indexing_objects_that_lack_index_signatures_6703", text: "Suppress 'noImplicitAny' errors when indexing objects that lack index signatures."} + +var Synchronously_call_callbacks_and_update_the_state_of_directory_watchers_on_platforms_that_don_t_support_recursive_watching_natively = &Message{code: 6704, category: CategoryMessage, key: "Synchronously_call_callbacks_and_update_the_state_of_directory_watchers_on_platforms_that_don_t_supp_6704", text: "Synchronously call callbacks and update the state of directory watchers on platforms that don`t support recursive watching natively."} + +var Set_the_JavaScript_language_version_for_emitted_JavaScript_and_include_compatible_library_declarations = &Message{code: 6705, category: CategoryMessage, key: "Set_the_JavaScript_language_version_for_emitted_JavaScript_and_include_compatible_library_declaratio_6705", text: "Set the JavaScript language version for emitted JavaScript and include compatible library declarations."} + +var Log_paths_used_during_the_moduleResolution_process = &Message{code: 6706, category: CategoryMessage, key: "Log_paths_used_during_the_moduleResolution_process_6706", text: "Log paths used during the 'moduleResolution' process."} + +var Specify_the_path_to_tsbuildinfo_incremental_compilation_file = &Message{code: 6707, category: CategoryMessage, key: "Specify_the_path_to_tsbuildinfo_incremental_compilation_file_6707", text: "Specify the path to .tsbuildinfo incremental compilation file."} + +var Specify_options_for_automatic_acquisition_of_declaration_files = &Message{code: 6709, category: CategoryMessage, key: "Specify_options_for_automatic_acquisition_of_declaration_files_6709", text: "Specify options for automatic acquisition of declaration files."} + +var Specify_multiple_folders_that_act_like_Slashnode_modules_Slash_types = &Message{code: 6710, category: CategoryMessage, key: "Specify_multiple_folders_that_act_like_Slashnode_modules_Slash_types_6710", text: "Specify multiple folders that act like './node_modules/@types'."} + +var Specify_type_package_names_to_be_included_without_being_referenced_in_a_source_file = &Message{code: 6711, category: CategoryMessage, key: "Specify_type_package_names_to_be_included_without_being_referenced_in_a_source_file_6711", text: "Specify type package names to be included without being referenced in a source file."} + +var Emit_ECMAScript_standard_compliant_class_fields = &Message{code: 6712, category: CategoryMessage, key: "Emit_ECMAScript_standard_compliant_class_fields_6712", text: "Emit ECMAScript-standard-compliant class fields."} + +var Enable_verbose_logging = &Message{code: 6713, category: CategoryMessage, key: "Enable_verbose_logging_6713", text: "Enable verbose logging."} + +var Specify_how_directories_are_watched_on_systems_that_lack_recursive_file_watching_functionality = &Message{code: 6714, category: CategoryMessage, key: "Specify_how_directories_are_watched_on_systems_that_lack_recursive_file_watching_functionality_6714", text: "Specify how directories are watched on systems that lack recursive file-watching functionality."} + +var Specify_how_the_TypeScript_watch_mode_works = &Message{code: 6715, category: CategoryMessage, key: "Specify_how_the_TypeScript_watch_mode_works_6715", text: "Specify how the TypeScript watch mode works."} + +var Require_undeclared_properties_from_index_signatures_to_use_element_accesses = &Message{code: 6717, category: CategoryMessage, key: "Require_undeclared_properties_from_index_signatures_to_use_element_accesses_6717", text: "Require undeclared properties from index signatures to use element accesses."} + +var Specify_emit_Slashchecking_behavior_for_imports_that_are_only_used_for_types = &Message{code: 6718, category: CategoryMessage, key: "Specify_emit_Slashchecking_behavior_for_imports_that_are_only_used_for_types_6718", text: "Specify emit/checking behavior for imports that are only used for types."} + +var Require_sufficient_annotation_on_exports_so_other_tools_can_trivially_generate_declaration_files = &Message{code: 6719, category: CategoryMessage, key: "Require_sufficient_annotation_on_exports_so_other_tools_can_trivially_generate_declaration_files_6719", text: "Require sufficient annotation on exports so other tools can trivially generate declaration files."} + +var Built_in_iterators_are_instantiated_with_a_TReturn_type_of_undefined_instead_of_any = &Message{code: 6720, category: CategoryMessage, key: "Built_in_iterators_are_instantiated_with_a_TReturn_type_of_undefined_instead_of_any_6720", text: "Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'."} + +var Do_not_allow_runtime_constructs_that_are_not_part_of_ECMAScript = &Message{code: 6721, category: CategoryMessage, key: "Do_not_allow_runtime_constructs_that_are_not_part_of_ECMAScript_6721", text: "Do not allow runtime constructs that are not part of ECMAScript."} + +var Default_catch_clause_variables_as_unknown_instead_of_any = &Message{code: 6803, category: CategoryMessage, key: "Default_catch_clause_variables_as_unknown_instead_of_any_6803", text: "Default catch clause variables as 'unknown' instead of 'any'."} + +var Do_not_transform_or_elide_any_imports_or_exports_not_marked_as_type_only_ensuring_they_are_written_in_the_output_file_s_format_based_on_the_module_setting = &Message{code: 6804, category: CategoryMessage, key: "Do_not_transform_or_elide_any_imports_or_exports_not_marked_as_type_only_ensuring_they_are_written_i_6804", text: "Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting."} + +var Disable_full_type_checking_only_critical_parse_and_emit_errors_will_be_reported = &Message{code: 6805, category: CategoryMessage, key: "Disable_full_type_checking_only_critical_parse_and_emit_errors_will_be_reported_6805", text: "Disable full type checking (only critical parse and emit errors will be reported)."} + +var Check_side_effect_imports = &Message{code: 6806, category: CategoryMessage, key: "Check_side_effect_imports_6806", text: "Check side effect imports."} + +var This_operation_can_be_simplified_This_shift_is_identical_to_0_1_2 = &Message{code: 6807, category: CategoryError, key: "This_operation_can_be_simplified_This_shift_is_identical_to_0_1_2_6807", text: "This operation can be simplified. This shift is identical to `{0} {1} {2}`."} + +var Enable_lib_replacement = &Message{code: 6808, category: CategoryMessage, key: "Enable_lib_replacement_6808", text: "Enable lib replacement."} + +var X_one_of_Colon = &Message{code: 6900, category: CategoryMessage, key: "one_of_Colon_6900", text: "one of:"} + +var X_one_or_more_Colon = &Message{code: 6901, category: CategoryMessage, key: "one_or_more_Colon_6901", text: "one or more:"} + +var X_type_Colon = &Message{code: 6902, category: CategoryMessage, key: "type_Colon_6902", text: "type:"} + +var X_default_Colon = &Message{code: 6903, category: CategoryMessage, key: "default_Colon_6903", text: "default:"} + +var X_module_system_or_esModuleInterop = &Message{code: 6904, category: CategoryMessage, key: "module_system_or_esModuleInterop_6904", text: "module === \"system\" or esModuleInterop"} + +var X_false_unless_strict_is_set = &Message{code: 6905, category: CategoryMessage, key: "false_unless_strict_is_set_6905", text: "`false`, unless `strict` is set"} + +var X_false_unless_composite_is_set = &Message{code: 6906, category: CategoryMessage, key: "false_unless_composite_is_set_6906", text: "`false`, unless `composite` is set"} + +var X_node_modules_bower_components_jspm_packages_plus_the_value_of_outDir_if_one_is_specified = &Message{code: 6907, category: CategoryMessage, key: "node_modules_bower_components_jspm_packages_plus_the_value_of_outDir_if_one_is_specified_6907", text: "`[\"node_modules\", \"bower_components\", \"jspm_packages\"]`, plus the value of `outDir` if one is specified."} + +var X_if_files_is_specified_otherwise_Asterisk_Asterisk_Slash_Asterisk = &Message{code: 6908, category: CategoryMessage, key: "if_files_is_specified_otherwise_Asterisk_Asterisk_Slash_Asterisk_6908", text: "`[]` if `files` is specified, otherwise `[\"**/*\"]`"} + +var X_true_if_composite_false_otherwise = &Message{code: 6909, category: CategoryMessage, key: "true_if_composite_false_otherwise_6909", text: "`true` if `composite`, `false` otherwise"} + +var Computed_from_the_list_of_input_files = &Message{code: 6911, category: CategoryMessage, key: "Computed_from_the_list_of_input_files_6911", text: "Computed from the list of input files"} + +var Platform_specific = &Message{code: 6912, category: CategoryMessage, key: "Platform_specific_6912", text: "Platform specific"} + +var You_can_learn_about_all_of_the_compiler_options_at_0 = &Message{code: 6913, category: CategoryMessage, key: "You_can_learn_about_all_of_the_compiler_options_at_0_6913", text: "You can learn about all of the compiler options at {0}"} + +var Including_watch_w_will_start_watching_the_current_project_for_the_file_changes_Once_set_you_can_config_watch_mode_with_Colon = &Message{code: 6914, category: CategoryMessage, key: "Including_watch_w_will_start_watching_the_current_project_for_the_file_changes_Once_set_you_can_conf_6914", text: "Including --watch, -w will start watching the current project for the file changes. Once set, you can config watch mode with:"} + +var Using_build_b_will_make_tsc_behave_more_like_a_build_orchestrator_than_a_compiler_This_is_used_to_trigger_building_composite_projects_which_you_can_learn_more_about_at_0 = &Message{code: 6915, category: CategoryMessage, key: "Using_build_b_will_make_tsc_behave_more_like_a_build_orchestrator_than_a_compiler_This_is_used_to_tr_6915", text: "Using --build, -b will make tsc behave more like a build orchestrator than a compiler. This is used to trigger building composite projects which you can learn more about at {0}"} + +var COMMON_COMMANDS = &Message{code: 6916, category: CategoryMessage, key: "COMMON_COMMANDS_6916", text: "COMMON COMMANDS"} + +var ALL_COMPILER_OPTIONS = &Message{code: 6917, category: CategoryMessage, key: "ALL_COMPILER_OPTIONS_6917", text: "ALL COMPILER OPTIONS"} + +var WATCH_OPTIONS = &Message{code: 6918, category: CategoryMessage, key: "WATCH_OPTIONS_6918", text: "WATCH OPTIONS"} + +var BUILD_OPTIONS = &Message{code: 6919, category: CategoryMessage, key: "BUILD_OPTIONS_6919", text: "BUILD OPTIONS"} + +var COMMON_COMPILER_OPTIONS = &Message{code: 6920, category: CategoryMessage, key: "COMMON_COMPILER_OPTIONS_6920", text: "COMMON COMPILER OPTIONS"} + +var COMMAND_LINE_FLAGS = &Message{code: 6921, category: CategoryMessage, key: "COMMAND_LINE_FLAGS_6921", text: "COMMAND LINE FLAGS"} + +var X_tsc_Colon_The_TypeScript_Compiler = &Message{code: 6922, category: CategoryMessage, key: "tsc_Colon_The_TypeScript_Compiler_6922", text: "tsc: The TypeScript Compiler"} + +var Compiles_the_current_project_tsconfig_json_in_the_working_directory = &Message{code: 6923, category: CategoryMessage, key: "Compiles_the_current_project_tsconfig_json_in_the_working_directory_6923", text: "Compiles the current project (tsconfig.json in the working directory.)"} + +var Ignoring_tsconfig_json_compiles_the_specified_files_with_default_compiler_options = &Message{code: 6924, category: CategoryMessage, key: "Ignoring_tsconfig_json_compiles_the_specified_files_with_default_compiler_options_6924", text: "Ignoring tsconfig.json, compiles the specified files with default compiler options."} + +var Build_a_composite_project_in_the_working_directory = &Message{code: 6925, category: CategoryMessage, key: "Build_a_composite_project_in_the_working_directory_6925", text: "Build a composite project in the working directory."} + +var Creates_a_tsconfig_json_with_the_recommended_settings_in_the_working_directory = &Message{code: 6926, category: CategoryMessage, key: "Creates_a_tsconfig_json_with_the_recommended_settings_in_the_working_directory_6926", text: "Creates a tsconfig.json with the recommended settings in the working directory."} + +var Compiles_the_TypeScript_project_located_at_the_specified_path = &Message{code: 6927, category: CategoryMessage, key: "Compiles_the_TypeScript_project_located_at_the_specified_path_6927", text: "Compiles the TypeScript project located at the specified path."} + +var An_expanded_version_of_this_information_showing_all_possible_compiler_options = &Message{code: 6928, category: CategoryMessage, key: "An_expanded_version_of_this_information_showing_all_possible_compiler_options_6928", text: "An expanded version of this information, showing all possible compiler options"} + +var Compiles_the_current_project_with_additional_settings = &Message{code: 6929, category: CategoryMessage, key: "Compiles_the_current_project_with_additional_settings_6929", text: "Compiles the current project, with additional settings."} + +var X_true_for_ES2022_and_above_including_ESNext = &Message{code: 6930, category: CategoryMessage, key: "true_for_ES2022_and_above_including_ESNext_6930", text: "`true` for ES2022 and above, including ESNext."} + +var List_of_file_name_suffixes_to_search_when_resolving_a_module = &Message{code: 6931, category: CategoryError, key: "List_of_file_name_suffixes_to_search_when_resolving_a_module_6931", text: "List of file name suffixes to search when resolving a module."} + +var Variable_0_implicitly_has_an_1_type = &Message{code: 7005, category: CategoryError, key: "Variable_0_implicitly_has_an_1_type_7005", text: "Variable '{0}' implicitly has an '{1}' type."} + +var Parameter_0_implicitly_has_an_1_type = &Message{code: 7006, category: CategoryError, key: "Parameter_0_implicitly_has_an_1_type_7006", text: "Parameter '{0}' implicitly has an '{1}' type."} + +var Member_0_implicitly_has_an_1_type = &Message{code: 7008, category: CategoryError, key: "Member_0_implicitly_has_an_1_type_7008", text: "Member '{0}' implicitly has an '{1}' type."} + +var X_new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type = &Message{code: 7009, category: CategoryError, key: "new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type_7009", text: "'new' expression, whose target lacks a construct signature, implicitly has an 'any' type."} + +var X_0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type = &Message{code: 7010, category: CategoryError, key: "_0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type_7010", text: "'{0}', which lacks return-type annotation, implicitly has an '{1}' return type."} + +var Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type = &Message{code: 7011, category: CategoryError, key: "Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type_7011", text: "Function expression, which lacks return-type annotation, implicitly has an '{0}' return type."} + +var This_overload_implicitly_returns_the_type_0_because_it_lacks_a_return_type_annotation = &Message{code: 7012, category: CategoryError, key: "This_overload_implicitly_returns_the_type_0_because_it_lacks_a_return_type_annotation_7012", text: "This overload implicitly returns the type '{0}' because it lacks a return type annotation."} + +var Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type = &Message{code: 7013, category: CategoryError, key: "Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type_7013", text: "Construct signature, which lacks return-type annotation, implicitly has an 'any' return type."} + +var Function_type_which_lacks_return_type_annotation_implicitly_has_an_0_return_type = &Message{code: 7014, category: CategoryError, key: "Function_type_which_lacks_return_type_annotation_implicitly_has_an_0_return_type_7014", text: "Function type, which lacks return-type annotation, implicitly has an '{0}' return type."} + +var Element_implicitly_has_an_any_type_because_index_expression_is_not_of_type_number = &Message{code: 7015, category: CategoryError, key: "Element_implicitly_has_an_any_type_because_index_expression_is_not_of_type_number_7015", text: "Element implicitly has an 'any' type because index expression is not of type 'number'."} + +var Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type = &Message{code: 7016, category: CategoryError, key: "Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type_7016", text: "Could not find a declaration file for module '{0}'. '{1}' implicitly has an 'any' type."} + +var Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature = &Message{code: 7017, category: CategoryError, key: "Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature_7017", text: "Element implicitly has an 'any' type because type '{0}' has no index signature."} + +var Object_literal_s_property_0_implicitly_has_an_1_type = &Message{code: 7018, category: CategoryError, key: "Object_literal_s_property_0_implicitly_has_an_1_type_7018", text: "Object literal's property '{0}' implicitly has an '{1}' type."} + +var Rest_parameter_0_implicitly_has_an_any_type = &Message{code: 7019, category: CategoryError, key: "Rest_parameter_0_implicitly_has_an_any_type_7019", text: "Rest parameter '{0}' implicitly has an 'any[]' type."} + +var Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type = &Message{code: 7020, category: CategoryError, key: "Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type_7020", text: "Call signature, which lacks return-type annotation, implicitly has an 'any' return type."} + +var X_0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer = &Message{code: 7022, category: CategoryError, key: "_0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or__7022", text: "'{0}' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer."} + +var X_0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions = &Message{code: 7023, category: CategoryError, key: "_0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_reference_7023", text: "'{0}' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions."} + +var Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions = &Message{code: 7024, category: CategoryError, key: "Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_ref_7024", text: "Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions."} + +var Generator_implicitly_has_yield_type_0_Consider_supplying_a_return_type_annotation = &Message{code: 7025, category: CategoryError, key: "Generator_implicitly_has_yield_type_0_Consider_supplying_a_return_type_annotation_7025", text: "Generator implicitly has yield type '{0}'. Consider supplying a return type annotation."} + +var JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists = &Message{code: 7026, category: CategoryError, key: "JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists_7026", text: "JSX element implicitly has type 'any' because no interface 'JSX.{0}' exists."} + +var Unreachable_code_detected = &Message{code: 7027, category: CategoryError, key: "Unreachable_code_detected_7027", text: "Unreachable code detected.", reportsUnnecessary: true} + +var Unused_label = &Message{code: 7028, category: CategoryError, key: "Unused_label_7028", text: "Unused label.", reportsUnnecessary: true} + +var Fallthrough_case_in_switch = &Message{code: 7029, category: CategoryError, key: "Fallthrough_case_in_switch_7029", text: "Fallthrough case in switch."} + +var Not_all_code_paths_return_a_value = &Message{code: 7030, category: CategoryError, key: "Not_all_code_paths_return_a_value_7030", text: "Not all code paths return a value."} + +var Binding_element_0_implicitly_has_an_1_type = &Message{code: 7031, category: CategoryError, key: "Binding_element_0_implicitly_has_an_1_type_7031", text: "Binding element '{0}' implicitly has an '{1}' type."} + +var Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation = &Message{code: 7032, category: CategoryError, key: "Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation_7032", text: "Property '{0}' implicitly has type 'any', because its set accessor lacks a parameter type annotation."} + +var Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation = &Message{code: 7033, category: CategoryError, key: "Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation_7033", text: "Property '{0}' implicitly has type 'any', because its get accessor lacks a return type annotation."} + +var Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined = &Message{code: 7034, category: CategoryError, key: "Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined_7034", text: "Variable '{0}' implicitly has type '{1}' in some locations where its type cannot be determined."} + +var Try_npm_i_save_dev_types_Slash_1_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_module_0 = &Message{code: 7035, category: CategoryError, key: "Try_npm_i_save_dev_types_Slash_1_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare__7035", text: "Try `npm i --save-dev @types/{1}` if it exists or add a new declaration (.d.ts) file containing `declare module '{0}';`"} + +var Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0 = &Message{code: 7036, category: CategoryError, key: "Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0_7036", text: "Dynamic import's specifier must be of type 'string', but here has type '{0}'."} + +var Enables_emit_interoperability_between_CommonJS_and_ES_Modules_via_creation_of_namespace_objects_for_all_imports_Implies_allowSyntheticDefaultImports = &Message{code: 7037, category: CategoryMessage, key: "Enables_emit_interoperability_between_CommonJS_and_ES_Modules_via_creation_of_namespace_objects_for__7037", text: "Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'."} + +var Type_originates_at_this_import_A_namespace_style_import_cannot_be_called_or_constructed_and_will_cause_a_failure_at_runtime_Consider_using_a_default_import_or_import_require_here_instead = &Message{code: 7038, category: CategoryMessage, key: "Type_originates_at_this_import_A_namespace_style_import_cannot_be_called_or_constructed_and_will_cau_7038", text: "Type originates at this import. A namespace-style import cannot be called or constructed, and will cause a failure at runtime. Consider using a default import or import require here instead."} + +var Mapped_object_type_implicitly_has_an_any_template_type = &Message{code: 7039, category: CategoryError, key: "Mapped_object_type_implicitly_has_an_any_template_type_7039", text: "Mapped object type implicitly has an 'any' template type."} + +var If_the_0_package_actually_exposes_this_module_consider_sending_a_pull_request_to_amend_https_Colon_Slash_Slashgithub_com_SlashDefinitelyTyped_SlashDefinitelyTyped_Slashtree_Slashmaster_Slashtypes_Slash_1 = &Message{code: 7040, category: CategoryError, key: "If_the_0_package_actually_exposes_this_module_consider_sending_a_pull_request_to_amend_https_Colon_S_7040", text: "If the '{0}' package actually exposes this module, consider sending a pull request to amend 'https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/{1}'"} + +var The_containing_arrow_function_captures_the_global_value_of_this = &Message{code: 7041, category: CategoryError, key: "The_containing_arrow_function_captures_the_global_value_of_this_7041", text: "The containing arrow function captures the global value of 'this'."} + +var Module_0_was_resolved_to_1_but_resolveJsonModule_is_not_used = &Message{code: 7042, category: CategoryError, key: "Module_0_was_resolved_to_1_but_resolveJsonModule_is_not_used_7042", text: "Module '{0}' was resolved to '{1}', but '--resolveJsonModule' is not used."} + +var Variable_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage = &Message{code: 7043, category: CategorySuggestion, key: "Variable_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage_7043", text: "Variable '{0}' implicitly has an '{1}' type, but a better type may be inferred from usage."} + +var Parameter_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage = &Message{code: 7044, category: CategorySuggestion, key: "Parameter_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage_7044", text: "Parameter '{0}' implicitly has an '{1}' type, but a better type may be inferred from usage."} + +var Member_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage = &Message{code: 7045, category: CategorySuggestion, key: "Member_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage_7045", text: "Member '{0}' implicitly has an '{1}' type, but a better type may be inferred from usage."} + +var Variable_0_implicitly_has_type_1_in_some_locations_but_a_better_type_may_be_inferred_from_usage = &Message{code: 7046, category: CategorySuggestion, key: "Variable_0_implicitly_has_type_1_in_some_locations_but_a_better_type_may_be_inferred_from_usage_7046", text: "Variable '{0}' implicitly has type '{1}' in some locations, but a better type may be inferred from usage."} + +var Rest_parameter_0_implicitly_has_an_any_type_but_a_better_type_may_be_inferred_from_usage = &Message{code: 7047, category: CategorySuggestion, key: "Rest_parameter_0_implicitly_has_an_any_type_but_a_better_type_may_be_inferred_from_usage_7047", text: "Rest parameter '{0}' implicitly has an 'any[]' type, but a better type may be inferred from usage."} + +var Property_0_implicitly_has_type_any_but_a_better_type_for_its_get_accessor_may_be_inferred_from_usage = &Message{code: 7048, category: CategorySuggestion, key: "Property_0_implicitly_has_type_any_but_a_better_type_for_its_get_accessor_may_be_inferred_from_usage_7048", text: "Property '{0}' implicitly has type 'any', but a better type for its get accessor may be inferred from usage."} + +var Property_0_implicitly_has_type_any_but_a_better_type_for_its_set_accessor_may_be_inferred_from_usage = &Message{code: 7049, category: CategorySuggestion, key: "Property_0_implicitly_has_type_any_but_a_better_type_for_its_set_accessor_may_be_inferred_from_usage_7049", text: "Property '{0}' implicitly has type 'any', but a better type for its set accessor may be inferred from usage."} + +var X_0_implicitly_has_an_1_return_type_but_a_better_type_may_be_inferred_from_usage = &Message{code: 7050, category: CategorySuggestion, key: "_0_implicitly_has_an_1_return_type_but_a_better_type_may_be_inferred_from_usage_7050", text: "'{0}' implicitly has an '{1}' return type, but a better type may be inferred from usage."} + +var Parameter_has_a_name_but_no_type_Did_you_mean_0_Colon_1 = &Message{code: 7051, category: CategoryError, key: "Parameter_has_a_name_but_no_type_Did_you_mean_0_Colon_1_7051", text: "Parameter has a name but no type. Did you mean '{0}: {1}'?"} + +var Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature_Did_you_mean_to_call_1 = &Message{code: 7052, category: CategoryError, key: "Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature_Did_you_mean_to_call_1_7052", text: "Element implicitly has an 'any' type because type '{0}' has no index signature. Did you mean to call '{1}'?"} + +var Element_implicitly_has_an_any_type_because_expression_of_type_0_can_t_be_used_to_index_type_1 = &Message{code: 7053, category: CategoryError, key: "Element_implicitly_has_an_any_type_because_expression_of_type_0_can_t_be_used_to_index_type_1_7053", text: "Element implicitly has an 'any' type because expression of type '{0}' can't be used to index type '{1}'."} + +var No_index_signature_with_a_parameter_of_type_0_was_found_on_type_1 = &Message{code: 7054, category: CategoryError, key: "No_index_signature_with_a_parameter_of_type_0_was_found_on_type_1_7054", text: "No index signature with a parameter of type '{0}' was found on type '{1}'."} + +var X_0_which_lacks_return_type_annotation_implicitly_has_an_1_yield_type = &Message{code: 7055, category: CategoryError, key: "_0_which_lacks_return_type_annotation_implicitly_has_an_1_yield_type_7055", text: "'{0}', which lacks return-type annotation, implicitly has an '{1}' yield type."} + +var The_inferred_type_of_this_node_exceeds_the_maximum_length_the_compiler_will_serialize_An_explicit_type_annotation_is_needed = &Message{code: 7056, category: CategoryError, key: "The_inferred_type_of_this_node_exceeds_the_maximum_length_the_compiler_will_serialize_An_explicit_ty_7056", text: "The inferred type of this node exceeds the maximum length the compiler will serialize. An explicit type annotation is needed."} + +var X_yield_expression_implicitly_results_in_an_any_type_because_its_containing_generator_lacks_a_return_type_annotation = &Message{code: 7057, category: CategoryError, key: "yield_expression_implicitly_results_in_an_any_type_because_its_containing_generator_lacks_a_return_t_7057", text: "'yield' expression implicitly results in an 'any' type because its containing generator lacks a return-type annotation."} + +var If_the_0_package_actually_exposes_this_module_try_adding_a_new_declaration_d_ts_file_containing_declare_module_1 = &Message{code: 7058, category: CategoryError, key: "If_the_0_package_actually_exposes_this_module_try_adding_a_new_declaration_d_ts_file_containing_decl_7058", text: "If the '{0}' package actually exposes this module, try adding a new declaration (.d.ts) file containing `declare module '{1}';`"} + +var This_syntax_is_reserved_in_files_with_the_mts_or_cts_extension_Use_an_as_expression_instead = &Message{code: 7059, category: CategoryError, key: "This_syntax_is_reserved_in_files_with_the_mts_or_cts_extension_Use_an_as_expression_instead_7059", text: "This syntax is reserved in files with the .mts or .cts extension. Use an `as` expression instead."} + +var This_syntax_is_reserved_in_files_with_the_mts_or_cts_extension_Add_a_trailing_comma_or_explicit_constraint = &Message{code: 7060, category: CategoryError, key: "This_syntax_is_reserved_in_files_with_the_mts_or_cts_extension_Add_a_trailing_comma_or_explicit_cons_7060", text: "This syntax is reserved in files with the .mts or .cts extension. Add a trailing comma or explicit constraint."} + +var A_mapped_type_may_not_declare_properties_or_methods = &Message{code: 7061, category: CategoryError, key: "A_mapped_type_may_not_declare_properties_or_methods_7061", text: "A mapped type may not declare properties or methods."} + +var You_cannot_rename_this_element = &Message{code: 8000, category: CategoryError, key: "You_cannot_rename_this_element_8000", text: "You cannot rename this element."} + +var You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library = &Message{code: 8001, category: CategoryError, key: "You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library_8001", text: "You cannot rename elements that are defined in the standard TypeScript library."} + +var X_import_can_only_be_used_in_TypeScript_files = &Message{code: 8002, category: CategoryError, key: "import_can_only_be_used_in_TypeScript_files_8002", text: "'import ... =' can only be used in TypeScript files."} + +var X_export_can_only_be_used_in_TypeScript_files = &Message{code: 8003, category: CategoryError, key: "export_can_only_be_used_in_TypeScript_files_8003", text: "'export =' can only be used in TypeScript files."} + +var Type_parameter_declarations_can_only_be_used_in_TypeScript_files = &Message{code: 8004, category: CategoryError, key: "Type_parameter_declarations_can_only_be_used_in_TypeScript_files_8004", text: "Type parameter declarations can only be used in TypeScript files."} + +var X_implements_clauses_can_only_be_used_in_TypeScript_files = &Message{code: 8005, category: CategoryError, key: "implements_clauses_can_only_be_used_in_TypeScript_files_8005", text: "'implements' clauses can only be used in TypeScript files."} + +var X_0_declarations_can_only_be_used_in_TypeScript_files = &Message{code: 8006, category: CategoryError, key: "_0_declarations_can_only_be_used_in_TypeScript_files_8006", text: "'{0}' declarations can only be used in TypeScript files."} + +var Type_aliases_can_only_be_used_in_TypeScript_files = &Message{code: 8008, category: CategoryError, key: "Type_aliases_can_only_be_used_in_TypeScript_files_8008", text: "Type aliases can only be used in TypeScript files."} + +var The_0_modifier_can_only_be_used_in_TypeScript_files = &Message{code: 8009, category: CategoryError, key: "The_0_modifier_can_only_be_used_in_TypeScript_files_8009", text: "The '{0}' modifier can only be used in TypeScript files."} + +var Type_annotations_can_only_be_used_in_TypeScript_files = &Message{code: 8010, category: CategoryError, key: "Type_annotations_can_only_be_used_in_TypeScript_files_8010", text: "Type annotations can only be used in TypeScript files."} + +var Type_arguments_can_only_be_used_in_TypeScript_files = &Message{code: 8011, category: CategoryError, key: "Type_arguments_can_only_be_used_in_TypeScript_files_8011", text: "Type arguments can only be used in TypeScript files."} + +var Parameter_modifiers_can_only_be_used_in_TypeScript_files = &Message{code: 8012, category: CategoryError, key: "Parameter_modifiers_can_only_be_used_in_TypeScript_files_8012", text: "Parameter modifiers can only be used in TypeScript files."} + +var Non_null_assertions_can_only_be_used_in_TypeScript_files = &Message{code: 8013, category: CategoryError, key: "Non_null_assertions_can_only_be_used_in_TypeScript_files_8013", text: "Non-null assertions can only be used in TypeScript files."} + +var Type_assertion_expressions_can_only_be_used_in_TypeScript_files = &Message{code: 8016, category: CategoryError, key: "Type_assertion_expressions_can_only_be_used_in_TypeScript_files_8016", text: "Type assertion expressions can only be used in TypeScript files."} + +var Signature_declarations_can_only_be_used_in_TypeScript_files = &Message{code: 8017, category: CategoryError, key: "Signature_declarations_can_only_be_used_in_TypeScript_files_8017", text: "Signature declarations can only be used in TypeScript files."} + +var Report_errors_in_js_files = &Message{code: 8019, category: CategoryMessage, key: "Report_errors_in_js_files_8019", text: "Report errors in .js files."} + +var JSDoc_types_can_only_be_used_inside_documentation_comments = &Message{code: 8020, category: CategoryError, key: "JSDoc_types_can_only_be_used_inside_documentation_comments_8020", text: "JSDoc types can only be used inside documentation comments."} + +var JSDoc_typedef_tag_should_either_have_a_type_annotation_or_be_followed_by_property_or_member_tags = &Message{code: 8021, category: CategoryError, key: "JSDoc_typedef_tag_should_either_have_a_type_annotation_or_be_followed_by_property_or_member_tags_8021", text: "JSDoc '@typedef' tag should either have a type annotation or be followed by '@property' or '@member' tags."} + +var JSDoc_0_is_not_attached_to_a_class = &Message{code: 8022, category: CategoryError, key: "JSDoc_0_is_not_attached_to_a_class_8022", text: "JSDoc '@{0}' is not attached to a class."} + +var JSDoc_0_1_does_not_match_the_extends_2_clause = &Message{code: 8023, category: CategoryError, key: "JSDoc_0_1_does_not_match_the_extends_2_clause_8023", text: "JSDoc '@{0} {1}' does not match the 'extends {2}' clause."} + +var JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name = &Message{code: 8024, category: CategoryError, key: "JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_8024", text: "JSDoc '@param' tag has name '{0}', but there is no parameter with that name."} + +var Class_declarations_cannot_have_more_than_one_augments_or_extends_tag = &Message{code: 8025, category: CategoryError, key: "Class_declarations_cannot_have_more_than_one_augments_or_extends_tag_8025", text: "Class declarations cannot have more than one '@augments' or '@extends' tag."} + +var Expected_0_type_arguments_provide_these_with_an_extends_tag = &Message{code: 8026, category: CategoryError, key: "Expected_0_type_arguments_provide_these_with_an_extends_tag_8026", text: "Expected {0} type arguments; provide these with an '@extends' tag."} + +var Expected_0_1_type_arguments_provide_these_with_an_extends_tag = &Message{code: 8027, category: CategoryError, key: "Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027", text: "Expected {0}-{1} type arguments; provide these with an '@extends' tag."} + +var JSDoc_may_only_appear_in_the_last_parameter_of_a_signature = &Message{code: 8028, category: CategoryError, key: "JSDoc_may_only_appear_in_the_last_parameter_of_a_signature_8028", text: "JSDoc '...' may only appear in the last parameter of a signature."} + +var JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_had_an_array_type = &Message{code: 8029, category: CategoryError, key: "JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_h_8029", text: "JSDoc '@param' tag has name '{0}', but there is no parameter with that name. It would match 'arguments' if it had an array type."} + +var A_JSDoc_type_tag_on_a_function_must_have_a_signature_with_the_correct_number_of_arguments = &Message{code: 8030, category: CategoryError, key: "A_JSDoc_type_tag_on_a_function_must_have_a_signature_with_the_correct_number_of_arguments_8030", text: "A JSDoc '@type' tag on a function must have a signature with the correct number of arguments."} + +var You_cannot_rename_a_module_via_a_global_import = &Message{code: 8031, category: CategoryError, key: "You_cannot_rename_a_module_via_a_global_import_8031", text: "You cannot rename a module via a global import."} + +var Qualified_name_0_is_not_allowed_without_a_leading_param_object_1 = &Message{code: 8032, category: CategoryError, key: "Qualified_name_0_is_not_allowed_without_a_leading_param_object_1_8032", text: "Qualified name '{0}' is not allowed without a leading '@param {object} {1}'."} + +var A_JSDoc_typedef_comment_may_not_contain_multiple_type_tags = &Message{code: 8033, category: CategoryError, key: "A_JSDoc_typedef_comment_may_not_contain_multiple_type_tags_8033", text: "A JSDoc '@typedef' comment may not contain multiple '@type' tags."} + +var The_tag_was_first_specified_here = &Message{code: 8034, category: CategoryError, key: "The_tag_was_first_specified_here_8034", text: "The tag was first specified here."} + +var You_cannot_rename_elements_that_are_defined_in_a_node_modules_folder = &Message{code: 8035, category: CategoryError, key: "You_cannot_rename_elements_that_are_defined_in_a_node_modules_folder_8035", text: "You cannot rename elements that are defined in a 'node_modules' folder."} + +var You_cannot_rename_elements_that_are_defined_in_another_node_modules_folder = &Message{code: 8036, category: CategoryError, key: "You_cannot_rename_elements_that_are_defined_in_another_node_modules_folder_8036", text: "You cannot rename elements that are defined in another 'node_modules' folder."} + +var Type_satisfaction_expressions_can_only_be_used_in_TypeScript_files = &Message{code: 8037, category: CategoryError, key: "Type_satisfaction_expressions_can_only_be_used_in_TypeScript_files_8037", text: "Type satisfaction expressions can only be used in TypeScript files."} + +var Decorators_may_not_appear_after_export_or_export_default_if_they_also_appear_before_export = &Message{code: 8038, category: CategoryError, key: "Decorators_may_not_appear_after_export_or_export_default_if_they_also_appear_before_export_8038", text: "Decorators may not appear after 'export' or 'export default' if they also appear before 'export'."} + +var A_JSDoc_template_tag_may_not_follow_a_typedef_callback_or_overload_tag = &Message{code: 8039, category: CategoryError, key: "A_JSDoc_template_tag_may_not_follow_a_typedef_callback_or_overload_tag_8039", text: "A JSDoc '@template' tag may not follow a '@typedef', '@callback', or '@overload' tag"} + +var A_JSDoc_type_tag_may_not_occur_with_a_param_or_returns_tag = &Message{code: 8040, category: CategoryError, key: "A_JSDoc_type_tag_may_not_occur_with_a_param_or_returns_tag_8040", text: "A JSDoc '@type' tag may not occur with a '@param' or '@returns' tag."} + +var Declaration_emit_for_this_file_requires_using_private_name_0_An_explicit_type_annotation_may_unblock_declaration_emit = &Message{code: 9005, category: CategoryError, key: "Declaration_emit_for_this_file_requires_using_private_name_0_An_explicit_type_annotation_may_unblock_9005", text: "Declaration emit for this file requires using private name '{0}'. An explicit type annotation may unblock declaration emit."} + +var Declaration_emit_for_this_file_requires_using_private_name_0_from_module_1_An_explicit_type_annotation_may_unblock_declaration_emit = &Message{code: 9006, category: CategoryError, key: "Declaration_emit_for_this_file_requires_using_private_name_0_from_module_1_An_explicit_type_annotati_9006", text: "Declaration emit for this file requires using private name '{0}' from module '{1}'. An explicit type annotation may unblock declaration emit."} + +var Function_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations = &Message{code: 9007, category: CategoryError, key: "Function_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations_9007", text: "Function must have an explicit return type annotation with --isolatedDeclarations."} + +var Method_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations = &Message{code: 9008, category: CategoryError, key: "Method_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations_9008", text: "Method must have an explicit return type annotation with --isolatedDeclarations."} + +var At_least_one_accessor_must_have_an_explicit_type_annotation_with_isolatedDeclarations = &Message{code: 9009, category: CategoryError, key: "At_least_one_accessor_must_have_an_explicit_type_annotation_with_isolatedDeclarations_9009", text: "At least one accessor must have an explicit type annotation with --isolatedDeclarations."} + +var Variable_must_have_an_explicit_type_annotation_with_isolatedDeclarations = &Message{code: 9010, category: CategoryError, key: "Variable_must_have_an_explicit_type_annotation_with_isolatedDeclarations_9010", text: "Variable must have an explicit type annotation with --isolatedDeclarations."} + +var Parameter_must_have_an_explicit_type_annotation_with_isolatedDeclarations = &Message{code: 9011, category: CategoryError, key: "Parameter_must_have_an_explicit_type_annotation_with_isolatedDeclarations_9011", text: "Parameter must have an explicit type annotation with --isolatedDeclarations."} + +var Property_must_have_an_explicit_type_annotation_with_isolatedDeclarations = &Message{code: 9012, category: CategoryError, key: "Property_must_have_an_explicit_type_annotation_with_isolatedDeclarations_9012", text: "Property must have an explicit type annotation with --isolatedDeclarations."} + +var Expression_type_can_t_be_inferred_with_isolatedDeclarations = &Message{code: 9013, category: CategoryError, key: "Expression_type_can_t_be_inferred_with_isolatedDeclarations_9013", text: "Expression type can't be inferred with --isolatedDeclarations."} + +var Computed_properties_must_be_number_or_string_literals_variables_or_dotted_expressions_with_isolatedDeclarations = &Message{code: 9014, category: CategoryError, key: "Computed_properties_must_be_number_or_string_literals_variables_or_dotted_expressions_with_isolatedD_9014", text: "Computed properties must be number or string literals, variables or dotted expressions with --isolatedDeclarations."} + +var Objects_that_contain_spread_assignments_can_t_be_inferred_with_isolatedDeclarations = &Message{code: 9015, category: CategoryError, key: "Objects_that_contain_spread_assignments_can_t_be_inferred_with_isolatedDeclarations_9015", text: "Objects that contain spread assignments can't be inferred with --isolatedDeclarations."} + +var Objects_that_contain_shorthand_properties_can_t_be_inferred_with_isolatedDeclarations = &Message{code: 9016, category: CategoryError, key: "Objects_that_contain_shorthand_properties_can_t_be_inferred_with_isolatedDeclarations_9016", text: "Objects that contain shorthand properties can't be inferred with --isolatedDeclarations."} + +var Only_const_arrays_can_be_inferred_with_isolatedDeclarations = &Message{code: 9017, category: CategoryError, key: "Only_const_arrays_can_be_inferred_with_isolatedDeclarations_9017", text: "Only const arrays can be inferred with --isolatedDeclarations."} + +var Arrays_with_spread_elements_can_t_inferred_with_isolatedDeclarations = &Message{code: 9018, category: CategoryError, key: "Arrays_with_spread_elements_can_t_inferred_with_isolatedDeclarations_9018", text: "Arrays with spread elements can't inferred with --isolatedDeclarations."} + +var Binding_elements_can_t_be_exported_directly_with_isolatedDeclarations = &Message{code: 9019, category: CategoryError, key: "Binding_elements_can_t_be_exported_directly_with_isolatedDeclarations_9019", text: "Binding elements can't be exported directly with --isolatedDeclarations."} + +var Enum_member_initializers_must_be_computable_without_references_to_external_symbols_with_isolatedDeclarations = &Message{code: 9020, category: CategoryError, key: "Enum_member_initializers_must_be_computable_without_references_to_external_symbols_with_isolatedDecl_9020", text: "Enum member initializers must be computable without references to external symbols with --isolatedDeclarations."} + +var Extends_clause_can_t_contain_an_expression_with_isolatedDeclarations = &Message{code: 9021, category: CategoryError, key: "Extends_clause_can_t_contain_an_expression_with_isolatedDeclarations_9021", text: "Extends clause can't contain an expression with --isolatedDeclarations."} + +var Inference_from_class_expressions_is_not_supported_with_isolatedDeclarations = &Message{code: 9022, category: CategoryError, key: "Inference_from_class_expressions_is_not_supported_with_isolatedDeclarations_9022", text: "Inference from class expressions is not supported with --isolatedDeclarations."} + +var Assigning_properties_to_functions_without_declaring_them_is_not_supported_with_isolatedDeclarations_Add_an_explicit_declaration_for_the_properties_assigned_to_this_function = &Message{code: 9023, category: CategoryError, key: "Assigning_properties_to_functions_without_declaring_them_is_not_supported_with_isolatedDeclarations__9023", text: "Assigning properties to functions without declaring them is not supported with --isolatedDeclarations. Add an explicit declaration for the properties assigned to this function."} + +var Declaration_emit_for_this_parameter_requires_implicitly_adding_undefined_to_its_type_This_is_not_supported_with_isolatedDeclarations = &Message{code: 9025, category: CategoryError, key: "Declaration_emit_for_this_parameter_requires_implicitly_adding_undefined_to_its_type_This_is_not_sup_9025", text: "Declaration emit for this parameter requires implicitly adding undefined to its type. This is not supported with --isolatedDeclarations."} + +var Declaration_emit_for_this_file_requires_preserving_this_import_for_augmentations_This_is_not_supported_with_isolatedDeclarations = &Message{code: 9026, category: CategoryError, key: "Declaration_emit_for_this_file_requires_preserving_this_import_for_augmentations_This_is_not_support_9026", text: "Declaration emit for this file requires preserving this import for augmentations. This is not supported with --isolatedDeclarations."} + +var Add_a_type_annotation_to_the_variable_0 = &Message{code: 9027, category: CategoryError, key: "Add_a_type_annotation_to_the_variable_0_9027", text: "Add a type annotation to the variable {0}."} + +var Add_a_type_annotation_to_the_parameter_0 = &Message{code: 9028, category: CategoryError, key: "Add_a_type_annotation_to_the_parameter_0_9028", text: "Add a type annotation to the parameter {0}."} + +var Add_a_type_annotation_to_the_property_0 = &Message{code: 9029, category: CategoryError, key: "Add_a_type_annotation_to_the_property_0_9029", text: "Add a type annotation to the property {0}."} + +var Add_a_return_type_to_the_function_expression = &Message{code: 9030, category: CategoryError, key: "Add_a_return_type_to_the_function_expression_9030", text: "Add a return type to the function expression."} + +var Add_a_return_type_to_the_function_declaration = &Message{code: 9031, category: CategoryError, key: "Add_a_return_type_to_the_function_declaration_9031", text: "Add a return type to the function declaration."} + +var Add_a_return_type_to_the_get_accessor_declaration = &Message{code: 9032, category: CategoryError, key: "Add_a_return_type_to_the_get_accessor_declaration_9032", text: "Add a return type to the get accessor declaration."} + +var Add_a_type_to_parameter_of_the_set_accessor_declaration = &Message{code: 9033, category: CategoryError, key: "Add_a_type_to_parameter_of_the_set_accessor_declaration_9033", text: "Add a type to parameter of the set accessor declaration."} + +var Add_a_return_type_to_the_method = &Message{code: 9034, category: CategoryError, key: "Add_a_return_type_to_the_method_9034", text: "Add a return type to the method"} + +var Add_satisfies_and_a_type_assertion_to_this_expression_satisfies_T_as_T_to_make_the_type_explicit = &Message{code: 9035, category: CategoryError, key: "Add_satisfies_and_a_type_assertion_to_this_expression_satisfies_T_as_T_to_make_the_type_explicit_9035", text: "Add satisfies and a type assertion to this expression (satisfies T as T) to make the type explicit."} + +var Move_the_expression_in_default_export_to_a_variable_and_add_a_type_annotation_to_it = &Message{code: 9036, category: CategoryError, key: "Move_the_expression_in_default_export_to_a_variable_and_add_a_type_annotation_to_it_9036", text: "Move the expression in default export to a variable and add a type annotation to it."} + +var Default_exports_can_t_be_inferred_with_isolatedDeclarations = &Message{code: 9037, category: CategoryError, key: "Default_exports_can_t_be_inferred_with_isolatedDeclarations_9037", text: "Default exports can't be inferred with --isolatedDeclarations."} + +var Computed_property_names_on_class_or_object_literals_cannot_be_inferred_with_isolatedDeclarations = &Message{code: 9038, category: CategoryError, key: "Computed_property_names_on_class_or_object_literals_cannot_be_inferred_with_isolatedDeclarations_9038", text: "Computed property names on class or object literals cannot be inferred with --isolatedDeclarations."} + +var Type_containing_private_name_0_can_t_be_used_with_isolatedDeclarations = &Message{code: 9039, category: CategoryError, key: "Type_containing_private_name_0_can_t_be_used_with_isolatedDeclarations_9039", text: "Type containing private name '{0}' can't be used with --isolatedDeclarations."} + +var JSX_attributes_must_only_be_assigned_a_non_empty_expression = &Message{code: 17000, category: CategoryError, key: "JSX_attributes_must_only_be_assigned_a_non_empty_expression_17000", text: "JSX attributes must only be assigned a non-empty 'expression'."} + +var JSX_elements_cannot_have_multiple_attributes_with_the_same_name = &Message{code: 17001, category: CategoryError, key: "JSX_elements_cannot_have_multiple_attributes_with_the_same_name_17001", text: "JSX elements cannot have multiple attributes with the same name."} + +var Expected_corresponding_JSX_closing_tag_for_0 = &Message{code: 17002, category: CategoryError, key: "Expected_corresponding_JSX_closing_tag_for_0_17002", text: "Expected corresponding JSX closing tag for '{0}'."} + +var Cannot_use_JSX_unless_the_jsx_flag_is_provided = &Message{code: 17004, category: CategoryError, key: "Cannot_use_JSX_unless_the_jsx_flag_is_provided_17004", text: "Cannot use JSX unless the '--jsx' flag is provided."} + +var A_constructor_cannot_contain_a_super_call_when_its_class_extends_null = &Message{code: 17005, category: CategoryError, key: "A_constructor_cannot_contain_a_super_call_when_its_class_extends_null_17005", text: "A constructor cannot contain a 'super' call when its class extends 'null'."} + +var An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses = &Message{code: 17006, category: CategoryError, key: "An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_ex_17006", text: "An unary expression with the '{0}' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses."} + +var A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses = &Message{code: 17007, category: CategoryError, key: "A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Con_17007", text: "A type assertion expression is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses."} + +var JSX_element_0_has_no_corresponding_closing_tag = &Message{code: 17008, category: CategoryError, key: "JSX_element_0_has_no_corresponding_closing_tag_17008", text: "JSX element '{0}' has no corresponding closing tag."} + +var X_super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class = &Message{code: 17009, category: CategoryError, key: "super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class_17009", text: "'super' must be called before accessing 'this' in the constructor of a derived class."} + +var Unknown_type_acquisition_option_0 = &Message{code: 17010, category: CategoryError, key: "Unknown_type_acquisition_option_0_17010", text: "Unknown type acquisition option '{0}'."} + +var X_super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class = &Message{code: 17011, category: CategoryError, key: "super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class_17011", text: "'super' must be called before accessing a property of 'super' in the constructor of a derived class."} + +var X_0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2 = &Message{code: 17012, category: CategoryError, key: "_0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2_17012", text: "'{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?"} + +var Meta_property_0_is_only_allowed_in_the_body_of_a_function_declaration_function_expression_or_constructor = &Message{code: 17013, category: CategoryError, key: "Meta_property_0_is_only_allowed_in_the_body_of_a_function_declaration_function_expression_or_constru_17013", text: "Meta-property '{0}' is only allowed in the body of a function declaration, function expression, or constructor."} + +var JSX_fragment_has_no_corresponding_closing_tag = &Message{code: 17014, category: CategoryError, key: "JSX_fragment_has_no_corresponding_closing_tag_17014", text: "JSX fragment has no corresponding closing tag."} + +var Expected_corresponding_closing_tag_for_JSX_fragment = &Message{code: 17015, category: CategoryError, key: "Expected_corresponding_closing_tag_for_JSX_fragment_17015", text: "Expected corresponding closing tag for JSX fragment."} + +var The_jsxFragmentFactory_compiler_option_must_be_provided_to_use_JSX_fragments_with_the_jsxFactory_compiler_option = &Message{code: 17016, category: CategoryError, key: "The_jsxFragmentFactory_compiler_option_must_be_provided_to_use_JSX_fragments_with_the_jsxFactory_com_17016", text: "The 'jsxFragmentFactory' compiler option must be provided to use JSX fragments with the 'jsxFactory' compiler option."} + +var An_jsxFrag_pragma_is_required_when_using_an_jsx_pragma_with_JSX_fragments = &Message{code: 17017, category: CategoryError, key: "An_jsxFrag_pragma_is_required_when_using_an_jsx_pragma_with_JSX_fragments_17017", text: "An @jsxFrag pragma is required when using an @jsx pragma with JSX fragments."} + +var Unknown_type_acquisition_option_0_Did_you_mean_1 = &Message{code: 17018, category: CategoryError, key: "Unknown_type_acquisition_option_0_Did_you_mean_1_17018", text: "Unknown type acquisition option '{0}'. Did you mean '{1}'?"} + +var X_0_at_the_end_of_a_type_is_not_valid_TypeScript_syntax_Did_you_mean_to_write_1 = &Message{code: 17019, category: CategoryError, key: "_0_at_the_end_of_a_type_is_not_valid_TypeScript_syntax_Did_you_mean_to_write_1_17019", text: "'{0}' at the end of a type is not valid TypeScript syntax. Did you mean to write '{1}'?"} + +var X_0_at_the_start_of_a_type_is_not_valid_TypeScript_syntax_Did_you_mean_to_write_1 = &Message{code: 17020, category: CategoryError, key: "_0_at_the_start_of_a_type_is_not_valid_TypeScript_syntax_Did_you_mean_to_write_1_17020", text: "'{0}' at the start of a type is not valid TypeScript syntax. Did you mean to write '{1}'?"} + +var Unicode_escape_sequence_cannot_appear_here = &Message{code: 17021, category: CategoryError, key: "Unicode_escape_sequence_cannot_appear_here_17021", text: "Unicode escape sequence cannot appear here."} + +var Circularity_detected_while_resolving_configuration_Colon_0 = &Message{code: 18000, category: CategoryError, key: "Circularity_detected_while_resolving_configuration_Colon_0_18000", text: "Circularity detected while resolving configuration: {0}"} + +var The_files_list_in_config_file_0_is_empty = &Message{code: 18002, category: CategoryError, key: "The_files_list_in_config_file_0_is_empty_18002", text: "The 'files' list in config file '{0}' is empty."} + +var No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2 = &Message{code: 18003, category: CategoryError, key: "No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2_18003", text: "No inputs were found in config file '{0}'. Specified 'include' paths were '{1}' and 'exclude' paths were '{2}'."} + +var No_value_exists_in_scope_for_the_shorthand_property_0_Either_declare_one_or_provide_an_initializer = &Message{code: 18004, category: CategoryError, key: "No_value_exists_in_scope_for_the_shorthand_property_0_Either_declare_one_or_provide_an_initializer_18004", text: "No value exists in scope for the shorthand property '{0}'. Either declare one or provide an initializer."} + +var Classes_may_not_have_a_field_named_constructor = &Message{code: 18006, category: CategoryError, key: "Classes_may_not_have_a_field_named_constructor_18006", text: "Classes may not have a field named 'constructor'."} + +var JSX_expressions_may_not_use_the_comma_operator_Did_you_mean_to_write_an_array = &Message{code: 18007, category: CategoryError, key: "JSX_expressions_may_not_use_the_comma_operator_Did_you_mean_to_write_an_array_18007", text: "JSX expressions may not use the comma operator. Did you mean to write an array?"} + +var Private_identifiers_cannot_be_used_as_parameters = &Message{code: 18009, category: CategoryError, key: "Private_identifiers_cannot_be_used_as_parameters_18009", text: "Private identifiers cannot be used as parameters."} + +var An_accessibility_modifier_cannot_be_used_with_a_private_identifier = &Message{code: 18010, category: CategoryError, key: "An_accessibility_modifier_cannot_be_used_with_a_private_identifier_18010", text: "An accessibility modifier cannot be used with a private identifier."} + +var The_operand_of_a_delete_operator_cannot_be_a_private_identifier = &Message{code: 18011, category: CategoryError, key: "The_operand_of_a_delete_operator_cannot_be_a_private_identifier_18011", text: "The operand of a 'delete' operator cannot be a private identifier."} + +var X_constructor_is_a_reserved_word = &Message{code: 18012, category: CategoryError, key: "constructor_is_a_reserved_word_18012", text: "'#constructor' is a reserved word."} + +var Property_0_is_not_accessible_outside_class_1_because_it_has_a_private_identifier = &Message{code: 18013, category: CategoryError, key: "Property_0_is_not_accessible_outside_class_1_because_it_has_a_private_identifier_18013", text: "Property '{0}' is not accessible outside class '{1}' because it has a private identifier."} + +var The_property_0_cannot_be_accessed_on_type_1_within_this_class_because_it_is_shadowed_by_another_private_identifier_with_the_same_spelling = &Message{code: 18014, category: CategoryError, key: "The_property_0_cannot_be_accessed_on_type_1_within_this_class_because_it_is_shadowed_by_another_priv_18014", text: "The property '{0}' cannot be accessed on type '{1}' within this class because it is shadowed by another private identifier with the same spelling."} + +var Property_0_in_type_1_refers_to_a_different_member_that_cannot_be_accessed_from_within_type_2 = &Message{code: 18015, category: CategoryError, key: "Property_0_in_type_1_refers_to_a_different_member_that_cannot_be_accessed_from_within_type_2_18015", text: "Property '{0}' in type '{1}' refers to a different member that cannot be accessed from within type '{2}'."} + +var Private_identifiers_are_not_allowed_outside_class_bodies = &Message{code: 18016, category: CategoryError, key: "Private_identifiers_are_not_allowed_outside_class_bodies_18016", text: "Private identifiers are not allowed outside class bodies."} + +var The_shadowing_declaration_of_0_is_defined_here = &Message{code: 18017, category: CategoryError, key: "The_shadowing_declaration_of_0_is_defined_here_18017", text: "The shadowing declaration of '{0}' is defined here"} + +var The_declaration_of_0_that_you_probably_intended_to_use_is_defined_here = &Message{code: 18018, category: CategoryError, key: "The_declaration_of_0_that_you_probably_intended_to_use_is_defined_here_18018", text: "The declaration of '{0}' that you probably intended to use is defined here"} + +var X_0_modifier_cannot_be_used_with_a_private_identifier = &Message{code: 18019, category: CategoryError, key: "_0_modifier_cannot_be_used_with_a_private_identifier_18019", text: "'{0}' modifier cannot be used with a private identifier."} + +var An_enum_member_cannot_be_named_with_a_private_identifier = &Message{code: 18024, category: CategoryError, key: "An_enum_member_cannot_be_named_with_a_private_identifier_18024", text: "An enum member cannot be named with a private identifier."} + +var X_can_only_be_used_at_the_start_of_a_file = &Message{code: 18026, category: CategoryError, key: "can_only_be_used_at_the_start_of_a_file_18026", text: "'#!' can only be used at the start of a file."} + +var Compiler_reserves_name_0_when_emitting_private_identifier_downlevel = &Message{code: 18027, category: CategoryError, key: "Compiler_reserves_name_0_when_emitting_private_identifier_downlevel_18027", text: "Compiler reserves name '{0}' when emitting private identifier downlevel."} + +var Private_identifiers_are_only_available_when_targeting_ECMAScript_2015_and_higher = &Message{code: 18028, category: CategoryError, key: "Private_identifiers_are_only_available_when_targeting_ECMAScript_2015_and_higher_18028", text: "Private identifiers are only available when targeting ECMAScript 2015 and higher."} + +var Private_identifiers_are_not_allowed_in_variable_declarations = &Message{code: 18029, category: CategoryError, key: "Private_identifiers_are_not_allowed_in_variable_declarations_18029", text: "Private identifiers are not allowed in variable declarations."} + +var An_optional_chain_cannot_contain_private_identifiers = &Message{code: 18030, category: CategoryError, key: "An_optional_chain_cannot_contain_private_identifiers_18030", text: "An optional chain cannot contain private identifiers."} + +var The_intersection_0_was_reduced_to_never_because_property_1_has_conflicting_types_in_some_constituents = &Message{code: 18031, category: CategoryError, key: "The_intersection_0_was_reduced_to_never_because_property_1_has_conflicting_types_in_some_constituent_18031", text: "The intersection '{0}' was reduced to 'never' because property '{1}' has conflicting types in some constituents."} + +var The_intersection_0_was_reduced_to_never_because_property_1_exists_in_multiple_constituents_and_is_private_in_some = &Message{code: 18032, category: CategoryError, key: "The_intersection_0_was_reduced_to_never_because_property_1_exists_in_multiple_constituents_and_is_pr_18032", text: "The intersection '{0}' was reduced to 'never' because property '{1}' exists in multiple constituents and is private in some."} + +var Type_0_is_not_assignable_to_type_1_as_required_for_computed_enum_member_values = &Message{code: 18033, category: CategoryError, key: "Type_0_is_not_assignable_to_type_1_as_required_for_computed_enum_member_values_18033", text: "Type '{0}' is not assignable to type '{1}' as required for computed enum member values."} + +var Specify_the_JSX_fragment_factory_function_to_use_when_targeting_react_JSX_emit_with_jsxFactory_compiler_option_is_specified_e_g_Fragment = &Message{code: 18034, category: CategoryMessage, key: "Specify_the_JSX_fragment_factory_function_to_use_when_targeting_react_JSX_emit_with_jsxFactory_compi_18034", text: "Specify the JSX fragment factory function to use when targeting 'react' JSX emit with 'jsxFactory' compiler option is specified, e.g. 'Fragment'."} + +var Invalid_value_for_jsxFragmentFactory_0_is_not_a_valid_identifier_or_qualified_name = &Message{code: 18035, category: CategoryError, key: "Invalid_value_for_jsxFragmentFactory_0_is_not_a_valid_identifier_or_qualified_name_18035", text: "Invalid value for 'jsxFragmentFactory'. '{0}' is not a valid identifier or qualified-name."} + +var Class_decorators_can_t_be_used_with_static_private_identifier_Consider_removing_the_experimental_decorator = &Message{code: 18036, category: CategoryError, key: "Class_decorators_can_t_be_used_with_static_private_identifier_Consider_removing_the_experimental_dec_18036", text: "Class decorators can't be used with static private identifier. Consider removing the experimental decorator."} + +var X_await_expression_cannot_be_used_inside_a_class_static_block = &Message{code: 18037, category: CategoryError, key: "await_expression_cannot_be_used_inside_a_class_static_block_18037", text: "'await' expression cannot be used inside a class static block."} + +var X_for_await_loops_cannot_be_used_inside_a_class_static_block = &Message{code: 18038, category: CategoryError, key: "for_await_loops_cannot_be_used_inside_a_class_static_block_18038", text: "'for await' loops cannot be used inside a class static block."} + +var Invalid_use_of_0_It_cannot_be_used_inside_a_class_static_block = &Message{code: 18039, category: CategoryError, key: "Invalid_use_of_0_It_cannot_be_used_inside_a_class_static_block_18039", text: "Invalid use of '{0}'. It cannot be used inside a class static block."} + +var A_return_statement_cannot_be_used_inside_a_class_static_block = &Message{code: 18041, category: CategoryError, key: "A_return_statement_cannot_be_used_inside_a_class_static_block_18041", text: "A 'return' statement cannot be used inside a class static block."} + +var X_0_is_a_type_and_cannot_be_imported_in_JavaScript_files_Use_1_in_a_JSDoc_type_annotation = &Message{code: 18042, category: CategoryError, key: "_0_is_a_type_and_cannot_be_imported_in_JavaScript_files_Use_1_in_a_JSDoc_type_annotation_18042", text: "'{0}' is a type and cannot be imported in JavaScript files. Use '{1}' in a JSDoc type annotation."} + +var Types_cannot_appear_in_export_declarations_in_JavaScript_files = &Message{code: 18043, category: CategoryError, key: "Types_cannot_appear_in_export_declarations_in_JavaScript_files_18043", text: "Types cannot appear in export declarations in JavaScript files."} + +var X_0_is_automatically_exported_here = &Message{code: 18044, category: CategoryMessage, key: "_0_is_automatically_exported_here_18044", text: "'{0}' is automatically exported here."} + +var Properties_with_the_accessor_modifier_are_only_available_when_targeting_ECMAScript_2015_and_higher = &Message{code: 18045, category: CategoryError, key: "Properties_with_the_accessor_modifier_are_only_available_when_targeting_ECMAScript_2015_and_higher_18045", text: "Properties with the 'accessor' modifier are only available when targeting ECMAScript 2015 and higher."} + +var X_0_is_of_type_unknown = &Message{code: 18046, category: CategoryError, key: "_0_is_of_type_unknown_18046", text: "'{0}' is of type 'unknown'."} + +var X_0_is_possibly_null = &Message{code: 18047, category: CategoryError, key: "_0_is_possibly_null_18047", text: "'{0}' is possibly 'null'."} + +var X_0_is_possibly_undefined = &Message{code: 18048, category: CategoryError, key: "_0_is_possibly_undefined_18048", text: "'{0}' is possibly 'undefined'."} + +var X_0_is_possibly_null_or_undefined = &Message{code: 18049, category: CategoryError, key: "_0_is_possibly_null_or_undefined_18049", text: "'{0}' is possibly 'null' or 'undefined'."} + +var The_value_0_cannot_be_used_here = &Message{code: 18050, category: CategoryError, key: "The_value_0_cannot_be_used_here_18050", text: "The value '{0}' cannot be used here."} + +var Compiler_option_0_cannot_be_given_an_empty_string = &Message{code: 18051, category: CategoryError, key: "Compiler_option_0_cannot_be_given_an_empty_string_18051", text: "Compiler option '{0}' cannot be given an empty string."} + +var Its_type_0_is_not_a_valid_JSX_element_type = &Message{code: 18053, category: CategoryError, key: "Its_type_0_is_not_a_valid_JSX_element_type_18053", text: "Its type '{0}' is not a valid JSX element type."} + +var X_await_using_statements_cannot_be_used_inside_a_class_static_block = &Message{code: 18054, category: CategoryError, key: "await_using_statements_cannot_be_used_inside_a_class_static_block_18054", text: "'await using' statements cannot be used inside a class static block."} + +var X_0_has_a_string_type_but_must_have_syntactically_recognizable_string_syntax_when_isolatedModules_is_enabled = &Message{code: 18055, category: CategoryError, key: "_0_has_a_string_type_but_must_have_syntactically_recognizable_string_syntax_when_isolatedModules_is__18055", text: "'{0}' has a string type, but must have syntactically recognizable string syntax when 'isolatedModules' is enabled."} + +var Enum_member_following_a_non_literal_numeric_member_must_have_an_initializer_when_isolatedModules_is_enabled = &Message{code: 18056, category: CategoryError, key: "Enum_member_following_a_non_literal_numeric_member_must_have_an_initializer_when_isolatedModules_is__18056", text: "Enum member following a non-literal numeric member must have an initializer when 'isolatedModules' is enabled."} + +var String_literal_import_and_export_names_are_not_supported_when_the_module_flag_is_set_to_es2015_or_es2020 = &Message{code: 18057, category: CategoryError, key: "String_literal_import_and_export_names_are_not_supported_when_the_module_flag_is_set_to_es2015_or_es_18057", text: "String literal import and export names are not supported when the '--module' flag is set to 'es2015' or 'es2020'."} + +var Default_imports_are_not_allowed_in_a_deferred_import = &Message{code: 18058, category: CategoryError, key: "Default_imports_are_not_allowed_in_a_deferred_import_18058", text: "Default imports are not allowed in a deferred import."} + +var Named_imports_are_not_allowed_in_a_deferred_import = &Message{code: 18059, category: CategoryError, key: "Named_imports_are_not_allowed_in_a_deferred_import_18059", text: "Named imports are not allowed in a deferred import."} + +var Deferred_imports_are_only_supported_when_the_module_flag_is_set_to_esnext_or_preserve = &Message{code: 18060, category: CategoryError, key: "Deferred_imports_are_only_supported_when_the_module_flag_is_set_to_esnext_or_preserve_18060", text: "Deferred imports are only supported when the '--module' flag is set to 'esnext' or 'preserve'."} + +var X_0_is_not_a_valid_meta_property_for_keyword_import_Did_you_mean_meta_or_defer = &Message{code: 18061, category: CategoryError, key: "_0_is_not_a_valid_meta_property_for_keyword_import_Did_you_mean_meta_or_defer_18061", text: "'{0}' is not a valid meta-property for keyword 'import'. Did you mean 'meta' or 'defer'?"} + +var X_module_AMD_or_UMD_or_System_or_ES6_then_Classic_Otherwise_Node = &Message{code: 69010, category: CategoryMessage, key: "module_AMD_or_UMD_or_System_or_ES6_then_Classic_Otherwise_Node_69010", text: "module === `AMD` or `UMD` or `System` or `ES6`, then `Classic`, Otherwise `Node`"} + +var File_is_a_CommonJS_module_it_may_be_converted_to_an_ES_module = &Message{code: 80001, category: CategorySuggestion, key: "File_is_a_CommonJS_module_it_may_be_converted_to_an_ES_module_80001", text: "File is a CommonJS module; it may be converted to an ES module."} + +var This_constructor_function_may_be_converted_to_a_class_declaration = &Message{code: 80002, category: CategorySuggestion, key: "This_constructor_function_may_be_converted_to_a_class_declaration_80002", text: "This constructor function may be converted to a class declaration."} + +var Import_may_be_converted_to_a_default_import = &Message{code: 80003, category: CategorySuggestion, key: "Import_may_be_converted_to_a_default_import_80003", text: "Import may be converted to a default import."} + +var JSDoc_types_may_be_moved_to_TypeScript_types = &Message{code: 80004, category: CategorySuggestion, key: "JSDoc_types_may_be_moved_to_TypeScript_types_80004", text: "JSDoc types may be moved to TypeScript types."} + +var X_require_call_may_be_converted_to_an_import = &Message{code: 80005, category: CategorySuggestion, key: "require_call_may_be_converted_to_an_import_80005", text: "'require' call may be converted to an import."} + +var This_may_be_converted_to_an_async_function = &Message{code: 80006, category: CategorySuggestion, key: "This_may_be_converted_to_an_async_function_80006", text: "This may be converted to an async function."} + +var X_await_has_no_effect_on_the_type_of_this_expression = &Message{code: 80007, category: CategorySuggestion, key: "await_has_no_effect_on_the_type_of_this_expression_80007", text: "'await' has no effect on the type of this expression."} + +var Numeric_literals_with_absolute_values_equal_to_2_53_or_greater_are_too_large_to_be_represented_accurately_as_integers = &Message{code: 80008, category: CategorySuggestion, key: "Numeric_literals_with_absolute_values_equal_to_2_53_or_greater_are_too_large_to_be_represented_accur_80008", text: "Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as integers."} + +var JSDoc_typedef_may_be_converted_to_TypeScript_type = &Message{code: 80009, category: CategorySuggestion, key: "JSDoc_typedef_may_be_converted_to_TypeScript_type_80009", text: "JSDoc typedef may be converted to TypeScript type."} + +var JSDoc_typedefs_may_be_converted_to_TypeScript_types = &Message{code: 80010, category: CategorySuggestion, key: "JSDoc_typedefs_may_be_converted_to_TypeScript_types_80010", text: "JSDoc typedefs may be converted to TypeScript types."} + +var Add_missing_super_call = &Message{code: 90001, category: CategoryMessage, key: "Add_missing_super_call_90001", text: "Add missing 'super()' call"} + +var Make_super_call_the_first_statement_in_the_constructor = &Message{code: 90002, category: CategoryMessage, key: "Make_super_call_the_first_statement_in_the_constructor_90002", text: "Make 'super()' call the first statement in the constructor"} + +var Change_extends_to_implements = &Message{code: 90003, category: CategoryMessage, key: "Change_extends_to_implements_90003", text: "Change 'extends' to 'implements'"} + +var Remove_unused_declaration_for_Colon_0 = &Message{code: 90004, category: CategoryMessage, key: "Remove_unused_declaration_for_Colon_0_90004", text: "Remove unused declaration for: '{0}'"} + +var Remove_import_from_0 = &Message{code: 90005, category: CategoryMessage, key: "Remove_import_from_0_90005", text: "Remove import from '{0}'"} + +var Implement_interface_0 = &Message{code: 90006, category: CategoryMessage, key: "Implement_interface_0_90006", text: "Implement interface '{0}'"} + +var Implement_inherited_abstract_class = &Message{code: 90007, category: CategoryMessage, key: "Implement_inherited_abstract_class_90007", text: "Implement inherited abstract class"} + +var Add_0_to_unresolved_variable = &Message{code: 90008, category: CategoryMessage, key: "Add_0_to_unresolved_variable_90008", text: "Add '{0}.' to unresolved variable"} + +var Remove_variable_statement = &Message{code: 90010, category: CategoryMessage, key: "Remove_variable_statement_90010", text: "Remove variable statement"} + +var Remove_template_tag = &Message{code: 90011, category: CategoryMessage, key: "Remove_template_tag_90011", text: "Remove template tag"} + +var Remove_type_parameters = &Message{code: 90012, category: CategoryMessage, key: "Remove_type_parameters_90012", text: "Remove type parameters"} + +var Import_0_from_1 = &Message{code: 90013, category: CategoryMessage, key: "Import_0_from_1_90013", text: "Import '{0}' from \"{1}\""} + +var Change_0_to_1 = &Message{code: 90014, category: CategoryMessage, key: "Change_0_to_1_90014", text: "Change '{0}' to '{1}'"} + +var Declare_property_0 = &Message{code: 90016, category: CategoryMessage, key: "Declare_property_0_90016", text: "Declare property '{0}'"} + +var Add_index_signature_for_property_0 = &Message{code: 90017, category: CategoryMessage, key: "Add_index_signature_for_property_0_90017", text: "Add index signature for property '{0}'"} + +var Disable_checking_for_this_file = &Message{code: 90018, category: CategoryMessage, key: "Disable_checking_for_this_file_90018", text: "Disable checking for this file"} + +var Ignore_this_error_message = &Message{code: 90019, category: CategoryMessage, key: "Ignore_this_error_message_90019", text: "Ignore this error message"} + +var Initialize_property_0_in_the_constructor = &Message{code: 90020, category: CategoryMessage, key: "Initialize_property_0_in_the_constructor_90020", text: "Initialize property '{0}' in the constructor"} + +var Initialize_static_property_0 = &Message{code: 90021, category: CategoryMessage, key: "Initialize_static_property_0_90021", text: "Initialize static property '{0}'"} + +var Change_spelling_to_0 = &Message{code: 90022, category: CategoryMessage, key: "Change_spelling_to_0_90022", text: "Change spelling to '{0}'"} + +var Declare_method_0 = &Message{code: 90023, category: CategoryMessage, key: "Declare_method_0_90023", text: "Declare method '{0}'"} + +var Declare_static_method_0 = &Message{code: 90024, category: CategoryMessage, key: "Declare_static_method_0_90024", text: "Declare static method '{0}'"} + +var Prefix_0_with_an_underscore = &Message{code: 90025, category: CategoryMessage, key: "Prefix_0_with_an_underscore_90025", text: "Prefix '{0}' with an underscore"} + +var Rewrite_as_the_indexed_access_type_0 = &Message{code: 90026, category: CategoryMessage, key: "Rewrite_as_the_indexed_access_type_0_90026", text: "Rewrite as the indexed access type '{0}'"} + +var Declare_static_property_0 = &Message{code: 90027, category: CategoryMessage, key: "Declare_static_property_0_90027", text: "Declare static property '{0}'"} + +var Call_decorator_expression = &Message{code: 90028, category: CategoryMessage, key: "Call_decorator_expression_90028", text: "Call decorator expression"} + +var Add_async_modifier_to_containing_function = &Message{code: 90029, category: CategoryMessage, key: "Add_async_modifier_to_containing_function_90029", text: "Add async modifier to containing function"} + +var Replace_infer_0_with_unknown = &Message{code: 90030, category: CategoryMessage, key: "Replace_infer_0_with_unknown_90030", text: "Replace 'infer {0}' with 'unknown'"} + +var Replace_all_unused_infer_with_unknown = &Message{code: 90031, category: CategoryMessage, key: "Replace_all_unused_infer_with_unknown_90031", text: "Replace all unused 'infer' with 'unknown'"} + +var Add_parameter_name = &Message{code: 90034, category: CategoryMessage, key: "Add_parameter_name_90034", text: "Add parameter name"} + +var Declare_private_property_0 = &Message{code: 90035, category: CategoryMessage, key: "Declare_private_property_0_90035", text: "Declare private property '{0}'"} + +var Replace_0_with_Promise_1 = &Message{code: 90036, category: CategoryMessage, key: "Replace_0_with_Promise_1_90036", text: "Replace '{0}' with 'Promise<{1}>'"} + +var Fix_all_incorrect_return_type_of_an_async_functions = &Message{code: 90037, category: CategoryMessage, key: "Fix_all_incorrect_return_type_of_an_async_functions_90037", text: "Fix all incorrect return type of an async functions"} + +var Declare_private_method_0 = &Message{code: 90038, category: CategoryMessage, key: "Declare_private_method_0_90038", text: "Declare private method '{0}'"} + +var Remove_unused_destructuring_declaration = &Message{code: 90039, category: CategoryMessage, key: "Remove_unused_destructuring_declaration_90039", text: "Remove unused destructuring declaration"} + +var Remove_unused_declarations_for_Colon_0 = &Message{code: 90041, category: CategoryMessage, key: "Remove_unused_declarations_for_Colon_0_90041", text: "Remove unused declarations for: '{0}'"} + +var Declare_a_private_field_named_0 = &Message{code: 90053, category: CategoryMessage, key: "Declare_a_private_field_named_0_90053", text: "Declare a private field named '{0}'."} + +var Includes_imports_of_types_referenced_by_0 = &Message{code: 90054, category: CategoryMessage, key: "Includes_imports_of_types_referenced_by_0_90054", text: "Includes imports of types referenced by '{0}'"} + +var Remove_type_from_import_declaration_from_0 = &Message{code: 90055, category: CategoryMessage, key: "Remove_type_from_import_declaration_from_0_90055", text: "Remove 'type' from import declaration from \"{0}\""} + +var Remove_type_from_import_of_0_from_1 = &Message{code: 90056, category: CategoryMessage, key: "Remove_type_from_import_of_0_from_1_90056", text: "Remove 'type' from import of '{0}' from \"{1}\""} + +var Add_import_from_0 = &Message{code: 90057, category: CategoryMessage, key: "Add_import_from_0_90057", text: "Add import from \"{0}\""} + +var Update_import_from_0 = &Message{code: 90058, category: CategoryMessage, key: "Update_import_from_0_90058", text: "Update import from \"{0}\""} + +var Export_0_from_module_1 = &Message{code: 90059, category: CategoryMessage, key: "Export_0_from_module_1_90059", text: "Export '{0}' from module '{1}'"} + +var Export_all_referenced_locals = &Message{code: 90060, category: CategoryMessage, key: "Export_all_referenced_locals_90060", text: "Export all referenced locals"} + +var Update_modifiers_of_0 = &Message{code: 90061, category: CategoryMessage, key: "Update_modifiers_of_0_90061", text: "Update modifiers of '{0}'"} + +var Add_annotation_of_type_0 = &Message{code: 90062, category: CategoryMessage, key: "Add_annotation_of_type_0_90062", text: "Add annotation of type '{0}'"} + +var Add_return_type_0 = &Message{code: 90063, category: CategoryMessage, key: "Add_return_type_0_90063", text: "Add return type '{0}'"} + +var Extract_base_class_to_variable = &Message{code: 90064, category: CategoryMessage, key: "Extract_base_class_to_variable_90064", text: "Extract base class to variable"} + +var Extract_default_export_to_variable = &Message{code: 90065, category: CategoryMessage, key: "Extract_default_export_to_variable_90065", text: "Extract default export to variable"} + +var Extract_binding_expressions_to_variable = &Message{code: 90066, category: CategoryMessage, key: "Extract_binding_expressions_to_variable_90066", text: "Extract binding expressions to variable"} + +var Add_all_missing_type_annotations = &Message{code: 90067, category: CategoryMessage, key: "Add_all_missing_type_annotations_90067", text: "Add all missing type annotations"} + +var Add_satisfies_and_an_inline_type_assertion_with_0 = &Message{code: 90068, category: CategoryMessage, key: "Add_satisfies_and_an_inline_type_assertion_with_0_90068", text: "Add satisfies and an inline type assertion with '{0}'"} + +var Extract_to_variable_and_replace_with_0_as_typeof_0 = &Message{code: 90069, category: CategoryMessage, key: "Extract_to_variable_and_replace_with_0_as_typeof_0_90069", text: "Extract to variable and replace with '{0} as typeof {0}'"} + +var Mark_array_literal_as_const = &Message{code: 90070, category: CategoryMessage, key: "Mark_array_literal_as_const_90070", text: "Mark array literal as const"} + +var Annotate_types_of_properties_expando_function_in_a_namespace = &Message{code: 90071, category: CategoryMessage, key: "Annotate_types_of_properties_expando_function_in_a_namespace_90071", text: "Annotate types of properties expando function in a namespace"} + +var Convert_function_to_an_ES2015_class = &Message{code: 95001, category: CategoryMessage, key: "Convert_function_to_an_ES2015_class_95001", text: "Convert function to an ES2015 class"} + +var Convert_0_to_1_in_0 = &Message{code: 95003, category: CategoryMessage, key: "Convert_0_to_1_in_0_95003", text: "Convert '{0}' to '{1} in {0}'"} + +var Extract_to_0_in_1 = &Message{code: 95004, category: CategoryMessage, key: "Extract_to_0_in_1_95004", text: "Extract to {0} in {1}"} + +var Extract_function = &Message{code: 95005, category: CategoryMessage, key: "Extract_function_95005", text: "Extract function"} + +var Extract_constant = &Message{code: 95006, category: CategoryMessage, key: "Extract_constant_95006", text: "Extract constant"} + +var Extract_to_0_in_enclosing_scope = &Message{code: 95007, category: CategoryMessage, key: "Extract_to_0_in_enclosing_scope_95007", text: "Extract to {0} in enclosing scope"} + +var Extract_to_0_in_1_scope = &Message{code: 95008, category: CategoryMessage, key: "Extract_to_0_in_1_scope_95008", text: "Extract to {0} in {1} scope"} + +var Annotate_with_type_from_JSDoc = &Message{code: 95009, category: CategoryMessage, key: "Annotate_with_type_from_JSDoc_95009", text: "Annotate with type from JSDoc"} + +var Infer_type_of_0_from_usage = &Message{code: 95011, category: CategoryMessage, key: "Infer_type_of_0_from_usage_95011", text: "Infer type of '{0}' from usage"} + +var Infer_parameter_types_from_usage = &Message{code: 95012, category: CategoryMessage, key: "Infer_parameter_types_from_usage_95012", text: "Infer parameter types from usage"} + +var Convert_to_default_import = &Message{code: 95013, category: CategoryMessage, key: "Convert_to_default_import_95013", text: "Convert to default import"} + +var Install_0 = &Message{code: 95014, category: CategoryMessage, key: "Install_0_95014", text: "Install '{0}'"} + +var Replace_import_with_0 = &Message{code: 95015, category: CategoryMessage, key: "Replace_import_with_0_95015", text: "Replace import with '{0}'."} + +var Use_synthetic_default_member = &Message{code: 95016, category: CategoryMessage, key: "Use_synthetic_default_member_95016", text: "Use synthetic 'default' member."} + +var Convert_to_ES_module = &Message{code: 95017, category: CategoryMessage, key: "Convert_to_ES_module_95017", text: "Convert to ES module"} + +var Add_undefined_type_to_property_0 = &Message{code: 95018, category: CategoryMessage, key: "Add_undefined_type_to_property_0_95018", text: "Add 'undefined' type to property '{0}'"} + +var Add_initializer_to_property_0 = &Message{code: 95019, category: CategoryMessage, key: "Add_initializer_to_property_0_95019", text: "Add initializer to property '{0}'"} + +var Add_definite_assignment_assertion_to_property_0 = &Message{code: 95020, category: CategoryMessage, key: "Add_definite_assignment_assertion_to_property_0_95020", text: "Add definite assignment assertion to property '{0}'"} + +var Convert_all_type_literals_to_mapped_type = &Message{code: 95021, category: CategoryMessage, key: "Convert_all_type_literals_to_mapped_type_95021", text: "Convert all type literals to mapped type"} + +var Add_all_missing_members = &Message{code: 95022, category: CategoryMessage, key: "Add_all_missing_members_95022", text: "Add all missing members"} + +var Infer_all_types_from_usage = &Message{code: 95023, category: CategoryMessage, key: "Infer_all_types_from_usage_95023", text: "Infer all types from usage"} + +var Delete_all_unused_declarations = &Message{code: 95024, category: CategoryMessage, key: "Delete_all_unused_declarations_95024", text: "Delete all unused declarations"} + +var Prefix_all_unused_declarations_with_where_possible = &Message{code: 95025, category: CategoryMessage, key: "Prefix_all_unused_declarations_with_where_possible_95025", text: "Prefix all unused declarations with '_' where possible"} + +var Fix_all_detected_spelling_errors = &Message{code: 95026, category: CategoryMessage, key: "Fix_all_detected_spelling_errors_95026", text: "Fix all detected spelling errors"} + +var Add_initializers_to_all_uninitialized_properties = &Message{code: 95027, category: CategoryMessage, key: "Add_initializers_to_all_uninitialized_properties_95027", text: "Add initializers to all uninitialized properties"} + +var Add_definite_assignment_assertions_to_all_uninitialized_properties = &Message{code: 95028, category: CategoryMessage, key: "Add_definite_assignment_assertions_to_all_uninitialized_properties_95028", text: "Add definite assignment assertions to all uninitialized properties"} + +var Add_undefined_type_to_all_uninitialized_properties = &Message{code: 95029, category: CategoryMessage, key: "Add_undefined_type_to_all_uninitialized_properties_95029", text: "Add undefined type to all uninitialized properties"} + +var Change_all_jsdoc_style_types_to_TypeScript = &Message{code: 95030, category: CategoryMessage, key: "Change_all_jsdoc_style_types_to_TypeScript_95030", text: "Change all jsdoc-style types to TypeScript"} + +var Change_all_jsdoc_style_types_to_TypeScript_and_add_undefined_to_nullable_types = &Message{code: 95031, category: CategoryMessage, key: "Change_all_jsdoc_style_types_to_TypeScript_and_add_undefined_to_nullable_types_95031", text: "Change all jsdoc-style types to TypeScript (and add '| undefined' to nullable types)"} + +var Implement_all_unimplemented_interfaces = &Message{code: 95032, category: CategoryMessage, key: "Implement_all_unimplemented_interfaces_95032", text: "Implement all unimplemented interfaces"} + +var Install_all_missing_types_packages = &Message{code: 95033, category: CategoryMessage, key: "Install_all_missing_types_packages_95033", text: "Install all missing types packages"} + +var Rewrite_all_as_indexed_access_types = &Message{code: 95034, category: CategoryMessage, key: "Rewrite_all_as_indexed_access_types_95034", text: "Rewrite all as indexed access types"} + +var Convert_all_to_default_imports = &Message{code: 95035, category: CategoryMessage, key: "Convert_all_to_default_imports_95035", text: "Convert all to default imports"} + +var Make_all_super_calls_the_first_statement_in_their_constructor = &Message{code: 95036, category: CategoryMessage, key: "Make_all_super_calls_the_first_statement_in_their_constructor_95036", text: "Make all 'super()' calls the first statement in their constructor"} + +var Add_qualifier_to_all_unresolved_variables_matching_a_member_name = &Message{code: 95037, category: CategoryMessage, key: "Add_qualifier_to_all_unresolved_variables_matching_a_member_name_95037", text: "Add qualifier to all unresolved variables matching a member name"} + +var Change_all_extended_interfaces_to_implements = &Message{code: 95038, category: CategoryMessage, key: "Change_all_extended_interfaces_to_implements_95038", text: "Change all extended interfaces to 'implements'"} + +var Add_all_missing_super_calls = &Message{code: 95039, category: CategoryMessage, key: "Add_all_missing_super_calls_95039", text: "Add all missing super calls"} + +var Implement_all_inherited_abstract_classes = &Message{code: 95040, category: CategoryMessage, key: "Implement_all_inherited_abstract_classes_95040", text: "Implement all inherited abstract classes"} + +var Add_all_missing_async_modifiers = &Message{code: 95041, category: CategoryMessage, key: "Add_all_missing_async_modifiers_95041", text: "Add all missing 'async' modifiers"} + +var Add_ts_ignore_to_all_error_messages = &Message{code: 95042, category: CategoryMessage, key: "Add_ts_ignore_to_all_error_messages_95042", text: "Add '@ts-ignore' to all error messages"} + +var Annotate_everything_with_types_from_JSDoc = &Message{code: 95043, category: CategoryMessage, key: "Annotate_everything_with_types_from_JSDoc_95043", text: "Annotate everything with types from JSDoc"} + +var Add_to_all_uncalled_decorators = &Message{code: 95044, category: CategoryMessage, key: "Add_to_all_uncalled_decorators_95044", text: "Add '()' to all uncalled decorators"} + +var Convert_all_constructor_functions_to_classes = &Message{code: 95045, category: CategoryMessage, key: "Convert_all_constructor_functions_to_classes_95045", text: "Convert all constructor functions to classes"} + +var Generate_get_and_set_accessors = &Message{code: 95046, category: CategoryMessage, key: "Generate_get_and_set_accessors_95046", text: "Generate 'get' and 'set' accessors"} + +var Convert_require_to_import = &Message{code: 95047, category: CategoryMessage, key: "Convert_require_to_import_95047", text: "Convert 'require' to 'import'"} + +var Convert_all_require_to_import = &Message{code: 95048, category: CategoryMessage, key: "Convert_all_require_to_import_95048", text: "Convert all 'require' to 'import'"} + +var Move_to_a_new_file = &Message{code: 95049, category: CategoryMessage, key: "Move_to_a_new_file_95049", text: "Move to a new file"} + +var Remove_unreachable_code = &Message{code: 95050, category: CategoryMessage, key: "Remove_unreachable_code_95050", text: "Remove unreachable code"} + +var Remove_all_unreachable_code = &Message{code: 95051, category: CategoryMessage, key: "Remove_all_unreachable_code_95051", text: "Remove all unreachable code"} + +var Add_missing_typeof = &Message{code: 95052, category: CategoryMessage, key: "Add_missing_typeof_95052", text: "Add missing 'typeof'"} + +var Remove_unused_label = &Message{code: 95053, category: CategoryMessage, key: "Remove_unused_label_95053", text: "Remove unused label"} + +var Remove_all_unused_labels = &Message{code: 95054, category: CategoryMessage, key: "Remove_all_unused_labels_95054", text: "Remove all unused labels"} + +var Convert_0_to_mapped_object_type = &Message{code: 95055, category: CategoryMessage, key: "Convert_0_to_mapped_object_type_95055", text: "Convert '{0}' to mapped object type"} + +var Convert_namespace_import_to_named_imports = &Message{code: 95056, category: CategoryMessage, key: "Convert_namespace_import_to_named_imports_95056", text: "Convert namespace import to named imports"} + +var Convert_named_imports_to_namespace_import = &Message{code: 95057, category: CategoryMessage, key: "Convert_named_imports_to_namespace_import_95057", text: "Convert named imports to namespace import"} + +var Add_or_remove_braces_in_an_arrow_function = &Message{code: 95058, category: CategoryMessage, key: "Add_or_remove_braces_in_an_arrow_function_95058", text: "Add or remove braces in an arrow function"} + +var Add_braces_to_arrow_function = &Message{code: 95059, category: CategoryMessage, key: "Add_braces_to_arrow_function_95059", text: "Add braces to arrow function"} + +var Remove_braces_from_arrow_function = &Message{code: 95060, category: CategoryMessage, key: "Remove_braces_from_arrow_function_95060", text: "Remove braces from arrow function"} + +var Convert_default_export_to_named_export = &Message{code: 95061, category: CategoryMessage, key: "Convert_default_export_to_named_export_95061", text: "Convert default export to named export"} + +var Convert_named_export_to_default_export = &Message{code: 95062, category: CategoryMessage, key: "Convert_named_export_to_default_export_95062", text: "Convert named export to default export"} + +var Add_missing_enum_member_0 = &Message{code: 95063, category: CategoryMessage, key: "Add_missing_enum_member_0_95063", text: "Add missing enum member '{0}'"} + +var Add_all_missing_imports = &Message{code: 95064, category: CategoryMessage, key: "Add_all_missing_imports_95064", text: "Add all missing imports"} + +var Convert_to_async_function = &Message{code: 95065, category: CategoryMessage, key: "Convert_to_async_function_95065", text: "Convert to async function"} + +var Convert_all_to_async_functions = &Message{code: 95066, category: CategoryMessage, key: "Convert_all_to_async_functions_95066", text: "Convert all to async functions"} + +var Add_missing_call_parentheses = &Message{code: 95067, category: CategoryMessage, key: "Add_missing_call_parentheses_95067", text: "Add missing call parentheses"} + +var Add_all_missing_call_parentheses = &Message{code: 95068, category: CategoryMessage, key: "Add_all_missing_call_parentheses_95068", text: "Add all missing call parentheses"} + +var Add_unknown_conversion_for_non_overlapping_types = &Message{code: 95069, category: CategoryMessage, key: "Add_unknown_conversion_for_non_overlapping_types_95069", text: "Add 'unknown' conversion for non-overlapping types"} + +var Add_unknown_to_all_conversions_of_non_overlapping_types = &Message{code: 95070, category: CategoryMessage, key: "Add_unknown_to_all_conversions_of_non_overlapping_types_95070", text: "Add 'unknown' to all conversions of non-overlapping types"} + +var Add_missing_new_operator_to_call = &Message{code: 95071, category: CategoryMessage, key: "Add_missing_new_operator_to_call_95071", text: "Add missing 'new' operator to call"} + +var Add_missing_new_operator_to_all_calls = &Message{code: 95072, category: CategoryMessage, key: "Add_missing_new_operator_to_all_calls_95072", text: "Add missing 'new' operator to all calls"} + +var Add_names_to_all_parameters_without_names = &Message{code: 95073, category: CategoryMessage, key: "Add_names_to_all_parameters_without_names_95073", text: "Add names to all parameters without names"} + +var Enable_the_experimentalDecorators_option_in_your_configuration_file = &Message{code: 95074, category: CategoryMessage, key: "Enable_the_experimentalDecorators_option_in_your_configuration_file_95074", text: "Enable the 'experimentalDecorators' option in your configuration file"} + +var Convert_parameters_to_destructured_object = &Message{code: 95075, category: CategoryMessage, key: "Convert_parameters_to_destructured_object_95075", text: "Convert parameters to destructured object"} + +var Extract_type = &Message{code: 95077, category: CategoryMessage, key: "Extract_type_95077", text: "Extract type"} + +var Extract_to_type_alias = &Message{code: 95078, category: CategoryMessage, key: "Extract_to_type_alias_95078", text: "Extract to type alias"} + +var Extract_to_typedef = &Message{code: 95079, category: CategoryMessage, key: "Extract_to_typedef_95079", text: "Extract to typedef"} + +var Infer_this_type_of_0_from_usage = &Message{code: 95080, category: CategoryMessage, key: "Infer_this_type_of_0_from_usage_95080", text: "Infer 'this' type of '{0}' from usage"} + +var Add_const_to_unresolved_variable = &Message{code: 95081, category: CategoryMessage, key: "Add_const_to_unresolved_variable_95081", text: "Add 'const' to unresolved variable"} + +var Add_const_to_all_unresolved_variables = &Message{code: 95082, category: CategoryMessage, key: "Add_const_to_all_unresolved_variables_95082", text: "Add 'const' to all unresolved variables"} + +var Add_await = &Message{code: 95083, category: CategoryMessage, key: "Add_await_95083", text: "Add 'await'"} + +var Add_await_to_initializer_for_0 = &Message{code: 95084, category: CategoryMessage, key: "Add_await_to_initializer_for_0_95084", text: "Add 'await' to initializer for '{0}'"} + +var Fix_all_expressions_possibly_missing_await = &Message{code: 95085, category: CategoryMessage, key: "Fix_all_expressions_possibly_missing_await_95085", text: "Fix all expressions possibly missing 'await'"} + +var Remove_unnecessary_await = &Message{code: 95086, category: CategoryMessage, key: "Remove_unnecessary_await_95086", text: "Remove unnecessary 'await'"} + +var Remove_all_unnecessary_uses_of_await = &Message{code: 95087, category: CategoryMessage, key: "Remove_all_unnecessary_uses_of_await_95087", text: "Remove all unnecessary uses of 'await'"} + +var Enable_the_jsx_flag_in_your_configuration_file = &Message{code: 95088, category: CategoryMessage, key: "Enable_the_jsx_flag_in_your_configuration_file_95088", text: "Enable the '--jsx' flag in your configuration file"} + +var Add_await_to_initializers = &Message{code: 95089, category: CategoryMessage, key: "Add_await_to_initializers_95089", text: "Add 'await' to initializers"} + +var Extract_to_interface = &Message{code: 95090, category: CategoryMessage, key: "Extract_to_interface_95090", text: "Extract to interface"} + +var Convert_to_a_bigint_numeric_literal = &Message{code: 95091, category: CategoryMessage, key: "Convert_to_a_bigint_numeric_literal_95091", text: "Convert to a bigint numeric literal"} + +var Convert_all_to_bigint_numeric_literals = &Message{code: 95092, category: CategoryMessage, key: "Convert_all_to_bigint_numeric_literals_95092", text: "Convert all to bigint numeric literals"} + +var Convert_const_to_let = &Message{code: 95093, category: CategoryMessage, key: "Convert_const_to_let_95093", text: "Convert 'const' to 'let'"} + +var Prefix_with_declare = &Message{code: 95094, category: CategoryMessage, key: "Prefix_with_declare_95094", text: "Prefix with 'declare'"} + +var Prefix_all_incorrect_property_declarations_with_declare = &Message{code: 95095, category: CategoryMessage, key: "Prefix_all_incorrect_property_declarations_with_declare_95095", text: "Prefix all incorrect property declarations with 'declare'"} + +var Convert_to_template_string = &Message{code: 95096, category: CategoryMessage, key: "Convert_to_template_string_95096", text: "Convert to template string"} + +var Add_export_to_make_this_file_into_a_module = &Message{code: 95097, category: CategoryMessage, key: "Add_export_to_make_this_file_into_a_module_95097", text: "Add 'export {}' to make this file into a module"} + +var Set_the_target_option_in_your_configuration_file_to_0 = &Message{code: 95098, category: CategoryMessage, key: "Set_the_target_option_in_your_configuration_file_to_0_95098", text: "Set the 'target' option in your configuration file to '{0}'"} + +var Set_the_module_option_in_your_configuration_file_to_0 = &Message{code: 95099, category: CategoryMessage, key: "Set_the_module_option_in_your_configuration_file_to_0_95099", text: "Set the 'module' option in your configuration file to '{0}'"} + +var Convert_invalid_character_to_its_html_entity_code = &Message{code: 95100, category: CategoryMessage, key: "Convert_invalid_character_to_its_html_entity_code_95100", text: "Convert invalid character to its html entity code"} + +var Convert_all_invalid_characters_to_HTML_entity_code = &Message{code: 95101, category: CategoryMessage, key: "Convert_all_invalid_characters_to_HTML_entity_code_95101", text: "Convert all invalid characters to HTML entity code"} + +var Convert_all_const_to_let = &Message{code: 95102, category: CategoryMessage, key: "Convert_all_const_to_let_95102", text: "Convert all 'const' to 'let'"} + +var Convert_function_expression_0_to_arrow_function = &Message{code: 95105, category: CategoryMessage, key: "Convert_function_expression_0_to_arrow_function_95105", text: "Convert function expression '{0}' to arrow function"} + +var Convert_function_declaration_0_to_arrow_function = &Message{code: 95106, category: CategoryMessage, key: "Convert_function_declaration_0_to_arrow_function_95106", text: "Convert function declaration '{0}' to arrow function"} + +var Fix_all_implicit_this_errors = &Message{code: 95107, category: CategoryMessage, key: "Fix_all_implicit_this_errors_95107", text: "Fix all implicit-'this' errors"} + +var Wrap_invalid_character_in_an_expression_container = &Message{code: 95108, category: CategoryMessage, key: "Wrap_invalid_character_in_an_expression_container_95108", text: "Wrap invalid character in an expression container"} + +var Wrap_all_invalid_characters_in_an_expression_container = &Message{code: 95109, category: CategoryMessage, key: "Wrap_all_invalid_characters_in_an_expression_container_95109", text: "Wrap all invalid characters in an expression container"} + +var Visit_https_Colon_Slash_Slashaka_ms_Slashtsconfig_to_read_more_about_this_file = &Message{code: 95110, category: CategoryMessage, key: "Visit_https_Colon_Slash_Slashaka_ms_Slashtsconfig_to_read_more_about_this_file_95110", text: "Visit https://aka.ms/tsconfig to read more about this file"} + +var Add_a_return_statement = &Message{code: 95111, category: CategoryMessage, key: "Add_a_return_statement_95111", text: "Add a return statement"} + +var Remove_braces_from_arrow_function_body = &Message{code: 95112, category: CategoryMessage, key: "Remove_braces_from_arrow_function_body_95112", text: "Remove braces from arrow function body"} + +var Wrap_the_following_body_with_parentheses_which_should_be_an_object_literal = &Message{code: 95113, category: CategoryMessage, key: "Wrap_the_following_body_with_parentheses_which_should_be_an_object_literal_95113", text: "Wrap the following body with parentheses which should be an object literal"} + +var Add_all_missing_return_statement = &Message{code: 95114, category: CategoryMessage, key: "Add_all_missing_return_statement_95114", text: "Add all missing return statement"} + +var Remove_braces_from_all_arrow_function_bodies_with_relevant_issues = &Message{code: 95115, category: CategoryMessage, key: "Remove_braces_from_all_arrow_function_bodies_with_relevant_issues_95115", text: "Remove braces from all arrow function bodies with relevant issues"} + +var Wrap_all_object_literal_with_parentheses = &Message{code: 95116, category: CategoryMessage, key: "Wrap_all_object_literal_with_parentheses_95116", text: "Wrap all object literal with parentheses"} + +var Move_labeled_tuple_element_modifiers_to_labels = &Message{code: 95117, category: CategoryMessage, key: "Move_labeled_tuple_element_modifiers_to_labels_95117", text: "Move labeled tuple element modifiers to labels"} + +var Convert_overload_list_to_single_signature = &Message{code: 95118, category: CategoryMessage, key: "Convert_overload_list_to_single_signature_95118", text: "Convert overload list to single signature"} + +var Generate_get_and_set_accessors_for_all_overriding_properties = &Message{code: 95119, category: CategoryMessage, key: "Generate_get_and_set_accessors_for_all_overriding_properties_95119", text: "Generate 'get' and 'set' accessors for all overriding properties"} + +var Wrap_in_JSX_fragment = &Message{code: 95120, category: CategoryMessage, key: "Wrap_in_JSX_fragment_95120", text: "Wrap in JSX fragment"} + +var Wrap_all_unparented_JSX_in_JSX_fragment = &Message{code: 95121, category: CategoryMessage, key: "Wrap_all_unparented_JSX_in_JSX_fragment_95121", text: "Wrap all unparented JSX in JSX fragment"} + +var Convert_arrow_function_or_function_expression = &Message{code: 95122, category: CategoryMessage, key: "Convert_arrow_function_or_function_expression_95122", text: "Convert arrow function or function expression"} + +var Convert_to_anonymous_function = &Message{code: 95123, category: CategoryMessage, key: "Convert_to_anonymous_function_95123", text: "Convert to anonymous function"} + +var Convert_to_named_function = &Message{code: 95124, category: CategoryMessage, key: "Convert_to_named_function_95124", text: "Convert to named function"} + +var Convert_to_arrow_function = &Message{code: 95125, category: CategoryMessage, key: "Convert_to_arrow_function_95125", text: "Convert to arrow function"} + +var Remove_parentheses = &Message{code: 95126, category: CategoryMessage, key: "Remove_parentheses_95126", text: "Remove parentheses"} + +var Could_not_find_a_containing_arrow_function = &Message{code: 95127, category: CategoryMessage, key: "Could_not_find_a_containing_arrow_function_95127", text: "Could not find a containing arrow function"} + +var Containing_function_is_not_an_arrow_function = &Message{code: 95128, category: CategoryMessage, key: "Containing_function_is_not_an_arrow_function_95128", text: "Containing function is not an arrow function"} + +var Could_not_find_export_statement = &Message{code: 95129, category: CategoryMessage, key: "Could_not_find_export_statement_95129", text: "Could not find export statement"} + +var This_file_already_has_a_default_export = &Message{code: 95130, category: CategoryMessage, key: "This_file_already_has_a_default_export_95130", text: "This file already has a default export"} + +var Could_not_find_import_clause = &Message{code: 95131, category: CategoryMessage, key: "Could_not_find_import_clause_95131", text: "Could not find import clause"} + +var Could_not_find_namespace_import_or_named_imports = &Message{code: 95132, category: CategoryMessage, key: "Could_not_find_namespace_import_or_named_imports_95132", text: "Could not find namespace import or named imports"} + +var Selection_is_not_a_valid_type_node = &Message{code: 95133, category: CategoryMessage, key: "Selection_is_not_a_valid_type_node_95133", text: "Selection is not a valid type node"} + +var No_type_could_be_extracted_from_this_type_node = &Message{code: 95134, category: CategoryMessage, key: "No_type_could_be_extracted_from_this_type_node_95134", text: "No type could be extracted from this type node"} + +var Could_not_find_property_for_which_to_generate_accessor = &Message{code: 95135, category: CategoryMessage, key: "Could_not_find_property_for_which_to_generate_accessor_95135", text: "Could not find property for which to generate accessor"} + +var Name_is_not_valid = &Message{code: 95136, category: CategoryMessage, key: "Name_is_not_valid_95136", text: "Name is not valid"} + +var Can_only_convert_property_with_modifier = &Message{code: 95137, category: CategoryMessage, key: "Can_only_convert_property_with_modifier_95137", text: "Can only convert property with modifier"} + +var Switch_each_misused_0_to_1 = &Message{code: 95138, category: CategoryMessage, key: "Switch_each_misused_0_to_1_95138", text: "Switch each misused '{0}' to '{1}'"} + +var Convert_to_optional_chain_expression = &Message{code: 95139, category: CategoryMessage, key: "Convert_to_optional_chain_expression_95139", text: "Convert to optional chain expression"} + +var Could_not_find_convertible_access_expression = &Message{code: 95140, category: CategoryMessage, key: "Could_not_find_convertible_access_expression_95140", text: "Could not find convertible access expression"} + +var Could_not_find_matching_access_expressions = &Message{code: 95141, category: CategoryMessage, key: "Could_not_find_matching_access_expressions_95141", text: "Could not find matching access expressions"} + +var Can_only_convert_logical_AND_access_chains = &Message{code: 95142, category: CategoryMessage, key: "Can_only_convert_logical_AND_access_chains_95142", text: "Can only convert logical AND access chains"} + +var Add_void_to_Promise_resolved_without_a_value = &Message{code: 95143, category: CategoryMessage, key: "Add_void_to_Promise_resolved_without_a_value_95143", text: "Add 'void' to Promise resolved without a value"} + +var Add_void_to_all_Promises_resolved_without_a_value = &Message{code: 95144, category: CategoryMessage, key: "Add_void_to_all_Promises_resolved_without_a_value_95144", text: "Add 'void' to all Promises resolved without a value"} + +var Use_element_access_for_0 = &Message{code: 95145, category: CategoryMessage, key: "Use_element_access_for_0_95145", text: "Use element access for '{0}'"} + +var Use_element_access_for_all_undeclared_properties = &Message{code: 95146, category: CategoryMessage, key: "Use_element_access_for_all_undeclared_properties_95146", text: "Use element access for all undeclared properties."} + +var Delete_all_unused_imports = &Message{code: 95147, category: CategoryMessage, key: "Delete_all_unused_imports_95147", text: "Delete all unused imports"} + +var Infer_function_return_type = &Message{code: 95148, category: CategoryMessage, key: "Infer_function_return_type_95148", text: "Infer function return type"} + +var Return_type_must_be_inferred_from_a_function = &Message{code: 95149, category: CategoryMessage, key: "Return_type_must_be_inferred_from_a_function_95149", text: "Return type must be inferred from a function"} + +var Could_not_determine_function_return_type = &Message{code: 95150, category: CategoryMessage, key: "Could_not_determine_function_return_type_95150", text: "Could not determine function return type"} + +var Could_not_convert_to_arrow_function = &Message{code: 95151, category: CategoryMessage, key: "Could_not_convert_to_arrow_function_95151", text: "Could not convert to arrow function"} + +var Could_not_convert_to_named_function = &Message{code: 95152, category: CategoryMessage, key: "Could_not_convert_to_named_function_95152", text: "Could not convert to named function"} + +var Could_not_convert_to_anonymous_function = &Message{code: 95153, category: CategoryMessage, key: "Could_not_convert_to_anonymous_function_95153", text: "Could not convert to anonymous function"} + +var Can_only_convert_string_concatenations_and_string_literals = &Message{code: 95154, category: CategoryMessage, key: "Can_only_convert_string_concatenations_and_string_literals_95154", text: "Can only convert string concatenations and string literals"} + +var Selection_is_not_a_valid_statement_or_statements = &Message{code: 95155, category: CategoryMessage, key: "Selection_is_not_a_valid_statement_or_statements_95155", text: "Selection is not a valid statement or statements"} + +var Add_missing_function_declaration_0 = &Message{code: 95156, category: CategoryMessage, key: "Add_missing_function_declaration_0_95156", text: "Add missing function declaration '{0}'"} + +var Add_all_missing_function_declarations = &Message{code: 95157, category: CategoryMessage, key: "Add_all_missing_function_declarations_95157", text: "Add all missing function declarations"} + +var Method_not_implemented = &Message{code: 95158, category: CategoryMessage, key: "Method_not_implemented_95158", text: "Method not implemented."} + +var Function_not_implemented = &Message{code: 95159, category: CategoryMessage, key: "Function_not_implemented_95159", text: "Function not implemented."} + +var Add_override_modifier = &Message{code: 95160, category: CategoryMessage, key: "Add_override_modifier_95160", text: "Add 'override' modifier"} + +var Remove_override_modifier = &Message{code: 95161, category: CategoryMessage, key: "Remove_override_modifier_95161", text: "Remove 'override' modifier"} + +var Add_all_missing_override_modifiers = &Message{code: 95162, category: CategoryMessage, key: "Add_all_missing_override_modifiers_95162", text: "Add all missing 'override' modifiers"} + +var Remove_all_unnecessary_override_modifiers = &Message{code: 95163, category: CategoryMessage, key: "Remove_all_unnecessary_override_modifiers_95163", text: "Remove all unnecessary 'override' modifiers"} + +var Can_only_convert_named_export = &Message{code: 95164, category: CategoryMessage, key: "Can_only_convert_named_export_95164", text: "Can only convert named export"} + +var Add_missing_properties = &Message{code: 95165, category: CategoryMessage, key: "Add_missing_properties_95165", text: "Add missing properties"} + +var Add_all_missing_properties = &Message{code: 95166, category: CategoryMessage, key: "Add_all_missing_properties_95166", text: "Add all missing properties"} + +var Add_missing_attributes = &Message{code: 95167, category: CategoryMessage, key: "Add_missing_attributes_95167", text: "Add missing attributes"} + +var Add_all_missing_attributes = &Message{code: 95168, category: CategoryMessage, key: "Add_all_missing_attributes_95168", text: "Add all missing attributes"} + +var Add_undefined_to_optional_property_type = &Message{code: 95169, category: CategoryMessage, key: "Add_undefined_to_optional_property_type_95169", text: "Add 'undefined' to optional property type"} + +var Convert_named_imports_to_default_import = &Message{code: 95170, category: CategoryMessage, key: "Convert_named_imports_to_default_import_95170", text: "Convert named imports to default import"} + +var Delete_unused_param_tag_0 = &Message{code: 95171, category: CategoryMessage, key: "Delete_unused_param_tag_0_95171", text: "Delete unused '@param' tag '{0}'"} + +var Delete_all_unused_param_tags = &Message{code: 95172, category: CategoryMessage, key: "Delete_all_unused_param_tags_95172", text: "Delete all unused '@param' tags"} + +var Rename_param_tag_name_0_to_1 = &Message{code: 95173, category: CategoryMessage, key: "Rename_param_tag_name_0_to_1_95173", text: "Rename '@param' tag name '{0}' to '{1}'"} + +var Use_0 = &Message{code: 95174, category: CategoryMessage, key: "Use_0_95174", text: "Use `{0}`."} + +var Use_Number_isNaN_in_all_conditions = &Message{code: 95175, category: CategoryMessage, key: "Use_Number_isNaN_in_all_conditions_95175", text: "Use `Number.isNaN` in all conditions."} + +var Convert_typedef_to_TypeScript_type = &Message{code: 95176, category: CategoryMessage, key: "Convert_typedef_to_TypeScript_type_95176", text: "Convert typedef to TypeScript type."} + +var Convert_all_typedef_to_TypeScript_types = &Message{code: 95177, category: CategoryMessage, key: "Convert_all_typedef_to_TypeScript_types_95177", text: "Convert all typedef to TypeScript types."} + +var Move_to_file = &Message{code: 95178, category: CategoryMessage, key: "Move_to_file_95178", text: "Move to file"} + +var Cannot_move_to_file_selected_file_is_invalid = &Message{code: 95179, category: CategoryMessage, key: "Cannot_move_to_file_selected_file_is_invalid_95179", text: "Cannot move to file, selected file is invalid"} + +var Use_import_type = &Message{code: 95180, category: CategoryMessage, key: "Use_import_type_95180", text: "Use 'import type'"} + +var Use_type_0 = &Message{code: 95181, category: CategoryMessage, key: "Use_type_0_95181", text: "Use 'type {0}'"} + +var Fix_all_with_type_only_imports = &Message{code: 95182, category: CategoryMessage, key: "Fix_all_with_type_only_imports_95182", text: "Fix all with type-only imports"} + +var Cannot_move_statements_to_the_selected_file = &Message{code: 95183, category: CategoryMessage, key: "Cannot_move_statements_to_the_selected_file_95183", text: "Cannot move statements to the selected file"} + +var Inline_variable = &Message{code: 95184, category: CategoryMessage, key: "Inline_variable_95184", text: "Inline variable"} + +var Could_not_find_variable_to_inline = &Message{code: 95185, category: CategoryMessage, key: "Could_not_find_variable_to_inline_95185", text: "Could not find variable to inline."} + +var Variables_with_multiple_declarations_cannot_be_inlined = &Message{code: 95186, category: CategoryMessage, key: "Variables_with_multiple_declarations_cannot_be_inlined_95186", text: "Variables with multiple declarations cannot be inlined."} + +var Add_missing_comma_for_object_member_completion_0 = &Message{code: 95187, category: CategoryMessage, key: "Add_missing_comma_for_object_member_completion_0_95187", text: "Add missing comma for object member completion '{0}'."} + +var Add_missing_parameter_to_0 = &Message{code: 95188, category: CategoryMessage, key: "Add_missing_parameter_to_0_95188", text: "Add missing parameter to '{0}'"} + +var Add_missing_parameters_to_0 = &Message{code: 95189, category: CategoryMessage, key: "Add_missing_parameters_to_0_95189", text: "Add missing parameters to '{0}'"} + +var Add_all_missing_parameters = &Message{code: 95190, category: CategoryMessage, key: "Add_all_missing_parameters_95190", text: "Add all missing parameters"} + +var Add_optional_parameter_to_0 = &Message{code: 95191, category: CategoryMessage, key: "Add_optional_parameter_to_0_95191", text: "Add optional parameter to '{0}'"} + +var Add_optional_parameters_to_0 = &Message{code: 95192, category: CategoryMessage, key: "Add_optional_parameters_to_0_95192", text: "Add optional parameters to '{0}'"} + +var Add_all_optional_parameters = &Message{code: 95193, category: CategoryMessage, key: "Add_all_optional_parameters_95193", text: "Add all optional parameters"} + +var Wrap_in_parentheses = &Message{code: 95194, category: CategoryMessage, key: "Wrap_in_parentheses_95194", text: "Wrap in parentheses"} + +var Wrap_all_invalid_decorator_expressions_in_parentheses = &Message{code: 95195, category: CategoryMessage, key: "Wrap_all_invalid_decorator_expressions_in_parentheses_95195", text: "Wrap all invalid decorator expressions in parentheses"} + +var Add_resolution_mode_import_attribute = &Message{code: 95196, category: CategoryMessage, key: "Add_resolution_mode_import_attribute_95196", text: "Add 'resolution-mode' import attribute"} + +var Add_resolution_mode_import_attribute_to_all_type_only_imports_that_need_it = &Message{code: 95197, category: CategoryMessage, key: "Add_resolution_mode_import_attribute_to_all_type_only_imports_that_need_it_95197", text: "Add 'resolution-mode' import attribute to all type-only imports that need it"} + +var Do_not_print_diagnostics = &Message{code: 100000, category: CategoryMessage, key: "Do_not_print_diagnostics_100000", text: "Do not print diagnostics."} + +var Run_in_single_threaded_mode = &Message{code: 100001, category: CategoryMessage, key: "Run_in_single_threaded_mode_100001", text: "Run in single threaded mode."} + +var Generate_pprof_CPU_Slashmemory_profiles_to_the_given_directory = &Message{code: 100002, category: CategoryMessage, key: "Generate_pprof_CPU_Slashmemory_profiles_to_the_given_directory_100002", text: "Generate pprof CPU/memory profiles to the given directory."} diff --git a/kitcom/internal/tsgo/diagnostics/extraDiagnosticMessages.json b/kitcom/internal/tsgo/diagnostics/extraDiagnosticMessages.json new file mode 100644 index 0000000..b735a67 --- /dev/null +++ b/kitcom/internal/tsgo/diagnostics/extraDiagnosticMessages.json @@ -0,0 +1,42 @@ +{ + "Do not print diagnostics.": { + "category": "Message", + "code": 100000 + }, + "Run in single threaded mode.": { + "category": "Message", + "code": 100001 + }, + "Generate pprof CPU/memory profiles to the given directory.": { + "category": "Message", + "code": 100002 + }, + "Non-relative paths are not allowed. Did you forget a leading './'?": { + "category": "Error", + "code": 5090 + }, + "A JSDoc '@type' tag on a function must have a signature with the correct number of arguments.": { + "category": "Error", + "code": 8030 + }, + "A JSDoc '@type' tag may not occur with a '@param' or '@returns' tag.": { + "category": "Error", + "code": 8040 + }, + "Failed to delete file '{0}'.": { + "category": "Message", + "code": 6353 + }, + "Project '{0}' is out of date because config file does not exist.": { + "category": "Message", + "code": 6401 + }, + "Project '{0}' is out of date because input '{1}' does not exist.": { + "category": "Message", + "code": 6420 + }, + "Project '{0}' is out of date because it has errors.": { + "category": "Message", + "code": 6423 + } +} diff --git a/kitcom/internal/tsgo/diagnostics/generate.go b/kitcom/internal/tsgo/diagnostics/generate.go new file mode 100644 index 0000000..464ca85 --- /dev/null +++ b/kitcom/internal/tsgo/diagnostics/generate.go @@ -0,0 +1,183 @@ +//go:build ignore + +package main + +import ( + "bytes" + "cmp" + "flag" + "fmt" + "go/format" + "go/token" + "log" + "maps" + "os" + "path/filepath" + "regexp" + "runtime" + "slices" + "strconv" + "strings" + "unicode" + + "github.com/go-json-experiment/json" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/repo" +) + +type diagnosticMessage struct { + Category string `json:"category"` + Code int `json:"code"` + ReportsUnnecessary bool `json:"reportsUnnecessary"` + ReportsDeprecated bool `json:"reportsDeprecated"` + // spelling error here is [sic] in Strada + ElidedInCompatibilityPyramid bool `json:"elidedInCompatabilityPyramid"` + + key string +} + +func main() { + log.SetFlags(log.LstdFlags | log.Lshortfile) + + output := flag.String("output", "", "path to the output diagnostics_generated.go file") + flag.Parse() + + if *output == "" { + flag.Usage() + return + } + + rawDiagnosticMessages := readRawMessages(filepath.Join(repo.TypeScriptSubmodulePath, "src", "compiler", "diagnosticMessages.json")) + + _, filename, _, ok := runtime.Caller(0) + if !ok { + panic("could not get current filename") + } + filename = filepath.FromSlash(filename) // runtime.Caller always returns forward slashes; https://go.dev/issues/3335, https://go.dev/cl/603275 + + rawExtraMessages := readRawMessages(filepath.Join(filepath.Dir(filename), "extraDiagnosticMessages.json")) + + maps.Copy(rawDiagnosticMessages, rawExtraMessages) + diagnosticMessages := slices.Collect(maps.Values(rawDiagnosticMessages)) + + slices.SortFunc(diagnosticMessages, func(a *diagnosticMessage, b *diagnosticMessage) int { + return cmp.Compare(a.Code, b.Code) + }) + + var buf bytes.Buffer + + buf.WriteString("// Code generated by generate.go; DO NOT EDIT.\n") + buf.WriteString("\n") + buf.WriteString("package diagnostics\n") + + for _, m := range diagnosticMessages { + varName, key := convertPropertyName(m.key, m.Code) + + fmt.Fprintf(&buf, "var %s = &Message{code: %d, category: Category%s, key: %q, text: %q", varName, m.Code, m.Category, key, m.key) + + if m.ReportsUnnecessary { + buf.WriteString(`, reportsUnnecessary: true`) + } + if m.ElidedInCompatibilityPyramid { + buf.WriteString(`, elidedInCompatibilityPyramid: true`) + } + if m.ReportsDeprecated { + buf.WriteString(`, reportsDeprecated: true`) + } + + buf.WriteString("}\n\n") + } + + formatted, err := format.Source(buf.Bytes()) + if err != nil { + log.Fatalf("failed to format output: %v", err) + return + } + + if err := os.WriteFile(*output, formatted, 0o666); err != nil { + log.Fatalf("failed to write output: %v", err) + return + } +} + +func readRawMessages(p string) map[int]*diagnosticMessage { + file, err := os.Open(p) + if err != nil { + log.Fatalf("failed to open file: %v", err) + return nil + } + defer file.Close() + + var rawMessages map[string]*diagnosticMessage + if err := json.UnmarshalRead(file, &rawMessages); err != nil { + log.Fatalf("failed to decode file: %v", err) + return nil + } + + codeToMessage := make(map[int]*diagnosticMessage, len(rawMessages)) + for k, m := range rawMessages { + m.key = k + codeToMessage[m.Code] = m + } + + return codeToMessage +} + +var ( + multipleUnderscoreRegexp = regexp.MustCompile(`_+`) + leadingUnderscoreUnlessDigitRegexp = regexp.MustCompile(`^_+(\D)`) + trailingUnderscoreRegexp = regexp.MustCompile(`_$`) +) + +func convertPropertyName(origName string, code int) (varName string, key string) { + var b strings.Builder + b.Grow(len(origName)) + + for _, r := range origName { + switch r { + case '*': + b.WriteString("_Asterisk") + case '/': + b.WriteString("_Slash") + case ':': + b.WriteString("_Colon") + default: + if !unicode.IsLetter(r) && !unicode.IsDigit(r) { + b.WriteRune('_') + } else { + b.WriteRune(r) + } + } + } + + varName = b.String() + // get rid of all multi-underscores + varName = multipleUnderscoreRegexp.ReplaceAllString(varName, "_") + // remove any leading underscore, unless it is followed by a number. + varName = leadingUnderscoreUnlessDigitRegexp.ReplaceAllString(varName, "$1") + // get rid of all trailing underscores. + varName = trailingUnderscoreRegexp.ReplaceAllString(varName, "") + + key = varName + if len(key) > 100 { + key = key[:100] + } + key = key + "_" + strconv.Itoa(code) + + if !token.IsExported(varName) { + var b strings.Builder + b.Grow(len(varName) + 2) + if varName[0] == '_' { + b.WriteString("X") + } else { + b.WriteString("X_") + } + b.WriteString(varName) + varName = b.String() + } + + if !token.IsIdentifier(varName) || !token.IsExported(varName) { + log.Fatalf("failed to convert property name to exported identifier: %q", origName) + } + + return varName, key +} diff --git a/kitcom/internal/tsgo/diagnostics/stringer_generated.go b/kitcom/internal/tsgo/diagnostics/stringer_generated.go new file mode 100644 index 0000000..c4bcd79 --- /dev/null +++ b/kitcom/internal/tsgo/diagnostics/stringer_generated.go @@ -0,0 +1,26 @@ +// Code generated by "stringer -type=Category -output=stringer_generated.go"; DO NOT EDIT. + +package diagnostics + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[CategoryWarning-0] + _ = x[CategoryError-1] + _ = x[CategorySuggestion-2] + _ = x[CategoryMessage-3] +} + +const _Category_name = "CategoryWarningCategoryErrorCategorySuggestionCategoryMessage" + +var _Category_index = [...]uint8{0, 15, 28, 46, 61} + +func (i Category) String() string { + if i < 0 || i >= Category(len(_Category_index)-1) { + return "Category(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _Category_name[_Category_index[i]:_Category_index[i+1]] +} diff --git a/kitcom/internal/tsgo/jsnum/jsnum.go b/kitcom/internal/tsgo/jsnum/jsnum.go new file mode 100644 index 0000000..9e54baa --- /dev/null +++ b/kitcom/internal/tsgo/jsnum/jsnum.go @@ -0,0 +1,159 @@ +// Package jsnum provides JS-like number handling. +package jsnum + +import ( + "math" +) + +const ( + MaxSafeInteger Number = 1<<53 - 1 + MinSafeInteger Number = -MaxSafeInteger +) + +// Number represents a JS-like number. +// +// All operations that can be performed directly on this type +// (e.g., conversion, arithmetic, etc.) behave as they would in JavaScript, +// but any other operation should use this type's methods, +// not the "math" package and conversions. +type Number float64 + +func NaN() Number { + return Number(math.NaN()) +} + +func (n Number) IsNaN() bool { + return math.IsNaN(float64(n)) +} + +func Inf(sign int) Number { + return Number(math.Inf(sign)) +} + +func (n Number) IsInf() bool { + return math.IsInf(float64(n), 0) +} + +func isNonFinite(x float64) bool { + // This is equivalent to checking `math.IsNaN(x) || math.IsInf(x, 0)` in one operation. + const mask = 0x7FF0000000000000 + return math.Float64bits(x)&mask == mask +} + +// https://tc39.es/ecma262/2024/multipage/abstract-operations.html#sec-touint32 +func (x Number) toUint32() uint32 { + // The only difference between ToUint32 and ToInt32 is the interpretation of the bits. + return uint32(x.toInt32()) +} + +// https://tc39.es/ecma262/2024/multipage/abstract-operations.html#sec-toint32 +func (n Number) toInt32() int32 { + x := float64(n) + + // Fast path: if the number is in the range (-2^31, 2^32), i.e. an SMI, + // then we don't need to do any special mapping. + if smi := int32(x); float64(smi) == x { + return smi + } + + // 2. If number is not finite or number is either +0𝔽 or -0𝔽, return +0𝔽. + // Zero was covered by the test above. + if isNonFinite(x) { + return 0 + } + + // Let int be truncate(ℝ(number)). + x = math.Trunc(x) + // Let int32bit be int modulo 2**32. + x = math.Mod(x, 1<<32) + // If int32bit ≥ 2**31, return 𝔽(int32bit - 2**32); otherwise return 𝔽(int32bit). + return int32(int64(x)) +} + +func (x Number) toShiftCount() uint32 { + return x.toUint32() & 31 +} + +// https://tc39.es/ecma262/2024/multipage/ecmascript-data-types-and-values.html#sec-numeric-types-number-signedRightShift +func (x Number) SignedRightShift(y Number) Number { + return Number(x.toInt32() >> y.toShiftCount()) +} + +// https://tc39.es/ecma262/2024/multipage/ecmascript-data-types-and-values.html#sec-numeric-types-number-unsignedRightShift +func (x Number) UnsignedRightShift(y Number) Number { + return Number(x.toUint32() >> y.toShiftCount()) +} + +// https://tc39.es/ecma262/2024/multipage/ecmascript-data-types-and-values.html#sec-numeric-types-number-leftShift +func (x Number) LeftShift(y Number) Number { + return Number(x.toInt32() << y.toShiftCount()) +} + +// https://tc39.es/ecma262/2024/multipage/ecmascript-data-types-and-values.html#sec-numeric-types-number-bitwiseNOT +func (x Number) BitwiseNOT() Number { + return Number(^x.toInt32()) +} + +// The below are implemented by https://tc39.es/ecma262/2024/multipage/ecmascript-data-types-and-values.html#sec-numberbitwiseop. + +// https://tc39.es/ecma262/2024/multipage/ecmascript-data-types-and-values.html#sec-numeric-types-number-bitwiseOR +func (x Number) BitwiseOR(y Number) Number { + return Number(x.toInt32() | y.toInt32()) +} + +// https://tc39.es/ecma262/2024/multipage/ecmascript-data-types-and-values.html#sec-numeric-types-number-bitwiseAND +func (x Number) BitwiseAND(y Number) Number { + return Number(x.toInt32() & y.toInt32()) +} + +// https://tc39.es/ecma262/2024/multipage/ecmascript-data-types-and-values.html#sec-numeric-types-number-bitwiseXOR +func (x Number) BitwiseXOR(y Number) Number { + return Number(x.toInt32() ^ y.toInt32()) +} + +func (x Number) trunc() Number { + return Number(math.Trunc(float64(x))) +} + +func (x Number) Floor() Number { + return Number(math.Floor(float64(x))) +} + +func (x Number) Abs() Number { + return Number(math.Abs(float64(x))) +} + +var negativeZero = Number(math.Copysign(0, -1)) + +// https://tc39.es/ecma262/2024/multipage/ecmascript-data-types-and-values.html#sec-numeric-types-number-remainder +func (n Number) Remainder(d Number) Number { + switch { + case n.IsNaN() || d.IsNaN(): + return NaN() + case n.IsInf(): + return NaN() + case d.IsInf(): + return n + case d == 0: + return NaN() + case n == 0: + return n + } + r := n - d*(n/d).trunc() + if r == 0 && n < 0 { + return negativeZero + } + return r +} + +// https://tc39.es/ecma262/2024/multipage/ecmascript-data-types-and-values.html#sec-numeric-types-number-exponentiate +func (base Number) Exponentiate(exponent Number) Number { + switch { + case (base == 1 || base == -1) && exponent.IsInf(): + return NaN() + case base == 1 && exponent.IsNaN(): + return NaN() + } + + return Number(math.Pow(float64(base), float64(exponent))) +} diff --git a/kitcom/internal/tsgo/jsnum/pseudobigint.go b/kitcom/internal/tsgo/jsnum/pseudobigint.go new file mode 100644 index 0000000..c06cdf8 --- /dev/null +++ b/kitcom/internal/tsgo/jsnum/pseudobigint.go @@ -0,0 +1,66 @@ +package jsnum + +import ( + "fmt" + "math/big" + "strings" +) + +// PseudoBigInt represents a JS-like bigint. The zero state of the struct represents the value 0. +type PseudoBigInt struct { + Negative bool // true if the value is a non-zero negative number. + Base10Value string // The absolute value in base 10 with no leading zeros. The value zero is represented as an empty string. +} + +func NewPseudoBigInt(value string, negative bool) PseudoBigInt { + value = strings.TrimLeft(value, "0") + return PseudoBigInt{Negative: negative && len(value) != 0, Base10Value: value} +} + +func (value PseudoBigInt) String() string { + if len(value.Base10Value) == 0 { + return "0" + } + if value.Negative { + return "-" + value.Base10Value + } + return value.Base10Value +} + +func (value PseudoBigInt) Sign() int { + if len(value.Base10Value) == 0 { + return 0 + } + if value.Negative { + return -1 + } + return 1 +} + +func ParseValidBigInt(text string) PseudoBigInt { + text, negative := strings.CutPrefix(text, "-") + return NewPseudoBigInt(ParsePseudoBigInt(text), negative) +} + +func ParsePseudoBigInt(stringValue string) string { + stringValue = strings.TrimSuffix(stringValue, "n") + var b1 byte + if len(stringValue) > 1 { + b1 = stringValue[1] + } + switch b1 { + case 'b', 'B', 'o', 'O', 'x', 'X': + // Not decimal. + default: + stringValue = strings.TrimLeft(stringValue, "0") + if stringValue == "" { + return "0" + } + return stringValue + } + bi, ok := new(big.Int).SetString(stringValue, 0) + if !ok { + panic(fmt.Sprintf("Failed to parse big int: %q", stringValue)) + } + return bi.String() // !!! +} diff --git a/kitcom/internal/tsgo/jsnum/string.go b/kitcom/internal/tsgo/jsnum/string.go new file mode 100644 index 0000000..637710c --- /dev/null +++ b/kitcom/internal/tsgo/jsnum/string.go @@ -0,0 +1,341 @@ +package jsnum + +import ( + "errors" + "math" + "math/big" + "strconv" + "strings" + "unicode" + "unicode/utf8" + + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/stringutil" + "github.com/go-json-experiment/json" +) + +// https://tc39.es/ecma262/2024/multipage/ecmascript-data-types-and-values.html#sec-numeric-types-number-tostring +func (n Number) String() string { + switch { + case n.IsNaN(): + return "NaN" + case n.IsInf(): + if n < 0 { + return "-Infinity" + } + return "Infinity" + } + + // Fast path: for safe integers, directly convert to string. + if MinSafeInteger <= n && n <= MaxSafeInteger { + if i := int64(n); float64(i) == float64(n) { + return strconv.FormatInt(i, 10) + } + } + + // Otherwise, the Go json package handles this correctly. + b, _ := json.Marshal(float64(n)) + return string(b) +} + +// https://tc39.es/ecma262/2024/multipage/abstract-operations.html#sec-stringtonumber +func FromString(s string) Number { + // Implementing StringToNumber exactly as written in the spec involves + // writing a parser, along with the conversion of the parsed AST into the + // actual value. + // + // We've already implemented a number parser in the scanner, but we can't + // import it here. We also do not have the conversion implemented since we + // previously just wrote `+literal` and let the runtime handle it. + // + // The strategy below is to instead break the number apart and fix it up + // such that Go's own parsing functionality can handle it. This won't be + // the fastest method, but it saves us from writing the full parser and + // conversion logic. + + s = strings.TrimFunc(s, isStrWhiteSpace) + + switch s { + case "": + return 0 + case "Infinity", "+Infinity": + return Inf(1) + case "-Infinity": + return Inf(-1) + } + + for _, r := range s { + if !isNumberRune(r) { + return NaN() + } + } + + if n, ok := tryParseInt(s); ok { + return n + } + + // Cut this off first so we can ensure -0 is returned as -0. + s, negative := strings.CutPrefix(s, "-") + + if !negative { + s, _ = strings.CutPrefix(s, "+") + } + + if first, _ := utf8.DecodeRuneInString(s); !stringutil.IsDigit(first) && first != '.' { + return NaN() + } + + f := parseFloatString(s) + if math.IsNaN(f) { + return NaN() + } + + sign := 1.0 + if negative { + sign = -1.0 + } + return Number(math.Copysign(f, sign)) +} + +func isStrWhiteSpace(r rune) bool { + // This is different than stringutil.IsWhiteSpaceLike. + + // https://tc39.es/ecma262/2024/multipage/ecmascript-language-lexical-grammar.html#prod-LineTerminator + // https://tc39.es/ecma262/2024/multipage/ecmascript-language-lexical-grammar.html#prod-WhiteSpace + + switch r { + // LineTerminator + case '\n', '\r', 0x2028, 0x2029: + return true + // WhiteSpace + case '\t', '\v', '\f', 0xFEFF: + return true + } + + // WhiteSpace + return unicode.Is(unicode.Zs, r) +} + +var errUnknownPrefix = errors.New("unknown number prefix") + +func tryParseInt(s string) (Number, bool) { + var i int64 + var err error + var hasIntResult bool + + if len(s) > 2 { + prefix, rest := s[:2], s[2:] + switch prefix { + case "0b", "0B": + if !isAllBinaryDigits(rest) { + return NaN(), true + } + i, err = strconv.ParseInt(rest, 2, 64) + hasIntResult = true + case "0o", "0O": + if !isAllOctalDigits(rest) { + return NaN(), true + } + i, err = strconv.ParseInt(rest, 8, 64) + hasIntResult = true + case "0x", "0X": + if !isAllHexDigits(rest) { + return NaN(), true + } + i, err = strconv.ParseInt(rest, 16, 64) + hasIntResult = true + } + } + + if !hasIntResult { + // StringToNumber does not parse leading zeros as octal. + s = trimLeadingZeros(s) + if !isAllDigits(s) { + return 0, false + } + i, err = strconv.ParseInt(s, 10, 64) + hasIntResult = true + } + + if hasIntResult && err == nil { + return Number(i), true + } + + // Using this to parse large integers. + bi, ok := new(big.Int).SetString(s, 0) + if !ok { + return NaN(), true + } + + f, _ := bi.Float64() + return Number(f), true +} + +func parseFloatString(s string) float64 { + var hasDot, hasExp bool + + // + // . + // .e + // e + var a, b, c, rest string + + a, rest, hasDot = strings.Cut(s, ".") + if hasDot { + // . + // .e + b, c, hasExp = cutAny(rest, "eE") + } else { + // + // e + a, c, hasExp = cutAny(s, "eE") + } + + var sb strings.Builder + sb.Grow(len(a) + len(b) + len(c) + 3) + + if a == "" { + if hasDot && b == "" { + return math.NaN() + } + if hasExp && c == "" { + return math.NaN() + } + sb.WriteString("0") + } else { + a = trimLeadingZeros(a) + if !isAllDigits(a) { + return math.NaN() + } + sb.WriteString(a) + } + + if hasDot { + sb.WriteString(".") + if b == "" { + sb.WriteString("0") + } else { + b = trimTrailingZeros(b) + if !isAllDigits(b) { + return math.NaN() + } + sb.WriteString(b) + } + } + + if hasExp { + sb.WriteString("e") + + c, negative := strings.CutPrefix(c, "-") + if negative { + sb.WriteString("-") + } else { + c, _ = strings.CutPrefix(c, "+") + } + c = trimLeadingZeros(c) + if !isAllDigits(c) { + return math.NaN() + } + sb.WriteString(c) + } + + return stringToFloat64(sb.String()) +} + +func cutAny(s string, cutset string) (before, after string, found bool) { + if i := strings.IndexAny(s, cutset); i >= 0 { + before = s[:i] + afterAndFound := s[i:] + _, size := utf8.DecodeRuneInString(afterAndFound) + after = afterAndFound[size:] + return before, after, true + } + return s, "", false +} + +func trimLeadingZeros(s string) string { + if strings.HasPrefix(s, "0") { + s = strings.TrimLeft(s, "0") + if s == "" { + return "0" + } + } + return s +} + +func trimTrailingZeros(s string) string { + if strings.HasSuffix(s, "0") { + s = strings.TrimRight(s, "0") + if s == "" { + return "0" + } + } + return s +} + +func stringToFloat64(s string) float64 { + if f, err := strconv.ParseFloat(s, 64); err == nil { + return f + } else { + if errors.Is(err, strconv.ErrRange) { + return f + } + } + return math.NaN() +} + +func isAllDigits(s string) bool { + for _, r := range s { + if !stringutil.IsDigit(r) { + return false + } + } + return true +} + +func isAllBinaryDigits(s string) bool { + for _, r := range s { + if r != '0' && r != '1' { + return false + } + } + return true +} + +func isAllOctalDigits(s string) bool { + for _, r := range s { + if !stringutil.IsOctalDigit(r) { + return false + } + } + return true +} + +func isAllHexDigits(s string) bool { + for _, r := range s { + if !stringutil.IsHexDigit(r) { + return false + } + } + return true +} + +func isNumberRune(r rune) bool { + if stringutil.IsDigit(r) { + return true + } + + if 'a' <= r && r <= 'f' { + return true + } + + if 'A' <= r && r <= 'F' { + return true + } + + switch r { + case '.', '-', '+', 'x', 'X', 'o', 'O': + return true + } + + return false +} diff --git a/kitcom/internal/tsgo/jsonutil/jsonutil.go b/kitcom/internal/tsgo/jsonutil/jsonutil.go new file mode 100644 index 0000000..82ae50f --- /dev/null +++ b/kitcom/internal/tsgo/jsonutil/jsonutil.go @@ -0,0 +1,24 @@ +package jsonutil + +import ( + "io" + + "github.com/go-json-experiment/json" + "github.com/go-json-experiment/json/jsontext" +) + +func MarshalIndent(in any, prefix, indent string) (out []byte, err error) { + if prefix == "" && indent == "" { + // WithIndentPrefix and WithIndent imply multiline output, so skip them. + return json.Marshal(in) + } + return json.Marshal(in, jsontext.WithIndentPrefix(prefix), jsontext.WithIndent(indent)) +} + +func MarshalIndentWrite(out io.Writer, in any, prefix, indent string) (err error) { + if prefix == "" && indent == "" { + // WithIndentPrefix and WithIndent imply multiline output, so skip them. + return json.MarshalWrite(out, in) + } + return json.MarshalWrite(out, in, jsontext.WithIndentPrefix(prefix), jsontext.WithIndent(indent)) +} diff --git a/kitcom/internal/tsgo/parser/jsdoc.go b/kitcom/internal/tsgo/parser/jsdoc.go new file mode 100644 index 0000000..04da3c2 --- /dev/null +++ b/kitcom/internal/tsgo/parser/jsdoc.go @@ -0,0 +1,1205 @@ +package parser + +import ( + "strings" + "unicode" + + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/ast" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/core" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/diagnostics" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/stringutil" +) + +type jsdocState int32 + +const ( + jsdocStateBeginningOfLine jsdocState = iota + jsdocStateSawAsterisk + jsdocStateSavingComments + jsdocStateSavingBackticks +) + +type propertyLikeParse int32 + +const ( + propertyLikeParseProperty propertyLikeParse = 1 << iota + propertyLikeParseParameter + propertyLikeParseCallbackParameter +) + +func (p *Parser) withJSDoc(node *ast.Node, hasJSDoc bool) []*ast.Node { + if !hasJSDoc { + return nil + } + + if p.jsdocCache == nil { + p.jsdocCache = make(map[*ast.Node][]*ast.Node, strings.Count(p.sourceText, "/**")) + } else if _, ok := p.jsdocCache[node]; ok { + panic("tried to set JSDoc on a node with existing JSDoc") + } + // Should only be called once per node + p.hasDeprecatedTag = false + ranges := GetJSDocCommentRanges(&p.factory, p.jsdocCommentRangesSpace, node, p.sourceText) + p.jsdocCommentRangesSpace = ranges[:0] + jsdoc := p.nodeSlicePool.NewSlice(len(ranges))[:0] + pos := node.Pos() + for _, comment := range ranges { + if parsed := p.parseJSDocComment(node, comment.Pos(), comment.End(), pos); parsed != nil { + parsed.Parent = node + jsdoc = append(jsdoc, parsed) + pos = parsed.End() + } + } + if len(jsdoc) != 0 { + if node.Flags&ast.NodeFlagsHasJSDoc == 0 { + node.Flags |= ast.NodeFlagsHasJSDoc + } + if p.hasDeprecatedTag { + p.hasDeprecatedTag = false + node.Flags |= ast.NodeFlagsDeprecated + } + if p.scriptKind == core.ScriptKindJS || p.scriptKind == core.ScriptKindJSX { + p.reparseTags(node, jsdoc) + } + p.jsdocCache[node] = jsdoc + return jsdoc + } + return nil +} + +func (p *Parser) parseJSDocTypeExpression(mayOmitBraces bool) *ast.Node { + pos := p.nodePos() + var hasBrace bool + if mayOmitBraces { + hasBrace = p.parseOptional(ast.KindOpenBraceToken) + } else { + hasBrace = p.parseExpected(ast.KindOpenBraceToken) + } + saveContextFlags := p.contextFlags + p.setContextFlags(ast.NodeFlagsJSDoc, true) + t := p.parseJSDocType() + p.contextFlags = saveContextFlags + if hasBrace { + p.parseExpectedJSDoc(ast.KindCloseBraceToken) + } + + return p.finishNode(p.factory.NewJSDocTypeExpression(t), pos) +} + +func (p *Parser) parseJSDocNameReference() *ast.Node { + pos := p.nodePos() + hasBrace := p.parseOptional(ast.KindOpenBraceToken) + p2 := p.nodePos() + entityName := p.parseEntityName(false, nil) + for p.token == ast.KindPrivateIdentifier { + p.scanner.ReScanHashToken() // rescan #id as # id + p.nextTokenJSDoc() // then skip the # + entityName = p.finishNode(p.factory.NewQualifiedName(entityName, p.parseIdentifier()), p2) + } + if hasBrace { + p.parseExpectedJSDoc(ast.KindCloseBraceToken) + } + + return p.finishNode(p.factory.NewJSDocNameReference(entityName), pos) +} + +// Pass end=-1 to parse the text to the end +func (p *Parser) parseJSDocComment(parent *ast.Node, start int, end int, fullStart int) *ast.Node { + if end == -1 { + end = len(p.sourceText) + } + // Check for /** (JSDoc opening part) + if !isJSDocLikeText(p.sourceText[start:]) { + // TODO: This should be a panic, unless parseSingleJSDocComment is calling this (not ported yet) + return nil + } + + saveSourceText := p.sourceText + saveToken := p.token + saveContextFlags := p.contextFlags + saveParsingContexts := p.parsingContexts + saveScannerState := p.scanner.Mark() + saveDiagnosticsLength := len(p.diagnostics) + saveHasParseError := p.hasParseError + saveHasAwaitIdentifier := p.statementHasAwaitIdentifier + + // initial indent is start+4 to account for leading `/** ` + // + 1 because \n is one character before the first character in the line and, + // if there is no \n before start, -1 is one index before the first character in the string + initialIndent := start + 4 - (strings.LastIndex(p.sourceText[:start], "\n") + 1) + // -2 for trailing `*/` + p.sourceText = p.sourceText[:end-2] + p.scanner.SetText(p.sourceText) + // +3 for leading `/**` + p.scanner.ResetPos(start + 3) + p.setContextFlags(ast.NodeFlagsJSDoc, true) + p.parsingContexts = p.parsingContexts | ParsingContexts(PCJSDocComment) + + comment := p.parseJSDocCommentWorker(start, end, fullStart, initialIndent) + // move jsdoc diagnostics to jsdocDiagnostics -- for JS files only + if p.contextFlags&ast.NodeFlagsJavaScriptFile != 0 { + p.jsdocDiagnostics = append(p.jsdocDiagnostics, p.diagnostics[saveDiagnosticsLength:]...) + } + p.diagnostics = p.diagnostics[0:saveDiagnosticsLength] + + p.sourceText = saveSourceText + p.scanner.SetText(p.sourceText) + p.parsingContexts = saveParsingContexts + p.contextFlags = saveContextFlags + p.scanner.Rewind(saveScannerState) + p.token = saveToken + p.hasParseError = saveHasParseError + p.statementHasAwaitIdentifier = saveHasAwaitIdentifier + + return comment +} + +/** + * @param offset - the offset in the containing file + * @param indent - the number of spaces to consider as the margin (applies to non-first lines only) + */ +func (p *Parser) parseJSDocCommentWorker(start int, end int, fullStart int, indent int) *ast.Node { + // Initially we can parse out a tag. We also have seen a starting asterisk. + // This is so that /** * @type */ doesn't parse. + tags := p.nodeSlicePool.NewSlice(1)[:0] + tagsPos := -1 + tagsEnd := -1 + state := jsdocStateSawAsterisk + commentParts := p.nodeSlicePool.NewSlice(1)[:0] + comments := p.jsdocCommentsSpace + commentsPos := -1 + linkEnd := start + margin := -1 + pushComment := func(text string) { + if margin == -1 { + margin = indent + } + comments = append(comments, text) + indent += len(text) + } + + p.nextTokenJSDoc() + for p.parseOptionalJsdoc(ast.KindWhitespaceTrivia) { + } + if p.parseOptionalJsdoc(ast.KindNewLineTrivia) { + state = jsdocStateBeginningOfLine + indent = 0 + } +loop: + for { + switch p.token { + case ast.KindAtToken: + comments = removeTrailingWhitespace(comments) + if commentsPos == -1 { + commentsPos = p.nodePos() + } + tag := p.parseTag(tags, indent) + if tagsPos == -1 { + tagsPos = tag.Pos() + } + tags = append(tags, tag) + tagsEnd = tag.End() + // NOTE: According to usejsdoc.org, a tag goes to end of line, except the last tag. + // Real-world comments may break this rule, so "BeginningOfLine" will not be a real line beginning + // for malformed examples like `/** @param {string} x @returns {number} the length */` + state = jsdocStateBeginningOfLine + margin = -1 + case ast.KindNewLineTrivia: + comments = append(comments, p.scanner.TokenText()) + state = jsdocStateBeginningOfLine + indent = 0 + case ast.KindAsteriskToken: + asterisk := p.scanner.TokenText() + if state == jsdocStateSawAsterisk { + // If we've already seen an asterisk, then we can no longer parse a tag on this line + state = jsdocStateSavingComments + pushComment(asterisk) + } else { + if state != jsdocStateBeginningOfLine { + panic("state must be BeginningOfLine") + } + // Ignore the first asterisk on a line + state = jsdocStateSawAsterisk + indent += len(asterisk) + } + case ast.KindWhitespaceTrivia: + if state == jsdocStateSavingComments { + panic("whitespace shouldn't come from the scanner while saving top-level comment text") + } + // only collect whitespace if we're already saving comments or have just crossed the comment indent margin + whitespace := p.scanner.TokenText() + if margin > -1 && indent+len(whitespace) > margin { + existingIndent := margin - indent + if existingIndent < 0 { + existingIndent += len(whitespace) + } + if existingIndent < 0 { + existingIndent = 0 + } + comments = append(comments, whitespace[existingIndent:]) + } + indent += len(whitespace) + case ast.KindEndOfFile: + break loop + case ast.KindJSDocCommentTextToken: + state = jsdocStateSavingComments + pushComment(p.scanner.TokenValue()) + case ast.KindOpenBraceToken: + state = jsdocStateSavingComments + commentEnd := p.scanner.TokenFullStart() + linkStart := p.scanner.TokenEnd() - 1 + link := p.parseJSDocLink(linkStart) + if link != nil { + if linkEnd == start { + comments = removeLeadingNewlines(comments) + } + jsdocText := p.finishNodeWithEnd(p.factory.NewJSDocText(p.stringSlicePool.Clone(comments)), linkEnd, commentEnd) + commentParts = append(commentParts, jsdocText, link) + comments = comments[:0] + linkEnd = p.scanner.TokenEnd() + break + } + fallthrough + default: + // Anything else is doc comment text. We just save it. Because it + // wasn't a tag, we can no longer parse a tag on this line until we hit the next + // line break. + state = jsdocStateSavingComments + pushComment(p.scanner.TokenText()) + } + if state == jsdocStateSavingComments { + p.nextJSDocCommentTextToken(false) + } else { + p.nextTokenJSDoc() + } + } + + p.jsdocCommentsSpace = comments[:0] // Reuse this slice for further parses + if commentsPos == -1 { + commentsPos = p.scanner.TokenFullStart() + } + + if len(comments) > 0 { + comments[len(comments)-1] = strings.TrimRightFunc(comments[len(comments)-1], unicode.IsSpace) + jsdocText := p.finishNodeWithEnd(p.factory.NewJSDocText(p.stringSlicePool.Clone(comments)), linkEnd, commentsPos) + commentParts = append(commentParts, jsdocText) + } + + if len(commentParts) > 0 && len(tags) > 0 && commentsPos == -1 { + panic("having parsed tags implies that the end of the comment span should be set") + } + + var tagsNodeList *ast.NodeList + if tagsPos != -1 { + tagsNodeList = p.newNodeList(core.NewTextRange(tagsPos, tagsEnd), tags) + } + + jsdocComment := p.factory.NewJSDoc( + p.newNodeList(core.NewTextRange(start, commentsPos), commentParts), + tagsNodeList, + ) + return p.finishNodeWithEnd(jsdocComment, fullStart, end) +} + +func removeLeadingNewlines(comments []string) []string { + i := 0 + for i < len(comments) && (comments[i] == "\n" || comments[i] == "\r") { + i++ + } + return comments[i:] +} + +func trimEnd(s string) string { + return strings.TrimRightFunc(s, stringutil.IsWhiteSpaceLike) +} + +func removeTrailingWhitespace(comments []string) []string { + end := len(comments) + for i := len(comments) - 1; i >= 0; i-- { + trimmed := trimEnd(comments[i]) + if trimmed == "" { + end = i + } else { + comments[i] = trimmed + break + } + } + return comments[:end] +} + +func (p *Parser) isNextNonwhitespaceTokenEndOfFile() bool { + // We must use infinite lookahead, as there could be any number of newlines :( + for { + p.nextTokenJSDoc() + if p.token == ast.KindEndOfFile { + return true + } + if !(p.token == ast.KindWhitespaceTrivia || p.token == ast.KindNewLineTrivia) { + return false + } + } +} + +func (p *Parser) skipWhitespace() { + if p.token == ast.KindWhitespaceTrivia || p.token == ast.KindNewLineTrivia { + if p.lookAhead((*Parser).isNextNonwhitespaceTokenEndOfFile) { + return + // Don't skip whitespace prior to EoF (or end of comment) - that shouldn't be included in any node's range + } + } + for p.token == ast.KindWhitespaceTrivia || p.token == ast.KindNewLineTrivia { + p.nextTokenJSDoc() + } +} + +func (p *Parser) skipWhitespaceOrAsterisk() string { + if p.token == ast.KindWhitespaceTrivia || p.token == ast.KindNewLineTrivia { + if p.lookAhead((*Parser).isNextNonwhitespaceTokenEndOfFile) { + return "" + // Don't skip whitespace prior to EoF (or end of comment) - that shouldn't be included in any node's range + } + } + + precedingLineBreak := p.scanner.HasPrecedingLineBreak() + seenLineBreak := false + indents := make([]string, 0, 4) + for (precedingLineBreak && p.token == ast.KindAsteriskToken) || p.token == ast.KindWhitespaceTrivia || p.token == ast.KindNewLineTrivia { + indents = append(indents, p.scanner.TokenText()) + if p.token == ast.KindNewLineTrivia { + precedingLineBreak = true + seenLineBreak = true + indents = indents[:0] + } else if p.token == ast.KindAsteriskToken { + precedingLineBreak = false + } + p.nextTokenJSDoc() + } + if seenLineBreak { + return strings.Join(indents, "") + } else { + return "" + } +} + +func (p *Parser) parseTag(tags []*ast.Node, margin int) *ast.Node { + if p.token != ast.KindAtToken { + panic("should be called only at the start of a tag") + } + start := p.scanner.TokenStart() + p.nextTokenJSDoc() + + tagName := p.parseJSDocIdentifierName(nil) + indentText := p.skipWhitespaceOrAsterisk() + + var tag *ast.Node + switch tagName.Text() { + case "implements": + tag = p.parseImplementsTag(start, tagName, margin, indentText) + case "augments", "extends": + tag = p.parseAugmentsTag(start, tagName, margin, indentText) + case "public": + tag = p.parseSimpleTag(start, func(tagName *ast.IdentifierNode, comments *ast.NodeList) *ast.Node { + return p.factory.NewJSDocPublicTag(tagName, comments) + }, tagName, margin, indentText) + case "private": + tag = p.parseSimpleTag(start, func(tagName *ast.IdentifierNode, comments *ast.NodeList) *ast.Node { + return p.factory.NewJSDocPrivateTag(tagName, comments) + }, tagName, margin, indentText) + case "protected": + tag = p.parseSimpleTag(start, func(tagName *ast.IdentifierNode, comments *ast.NodeList) *ast.Node { + return p.factory.NewJSDocProtectedTag(tagName, comments) + }, tagName, margin, indentText) + case "readonly": + tag = p.parseSimpleTag(start, func(tagName *ast.IdentifierNode, comments *ast.NodeList) *ast.Node { + return p.factory.NewJSDocReadonlyTag(tagName, comments) + }, tagName, margin, indentText) + case "override": + tag = p.parseSimpleTag(start, func(tagName *ast.IdentifierNode, comments *ast.NodeList) *ast.Node { + return p.factory.NewJSDocOverrideTag(tagName, comments) + }, tagName, margin, indentText) + case "deprecated": + p.hasDeprecatedTag = true + tag = p.parseSimpleTag(start, func(tagName *ast.IdentifierNode, comments *ast.NodeList) *ast.Node { + return p.factory.NewJSDocDeprecatedTag(tagName, comments) + }, tagName, margin, indentText) + case "this": + tag = p.parseThisTag(start, tagName, margin, indentText) + case "arg", "argument", "param": + tag = p.parseParameterOrPropertyTag(start, tagName, propertyLikeParseParameter, margin) + case "return", "returns": + tag = p.parseReturnTag(tags, start, tagName, margin, indentText) + case "template": + tag = p.parseTemplateTag(start, tagName, margin, indentText) + case "type": + tag = p.parseTypeTag(tags, start, tagName, margin, indentText) + case "typedef": + tag = p.parseTypedefTag(start, tagName, margin, indentText) + case "callback": + tag = p.parseCallbackTag(start, tagName, margin, indentText) + case "overload": + tag = p.parseOverloadTag(start, tagName, margin, indentText) + case "satisfies": + tag = p.parseSatisfiesTag(start, tagName, margin, indentText) + case "see": + tag = p.parseSeeTag(start, tagName, margin, indentText) + case "import": + tag = p.parseImportTag(start, tagName, margin, indentText) + default: + tag = p.parseUnknownTag(start, tagName, margin, indentText) + } + if tag == nil { + panic("tag should not be nil") + } + return tag +} + +func (p *Parser) parseTrailingTagComments(pos int, end int, margin int, indentText string) *ast.NodeList { + // some tags, like typedef and callback, have already parsed their comments earlier + if len(indentText) == 0 { + margin += end - pos + } + var initialMargin string + if margin < len(indentText) { + initialMargin = indentText[margin:] + } + return p.parseTagComments(margin, &initialMargin) +} + +func (p *Parser) parseTagComments(indent int, initialMargin *string) *ast.NodeList { + commentsPos := p.nodePos() + comments := p.jsdocTagCommentsSpace + p.jsdocTagCommentsSpace = nil // !!! can parseTagComments call itself? + parts := p.jsdocTagCommentsPartsSpace + p.jsdocTagCommentsPartsSpace = nil + linkEnd := -1 + state := jsdocStateBeginningOfLine + if indent < 0 { + panic("indent must be a natural number") + } + margin := -1 + pushComment := func(text string) { + if margin == -1 { + margin = indent + } + comments = append(comments, text) + indent += len(text) + } + + if initialMargin != nil { + // jump straight to saving comments if there is some initial indentation + if *initialMargin != "" { + pushComment(*initialMargin) + } + state = jsdocStateSawAsterisk + } + tok := p.token +loop: + for { + switch tok { + case ast.KindNewLineTrivia: + state = jsdocStateBeginningOfLine + // don't use pushComment here because we want to keep the margin unchanged + comments = append(comments, p.scanner.TokenText()) + indent = 0 + case ast.KindAtToken: + p.scanner.ResetPos(p.scanner.TokenEnd() - 1) + break loop + case ast.KindEndOfFile: + // Done + break loop + case ast.KindWhitespaceTrivia: + if state == jsdocStateSavingComments || state == jsdocStateSavingBackticks { + panic("whitespace shouldn't come from the scanner while saving comment text") + } + whitespace := p.scanner.TokenText() + // if the whitespace crosses the margin, take only the whitespace that passes the margin + if margin > -1 && indent+len(whitespace) > margin { + comments = append(comments, whitespace[max(margin-indent, 0):]) + state = jsdocStateSavingComments + } + indent += len(whitespace) + case ast.KindOpenBraceToken: + state = jsdocStateSavingComments + commentEnd := p.scanner.TokenFullStart() + linkStart := p.scanner.TokenEnd() - 1 + link := p.parseJSDocLink(linkStart) + if link != nil { + var commentStart int + if linkEnd > -1 { + commentStart = linkEnd + } else { + commentStart = commentsPos + } + text := p.finishNodeWithEnd(p.factory.NewJSDocText(p.stringSlicePool.Clone(comments)), commentStart, commentEnd) + parts = append(parts, text) + parts = append(parts, link) + comments = comments[:0] + linkEnd = p.scanner.TokenEnd() + } else { + pushComment(p.scanner.TokenText()) + } + case ast.KindBacktickToken: + if state == jsdocStateSavingBackticks { + state = jsdocStateSavingComments + } else { + state = jsdocStateSavingBackticks + } + pushComment(p.scanner.TokenText()) + case ast.KindJSDocCommentTextToken: + if state != jsdocStateSavingBackticks { + state = jsdocStateSavingComments + // leading identifiers start recording as well + } + pushComment(p.scanner.TokenValue()) + case ast.KindAsteriskToken: + if state == jsdocStateBeginningOfLine { + // leading asterisks start recording on the *next* (non-whitespace) token + state = jsdocStateSawAsterisk + indent += 1 + break + } + // record the * as a comment + fallthrough + default: + if state != jsdocStateSavingBackticks { + state = jsdocStateSavingComments + // leading identifiers start recording as well + } + pushComment(p.scanner.TokenText()) + } + if state == jsdocStateSavingComments || state == jsdocStateSavingBackticks { + tok = p.nextJSDocCommentTextToken(state == jsdocStateSavingBackticks) + } else { + tok = p.nextTokenJSDoc() + } + } + + p.jsdocTagCommentsSpace = comments[:0] + + comments = removeLeadingNewlines(comments) + if len(comments) > 0 { + var commentStart int + if linkEnd > -1 { + commentStart = linkEnd + } else { + commentStart = commentsPos + } + text := p.finishNode(p.factory.NewJSDocText(p.stringSlicePool.Clone(comments)), commentStart) + parts = append(parts, text) + } + + p.jsdocTagCommentsPartsSpace = parts[:0] + + if len(parts) > 0 { + return p.newNodeList(core.NewTextRange(commentsPos, p.scanner.TokenEnd()), p.nodeSlicePool.Clone(parts)) + } + return nil +} + +func (p *Parser) parseJSDocLink(start int) *ast.Node { + state := p.mark() + linkType, ok := p.parseJSDocLinkPrefix() + if !ok { + p.rewind(state) + return nil + } + p.nextTokenJSDoc() + // start at token after link, then skip any whitespace + p.skipWhitespace() + name := p.parseJSDocLinkName() + var text []string + for p.token != ast.KindCloseBraceToken && p.token != ast.KindNewLineTrivia && p.token != ast.KindEndOfFile { + text = append(text, p.scanner.TokenText()) + p.nextTokenJSDoc() // Couldn't this be nextTokenCommentJSDoc? + } + var create *ast.Node + switch linkType { + case "link": + create = p.factory.NewJSDocLink(name, text) + case "linkcode": + create = p.factory.NewJSDocLinkCode(name, text) + default: + create = p.factory.NewJSDocLinkPlain(name, text) + } + return p.finishNodeWithEnd(create, start, p.scanner.TokenEnd()) +} + +func (p *Parser) parseJSDocLinkName() *ast.Node { + if tokenIsIdentifierOrKeyword(p.token) { + pos := p.nodePos() + + name := p.parseIdentifierName() + for p.parseOptional(ast.KindDotToken) { + var right *ast.IdentifierNode + if p.token == ast.KindPrivateIdentifier { + right = p.createMissingIdentifier() + } else { + right = p.parseIdentifierName() + } + name = p.finishNode(p.factory.NewQualifiedName(name, right), pos) + } + + for p.token == ast.KindPrivateIdentifier { + p.scanner.ReScanHashToken() + p.nextTokenJSDoc() + name = p.finishNode(p.factory.NewQualifiedName(name, p.parseIdentifier()), pos) + } + return name + } + return nil +} + +func (p *Parser) parseJSDocLinkPrefix() (string, bool) { + p.skipWhitespaceOrAsterisk() + if p.token == ast.KindOpenBraceToken && p.nextTokenJSDoc() == ast.KindAtToken && tokenIsIdentifierOrKeyword(p.nextTokenJSDoc()) { + kind := p.scanner.TokenValue() + if isJSDocLinkTag(kind) { + return kind, true + } + } + return "NONE", false +} + +func isJSDocLinkTag(kind string) bool { + return kind == "link" || kind == "linkcode" || kind == "linkplain" +} + +func (p *Parser) parseUnknownTag(start int, tagName *ast.IdentifierNode, indent int, indentText string) *ast.Node { + return p.finishNode(p.factory.NewJSDocUnknownTag(tagName, p.parseTrailingTagComments(start, p.nodePos(), indent, indentText)), start) +} + +func (p *Parser) tryParseTypeExpression() *ast.Node { + p.skipWhitespaceOrAsterisk() + if p.token == ast.KindOpenBraceToken { + return p.parseJSDocTypeExpression(false /*mayOmitBraces*/) + } else { + return nil + } +} + +func (p *Parser) parseBracketNameInPropertyAndParamTag() (name *ast.EntityName, isBracketed bool) { + // Looking for something like '[foo]', 'foo', '[foo.bar]' or 'foo.bar' + isBracketed = p.parseOptionalJsdoc(ast.KindOpenBracketToken) + if isBracketed { + p.skipWhitespace() + } + // a markdown-quoted name: `arg` is not legal jsdoc, but occurs in the wild + isBackquoted := p.parseOptionalJsdoc(ast.KindBacktickToken) + name = p.parseJSDocEntityName() + if isBackquoted { + p.parseExpectedTokenJSDoc(ast.KindBacktickToken) + } + if isBracketed { + p.skipWhitespace() + // May have an optional default, e.g. '[foo = 42]' + if p.parseOptionalToken(ast.KindEqualsToken) != nil { + p.parseExpression() + } + + p.parseExpected(ast.KindCloseBracketToken) + } + + return name, isBracketed +} + +func isObjectOrObjectArrayTypeReference(node *ast.TypeNode) bool { + switch node.Kind { + case ast.KindObjectKeyword: + return true + case ast.KindArrayType: + return isObjectOrObjectArrayTypeReference(node.AsArrayTypeNode().ElementType) + default: + if ast.IsTypeReferenceNode(node) { + ref := node.AsTypeReferenceNode() + return ast.IsIdentifier(ref.TypeName) && ref.TypeName.AsIdentifier().Text == "Object" && ref.TypeArguments == nil + } + return false + } +} + +func (p *Parser) parseParameterOrPropertyTag(start int, tagName *ast.IdentifierNode, target propertyLikeParse, indent int) *ast.Node { + typeExpression := p.tryParseTypeExpression() + isNameFirst := typeExpression == nil + p.skipWhitespaceOrAsterisk() + + name, isBracketed := p.parseBracketNameInPropertyAndParamTag() + indentText := p.skipWhitespaceOrAsterisk() + + if isNameFirst && p.lookAhead(func(p *Parser) bool { _, ok := p.parseJSDocLinkPrefix(); return !ok }) { + typeExpression = p.tryParseTypeExpression() + } + + comment := p.parseTrailingTagComments(start, p.nodePos(), indent, indentText) + + nestedTypeLiteral := p.parseNestedTypeLiteral(typeExpression, name, target, indent) + if nestedTypeLiteral != nil { + typeExpression = nestedTypeLiteral + isNameFirst = true + } + var result *ast.Node /* JSDocPropertyTag | JSDocParameterTag */ + if target == propertyLikeParseProperty { + result = p.factory.NewJSDocPropertyTag(tagName, name, isBracketed, typeExpression, isNameFirst, comment) + } else { + result = p.factory.NewJSDocParameterTag(tagName, name, isBracketed, typeExpression, isNameFirst, comment) + } + return p.finishNode(result, start) +} + +func (p *Parser) parseNestedTypeLiteral(typeExpression *ast.Node, name *ast.EntityName, target propertyLikeParse, indent int) *ast.Node { + if typeExpression != nil && isObjectOrObjectArrayTypeReference(typeExpression.Type()) { + pos := p.nodePos() + var children []*ast.Node + for { + state := p.mark() + child := p.parseChildParameterOrPropertyTag(target, indent, name) + if child == nil { + p.rewind(state) + break + } + if child.Kind == ast.KindJSDocParameterTag || child.Kind == ast.KindJSDocPropertyTag { + children = append(children, child) + } else if child.Kind == ast.KindJSDocTemplateTag { + p.parseErrorAtRange(child.AsJSDocTemplateTag().TagName.Loc, diagnostics.A_JSDoc_template_tag_may_not_follow_a_typedef_callback_or_overload_tag) + } + } + if children != nil { + literal := p.finishNode(p.factory.NewJSDocTypeLiteral(children, typeExpression.Type().Kind == ast.KindArrayType), pos) + return p.finishNode(p.factory.NewJSDocTypeExpression(literal), pos) + } + } + return nil +} + +func (p *Parser) parseReturnTag(previousTags []*ast.Node, start int, tagName *ast.IdentifierNode, indent int, indentText string) *ast.Node { + if core.Some(previousTags, ast.IsJSDocReturnTag) { + p.parseErrorAt(tagName.Pos(), p.scanner.TokenStart(), diagnostics.X_0_tag_already_specified, tagName.Text()) + } + + typeExpression := p.tryParseTypeExpression() + return p.finishNode(p.factory.NewJSDocReturnTag(tagName, typeExpression, p.parseTrailingTagComments(start, p.nodePos(), indent, indentText)), start) +} + +// pass indent=-1 to skip parsing trailing comments (as when a type tag is nested in a typedef) +func (p *Parser) parseTypeTag(previousTags []*ast.Node, start int, tagName *ast.IdentifierNode, indent int, indentText string) *ast.Node { + if core.Some(previousTags, ast.IsJSDocTypeTag) { + p.parseErrorAt(tagName.Pos(), p.scanner.TokenStart(), diagnostics.X_0_tag_already_specified, tagName.Text()) + } + + typeExpression := p.parseJSDocTypeExpression(true) + var comments *ast.NodeList + if indent != -1 { + comments = p.parseTrailingTagComments(start, p.nodePos(), indent, indentText) + } + return p.finishNode(p.factory.NewJSDocTypeTag(tagName, typeExpression, comments), start) +} + +func (p *Parser) parseSeeTag(start int, tagName *ast.IdentifierNode, indent int, indentText string) *ast.Node { + isMarkdownOrJSDocLink := p.token == ast.KindOpenBracketToken || p.lookAhead(func(p *Parser) bool { + return p.nextTokenJSDoc() == ast.KindAtToken && tokenIsIdentifierOrKeyword(p.nextTokenJSDoc()) && isJSDocLinkTag(p.scanner.TokenValue()) + }) + var nameExpression *ast.Node + if !isMarkdownOrJSDocLink { + nameExpression = p.parseJSDocNameReference() + } + comments := p.parseTrailingTagComments(start, p.nodePos(), indent, indentText) + return p.finishNode(p.factory.NewJSDocSeeTag(tagName, nameExpression, comments), start) +} + +func (p *Parser) parseImplementsTag(start int, tagName *ast.IdentifierNode, margin int, indentText string) *ast.Node { + className := p.parseExpressionWithTypeArgumentsForAugments() + return p.finishNode(p.factory.NewJSDocImplementsTag(tagName, className, p.parseTrailingTagComments(start, p.nodePos(), margin, indentText)), start) +} + +func (p *Parser) parseAugmentsTag(start int, tagName *ast.IdentifierNode, margin int, indentText string) *ast.Node { + className := p.parseExpressionWithTypeArgumentsForAugments() + return p.finishNode(p.factory.NewJSDocAugmentsTag(tagName, className, p.parseTrailingTagComments(start, p.nodePos(), margin, indentText)), start) +} + +func (p *Parser) parseSatisfiesTag(start int, tagName *ast.IdentifierNode, margin int, indentText string) *ast.Node { + typeExpression := p.parseJSDocTypeExpression(false) + comments := p.parseTrailingTagComments(start, p.nodePos(), margin, indentText) + return p.finishNode(p.factory.NewJSDocSatisfiesTag(tagName, typeExpression, comments), start) +} + +func (p *Parser) parseImportTag(start int, tagName *ast.IdentifierNode, margin int, indentText string) *ast.Node { + afterImportTagPos := p.scanner.TokenFullStart() + + var identifier *ast.IdentifierNode + if p.isIdentifier() { + identifier = p.parseIdentifier() + } + + importClause := p.tryParseImportClause(identifier, afterImportTagPos, ast.KindTypeKeyword, true /*skipJSDocLeadingAsterisks*/) + moduleSpecifier := p.parseModuleSpecifier() + attributes := p.tryParseImportAttributes() + + comments := p.parseTrailingTagComments(start, p.nodePos(), margin, indentText) + return p.finishNode(p.factory.NewJSDocImportTag(tagName, importClause, moduleSpecifier, attributes, comments), start) +} + +func (p *Parser) parseExpressionWithTypeArgumentsForAugments() *ast.Node { + usedBrace := p.parseOptional(ast.KindOpenBraceToken) + pos := p.nodePos() + expression := p.parsePropertyAccessEntityNameExpression() + p.scanner.SetSkipJSDocLeadingAsterisks(true) + typeArguments := p.parseTypeArguments() + p.scanner.SetSkipJSDocLeadingAsterisks(false) + node := p.finishNode(p.factory.NewExpressionWithTypeArguments(expression, typeArguments), pos) + if usedBrace { + p.skipWhitespace() + p.parseExpected(ast.KindCloseBraceToken) + } + return node +} + +func (p *Parser) parsePropertyAccessEntityNameExpression() *ast.Node { + pos := p.nodePos() + node := p.parseJSDocIdentifierName(nil) + for p.parseOptional(ast.KindDotToken) { + name := p.parseJSDocIdentifierName(nil) + node = p.finishNode(p.factory.NewPropertyAccessExpression(node, nil, name, ast.NodeFlagsNone), pos) + } + return node +} + +func (p *Parser) parseSimpleTag(start int, createTag func(tagName *ast.IdentifierNode, comment *ast.NodeList) *ast.Node, tagName *ast.IdentifierNode, margin int, indentText string) *ast.Node { + return p.finishNode(createTag(tagName, p.parseTrailingTagComments(start, p.nodePos(), margin, indentText)), start) +} + +func (p *Parser) parseThisTag(start int, tagName *ast.IdentifierNode, margin int, indentText string) *ast.Node { + typeExpression := p.parseJSDocTypeExpression(true) + p.skipWhitespace() + result := p.factory.NewJSDocThisTag(tagName, typeExpression, p.parseTrailingTagComments(start, p.nodePos(), margin, indentText)) + return p.finishNode(result, start) +} + +func (p *Parser) parseTypedefTag(start int, tagName *ast.IdentifierNode, indent int, indentText string) *ast.Node { + typeExpression := p.tryParseTypeExpression() + p.skipWhitespaceOrAsterisk() + fullName := p.parseJSDocIdentifierName(nil) + p.skipWhitespace() + comment := p.parseTagComments(indent, nil) + + end := -1 + hasChildren := false + if typeExpression == nil || isObjectOrObjectArrayTypeReference(typeExpression.Type()) { + var child *ast.Node + var childTypeTag *ast.JSDocTypeTag + var jsdocPropertyTags []*ast.Node + for { + state := p.mark() + child = p.parseChildPropertyTag(indent) + if child == nil { + p.rewind(state) + break + } + if child.Kind == ast.KindJSDocTemplateTag { + break + } + hasChildren = true + if child.Kind == ast.KindJSDocTypeTag { + if childTypeTag == nil { + childTypeTag = child.AsJSDocTypeTag() + } else { + lastError := p.parseErrorAtCurrentToken(diagnostics.A_JSDoc_typedef_comment_may_not_contain_multiple_type_tags) + if lastError != nil { + related := ast.NewDiagnostic(nil, core.NewTextRange(0, 0), diagnostics.The_tag_was_first_specified_here) + lastError.AddRelatedInfo(related) + } + break + } + } else { + jsdocPropertyTags = append(jsdocPropertyTags, child) + } + } + if hasChildren { + isArrayType := typeExpression != nil && typeExpression.Type().Kind == ast.KindArrayType + jsdocTypeLiteral := p.factory.NewJSDocTypeLiteral(jsdocPropertyTags, isArrayType) + if childTypeTag != nil && childTypeTag.TypeExpression != nil && !isObjectOrObjectArrayTypeReference(childTypeTag.TypeExpression.Type()) { + typeExpression = childTypeTag.TypeExpression + } else { + typeExpression = p.finishNode(jsdocTypeLiteral, jsdocPropertyTags[0].Pos()) + } + } + } + + // Only include the characters between the name end and the next token if a comment was actually parsed out - otherwise it's just whitespace + if end == -1 { + if hasChildren && typeExpression != nil { + end = typeExpression.End() + } else if comment != nil { + end = p.nodePos() + } else if fullName != nil { + end = fullName.End() + } else if typeExpression != nil { + end = typeExpression.End() + } else { + end = tagName.End() + } + } + + if comment == nil { + comment = p.parseTrailingTagComments(start, end, indent, indentText) + } + + typedefTag := p.finishNodeWithEnd(p.factory.NewJSDocTypedefTag(tagName, typeExpression, fullName, comment), start, end) + if typeExpression != nil { + typeExpression.Parent = typedefTag // forcibly overwrite parent potentially set by inner type expression parse + } + return typedefTag +} + +func (p *Parser) parseCallbackTagParameters(indent int) *ast.NodeList { + var child *ast.Node + var parameters []*ast.Node + pos := p.nodePos() + for { + state := p.mark() + child = p.parseChildParameterOrPropertyTag(propertyLikeParseCallbackParameter, indent, nil) + if child == nil { + p.rewind(state) + break + } + if child.Kind == ast.KindJSDocTemplateTag { + p.parseErrorAtRange(child.AsJSDocTemplateTag().TagName.Loc, diagnostics.A_JSDoc_template_tag_may_not_follow_a_typedef_callback_or_overload_tag) + break + } + parameters = append(parameters, child) + } + return p.newNodeList(core.NewTextRange(pos, p.nodePos()), parameters) +} + +func (p *Parser) parseJSDocSignature(start int, indent int) *ast.Node { + parameters := p.parseCallbackTagParameters(indent) + var returnTag *ast.JSDocTag + state := p.mark() + if p.parseOptionalJsdoc(ast.KindAtToken) { + tag := p.parseTag(nil, indent) + if tag.Kind == ast.KindJSDocReturnTag { + returnTag = tag + } + } + if returnTag == nil { + p.rewind(state) + } + return p.finishNode(p.factory.NewJSDocSignature(nil, parameters, returnTag), start) +} + +func (p *Parser) parseCallbackTag(start int, tagName *ast.IdentifierNode, indent int, indentText string) *ast.Node { + fullName := p.parseJSDocIdentifierName(nil) + p.skipWhitespace() + comment := p.parseTagComments(indent, nil) + typeExpression := p.parseJSDocSignature(p.nodePos(), indent) + if comment == nil { + comment = p.parseTrailingTagComments(start, p.nodePos(), indent, indentText) + } + var end int + if comment != nil { + end = p.nodePos() + } else { + end = typeExpression.End() + } + return p.finishNodeWithEnd(p.factory.NewJSDocCallbackTag(tagName, typeExpression, fullName, comment), start, end) +} + +func (p *Parser) parseOverloadTag(start int, tagName *ast.IdentifierNode, indent int, indentText string) *ast.Node { + p.skipWhitespace() + comment := p.parseTagComments(indent, nil) + typeExpression := p.parseJSDocSignature(start, indent) + if comment == nil { + comment = p.parseTrailingTagComments(start, p.nodePos(), indent, indentText) + } + var end int + if comment != nil { + end = p.nodePos() + } else { + end = typeExpression.End() + } + return p.finishNodeWithEnd(p.factory.NewJSDocOverloadTag(tagName, typeExpression, comment), start, end) +} + +func textsEqual(a *ast.EntityName, b *ast.EntityName) bool { + for !ast.IsIdentifier(a) || !ast.IsIdentifier(b) { + if !ast.IsIdentifier(a) && !ast.IsIdentifier(b) && a.AsQualifiedName().Right.Text() == b.AsQualifiedName().Right.Text() { + a = a.AsQualifiedName().Left + b = b.AsQualifiedName().Left + } else { + return false + } + } + return a.AsIdentifier().Text == b.AsIdentifier().Text +} + +func (p *Parser) parseChildPropertyTag(indent int) *ast.Node { + return p.parseChildParameterOrPropertyTag(propertyLikeParseProperty, indent, nil) +} + +func (p *Parser) parseChildParameterOrPropertyTag(target propertyLikeParse, indent int, name *ast.EntityName) *ast.Node { + canParseTag := true + seenAsterisk := false + for { + switch p.nextTokenJSDoc() { + case ast.KindAtToken: + if canParseTag { + child := p.tryParseChildTag(target, indent) + if child != nil && name != nil && + (child.Kind == ast.KindJSDocParameterTag || child.Kind == ast.KindJSDocPropertyTag) && + (ast.IsIdentifier(child.Name()) || !textsEqual(name, child.Name().AsQualifiedName().Left)) { + return nil + } + return child + } + seenAsterisk = false + case ast.KindNewLineTrivia: + canParseTag = true + seenAsterisk = false + case ast.KindAsteriskToken: + if seenAsterisk { + canParseTag = false + } + seenAsterisk = true + case ast.KindIdentifier: + canParseTag = false + case ast.KindEndOfFile: + return nil + } + } +} + +func (p *Parser) tryParseChildTag(target propertyLikeParse, indent int) *ast.Node { + if p.token != ast.KindAtToken { + panic("should only be called when at @") + } + start := p.scanner.TokenFullStart() + p.nextTokenJSDoc() + + tagName := p.parseJSDocIdentifierName(nil) + indentText := p.skipWhitespaceOrAsterisk() + var t propertyLikeParse + switch tagName.Text() { + case "type": + if target == propertyLikeParseProperty { + return p.parseTypeTag(nil, start, tagName, -1, "") + } + case "prop", "property": + t = propertyLikeParseProperty + case "arg", "argument", "param": + t = propertyLikeParseParameter | propertyLikeParseCallbackParameter + case "template": + return p.parseTemplateTag(start, tagName, indent, indentText) + case "this": + return p.parseThisTag(start, tagName, indent, indentText) + default: + return nil + } + if (target & t) == 0 { + return nil + } + return p.parseParameterOrPropertyTag(start, tagName, target, indent) +} + +func (p *Parser) parseTemplateTagTypeParameter() *ast.Node { + typeParameterPos := p.nodePos() + isBracketed := p.parseOptionalJsdoc(ast.KindOpenBracketToken) + if isBracketed { + p.skipWhitespace() + } + + modifiers := p.parseModifiersEx(false, true /*permitConstAsModifier*/, false) + name := p.parseJSDocIdentifierName(diagnostics.Unexpected_token_A_type_parameter_name_was_expected_without_curly_braces) + var defaultType *ast.Node + if isBracketed { + p.skipWhitespace() + p.parseExpected(ast.KindEqualsToken) + saveContextFlags := p.contextFlags + p.setContextFlags(ast.NodeFlagsJSDoc, true) + defaultType = p.parseJSDocType() + p.contextFlags = saveContextFlags + p.parseExpected(ast.KindCloseBracketToken) + } + + if ast.NodeIsMissing(name) { + return nil + } + return p.finishNode(p.factory.NewTypeParameterDeclaration(modifiers, name, nil /*constraint*/, defaultType), typeParameterPos) +} + +func (p *Parser) parseTemplateTagTypeParameters() *ast.TypeParameterList { + typeParameters := ast.TypeParameterList{} + for ok := true; ok; ok = p.parseOptionalJsdoc(ast.KindCommaToken) { // do-while loop + p.skipWhitespace() + node := p.parseTemplateTagTypeParameter() + if node != nil { + typeParameters.Nodes = append(typeParameters.Nodes, node) + } + p.skipWhitespaceOrAsterisk() + } + return &typeParameters +} + +func (p *Parser) parseTemplateTag(start int, tagName *ast.IdentifierNode, indent int, indentText string) *ast.Node { + // The template tag looks like one of the following: + // @template T,U,V + // @template {Constraint} T + // + // According to the [closure docs](https://github.com/google/closure-compiler/wiki/Generic-Types#multiple-bounded-template-types): + // > Multiple bounded generics cannot be declared on the same line. For the sake of clarity, if multiple templates share the same + // > type bound they must be declared on separate lines. + // + // TODO: Determine whether we should enforce this in the checker. + // TODO: Consider moving the `constraint` to the first type parameter as we could then remove `getEffectiveConstraintOfTypeParameter`. + // TODO: Consider only parsing a single type parameter if there is a constraint. + var constraint *ast.Node + if p.token == ast.KindOpenBraceToken { + constraint = p.parseJSDocTypeExpression(false) + } + typeParameters := p.parseTemplateTagTypeParameters() + result := p.factory.NewJSDocTemplateTag(tagName, constraint, typeParameters, p.parseTrailingTagComments(start, p.nodePos(), indent, indentText)) + return p.finishNode(result, start) +} + +func (p *Parser) parseOptionalJsdoc(t ast.Kind) bool { + if p.token == t { + p.nextTokenJSDoc() + return true + } + return false +} + +func (p *Parser) parseJSDocEntityName() *ast.EntityName { + var entity *ast.EntityName = p.parseJSDocIdentifierName(nil) + if p.parseOptional(ast.KindOpenBracketToken) { + p.parseExpected(ast.KindCloseBracketToken) + // Note that y[] is accepted as an entity name, but the postfix brackets are not saved for checking. + // Technically usejsdoc.org requires them for specifying a property of a type equivalent to Array<{ x: ...}> + // but it's not worth it to enforce that restriction. + } + for p.parseOptional(ast.KindDotToken) { + name := p.parseJSDocIdentifierName(nil) + if p.parseOptional(ast.KindOpenBracketToken) { + p.parseExpected(ast.KindCloseBracketToken) + } + pos := entity.Pos() + entity = p.finishNode(p.factory.NewQualifiedName(entity, name), pos) + } + return entity +} + +func (p *Parser) parseJSDocIdentifierName(diagnosticMessage *diagnostics.Message) *ast.IdentifierNode { + if !tokenIsIdentifierOrKeyword(p.token) { + if diagnosticMessage != nil { + p.parseErrorAtCurrentToken(diagnosticMessage) + } else if isReservedWord(p.token) { + p.parseErrorAtCurrentToken(diagnostics.Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here, p.scanner.TokenText()) + } else { + p.parseErrorAtCurrentToken(diagnostics.Identifier_expected) + } + return p.finishNode(p.newIdentifier(""), p.nodePos()) + } + pos := p.scanner.TokenStart() + end := p.scanner.TokenEnd() + text := p.scanner.TokenValue() + p.internIdentifier(text) + p.nextTokenJSDoc() + return p.finishNodeWithEnd(p.newIdentifier(text), pos, end) +} diff --git a/kitcom/internal/tsgo/parser/parser.go b/kitcom/internal/tsgo/parser/parser.go new file mode 100644 index 0000000..3952ef1 --- /dev/null +++ b/kitcom/internal/tsgo/parser/parser.go @@ -0,0 +1,6587 @@ +package parser + +import ( + "strings" + "sync" + + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/ast" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/collections" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/core" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/debug" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/diagnostics" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/scanner" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/tspath" +) + +type ParsingContext int + +const ( + PCSourceElements ParsingContext = iota // Elements in source file + PCBlockStatements // Statements in block + PCSwitchClauses // Clauses in switch statement + PCSwitchClauseStatements // Statements in switch clause + PCTypeMembers // Members in interface or type literal + PCClassMembers // Members in class declaration + PCEnumMembers // Members in enum declaration + PCHeritageClauseElement // Elements in a heritage clause + PCVariableDeclarations // Variable declarations in variable statement + PCObjectBindingElements // Binding elements in object binding list + PCArrayBindingElements // Binding elements in array binding list + PCArgumentExpressions // Expressions in argument list + PCObjectLiteralMembers // Members in object literal + PCJsxAttributes // Attributes in jsx element + PCJsxChildren // Things between opening and closing JSX tags + PCArrayLiteralMembers // Members in array literal + PCParameters // Parameters in parameter list + PCJSDocParameters // JSDoc parameters in parameter list of JSDoc function type + PCRestProperties // Property names in a rest type list + PCTypeParameters // Type parameters in type parameter list + PCTypeArguments // Type arguments in type argument list + PCTupleElementTypes // Element types in tuple element type list + PCHeritageClauses // Heritage clauses for a class or interface declaration. + PCImportOrExportSpecifiers // Named import clause's import specifier list + PCImportAttributes // Import attributes + PCJSDocComment // Parsing via JSDocParser + PCCount // Number of parsing contexts +) + +type ParsingContexts int + +type Parser struct { + scanner *scanner.Scanner + factory ast.NodeFactory + + opts ast.SourceFileParseOptions + sourceText string + + scriptKind core.ScriptKind + languageVariant core.LanguageVariant + diagnostics []*ast.Diagnostic + jsDiagnostics []*ast.Diagnostic + jsdocDiagnostics []*ast.Diagnostic + + token ast.Kind + sourceFlags ast.NodeFlags + contextFlags ast.NodeFlags + parsingContexts ParsingContexts + statementHasAwaitIdentifier bool + hasDeprecatedTag bool + hasParseError bool + + identifiers map[string]string + identifierCount int + notParenthesizedArrow collections.Set[int] + nodeSlicePool core.Pool[*ast.Node] + stringSlicePool core.Pool[string] + jsdocCache map[*ast.Node][]*ast.Node + possibleAwaitSpans []int + jsdocCommentsSpace []string + jsdocCommentRangesSpace []ast.CommentRange + jsdocTagCommentsSpace []string + jsdocTagCommentsPartsSpace []*ast.Node + reparseList []*ast.Node + commonJSModuleIndicator *ast.Node + + currentParent *ast.Node + setParentFromContext ast.Visitor +} + +func newParser() *Parser { + res := &Parser{} + res.initializeClosures() + return res +} + +var viableKeywordSuggestions = scanner.GetViableKeywordSuggestions() + +var parserPool = sync.Pool{ + New: func() any { + return newParser() + }, +} + +func getParser() *Parser { + return parserPool.Get().(*Parser) +} + +func putParser(p *Parser) { + *p = Parser{scanner: p.scanner, setParentFromContext: p.setParentFromContext} + parserPool.Put(p) +} + +func ParseSourceFile(opts ast.SourceFileParseOptions, sourceText string, scriptKind core.ScriptKind) *ast.SourceFile { + p := getParser() + defer putParser(p) + p.initializeState(opts, sourceText, scriptKind) + p.nextToken() + if p.scriptKind == core.ScriptKindJSON { + return p.parseJSONText() + } + return p.parseSourceFileWorker() +} + +func (p *Parser) initializeClosures() { + p.setParentFromContext = func(n *ast.Node) bool { + n.Parent = p.currentParent + return false + } +} + +func (p *Parser) parseJSONText() *ast.SourceFile { + pos := p.nodePos() + var statements *ast.NodeList + var eof *ast.TokenNode + + if p.token == ast.KindEndOfFile { + statements = p.newNodeList(core.NewTextRange(pos, p.nodePos()), nil) + eof = p.parseTokenNode() + } else { + var expressions any // []*ast.Expression | *ast.Expression + + for p.token != ast.KindEndOfFile { + var expression *ast.Expression + switch p.token { + case ast.KindOpenBracketToken: + expression = p.parseArrayLiteralExpression() + case ast.KindTrueKeyword, ast.KindFalseKeyword, ast.KindNullKeyword: + expression = p.parseTokenNode() + case ast.KindMinusToken: + if p.lookAhead(func(p *Parser) bool { + return p.nextToken() == ast.KindNumericLiteral && p.nextToken() != ast.KindColonToken + }) { + expression = p.parsePrefixUnaryExpression() + } else { + expression = p.parseObjectLiteralExpression() + } + case ast.KindNumericLiteral, ast.KindStringLiteral: + if p.lookAhead(func(p *Parser) bool { return p.nextToken() != ast.KindColonToken }) { + expression = p.parseLiteralExpression(false /*intern*/) + break + } + fallthrough + default: + expression = p.parseObjectLiteralExpression() + } + + // Error recovery: collect multiple top-level expressions + if expressions != nil { + if es, ok := expressions.([]*ast.Expression); ok { + expressions = append(es, expression) + } else { + expressions = []*ast.Expression{expressions.(*ast.Expression), expression} + } + } else { + expressions = expression + if p.token != ast.KindEndOfFile { + p.parseErrorAtCurrentToken(diagnostics.Unexpected_token) + } + } + } + + var expression *ast.Expression + if es, ok := expressions.([]*ast.Expression); ok { + expression = p.factory.NewArrayLiteralExpression(p.newNodeList(core.NewTextRange(pos, p.nodePos()), es), false) + } else { + expression = expressions.(*ast.Expression) + } + statement := p.finishNode(p.factory.NewExpressionStatement(expression), pos) + statements = p.newNodeList(core.NewTextRange(pos, p.nodePos()), []*ast.Node{statement}) + eof = p.parseExpectedToken(ast.KindEndOfFile) + } + node := p.finishNode(p.factory.NewSourceFile(p.opts, p.sourceText, statements, eof), pos) + result := node.AsSourceFile() + p.finishSourceFile(result, false) + return result +} + +func ParseIsolatedEntityName(text string) *ast.EntityName { + p := getParser() + defer putParser(p) + p.initializeState(ast.SourceFileParseOptions{ + JSDocParsingMode: ast.JSDocParsingModeParseAll, + }, text, core.ScriptKindJS) + p.nextToken() + entityName := p.parseEntityName(true, nil) + return core.IfElse(p.token == ast.KindEndOfFile && len(p.diagnostics) == 0, entityName, nil) +} + +func (p *Parser) initializeState(opts ast.SourceFileParseOptions, sourceText string, scriptKind core.ScriptKind) { + if scriptKind == core.ScriptKindUnknown { + panic("ScriptKind must be specified when parsing source files.") + } + + if p.scanner == nil { + p.scanner = scanner.NewScanner() + } else { + p.scanner.Reset() + } + p.opts = opts + p.sourceText = sourceText + p.scriptKind = scriptKind + p.languageVariant = getLanguageVariant(p.scriptKind) + switch p.scriptKind { + case core.ScriptKindJS, core.ScriptKindJSX: + p.contextFlags = ast.NodeFlagsJavaScriptFile + case core.ScriptKindJSON: + p.contextFlags = ast.NodeFlagsJavaScriptFile | ast.NodeFlagsJsonFile + default: + p.contextFlags = ast.NodeFlagsNone + } + p.scanner.SetText(p.sourceText) + p.scanner.SetOnError(p.scanError) + p.scanner.SetLanguageVariant(p.languageVariant) + p.scanner.SetScriptKind(p.scriptKind) + p.scanner.SetJSDocParsingMode(p.opts.JSDocParsingMode) +} + +func (p *Parser) scanError(message *diagnostics.Message, pos int, length int, args ...any) { + p.parseErrorAtRange(core.NewTextRange(pos, pos+length), message, args...) +} + +func (p *Parser) parseErrorAt(pos int, end int, message *diagnostics.Message, args ...any) *ast.Diagnostic { + return p.parseErrorAtRange(core.NewTextRange(pos, end), message, args...) +} + +func (p *Parser) parseErrorAtCurrentToken(message *diagnostics.Message, args ...any) *ast.Diagnostic { + return p.parseErrorAtRange(p.scanner.TokenRange(), message, args...) +} + +func (p *Parser) parseErrorAtRange(loc core.TextRange, message *diagnostics.Message, args ...any) *ast.Diagnostic { + // Don't report another error if it would just be at the same location as the last error + var result *ast.Diagnostic + if len(p.diagnostics) == 0 || p.diagnostics[len(p.diagnostics)-1].Pos() != loc.Pos() { + result = ast.NewDiagnostic(nil, loc, message, args...) + p.diagnostics = append(p.diagnostics, result) + } + p.hasParseError = true + return result +} + +type ParserState struct { + scannerState scanner.ScannerState + contextFlags ast.NodeFlags + diagnosticsLen int + jsDiagnosticsLen int + statementHasAwaitIdentifier bool + hasParseError bool +} + +func (p *Parser) mark() ParserState { + return ParserState{ + scannerState: p.scanner.Mark(), + contextFlags: p.contextFlags, + diagnosticsLen: len(p.diagnostics), + jsDiagnosticsLen: len(p.jsDiagnostics), + statementHasAwaitIdentifier: p.statementHasAwaitIdentifier, + hasParseError: p.hasParseError, + } +} + +func (p *Parser) rewind(state ParserState) { + p.scanner.Rewind(state.scannerState) + p.token = p.scanner.Token() + p.contextFlags = state.contextFlags + p.diagnostics = p.diagnostics[0:state.diagnosticsLen] + p.jsDiagnostics = p.jsDiagnostics[0:state.jsDiagnosticsLen] + p.statementHasAwaitIdentifier = state.statementHasAwaitIdentifier + p.hasParseError = state.hasParseError +} + +func (p *Parser) lookAhead(callback func(p *Parser) bool) bool { + state := p.mark() + result := callback(p) + p.rewind(state) + return result +} + +func (p *Parser) nextToken() ast.Kind { + // if the keyword had an escape + if ast.IsKeyword(p.token) && (p.scanner.HasUnicodeEscape() || p.scanner.HasExtendedUnicodeEscape()) { + // issue a parse error for the escape + p.parseErrorAtCurrentToken(diagnostics.Keywords_cannot_contain_escape_characters) + } + p.token = p.scanner.Scan() + return p.token +} + +func (p *Parser) nextTokenWithoutCheck() ast.Kind { + p.token = p.scanner.Scan() + return p.token +} + +func (p *Parser) nextTokenJSDoc() ast.Kind { + p.token = p.scanner.ScanJSDocToken() + return p.token +} + +func (p *Parser) nextJSDocCommentTextToken(inBackticks bool) ast.Kind { + p.token = p.scanner.ScanJSDocCommentTextToken(inBackticks) + return p.token +} + +func (p *Parser) nodePos() int { + return p.scanner.TokenFullStart() +} + +func (p *Parser) hasPrecedingLineBreak() bool { + return p.scanner.HasPrecedingLineBreak() +} + +func (p *Parser) hasPrecedingJSDocComment() bool { + return p.scanner.HasPrecedingJSDocComment() +} + +func (p *Parser) parseSourceFileWorker() *ast.SourceFile { + isDeclarationFile := tspath.IsDeclarationFileName(p.opts.FileName) + if isDeclarationFile { + p.contextFlags |= ast.NodeFlagsAmbient + } + pos := p.nodePos() + statements := p.parseListIndex(PCSourceElements, (*Parser).parseToplevelStatement) + end := p.nodePos() + endHasJSDoc := p.hasPrecedingJSDocComment() + eof := p.parseTokenNode() + p.withJSDoc(eof, endHasJSDoc) + if eof.Kind != ast.KindEndOfFile { + panic("Expected end of file token from scanner.") + } + if len(p.reparseList) > 0 { + statements = append(statements, p.reparseList...) + p.reparseList = nil + } + node := p.finishNode(p.factory.NewSourceFile(p.opts, p.sourceText, p.newNodeList(core.NewTextRange(pos, end), statements), eof), pos) + result := node.AsSourceFile() + p.finishSourceFile(result, isDeclarationFile) + if !result.IsDeclarationFile && result.ExternalModuleIndicator != nil && len(p.possibleAwaitSpans) > 0 { + reparse := p.finishNode(p.reparseTopLevelAwait(result), pos) + if node != reparse { + result = reparse.AsSourceFile() + p.finishSourceFile(result, isDeclarationFile) + } + } + collectExternalModuleReferences(result) + if ast.IsInJSFile(node) { + result.SetJSDiagnostics(attachFileToDiagnostics(p.jsDiagnostics, result)) + } + return result +} + +func (p *Parser) finishSourceFile(result *ast.SourceFile, isDeclarationFile bool) { + result.CommentDirectives = p.scanner.CommentDirectives() + result.Pragmas = getCommentPragmas(&p.factory, p.sourceText) + p.processPragmasIntoFields(result) + result.SetDiagnostics(attachFileToDiagnostics(p.diagnostics, result)) + result.SetJSDocDiagnostics(attachFileToDiagnostics(p.jsdocDiagnostics, result)) + result.CommonJSModuleIndicator = p.commonJSModuleIndicator + result.IsDeclarationFile = isDeclarationFile + result.LanguageVariant = p.languageVariant + result.ScriptKind = p.scriptKind + result.Flags |= p.sourceFlags + result.Identifiers = p.identifiers + result.NodeCount = p.factory.NodeCount() + result.TextCount = p.factory.TextCount() + result.IdentifierCount = p.identifierCount + result.SetJSDocCache(p.jsdocCache) + + ast.SetExternalModuleIndicator(result, p.opts.ExternalModuleIndicatorOptions) +} + +func (p *Parser) parseToplevelStatement(i int) *ast.Node { + p.statementHasAwaitIdentifier = false + statement := p.parseStatement() + if p.statementHasAwaitIdentifier && statement.Flags&ast.NodeFlagsAwaitContext == 0 { + if len(p.possibleAwaitSpans) == 0 || p.possibleAwaitSpans[len(p.possibleAwaitSpans)-1] != i { + p.possibleAwaitSpans = append(p.possibleAwaitSpans, i, i+1) + } else { + p.possibleAwaitSpans[len(p.possibleAwaitSpans)-1] = i + 1 + } + } + return statement +} + +func (p *Parser) reparseTopLevelAwait(sourceFile *ast.SourceFile) *ast.Node { + if len(p.possibleAwaitSpans)%2 == 1 { + panic("possibleAwaitSpans malformed: odd number of indices, not paired into spans.") + } + statements := []*ast.Statement{} + savedParseDiagnostics := p.diagnostics + p.diagnostics = []*ast.Diagnostic{} + + afterAwaitStatement := 0 + for i := 0; i < len(p.possibleAwaitSpans); i += 2 { + nextAwaitStatement := p.possibleAwaitSpans[i] + // append all non-await statements between afterAwaitStatement and nextAwaitStatement + prevStatement := sourceFile.Statements.Nodes[afterAwaitStatement] + nextStatement := sourceFile.Statements.Nodes[nextAwaitStatement] + statements = append(statements, sourceFile.Statements.Nodes[afterAwaitStatement:nextAwaitStatement]...) + + // append all diagnostics associated with the copied range + diagnosticStart := core.FindIndex(savedParseDiagnostics, func(diagnostic *ast.Diagnostic) bool { + return diagnostic.Pos() >= prevStatement.Pos() + }) + var diagnosticEnd int + if diagnosticStart >= 0 { + diagnosticEnd = core.FindIndex(savedParseDiagnostics[:diagnosticStart], func(diagnostic *ast.Diagnostic) bool { + return diagnostic.Pos() >= nextStatement.Pos() + }) + } else { + diagnosticEnd = -1 + } + if diagnosticStart >= 0 { + var slice []*ast.Diagnostic + if diagnosticEnd >= 0 { + slice = savedParseDiagnostics[diagnosticStart : diagnosticStart+diagnosticEnd] + } else { + slice = savedParseDiagnostics[diagnosticStart:] + } + p.diagnostics = append(p.diagnostics, slice...) + } + + state := p.mark() + // reparse all statements between start and pos. We skip existing diagnostics for the same range and allow the parser to generate new ones. + p.contextFlags |= ast.NodeFlagsAwaitContext + p.scanner.ResetPos(nextStatement.Pos()) + p.nextToken() + + afterAwaitStatement = p.possibleAwaitSpans[i+1] + for p.token != ast.KindEndOfFile { + startPos := p.scanner.TokenFullStart() + statement := p.parseStatement() + statements = append(statements, statement) + if startPos == p.scanner.TokenFullStart() { + p.nextToken() + } + if afterAwaitStatement < len(sourceFile.Statements.Nodes) { + nonAwaitStatement := sourceFile.Statements.Nodes[afterAwaitStatement] + if statement.End() == nonAwaitStatement.Pos() { + // done reparsing this section + break + } + if statement.End() > nonAwaitStatement.Pos() { + // we ate into the next statement, so we must continue reparsing the next span + i += 2 + if i < len(p.possibleAwaitSpans) { + afterAwaitStatement = p.possibleAwaitSpans[i+1] + } else { + afterAwaitStatement = len(sourceFile.Statements.Nodes) + } + } + } + } + + // Keep diagnostics from the reparse + state.diagnosticsLen = len(p.diagnostics) + p.rewind(state) + } + + // append all statements between pos and the end of the list + if afterAwaitStatement < len(sourceFile.Statements.Nodes) { + prevStatement := sourceFile.Statements.Nodes[afterAwaitStatement] + statements = append(statements, sourceFile.Statements.Nodes[afterAwaitStatement:]...) + + // append all diagnostics associated with the copied range + diagnosticStart := core.FindIndex(savedParseDiagnostics, func(diagnostic *ast.Diagnostic) bool { + return diagnostic.Pos() >= prevStatement.Pos() + }) + if diagnosticStart >= 0 { + p.diagnostics = append(p.diagnostics, savedParseDiagnostics[diagnosticStart:]...) + } + } + + result := p.factory.NewSourceFile(sourceFile.ParseOptions(), p.sourceText, p.newNodeList(sourceFile.Statements.Loc, statements), sourceFile.EndOfFileToken) + for _, s := range statements { + s.Parent = result.AsNode() // force (re)set parent to reparsed source file + } + return result +} + +func (p *Parser) parseListIndex(kind ParsingContext, parseElement func(p *Parser, index int) *ast.Node) []*ast.Node { + saveParsingContexts := p.parsingContexts + p.parsingContexts |= 1 << kind + list := make([]*ast.Node, 0, 16) + for i := 0; !p.isListTerminator(kind); i++ { + if p.isListElement(kind, false /*inErrorRecovery*/) { + elt := parseElement(p, i) + if len(p.reparseList) > 0 { + list = append(list, p.reparseList...) + p.reparseList = nil + } + list = append(list, elt) + continue + } + if p.abortParsingListOrMoveToNextToken(kind) { + break + } + } + p.parsingContexts = saveParsingContexts + return p.nodeSlicePool.Clone(list) +} + +func (p *Parser) parseList(kind ParsingContext, parseElement func(p *Parser) *ast.Node) *ast.NodeList { + pos := p.nodePos() + nodes := p.parseListIndex(kind, func(p *Parser, _ int) *ast.Node { return parseElement(p) }) + return p.newNodeList(core.NewTextRange(pos, p.nodePos()), nodes) +} + +// Return a non-nil (but possibly empty) slice if parsing was successful, or nil if parseElement returned nil +func (p *Parser) parseDelimitedList(kind ParsingContext, parseElement func(p *Parser) *ast.Node) *ast.NodeList { + pos := p.nodePos() + saveParsingContexts := p.parsingContexts + p.parsingContexts |= 1 << kind + list := make([]*ast.Node, 0, 16) + for { + if p.isListElement(kind, false /*inErrorRecovery*/) { + startPos := p.nodePos() + element := parseElement(p) + if element == nil { + p.parsingContexts = saveParsingContexts + // Return nil to indicate parseElement failed + return nil + } + list = append(list, element) + if p.parseOptional(ast.KindCommaToken) { + // No need to check for a zero length node since we know we parsed a comma + continue + } + if p.isListTerminator(kind) { + break + } + // We didn't get a comma, and the list wasn't terminated, explicitly parse + // out a comma so we give a good error message. + if p.token != ast.KindCommaToken && kind == PCEnumMembers { + p.parseErrorAtCurrentToken(diagnostics.An_enum_member_name_must_be_followed_by_a_or) + } else { + p.parseExpected(ast.KindCommaToken) + } + // If the token was a semicolon, and the caller allows that, then skip it and + // continue. This ensures we get back on track and don't result in tons of + // parse errors. For example, this can happen when people do things like use + // a semicolon to delimit object literal members. Note: we'll have already + // reported an error when we called parseExpected above. + if (kind == PCObjectLiteralMembers || kind == PCImportAttributes) && p.token == ast.KindSemicolonToken && !p.hasPrecedingLineBreak() { + p.nextToken() + } + if startPos == p.nodePos() { + // What we're parsing isn't actually remotely recognizable as a element and we've consumed no tokens whatsoever + // Consume a token to advance the parser in some way and avoid an infinite loop + // This can happen when we're speculatively parsing parenthesized expressions which we think may be arrow functions, + // or when a modifier keyword which is disallowed as a parameter name (ie, `static` in strict mode) is supplied + p.nextToken() + } + continue + } + if p.isListTerminator(kind) { + break + } + if p.abortParsingListOrMoveToNextToken(kind) { + break + } + } + p.parsingContexts = saveParsingContexts + return p.newNodeList(core.NewTextRange(pos, p.nodePos()), p.nodeSlicePool.Clone(list)) +} + +// Return a non-nil (but possibly empty) NodeList if parsing was successful, or nil if opening token wasn't found +// or parseElement returned nil. +func (p *Parser) parseBracketedList(kind ParsingContext, parseElement func(p *Parser) *ast.Node, opening ast.Kind, closing ast.Kind) *ast.NodeList { + if p.parseExpected(opening) { + result := p.parseDelimitedList(kind, parseElement) + p.parseExpected(closing) + return result + } + return p.parseEmptyNodeList() +} + +func (p *Parser) parseEmptyNodeList() *ast.NodeList { + return p.newNodeList(core.NewTextRange(p.nodePos(), p.nodePos()), nil) +} + +// Returns true if we should abort parsing. +func (p *Parser) abortParsingListOrMoveToNextToken(kind ParsingContext) bool { + p.parsingContextErrors(kind) + if p.isInSomeParsingContext() { + return true + } + p.nextToken() + return false +} + +// True if positioned at element or terminator of the current list or any enclosing list +func (p *Parser) isInSomeParsingContext() bool { + // We should be in at least one parsing context, be it SourceElements while parsing + // a SourceFile, or JSDocComment when lazily parsing JSDoc. + debug.Assert(p.parsingContexts != 0, "Missing parsing context") + for kind := ParsingContext(0); kind < PCCount; kind++ { + if p.parsingContexts&(1<' then we just stop immediately. We've got an + // arrow function here and it's going to be very unlikely that we'll resynchronize and get + // another variable declaration. + return p.canParseSemicolon() || p.token == ast.KindInKeyword || p.token == ast.KindOfKeyword || p.token == ast.KindEqualsGreaterThanToken + case PCTypeParameters: + // Tokens other than '>' are here for better error recovery + return p.token == ast.KindGreaterThanToken || p.token == ast.KindOpenParenToken || p.token == ast.KindOpenBraceToken || p.token == ast.KindExtendsKeyword || p.token == ast.KindImplementsKeyword + case PCArgumentExpressions: + // Tokens other than ')' are here for better error recovery + return p.token == ast.KindCloseParenToken || p.token == ast.KindSemicolonToken + case PCArrayLiteralMembers, PCTupleElementTypes, PCArrayBindingElements: + return p.token == ast.KindCloseBracketToken + case PCJSDocParameters, PCParameters, PCRestProperties: + // Tokens other than ')' and ']' (the latter for index signatures) are here for better error recovery + return p.token == ast.KindCloseParenToken || p.token == ast.KindCloseBracketToken /*|| token == ast.KindOpenBraceToken*/ + case PCTypeArguments: + // All other tokens should cause the type-argument to terminate except comma token + return p.token != ast.KindCommaToken + case PCHeritageClauses: + return p.token == ast.KindOpenBraceToken || p.token == ast.KindCloseBraceToken + case PCJsxAttributes: + return p.token == ast.KindGreaterThanToken || p.token == ast.KindSlashToken + case PCJsxChildren: + return p.token == ast.KindLessThanToken && p.lookAhead((*Parser).nextTokenIsSlash) + } + return false +} + +func (p *Parser) parseExpectedJSDoc(kind ast.Kind) bool { + if p.token == kind { + p.nextTokenJSDoc() + return true + } + if !isKeywordOrPunctuation(kind) { + panic("Invalid JSDoc kind: expected keyword or punctuation") + } + p.parseErrorAtCurrentToken(diagnostics.X_0_expected, scanner.TokenToString(kind)) + return false +} + +func (p *Parser) parseExpectedMatchingBrackets(openKind ast.Kind, closeKind ast.Kind, openParsed bool, openPosition int) { + if p.token == closeKind { + p.nextToken() + return + } + lastError := p.parseErrorAtCurrentToken(diagnostics.X_0_expected, scanner.TokenToString(closeKind)) + if !openParsed { + return + } + if lastError != nil { + related := ast.NewDiagnostic(nil, core.NewTextRange(openPosition, openPosition+1), diagnostics.The_parser_expected_to_find_a_1_to_match_the_0_token_here, scanner.TokenToString(openKind), scanner.TokenToString(closeKind)) + lastError.AddRelatedInfo(related) + } +} + +func (p *Parser) parseOptional(token ast.Kind) bool { + if p.token == token { + p.nextToken() + return true + } + return false +} + +func (p *Parser) parseExpected(kind ast.Kind) bool { + return p.parseExpectedWithDiagnostic(kind, nil, true) +} + +func (p *Parser) parseExpectedWithoutAdvancing(kind ast.Kind) bool { + return p.parseExpectedWithDiagnostic(kind, nil, false) +} + +func (p *Parser) parseExpectedWithDiagnostic(kind ast.Kind, message *diagnostics.Message, shouldAdvance bool) bool { + if p.token == kind { + if shouldAdvance { + p.nextToken() + } + return true + } + // Report specific message if provided with one. Otherwise, report generic fallback message. + if message != nil { + p.parseErrorAtCurrentToken(message) + } else { + p.parseErrorAtCurrentToken(diagnostics.X_0_expected, scanner.TokenToString(kind)) + } + return false +} + +func (p *Parser) parseTokenNode() *ast.Node { + pos := p.nodePos() + kind := p.token + p.nextToken() + return p.finishNode(p.factory.NewToken(kind), pos) +} + +func (p *Parser) parseExpectedToken(kind ast.Kind) *ast.Node { + token := p.parseOptionalToken(kind) + if token == nil { + p.parseErrorAtCurrentToken(diagnostics.X_0_expected, scanner.TokenToString(kind)) + token = p.finishNode(p.factory.NewToken(kind), p.nodePos()) + } + return token +} + +func (p *Parser) parseOptionalToken(kind ast.Kind) *ast.Node { + if p.token == kind { + return p.parseTokenNode() + } + return nil +} + +func (p *Parser) parseExpectedTokenJSDoc(kind ast.Kind) *ast.Node { + optional := p.parseOptionalTokenJSDoc(kind) + if optional == nil { + if !isKeywordOrPunctuation(kind) { + panic("expected keyword or punctuation") + } + p.parseErrorAtCurrentToken(diagnostics.X_0_expected, scanner.TokenToString(kind)) + optional = p.finishNode(p.factory.NewToken(kind), p.nodePos()) + } + return optional +} + +func (p *Parser) parseOptionalTokenJSDoc(kind ast.Kind) *ast.Node { + if p.token == kind { + return p.parseTokenNode() + } + return nil +} + +func (p *Parser) parseStatement() *ast.Statement { + switch p.token { + case ast.KindSemicolonToken: + return p.parseEmptyStatement() + case ast.KindOpenBraceToken: + return p.parseBlock(false /*ignoreMissingOpenBrace*/, nil) + case ast.KindVarKeyword: + return p.parseVariableStatement(p.nodePos(), p.hasPrecedingJSDocComment(), nil /*modifiers*/) + case ast.KindLetKeyword: + if p.isLetDeclaration() { + return p.parseVariableStatement(p.nodePos(), p.hasPrecedingJSDocComment(), nil /*modifiers*/) + } + case ast.KindAwaitKeyword: + if p.isAwaitUsingDeclaration() { + return p.parseVariableStatement(p.nodePos(), p.hasPrecedingJSDocComment(), nil /*modifiers*/) + } + case ast.KindUsingKeyword: + if p.isUsingDeclaration() { + return p.parseVariableStatement(p.nodePos(), p.hasPrecedingJSDocComment(), nil /*modifiers*/) + } + case ast.KindFunctionKeyword: + return p.parseFunctionDeclaration(p.nodePos(), p.hasPrecedingJSDocComment(), nil /*modifiers*/) + case ast.KindClassKeyword: + return p.parseClassDeclaration(p.nodePos(), p.hasPrecedingJSDocComment(), nil /*modifiers*/) + case ast.KindIfKeyword: + return p.parseIfStatement() + case ast.KindDoKeyword: + return p.parseDoStatement() + case ast.KindWhileKeyword: + return p.parseWhileStatement() + case ast.KindForKeyword: + return p.parseForOrForInOrForOfStatement() + case ast.KindContinueKeyword: + return p.parseContinueStatement() + case ast.KindBreakKeyword: + return p.parseBreakStatement() + case ast.KindReturnKeyword: + return p.parseReturnStatement() + case ast.KindWithKeyword: + return p.parseWithStatement() + case ast.KindSwitchKeyword: + return p.parseSwitchStatement() + case ast.KindThrowKeyword: + return p.parseThrowStatement() + case ast.KindTryKeyword, ast.KindCatchKeyword, ast.KindFinallyKeyword: + return p.parseTryStatement() + case ast.KindDebuggerKeyword: + return p.parseDebuggerStatement() + case ast.KindAtToken: + return p.parseDeclaration() + case ast.KindAsyncKeyword, ast.KindInterfaceKeyword, ast.KindTypeKeyword, ast.KindModuleKeyword, ast.KindNamespaceKeyword, + ast.KindDeclareKeyword, ast.KindConstKeyword, ast.KindEnumKeyword, ast.KindExportKeyword, ast.KindImportKeyword, + ast.KindPrivateKeyword, ast.KindProtectedKeyword, ast.KindPublicKeyword, ast.KindAbstractKeyword, ast.KindAccessorKeyword, + ast.KindStaticKeyword, ast.KindReadonlyKeyword, ast.KindGlobalKeyword: + if p.isStartOfDeclaration() { + return p.parseDeclaration() + } + } + return p.parseExpressionOrLabeledStatement() +} + +func (p *Parser) parseDeclaration() *ast.Statement { + // `parseListElement` attempted to get the reused node at this position, + // but the ambient context flag was not yet set, so the node appeared + // not reusable in that context. + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + modifiers := p.parseModifiersEx( /*allowDecorators*/ true, false /*permitConstAsModifier*/, false /*stopOnStartOfClassStaticBlock*/) + isAmbient := modifiers != nil && core.Some(modifiers.Nodes, isDeclareModifier) + if isAmbient { + // !!! incremental parsing + // node := p.tryReuseAmbientDeclaration(pos) + // if node { + // return node + // } + for _, m := range modifiers.Nodes { + m.Flags |= ast.NodeFlagsAmbient + } + saveContextFlags := p.contextFlags + p.setContextFlags(ast.NodeFlagsAmbient, true) + result := p.parseDeclarationWorker(pos, hasJSDoc, modifiers) + p.contextFlags = saveContextFlags + return result + } else { + return p.parseDeclarationWorker(pos, hasJSDoc, modifiers) + } +} + +func (p *Parser) parseDeclarationWorker(pos int, hasJSDoc bool, modifiers *ast.ModifierList) *ast.Statement { + switch p.token { + case ast.KindVarKeyword, ast.KindLetKeyword, ast.KindConstKeyword, ast.KindUsingKeyword, ast.KindAwaitKeyword: + return p.parseVariableStatement(pos, hasJSDoc, modifiers) + case ast.KindFunctionKeyword: + return p.parseFunctionDeclaration(pos, hasJSDoc, modifiers) + case ast.KindClassKeyword: + return p.parseClassDeclaration(pos, hasJSDoc, modifiers) + case ast.KindInterfaceKeyword: + return p.parseInterfaceDeclaration(pos, hasJSDoc, modifiers) + case ast.KindTypeKeyword: + return p.parseTypeAliasDeclaration(pos, hasJSDoc, modifiers) + case ast.KindEnumKeyword: + return p.parseEnumDeclaration(pos, hasJSDoc, modifiers) + case ast.KindGlobalKeyword, ast.KindModuleKeyword, ast.KindNamespaceKeyword: + return p.parseModuleDeclaration(pos, hasJSDoc, modifiers) + case ast.KindImportKeyword: + return p.parseImportDeclarationOrImportEqualsDeclaration(pos, hasJSDoc, modifiers) + case ast.KindExportKeyword: + p.nextToken() + switch p.token { + case ast.KindDefaultKeyword, ast.KindEqualsToken: + return p.parseExportAssignment(pos, hasJSDoc, modifiers) + case ast.KindAsKeyword: + return p.parseNamespaceExportDeclaration(pos, hasJSDoc, modifiers) + default: + return p.parseExportDeclaration(pos, hasJSDoc, modifiers) + } + } + if modifiers != nil { + // We reached this point because we encountered decorators and/or modifiers and assumed a declaration + // would follow. For recovery and error reporting purposes, return an incomplete declaration. + p.parseErrorAt(p.nodePos(), p.nodePos(), diagnostics.Declaration_expected) + return p.finishNode(p.factory.NewMissingDeclaration(modifiers), pos) + } + panic("Unhandled case in parseDeclarationWorker") +} + +func isDeclareModifier(modifier *ast.Node) bool { + return modifier.Kind == ast.KindDeclareKeyword +} + +func (p *Parser) isLetDeclaration() bool { + // In ES6 'let' always starts a lexical declaration if followed by an identifier or { + // or [. + return p.lookAhead((*Parser).nextTokenIsBindingIdentifierOrStartOfDestructuring) +} + +func (p *Parser) nextTokenIsBindingIdentifierOrStartOfDestructuring() bool { + p.nextToken() + return p.isBindingIdentifier() || p.token == ast.KindOpenBraceToken || p.token == ast.KindOpenBracketToken +} + +func (p *Parser) parseBlock(ignoreMissingOpenBrace bool, diagnosticMessage *diagnostics.Message) *ast.Node { + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + openBracePosition := p.scanner.TokenStart() + openBraceParsed := p.parseExpectedWithDiagnostic(ast.KindOpenBraceToken, diagnosticMessage, true /*shouldAdvance*/) + multiline := false + if openBraceParsed || ignoreMissingOpenBrace { + multiline = p.hasPrecedingLineBreak() + statements := p.parseList(PCBlockStatements, (*Parser).parseStatement) + p.parseExpectedMatchingBrackets(ast.KindOpenBraceToken, ast.KindCloseBraceToken, openBraceParsed, openBracePosition) + result := p.finishNode(p.factory.NewBlock(statements, multiline), pos) + p.withJSDoc(result, hasJSDoc) + if p.token == ast.KindEqualsToken { + p.parseErrorAtCurrentToken(diagnostics.Declaration_or_statement_expected_This_follows_a_block_of_statements_so_if_you_intended_to_write_a_destructuring_assignment_you_might_need_to_wrap_the_whole_assignment_in_parentheses) + p.nextToken() + } + return result + } + result := p.finishNode(p.factory.NewBlock(p.parseEmptyNodeList(), multiline), pos) + p.withJSDoc(result, hasJSDoc) + return result +} + +func (p *Parser) parseEmptyStatement() *ast.Node { + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + p.parseExpected(ast.KindSemicolonToken) + result := p.finishNode(p.factory.NewEmptyStatement(), pos) + p.withJSDoc(result, hasJSDoc) + return result +} + +func (p *Parser) parseIfStatement() *ast.Node { + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + p.parseExpected(ast.KindIfKeyword) + openParenPosition := p.scanner.TokenStart() + openParenParsed := p.parseExpected(ast.KindOpenParenToken) + expression := p.parseExpressionAllowIn() + p.parseExpectedMatchingBrackets(ast.KindOpenParenToken, ast.KindCloseParenToken, openParenParsed, openParenPosition) + thenStatement := p.parseStatement() + var elseStatement *ast.Statement + if p.parseOptional(ast.KindElseKeyword) { + elseStatement = p.parseStatement() + } + result := p.finishNode(p.factory.NewIfStatement(expression, thenStatement, elseStatement), pos) + p.withJSDoc(result, hasJSDoc) + return result +} + +func (p *Parser) parseDoStatement() *ast.Node { + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + p.parseExpected(ast.KindDoKeyword) + statement := p.parseStatement() + p.parseExpected(ast.KindWhileKeyword) + openParenPosition := p.scanner.TokenStart() + openParenParsed := p.parseExpected(ast.KindOpenParenToken) + expression := p.parseExpressionAllowIn() + p.parseExpectedMatchingBrackets(ast.KindOpenParenToken, ast.KindCloseParenToken, openParenParsed, openParenPosition) + // From: https://mail.mozilla.org/pipermail/es-discuss/2011-August/016188.html + // 157 min --- All allen at wirfs-brock.com CONF --- "do{;}while(false)false" prohibited in + // spec but allowed in consensus reality. Approved -- this is the de-facto standard whereby + // do;while(0)x will have a semicolon inserted before x. + p.parseOptional(ast.KindSemicolonToken) + result := p.finishNode(p.factory.NewDoStatement(statement, expression), pos) + p.withJSDoc(result, hasJSDoc) + return result +} + +func (p *Parser) parseWhileStatement() *ast.Node { + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + p.parseExpected(ast.KindWhileKeyword) + openParenPosition := p.scanner.TokenStart() + openParenParsed := p.parseExpected(ast.KindOpenParenToken) + expression := p.parseExpressionAllowIn() + p.parseExpectedMatchingBrackets(ast.KindOpenParenToken, ast.KindCloseParenToken, openParenParsed, openParenPosition) + statement := p.parseStatement() + result := p.finishNode(p.factory.NewWhileStatement(expression, statement), pos) + p.withJSDoc(result, hasJSDoc) + return result +} + +func (p *Parser) parseForOrForInOrForOfStatement() *ast.Node { + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + p.parseExpected(ast.KindForKeyword) + awaitToken := p.parseOptionalToken(ast.KindAwaitKeyword) + p.parseExpected(ast.KindOpenParenToken) + var initializer *ast.ForInitializer + if p.token != ast.KindSemicolonToken { + if p.token == ast.KindVarKeyword || p.token == ast.KindLetKeyword || p.token == ast.KindConstKeyword || + p.token == ast.KindUsingKeyword && p.lookAhead((*Parser).nextTokenIsBindingIdentifierOrStartOfDestructuringOnSameLineDisallowOf) || + // this one is meant to allow of + p.token == ast.KindAwaitKeyword && p.lookAhead((*Parser).nextIsUsingKeywordThenBindingIdentifierOrStartOfObjectDestructuringOnSameLine) { + initializer = p.parseVariableDeclarationList(true /*inForStatementInitializer*/) + } else { + initializer = doInContext(p, ast.NodeFlagsDisallowInContext, true, (*Parser).parseExpression) + } + } + var result *ast.Statement + switch { + case awaitToken != nil && p.parseExpected(ast.KindOfKeyword) || awaitToken == nil && p.parseOptional(ast.KindOfKeyword): + expression := doInContext(p, ast.NodeFlagsDisallowInContext, false, (*Parser).parseAssignmentExpressionOrHigher) + p.parseExpected(ast.KindCloseParenToken) + result = p.factory.NewForInOrOfStatement(ast.KindForOfStatement, awaitToken, initializer, expression, p.parseStatement()) + case p.parseOptional(ast.KindInKeyword): + expression := p.parseExpressionAllowIn() + p.parseExpected(ast.KindCloseParenToken) + result = p.factory.NewForInOrOfStatement(ast.KindForInStatement, nil /*awaitToken*/, initializer, expression, p.parseStatement()) + default: + p.parseExpected(ast.KindSemicolonToken) + var condition *ast.Expression + if p.token != ast.KindSemicolonToken && p.token != ast.KindCloseParenToken { + condition = p.parseExpressionAllowIn() + } + p.parseExpected(ast.KindSemicolonToken) + var incrementor *ast.Expression + if p.token != ast.KindCloseParenToken { + incrementor = p.parseExpressionAllowIn() + } + p.parseExpected(ast.KindCloseParenToken) + result = p.factory.NewForStatement(initializer, condition, incrementor, p.parseStatement()) + } + p.finishNode(result, pos) + p.withJSDoc(result, hasJSDoc) + return result +} + +func (p *Parser) parseBreakStatement() *ast.Node { + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + p.parseExpected(ast.KindBreakKeyword) + label := p.parseIdentifierUnlessAtSemicolon() + p.parseSemicolon() + result := p.finishNode(p.factory.NewBreakStatement(label), pos) + p.withJSDoc(result, hasJSDoc) + return result +} + +func (p *Parser) parseContinueStatement() *ast.Node { + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + p.parseExpected(ast.KindContinueKeyword) + label := p.parseIdentifierUnlessAtSemicolon() + p.parseSemicolon() + result := p.finishNode(p.factory.NewContinueStatement(label), pos) + p.withJSDoc(result, hasJSDoc) + return result +} + +func (p *Parser) parseIdentifierUnlessAtSemicolon() *ast.Node { + if !p.canParseSemicolon() { + return p.parseIdentifier() + } + return nil +} + +func (p *Parser) parseReturnStatement() *ast.Node { + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + p.parseExpected(ast.KindReturnKeyword) + var expression *ast.Expression + if !p.canParseSemicolon() { + expression = p.parseExpressionAllowIn() + } + p.parseSemicolon() + result := p.finishNode(p.factory.NewReturnStatement(expression), pos) + p.withJSDoc(result, hasJSDoc) + return result +} + +func (p *Parser) parseWithStatement() *ast.Node { + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + p.parseExpected(ast.KindWithKeyword) + openParenPosition := p.scanner.TokenStart() + openParenParsed := p.parseExpected(ast.KindOpenParenToken) + expression := p.parseExpressionAllowIn() + p.parseExpectedMatchingBrackets(ast.KindOpenParenToken, ast.KindCloseParenToken, openParenParsed, openParenPosition) + statement := doInContext(p, ast.NodeFlagsInWithStatement, true, (*Parser).parseStatement) + result := p.finishNode(p.factory.NewWithStatement(expression, statement), pos) + p.withJSDoc(result, hasJSDoc) + return result +} + +func (p *Parser) parseCaseClause() *ast.Node { + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + p.parseExpected(ast.KindCaseKeyword) + expression := p.parseExpressionAllowIn() + p.parseExpected(ast.KindColonToken) + statements := p.parseList(PCSwitchClauseStatements, (*Parser).parseStatement) + result := p.finishNode(p.factory.NewCaseOrDefaultClause(ast.KindCaseClause, expression, statements), pos) + p.withJSDoc(result, hasJSDoc) + return result +} + +func (p *Parser) parseDefaultClause() *ast.Node { + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + p.parseExpected(ast.KindDefaultKeyword) + p.parseExpected(ast.KindColonToken) + statements := p.parseList(PCSwitchClauseStatements, (*Parser).parseStatement) + result := p.finishNode(p.factory.NewCaseOrDefaultClause(ast.KindDefaultClause, nil /*expression*/, statements), pos) + p.withJSDoc(result, hasJSDoc) + return result +} + +func (p *Parser) parseCaseOrDefaultClause() *ast.Node { + if p.token == ast.KindCaseKeyword { + return p.parseCaseClause() + } + return p.parseDefaultClause() +} + +func (p *Parser) parseCaseBlock() *ast.Node { + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + p.parseExpected(ast.KindOpenBraceToken) + clauses := p.parseList(PCSwitchClauses, (*Parser).parseCaseOrDefaultClause) + p.parseExpected(ast.KindCloseBraceToken) + result := p.finishNode(p.factory.NewCaseBlock(clauses), pos) + p.withJSDoc(result, hasJSDoc) + return result +} + +func (p *Parser) parseSwitchStatement() *ast.Node { + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + p.parseExpected(ast.KindSwitchKeyword) + p.parseExpected(ast.KindOpenParenToken) + expression := p.parseExpressionAllowIn() + p.parseExpected(ast.KindCloseParenToken) + caseBlock := p.parseCaseBlock() + result := p.finishNode(p.factory.NewSwitchStatement(expression, caseBlock), pos) + p.withJSDoc(result, hasJSDoc) + return result +} + +func (p *Parser) parseThrowStatement() *ast.Node { + // ThrowStatement[Yield] : + // throw [no LineTerminator here]Expression[In, ?Yield]; + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + p.parseExpected(ast.KindThrowKeyword) + // Because of automatic semicolon insertion, we need to report error if this + // throw could be terminated with a semicolon. Note: we can't call 'parseExpression' + // directly as that might consume an expression on the following line. + // Instead, we create a "missing" identifier, but don't report an error. The actual error + // will be reported in the grammar walker. + var expression *ast.Expression + if !p.hasPrecedingLineBreak() { + expression = p.parseExpressionAllowIn() + } else { + expression = p.createMissingIdentifier() + } + if !p.tryParseSemicolon() { + p.parseErrorForMissingSemicolonAfter(expression) + } + result := p.finishNode(p.factory.NewThrowStatement(expression), pos) + p.withJSDoc(result, hasJSDoc) + return result +} + +// TODO: Review for error recovery +func (p *Parser) parseTryStatement() *ast.Node { + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + p.parseExpected(ast.KindTryKeyword) + tryBlock := p.parseBlock(false /*ignoreMissingOpenBrace*/, nil) + var catchClause *ast.Node + if p.token == ast.KindCatchKeyword { + catchClause = p.parseCatchClause() + } + // If we don't have a catch clause, then we must have a finally clause. Try to parse + // one out no matter what. + var finallyBlock *ast.Node + if catchClause == nil || p.token == ast.KindFinallyKeyword { + p.parseExpectedWithDiagnostic(ast.KindFinallyKeyword, diagnostics.X_catch_or_finally_expected, true /*shouldAdvance*/) + finallyBlock = p.parseBlock(false /*ignoreMissingOpenBrace*/, nil) + } + result := p.finishNode(p.factory.NewTryStatement(tryBlock, catchClause, finallyBlock), pos) + p.withJSDoc(result, hasJSDoc) + return result +} + +func (p *Parser) parseCatchClause() *ast.Node { + pos := p.nodePos() + p.parseExpected(ast.KindCatchKeyword) + var variableDeclaration *ast.Node + if p.parseOptional(ast.KindOpenParenToken) { + variableDeclaration = p.parseVariableDeclaration() + p.parseExpected(ast.KindCloseParenToken) + } + block := p.parseBlock(false /*ignoreMissingOpenBrace*/, nil) + result := p.finishNode(p.factory.NewCatchClause(variableDeclaration, block), pos) + return result +} + +func (p *Parser) parseDebuggerStatement() *ast.Node { + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + p.parseExpected(ast.KindDebuggerKeyword) + p.parseSemicolon() + result := p.finishNode(p.factory.NewDebuggerStatement(), pos) + p.withJSDoc(result, hasJSDoc) + return result +} + +func (p *Parser) parseExpressionOrLabeledStatement() *ast.Statement { + // Avoiding having to do the lookahead for a labeled statement by just trying to parse + // out an expression, seeing if it is identifier and then seeing if it is followed by + // a colon. + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + hasParen := p.token == ast.KindOpenParenToken + expression := p.parseExpression() + + if expression.Kind == ast.KindIdentifier && p.parseOptional(ast.KindColonToken) { + result := p.finishNode(p.factory.NewLabeledStatement(expression, p.parseStatement()), pos) + p.withJSDoc(result, hasJSDoc) + return result + } + + if !p.tryParseSemicolon() { + p.parseErrorForMissingSemicolonAfter(expression) + } + result := p.finishNode(p.factory.NewExpressionStatement(expression), pos) + jsdoc := p.withJSDoc(result, hasJSDoc && !hasParen) + p.reparseCommonJS(result, jsdoc) + return result +} + +func (p *Parser) parseVariableStatement(pos int, hasJSDoc bool, modifiers *ast.ModifierList) *ast.Node { + declarationList := p.parseVariableDeclarationList(false /*inForStatementInitializer*/) + p.parseSemicolon() + result := p.finishNode(p.factory.NewVariableStatement(modifiers, declarationList), pos) + p.withJSDoc(result, hasJSDoc) + p.checkJSSyntax(result) + return result +} + +func (p *Parser) parseVariableDeclarationList(inForStatementInitializer bool) *ast.Node { + pos := p.nodePos() + var flags ast.NodeFlags + switch p.token { + case ast.KindVarKeyword: + flags = ast.NodeFlagsNone + case ast.KindLetKeyword: + flags = ast.NodeFlagsLet + case ast.KindConstKeyword: + flags = ast.NodeFlagsConst + case ast.KindUsingKeyword: + flags = ast.NodeFlagsUsing + case ast.KindAwaitKeyword: + debug.Assert(p.isAwaitUsingDeclaration()) + flags = ast.NodeFlagsAwaitUsing + p.nextToken() + default: + panic("Unhandled case in parseVariableDeclarationList") + } + p.nextToken() + // The user may have written the following: + // + // for (let of X) { } + // + // In this case, we want to parse an empty declaration list, and then parse 'of' + // as a keyword. The reason this is not automatic is that 'of' is a valid identifier. + // So we need to look ahead to determine if 'of' should be treated as a keyword in + // this context. + // The checker will then give an error that there is an empty declaration list. + var declarations *ast.NodeList + if p.token == ast.KindOfKeyword && p.lookAhead((*Parser).nextIsIdentifierAndCloseParen) { + declarations = p.parseEmptyNodeList() + } else { + saveContextFlags := p.contextFlags + p.setContextFlags(ast.NodeFlagsDisallowInContext, inForStatementInitializer) + declarations = p.parseDelimitedList(PCVariableDeclarations, core.IfElse(inForStatementInitializer, (*Parser).parseVariableDeclaration, (*Parser).parseVariableDeclarationAllowExclamation)) + p.contextFlags = saveContextFlags + } + result := p.finishNode(p.factory.NewVariableDeclarationList(flags, declarations), pos) + return result +} + +func (p *Parser) nextIsIdentifierAndCloseParen() bool { + return p.nextTokenIsIdentifier() && p.nextToken() == ast.KindCloseParenToken +} + +func (p *Parser) nextTokenIsIdentifier() bool { + p.nextToken() + return p.isIdentifier() +} + +func (p *Parser) parseVariableDeclaration() *ast.Node { + return p.parseVariableDeclarationWorker(false /*allowExclamation*/) +} + +func (p *Parser) parseVariableDeclarationAllowExclamation() *ast.Node { + return p.parseVariableDeclarationWorker(true /*allowExclamation*/) +} + +func (p *Parser) parseVariableDeclarationWorker(allowExclamation bool) *ast.Node { + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + name := p.parseIdentifierOrPatternWithDiagnostic(diagnostics.Private_identifiers_are_not_allowed_in_variable_declarations) + var exclamationToken *ast.Node + if allowExclamation && name.Kind == ast.KindIdentifier && p.token == ast.KindExclamationToken && !p.hasPrecedingLineBreak() { + exclamationToken = p.parseTokenNode() + } + typeNode := p.parseTypeAnnotation() + var initializer *ast.Expression + if p.token != ast.KindInKeyword && p.token != ast.KindOfKeyword { + initializer = p.parseInitializer() + } + result := p.finishNode(p.factory.NewVariableDeclaration(name, exclamationToken, typeNode, initializer), pos) + p.withJSDoc(result, hasJSDoc) + p.checkJSSyntax(result) + return result +} + +func (p *Parser) parseIdentifierOrPattern() *ast.Node { + return p.parseIdentifierOrPatternWithDiagnostic(nil) +} + +func (p *Parser) parseIdentifierOrPatternWithDiagnostic(privateIdentifierDiagnosticMessage *diagnostics.Message) *ast.Node { + if p.token == ast.KindOpenBracketToken { + return p.parseArrayBindingPattern() + } + if p.token == ast.KindOpenBraceToken { + return p.parseObjectBindingPattern() + } + return p.parseBindingIdentifierWithDiagnostic(privateIdentifierDiagnosticMessage) +} + +func (p *Parser) parseArrayBindingPattern() *ast.Node { + pos := p.nodePos() + p.parseExpected(ast.KindOpenBracketToken) + saveContextFlags := p.contextFlags + p.setContextFlags(ast.NodeFlagsDisallowInContext, false) + elements := p.parseDelimitedList(PCArrayBindingElements, (*Parser).parseArrayBindingElement) + p.contextFlags = saveContextFlags + p.parseExpected(ast.KindCloseBracketToken) + return p.finishNode(p.factory.NewBindingPattern(ast.KindArrayBindingPattern, elements), pos) +} + +func (p *Parser) parseArrayBindingElement() *ast.Node { + pos := p.nodePos() + var dotDotDotToken *ast.Node + var name *ast.Node + var initializer *ast.Expression + if p.token != ast.KindCommaToken { + // These are all nil for a missing element + dotDotDotToken = p.parseOptionalToken(ast.KindDotDotDotToken) + name = p.parseIdentifierOrPattern() + initializer = p.parseInitializer() + } + return p.finishNode(p.factory.NewBindingElement(dotDotDotToken, nil /*propertyName*/, name, initializer), pos) +} + +func (p *Parser) parseObjectBindingPattern() *ast.Node { + pos := p.nodePos() + p.parseExpected(ast.KindOpenBraceToken) + saveContextFlags := p.contextFlags + p.setContextFlags(ast.NodeFlagsDisallowInContext, false) + elements := p.parseDelimitedList(PCObjectBindingElements, (*Parser).parseObjectBindingElement) + p.contextFlags = saveContextFlags + p.parseExpected(ast.KindCloseBraceToken) + return p.finishNode(p.factory.NewBindingPattern(ast.KindObjectBindingPattern, elements), pos) +} + +func (p *Parser) parseObjectBindingElement() *ast.Node { + pos := p.nodePos() + dotDotDotToken := p.parseOptionalToken(ast.KindDotDotDotToken) + tokenIsIdentifier := p.isBindingIdentifier() + propertyName := p.parsePropertyName() + var name *ast.Node + if tokenIsIdentifier && p.token != ast.KindColonToken { + name = propertyName + propertyName = nil + } else { + p.parseExpected(ast.KindColonToken) + name = p.parseIdentifierOrPattern() + } + initializer := p.parseInitializer() + return p.finishNode(p.factory.NewBindingElement(dotDotDotToken, propertyName, name, initializer), pos) +} + +func (p *Parser) parseInitializer() *ast.Expression { + if p.parseOptional(ast.KindEqualsToken) { + return p.parseAssignmentExpressionOrHigher() + } + return nil +} + +func (p *Parser) parseTypeAnnotation() *ast.TypeNode { + if p.parseOptional(ast.KindColonToken) { + return p.parseType() + } + return nil +} + +func (p *Parser) parseFunctionDeclaration(pos int, hasJSDoc bool, modifiers *ast.ModifierList) *ast.Node { + p.parseExpected(ast.KindFunctionKeyword) + asteriskToken := p.parseOptionalToken(ast.KindAsteriskToken) + // We don't parse the name here in await context, instead we will report a grammar error in the checker. + var name *ast.Node + if modifiers == nil || modifiers.ModifierFlags&ast.ModifierFlagsDefault == 0 || p.isBindingIdentifier() { + name = p.parseBindingIdentifier() + } + signatureFlags := core.IfElse(asteriskToken != nil, ParseFlagsYield, ParseFlagsNone) | core.IfElse(modifiers != nil && modifiers.ModifierFlags&ast.ModifierFlagsAsync != 0, ParseFlagsAwait, ParseFlagsNone) + typeParameters := p.parseTypeParameters() + saveContextFlags := p.contextFlags + if modifiers != nil && modifiers.ModifierFlags&ast.ModifierFlagsExport != 0 { + p.setContextFlags(ast.NodeFlagsAwaitContext, true) + } + parameters := p.parseParameters(signatureFlags) + returnType := p.parseReturnType(ast.KindColonToken, false /*isType*/) + body := p.parseFunctionBlockOrSemicolon(signatureFlags, diagnostics.X_or_expected) + p.contextFlags = saveContextFlags + result := p.finishNode(p.factory.NewFunctionDeclaration(modifiers, asteriskToken, name, typeParameters, parameters, returnType, nil /*fullSignature*/, body), pos) + p.withJSDoc(result, hasJSDoc) + p.checkJSSyntax(result) + return result +} + +func (p *Parser) parseClassDeclaration(pos int, hasJSDoc bool, modifiers *ast.ModifierList) *ast.Node { + return p.parseClassDeclarationOrExpression(pos, hasJSDoc, modifiers, ast.KindClassDeclaration) +} + +func (p *Parser) parseClassExpression() *ast.Node { + return p.parseClassDeclarationOrExpression(p.nodePos(), p.hasPrecedingJSDocComment(), nil /*modifiers*/, ast.KindClassExpression) +} + +func (p *Parser) parseClassDeclarationOrExpression(pos int, hasJSDoc bool, modifiers *ast.ModifierList, kind ast.Kind) *ast.Node { + saveContextFlags := p.contextFlags + saveHasAwaitIdentifier := p.statementHasAwaitIdentifier + p.parseExpected(ast.KindClassKeyword) + // We don't parse the name here in await context, instead we will report a grammar error in the checker. + name := p.parseNameOfClassDeclarationOrExpression() + typeParameters := p.parseTypeParameters() + if modifiers != nil && core.Some(modifiers.Nodes, isExportModifier) { + p.setContextFlags(ast.NodeFlagsAwaitContext, true /*value*/) + } + heritageClauses := p.parseHeritageClauses() + var members *ast.NodeList + if p.parseExpected(ast.KindOpenBraceToken) { + // ClassTail[Yield,Await] : (Modified) See 14.5 + // ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt } + members = p.parseList(PCClassMembers, (*Parser).parseClassElement) + p.parseExpected(ast.KindCloseBraceToken) + } else { + members = p.parseEmptyNodeList() + } + p.contextFlags = saveContextFlags + var result *ast.Node + if modifiers != nil && ast.ModifiersToFlags(modifiers.Nodes)&ast.ModifierFlagsAmbient != 0 { + p.statementHasAwaitIdentifier = saveHasAwaitIdentifier + } + if kind == ast.KindClassDeclaration { + result = p.factory.NewClassDeclaration(modifiers, name, typeParameters, heritageClauses, members) + } else { + result = p.factory.NewClassExpression(modifiers, name, typeParameters, heritageClauses, members) + } + p.finishNode(result, pos) + p.withJSDoc(result, hasJSDoc) + if result.Flags&ast.NodeFlagsJavaScriptFile != 0 { + p.checkJSSyntax(result) + if heritageClauses != nil { + for _, clause := range heritageClauses.Nodes { + if clause.AsHeritageClause().Token == ast.KindExtendsKeyword { + for _, expr := range clause.AsHeritageClause().Types.Nodes { + p.checkJSSyntax(expr) + } + } + } + } + } + return result +} + +func (p *Parser) parseNameOfClassDeclarationOrExpression() *ast.Node { + // implements is a future reserved word so + // 'class implements' might mean either + // - class expression with omitted name, 'implements' starts heritage clause + // - class with name 'implements' + // 'isImplementsClause' helps to disambiguate between these two cases + if p.isBindingIdentifier() && !p.isImplementsClause() { + saveHasAwaitIdentifier := p.statementHasAwaitIdentifier + id := p.createIdentifier(p.isBindingIdentifier()) + p.statementHasAwaitIdentifier = saveHasAwaitIdentifier + return id + } + return nil +} + +func (p *Parser) isImplementsClause() bool { + return p.token == ast.KindImplementsKeyword && p.lookAhead((*Parser).nextTokenIsIdentifierOrKeyword) +} + +func isExportModifier(modifier *ast.Node) bool { + return modifier.Kind == ast.KindExportKeyword +} + +func isAsyncModifier(modifier *ast.Node) bool { + return modifier.Kind == ast.KindAsyncKeyword +} + +func (p *Parser) parseHeritageClauses() *ast.NodeList { + // ClassTail[Yield,Await] : (Modified) See 14.5 + // ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt } + if p.isHeritageClause() { + return p.parseList(PCHeritageClauses, (*Parser).parseHeritageClause) + } + return nil +} + +func (p *Parser) parseHeritageClause() *ast.Node { + pos := p.nodePos() + kind := p.token + p.nextToken() + types := p.parseDelimitedList(PCHeritageClauseElement, (*Parser).parseExpressionWithTypeArguments) + return p.checkJSSyntax(p.finishNode(p.factory.NewHeritageClause(kind, types), pos)) +} + +func (p *Parser) parseExpressionWithTypeArguments() *ast.Node { + pos := p.nodePos() + expression := p.parseLeftHandSideExpressionOrHigher() + if ast.IsExpressionWithTypeArguments(expression) { + return expression + } + typeArguments := p.parseTypeArguments() + return p.finishNode(p.factory.NewExpressionWithTypeArguments(expression, typeArguments), pos) +} + +func (p *Parser) parseClassElement() *ast.Node { + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + if p.token == ast.KindSemicolonToken { + p.nextToken() + result := p.finishNode(p.factory.NewSemicolonClassElement(), pos) + p.withJSDoc(result, hasJSDoc) + return result + } + modifiers := p.parseModifiersEx(true /*allowDecorators*/, true /*permitConstAsModifier*/, true /*stopOnStartOfClassStaticBlock*/) + if p.token == ast.KindStaticKeyword && p.lookAhead((*Parser).nextTokenIsOpenBrace) { + return p.parseClassStaticBlockDeclaration(pos, hasJSDoc, modifiers) + } + if p.parseContextualModifier(ast.KindGetKeyword) { + return p.parseAccessorDeclaration(pos, hasJSDoc, modifiers, ast.KindGetAccessor, ParseFlagsNone) + } + if p.parseContextualModifier(ast.KindSetKeyword) { + return p.parseAccessorDeclaration(pos, hasJSDoc, modifiers, ast.KindSetAccessor, ParseFlagsNone) + } + if p.token == ast.KindConstructorKeyword || p.token == ast.KindStringLiteral { + constructorDeclaration := p.tryParseConstructorDeclaration(pos, hasJSDoc, modifiers) + if constructorDeclaration != nil { + return constructorDeclaration + } + } + if p.isIndexSignature() { + return p.checkJSSyntax(p.parseIndexSignatureDeclaration(pos, hasJSDoc, modifiers)) + } + // It is very important that we check this *after* checking indexers because + // the [ token can start an index signature or a computed property name + if tokenIsIdentifierOrKeyword(p.token) || p.token == ast.KindStringLiteral || p.token == ast.KindNumericLiteral || p.token == ast.KindBigIntLiteral || p.token == ast.KindAsteriskToken || p.token == ast.KindOpenBracketToken { + isAmbient := modifiers != nil && core.Some(modifiers.Nodes, isDeclareModifier) + if isAmbient { + for _, m := range modifiers.Nodes { + m.Flags |= ast.NodeFlagsAmbient + } + saveContextFlags := p.contextFlags + p.setContextFlags(ast.NodeFlagsAmbient, true) + result := p.parsePropertyOrMethodDeclaration(pos, hasJSDoc, modifiers) + p.contextFlags = saveContextFlags + return result + } else { + return p.parsePropertyOrMethodDeclaration(pos, hasJSDoc, modifiers) + } + } + if modifiers != nil { + // treat this as a property declaration with a missing name. + p.parseErrorAt(p.nodePos(), p.nodePos(), diagnostics.Declaration_expected) + name := p.createMissingIdentifier() + return p.parsePropertyDeclaration(pos, hasJSDoc, modifiers, name, nil /*questionToken*/) + } + // 'isClassMemberStart' should have hinted not to attempt parsing. + panic("Should not have attempted to parse class member declaration.") +} + +func (p *Parser) parseClassStaticBlockDeclaration(pos int, hasJSDoc bool, modifiers *ast.ModifierList) *ast.Node { + p.parseExpectedToken(ast.KindStaticKeyword) + body := p.parseClassStaticBlockBody() + result := p.finishNode(p.factory.NewClassStaticBlockDeclaration(modifiers, body), pos) + p.withJSDoc(result, hasJSDoc) + return result +} + +func (p *Parser) parseClassStaticBlockBody() *ast.Node { + saveContextFlags := p.contextFlags + p.setContextFlags(ast.NodeFlagsYieldContext, false) + p.setContextFlags(ast.NodeFlagsAwaitContext, true) + body := p.parseBlock(false /*ignoreMissingOpenBrace*/, nil /*diagnosticMessage*/) + p.contextFlags = saveContextFlags + return body +} + +func (p *Parser) tryParseConstructorDeclaration(pos int, hasJSDoc bool, modifiers *ast.ModifierList) *ast.Node { + state := p.mark() + if p.token == ast.KindConstructorKeyword || p.token == ast.KindStringLiteral && p.scanner.TokenValue() == "constructor" && p.lookAhead((*Parser).nextTokenIsOpenParen) { + p.nextToken() + typeParameters := p.parseTypeParameters() + parameters := p.parseParameters(ParseFlagsNone) + returnType := p.parseReturnType(ast.KindColonToken, false /*isType*/) + body := p.parseFunctionBlockOrSemicolon(ParseFlagsNone, diagnostics.X_or_expected) + result := p.finishNode(p.factory.NewConstructorDeclaration(modifiers, typeParameters, parameters, returnType, nil /*fullSignature*/, body), pos) + p.withJSDoc(result, hasJSDoc) + p.checkJSSyntax(result) + return result + } + p.rewind(state) + return nil +} + +func (p *Parser) nextTokenIsOpenParen() bool { + return p.nextToken() == ast.KindOpenParenToken +} + +func (p *Parser) parsePropertyOrMethodDeclaration(pos int, hasJSDoc bool, modifiers *ast.ModifierList) *ast.Node { + asteriskToken := p.parseOptionalToken(ast.KindAsteriskToken) + name := p.parsePropertyName() + // Note: this is not legal as per the grammar. But we allow it in the parser and + // report an error in the grammar checker. + questionToken := p.parseOptionalToken(ast.KindQuestionToken) + if asteriskToken != nil || p.token == ast.KindOpenParenToken || p.token == ast.KindLessThanToken { + return p.parseMethodDeclaration(pos, hasJSDoc, modifiers, asteriskToken, name, questionToken, diagnostics.X_or_expected) + } + return p.parsePropertyDeclaration(pos, hasJSDoc, modifiers, name, questionToken) +} + +func (p *Parser) parseMethodDeclaration(pos int, hasJSDoc bool, modifiers *ast.ModifierList, asteriskToken *ast.Node, name *ast.Node, questionToken *ast.Node, diagnosticMessage *diagnostics.Message) *ast.Node { + signatureFlags := core.IfElse(asteriskToken != nil, ParseFlagsYield, ParseFlagsNone) | core.IfElse(modifierListHasAsync(modifiers), ParseFlagsAwait, ParseFlagsNone) + typeParameters := p.parseTypeParameters() + parameters := p.parseParameters(signatureFlags) + typeNode := p.parseReturnType(ast.KindColonToken, false /*isType*/) + body := p.parseFunctionBlockOrSemicolon(signatureFlags, diagnosticMessage) + result := p.finishNode(p.factory.NewMethodDeclaration(modifiers, asteriskToken, name, questionToken, typeParameters, parameters, typeNode, nil /*fullSignature*/, body), pos) + p.withJSDoc(result, hasJSDoc) + p.checkJSSyntax(result) + return result +} + +func modifierListHasAsync(modifiers *ast.ModifierList) bool { + return modifiers != nil && core.Some(modifiers.Nodes, isAsyncModifier) +} + +func (p *Parser) parsePropertyDeclaration(pos int, hasJSDoc bool, modifiers *ast.ModifierList, name *ast.Node, questionToken *ast.Node) *ast.Node { + postfixToken := questionToken + if postfixToken == nil && !p.hasPrecedingLineBreak() { + postfixToken = p.parseOptionalToken(ast.KindExclamationToken) + } + typeNode := p.parseTypeAnnotation() + initializer := doInContext(p, ast.NodeFlagsYieldContext|ast.NodeFlagsAwaitContext|ast.NodeFlagsDisallowInContext, false, (*Parser).parseInitializer) + p.parseSemicolonAfterPropertyName(name, typeNode, initializer) + result := p.finishNode(p.factory.NewPropertyDeclaration(modifiers, name, postfixToken, typeNode, initializer), pos) + p.withJSDoc(result, hasJSDoc) + p.checkJSSyntax(result) + return result +} + +func (p *Parser) parseSemicolonAfterPropertyName(name *ast.Node, typeNode *ast.TypeNode, initializer *ast.Expression) { + if p.token == ast.KindAtToken && !p.hasPrecedingLineBreak() { + p.parseErrorAtCurrentToken(diagnostics.Decorators_must_precede_the_name_and_all_keywords_of_property_declarations) + return + } + if p.token == ast.KindOpenParenToken { + p.parseErrorAtCurrentToken(diagnostics.Cannot_start_a_function_call_in_a_type_annotation) + p.nextToken() + return + } + if typeNode != nil && !p.canParseSemicolon() { + if initializer != nil { + p.parseErrorAtCurrentToken(diagnostics.X_0_expected, scanner.TokenToString(ast.KindSemicolonToken)) + } else { + p.parseErrorAtCurrentToken(diagnostics.Expected_for_property_initializer) + } + return + } + if p.tryParseSemicolon() { + return + } + if initializer != nil { + p.parseErrorAtCurrentToken(diagnostics.X_0_expected, scanner.TokenToString(ast.KindSemicolonToken)) + return + } + p.parseErrorForMissingSemicolonAfter(name) +} + +func (p *Parser) parseErrorForMissingSemicolonAfter(node *ast.Node) { + // Tagged template literals are sometimes used in places where only simple strings are allowed, i.e.: + // module `M1` { + // ^^^^^^^^^^^ This block is parsed as a template literal like module`M1`. + if node.Kind == ast.KindTaggedTemplateExpression { + p.parseErrorAtRange(p.skipRangeTrivia(node.AsTaggedTemplateExpression().Template.Loc), diagnostics.Module_declaration_names_may_only_use_or_quoted_strings) + return + } + // Otherwise, if this isn't a well-known keyword-like identifier, give the generic fallback message. + var expressionText string + if node.Kind == ast.KindIdentifier { + expressionText = node.AsIdentifier().Text + } + if expressionText == "" { + p.parseErrorAtCurrentToken(diagnostics.X_0_expected, scanner.TokenToString(ast.KindSemicolonToken)) + return + } + pos := scanner.SkipTrivia(p.sourceText, node.Pos()) + // Some known keywords are likely signs of syntax being used improperly. + switch expressionText { + case "const", "let", "var": + p.parseErrorAt(pos, node.End(), diagnostics.Variable_declaration_not_allowed_at_this_location) + return + case "declare": + // If a declared node failed to parse, it would have emitted a diagnostic already. + return + case "interface": + p.parseErrorForInvalidName(diagnostics.Interface_name_cannot_be_0, diagnostics.Interface_must_be_given_a_name, ast.KindOpenBraceToken) + return + case "is": + p.parseErrorAt(pos, p.scanner.TokenStart(), diagnostics.A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods) + return + case "module", "namespace": + p.parseErrorForInvalidName(diagnostics.Namespace_name_cannot_be_0, diagnostics.Namespace_must_be_given_a_name, ast.KindOpenBraceToken) + return + case "type": + p.parseErrorForInvalidName(diagnostics.Type_alias_name_cannot_be_0, diagnostics.Type_alias_must_be_given_a_name, ast.KindEqualsToken) + return + } + // The user alternatively might have misspelled or forgotten to add a space after a common keyword. + suggestion := core.GetSpellingSuggestion(expressionText, viableKeywordSuggestions, func(s string) string { return s }) + if suggestion == "" { + suggestion = getSpaceSuggestion(expressionText) + } + if suggestion != "" { + p.parseErrorAt(pos, node.End(), diagnostics.Unknown_keyword_or_identifier_Did_you_mean_0, suggestion) + return + } + // Unknown tokens are handled with their own errors in the scanner + if p.token == ast.KindUnknown { + return + } + // Otherwise, we know this some kind of unknown word, not just a missing expected semicolon. + p.parseErrorAt(pos, node.End(), diagnostics.Unexpected_keyword_or_identifier) +} + +func getSpaceSuggestion(expressionText string) string { + for _, keyword := range viableKeywordSuggestions { + if len(expressionText) > len(keyword)+2 && strings.HasPrefix(expressionText, keyword) { + return keyword + " " + expressionText[len(keyword):] + } + } + return "" +} + +func (p *Parser) parseErrorForInvalidName(nameDiagnostic *diagnostics.Message, blankDiagnostic *diagnostics.Message, tokenIfBlankName ast.Kind) { + if p.token == tokenIfBlankName { + p.parseErrorAtCurrentToken(blankDiagnostic) + } else { + p.parseErrorAtCurrentToken(nameDiagnostic, p.scanner.TokenValue()) + } +} + +func (p *Parser) parseInterfaceDeclaration(pos int, hasJSDoc bool, modifiers *ast.ModifierList) *ast.Node { + p.parseExpected(ast.KindInterfaceKeyword) + name := p.parseIdentifier() + typeParameters := p.parseTypeParameters() + heritageClauses := p.parseHeritageClauses() + members := p.parseObjectTypeMembers() + result := p.finishNode(p.factory.NewInterfaceDeclaration(modifiers, name, typeParameters, heritageClauses, members), pos) + p.withJSDoc(result, hasJSDoc) + p.checkJSSyntax(result) + return result +} + +func (p *Parser) parseTypeAliasDeclaration(pos int, hasJSDoc bool, modifiers *ast.ModifierList) *ast.Node { + p.parseExpected(ast.KindTypeKeyword) + if p.hasPrecedingLineBreak() { + p.parseErrorAtCurrentToken(diagnostics.Line_break_not_permitted_here) + } + name := p.parseIdentifier() + typeParameters := p.parseTypeParameters() + p.parseExpected(ast.KindEqualsToken) + var typeNode *ast.TypeNode + if p.token == ast.KindIntrinsicKeyword && p.lookAhead((*Parser).nextIsNotDot) { + typeNode = p.parseKeywordTypeNode() + } else { + typeNode = p.parseType() + } + p.parseSemicolon() + result := p.finishNode(p.factory.NewTypeAliasDeclaration(modifiers, name, typeParameters, typeNode), pos) + p.withJSDoc(result, hasJSDoc) + p.checkJSSyntax(result) + return result +} + +func (p *Parser) nextIsNotDot() bool { + return p.nextToken() != ast.KindDotToken +} + +// In an ambient declaration, the grammar only allows integer literals as initializers. +// In a non-ambient declaration, the grammar allows uninitialized members only in a +// ConstantEnumMemberSection, which starts at the beginning of an enum declaration +// or any time an integer literal initializer is encountered. +func (p *Parser) parseEnumMember() *ast.Node { + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + name := p.parsePropertyName() + initializer := doInContext(p, ast.NodeFlagsDisallowInContext, false, (*Parser).parseInitializer) + result := p.finishNode(p.factory.NewEnumMember(name, initializer), pos) + p.withJSDoc(result, hasJSDoc) + return result +} + +func (p *Parser) parseEnumDeclaration(pos int, hasJSDoc bool, modifiers *ast.ModifierList) *ast.Node { + saveHasAwaitIdentifier := p.statementHasAwaitIdentifier + p.parseExpected(ast.KindEnumKeyword) + name := p.parseIdentifier() + var members *ast.NodeList + if p.parseExpected(ast.KindOpenBraceToken) { + saveContextFlags := p.contextFlags + p.setContextFlags(ast.NodeFlagsYieldContext|ast.NodeFlagsAwaitContext, false) + members = p.parseDelimitedList(PCEnumMembers, (*Parser).parseEnumMember) + p.contextFlags = saveContextFlags + p.parseExpected(ast.KindCloseBraceToken) + } else { + members = p.parseEmptyNodeList() + } + result := p.finishNode(p.factory.NewEnumDeclaration(modifiers, name, members), pos) + p.withJSDoc(result, hasJSDoc) + p.checkJSSyntax(result) + p.statementHasAwaitIdentifier = saveHasAwaitIdentifier + return result +} + +func (p *Parser) parseModuleDeclaration(pos int, hasJSDoc bool, modifiers *ast.ModifierList) *ast.Statement { + keyword := ast.KindModuleKeyword + if p.token == ast.KindGlobalKeyword { + // global augmentation + return p.parseAmbientExternalModuleDeclaration(pos, hasJSDoc, modifiers) + } else if p.parseOptional(ast.KindNamespaceKeyword) { + keyword = ast.KindNamespaceKeyword + } else { + p.parseExpected(ast.KindModuleKeyword) + if p.token == ast.KindStringLiteral { + return p.parseAmbientExternalModuleDeclaration(pos, hasJSDoc, modifiers) + } + } + return p.parseModuleOrNamespaceDeclaration(pos, hasJSDoc, modifiers, false /*nested*/, keyword) +} + +func (p *Parser) parseAmbientExternalModuleDeclaration(pos int, hasJSDoc bool, modifiers *ast.ModifierList) *ast.Node { + var name *ast.Node + keyword := ast.KindModuleKeyword + saveHasAwaitIdentifier := p.statementHasAwaitIdentifier + if p.token == ast.KindGlobalKeyword { + // parse 'global' as name of global scope augmentation + name = p.parseIdentifier() + keyword = ast.KindGlobalKeyword + } else { + // parse string literal + name = p.parseLiteralExpression(true /*intern*/) + } + var body *ast.Node + if p.token == ast.KindOpenBraceToken { + body = p.parseModuleBlock() + } else { + p.parseSemicolon() + } + result := p.finishNode(p.factory.NewModuleDeclaration(modifiers, keyword, name, body), pos) + p.withJSDoc(result, hasJSDoc) + p.statementHasAwaitIdentifier = saveHasAwaitIdentifier + return result +} + +func (p *Parser) parseModuleBlock() *ast.Node { + pos := p.nodePos() + var statements *ast.NodeList + if p.parseExpected(ast.KindOpenBraceToken) { + statements = p.parseList(PCBlockStatements, (*Parser).parseStatement) + p.parseExpected(ast.KindCloseBraceToken) + } else { + statements = p.parseEmptyNodeList() + } + return p.finishNode(p.factory.NewModuleBlock(statements), pos) +} + +func (p *Parser) parseModuleOrNamespaceDeclaration(pos int, hasJSDoc bool, modifiers *ast.ModifierList, nested bool, keyword ast.Kind) *ast.Node { + saveHasAwaitIdentifier := p.statementHasAwaitIdentifier + var name *ast.Node + if nested { + name = p.parseIdentifierName() + } else { + name = p.parseIdentifier() + } + var body *ast.Node + if p.parseOptional(ast.KindDotToken) { + implicitExport := p.factory.NewModifier(ast.KindExportKeyword) + implicitExport.Loc = core.NewTextRange(p.nodePos(), p.nodePos()) + implicitExport.Flags = ast.NodeFlagsReparsed + implicitModifiers := p.newModifierList(implicitExport.Loc, p.nodeSlicePool.NewSlice1(implicitExport)) + body = p.parseModuleOrNamespaceDeclaration(p.nodePos(), false /*hasJSDoc*/, implicitModifiers, true /*nested*/, keyword) + } else { + body = p.parseModuleBlock() + } + result := p.finishNode(p.factory.NewModuleDeclaration(modifiers, keyword, name, body), pos) + p.withJSDoc(result, hasJSDoc) + p.checkJSSyntax(result) + p.statementHasAwaitIdentifier = saveHasAwaitIdentifier + return result +} + +func (p *Parser) parseImportDeclarationOrImportEqualsDeclaration(pos int, hasJSDoc bool, modifiers *ast.ModifierList) *ast.Statement { + p.parseExpected(ast.KindImportKeyword) + afterImportPos := p.nodePos() + // We don't parse the identifier here in await context, instead we will report a grammar error in the checker. + saveHasAwaitIdentifier := p.statementHasAwaitIdentifier + var identifier *ast.Node + if p.isIdentifier() { + identifier = p.parseIdentifier() + } + phaseModifier := ast.KindUnknown + if identifier != nil && identifier.AsIdentifier().Text == "type" && + (p.token != ast.KindFromKeyword || p.isIdentifier() && p.lookAhead((*Parser).nextTokenIsFromKeywordOrEqualsToken)) && + (p.isIdentifier() || p.tokenAfterImportDefinitelyProducesImportDeclaration()) { + phaseModifier = ast.KindTypeKeyword + identifier = nil + if p.isIdentifier() { + identifier = p.parseIdentifier() + } + } else if identifier != nil && identifier.AsIdentifier().Text == "defer" { + var shouldParseAsDeferModifier bool + if p.token == ast.KindFromKeyword { + shouldParseAsDeferModifier = !p.lookAhead((*Parser).nextTokenIsTokenStringLiteral) + } else { + shouldParseAsDeferModifier = p.token != ast.KindCommaToken && p.token != ast.KindEqualsToken + } + if shouldParseAsDeferModifier { + phaseModifier = ast.KindDeferKeyword + identifier = nil + if p.isIdentifier() { + identifier = p.parseIdentifier() + } + } + } + if identifier != nil && !p.tokenAfterImportedIdentifierDefinitelyProducesImportDeclaration() && phaseModifier != ast.KindDeferKeyword { + importEquals := p.checkJSSyntax(p.parseImportEqualsDeclaration(pos, hasJSDoc, modifiers, identifier, phaseModifier == ast.KindTypeKeyword)) + p.statementHasAwaitIdentifier = saveHasAwaitIdentifier // Import= declaration is always parsed in an Await context, no need to reparse + return importEquals + } + importClause := p.tryParseImportClause(identifier, afterImportPos, phaseModifier, false /*skipJSDocLeadingAsterisks*/) + p.statementHasAwaitIdentifier = saveHasAwaitIdentifier // import clause is always parsed in an Await context + moduleSpecifier := p.parseModuleSpecifier() + attributes := p.tryParseImportAttributes() + p.parseSemicolon() + result := p.finishNode(p.factory.NewImportDeclaration(modifiers, importClause, moduleSpecifier, attributes), pos) + p.withJSDoc(result, hasJSDoc) + p.checkJSSyntax(result) + return result +} + +func (p *Parser) nextTokenIsFromKeywordOrEqualsToken() bool { + p.nextToken() + return p.token == ast.KindFromKeyword || p.token == ast.KindEqualsToken +} + +func (p *Parser) tokenAfterImportDefinitelyProducesImportDeclaration() bool { + return p.token == ast.KindAsteriskToken || p.token == ast.KindOpenBraceToken +} + +func (p *Parser) tokenAfterImportedIdentifierDefinitelyProducesImportDeclaration() bool { + // In `import id ___`, the current token decides whether to produce + // an ImportDeclaration or ImportEqualsDeclaration. + return p.token == ast.KindCommaToken || p.token == ast.KindFromKeyword +} + +func (p *Parser) parseImportEqualsDeclaration(pos int, hasJSDoc bool, modifiers *ast.ModifierList, identifier *ast.Node, isTypeOnly bool) *ast.Node { + p.parseExpected(ast.KindEqualsToken) + moduleReference := p.parseModuleReference() + p.parseSemicolon() + result := p.finishNode(p.factory.NewImportEqualsDeclaration(modifiers, isTypeOnly, identifier, moduleReference), pos) + p.withJSDoc(result, hasJSDoc) + return result +} + +func (p *Parser) parseModuleReference() *ast.Node { + if p.token == ast.KindRequireKeyword && p.lookAhead((*Parser).nextTokenIsOpenParen) { + return p.parseExternalModuleReference() + } + return p.parseEntityName(false /*allowReservedWords*/, nil /*diagnosticMessage*/) +} + +func (p *Parser) parseExternalModuleReference() *ast.Node { + saveHasAwaitIdentifier := p.statementHasAwaitIdentifier + pos := p.nodePos() + p.parseExpected(ast.KindRequireKeyword) + p.parseExpected(ast.KindOpenParenToken) + expression := p.parseModuleSpecifier() + p.parseExpected(ast.KindCloseParenToken) + result := p.finishNode(p.factory.NewExternalModuleReference(expression), pos) + p.statementHasAwaitIdentifier = saveHasAwaitIdentifier + return result +} + +func (p *Parser) parseModuleSpecifier() *ast.Expression { + if p.token == ast.KindStringLiteral { + result := p.parseLiteralExpression(true /*intern*/) + return result + } + // We allow arbitrary expressions here, even though the grammar only allows string + // literals. We check to ensure that it is only a string literal later in the grammar + // check pass. + return p.parseExpression() +} + +func (p *Parser) tryParseImportClause(identifier *ast.Node, pos int, phaseModifier ast.Kind, skipJSDocLeadingAsterisks bool) *ast.Node { + // ImportDeclaration: + // import ImportClause from ModuleSpecifier ; + // import ModuleSpecifier; + if identifier != nil || p.token == ast.KindAsteriskToken || p.token == ast.KindOpenBraceToken { + importClause := p.parseImportClause(identifier, pos, phaseModifier, skipJSDocLeadingAsterisks) + p.parseExpected(ast.KindFromKeyword) + return importClause + } + return nil +} + +func (p *Parser) parseImportClause(identifier *ast.Node, pos int, phaseModifier ast.Kind, skipJSDocLeadingAsterisks bool) *ast.Node { + // ImportClause: + // ImportedDefaultBinding + // NameSpaceImport + // NamedImports + // ImportedDefaultBinding, NameSpaceImport + // ImportedDefaultBinding, NamedImports + // If there was no default import or if there is comma token after default import + // parse namespace or named imports + var namedBindings *ast.Node + saveHasAwaitIdentifier := p.statementHasAwaitIdentifier + if identifier == nil || p.parseOptional(ast.KindCommaToken) { + if skipJSDocLeadingAsterisks { + p.scanner.SetSkipJSDocLeadingAsterisks(true) + } + if p.token == ast.KindAsteriskToken { + namedBindings = p.parseNamespaceImport() + } else { + namedBindings = p.parseNamedImports() + } + if skipJSDocLeadingAsterisks { + p.scanner.SetSkipJSDocLeadingAsterisks(false) + } + } + result := p.finishNode(p.factory.NewImportClause(phaseModifier, identifier, namedBindings), pos) + p.statementHasAwaitIdentifier = saveHasAwaitIdentifier + return result +} + +func (p *Parser) parseNamespaceImport() *ast.Node { + // NameSpaceImport: + // * as ImportedBinding + pos := p.nodePos() + p.parseExpected(ast.KindAsteriskToken) + p.parseExpected(ast.KindAsKeyword) + name := p.parseIdentifier() + return p.finishNode(p.factory.NewNamespaceImport(name), pos) +} + +func (p *Parser) parseNamedImports() *ast.Node { + pos := p.nodePos() + // NamedImports: + // { } + // { ImportsList } + // { ImportsList, } + imports := p.parseBracketedList(PCImportOrExportSpecifiers, (*Parser).parseImportSpecifier, ast.KindOpenBraceToken, ast.KindCloseBraceToken) + return p.finishNode(p.factory.NewNamedImports(imports), pos) +} + +func (p *Parser) parseImportSpecifier() *ast.Node { + pos := p.nodePos() + isTypeOnly, propertyName, name := p.parseImportOrExportSpecifier(ast.KindImportSpecifier) + var identifierName *ast.Node + if name.Kind == ast.KindIdentifier { + identifierName = name + } else { + p.parseErrorAtRange(p.skipRangeTrivia(name.Loc), diagnostics.Identifier_expected) + identifierName = p.newIdentifier("") + p.finishNode(identifierName, name.Pos()) + } + result := p.checkJSSyntax(p.finishNode(p.factory.NewImportSpecifier(isTypeOnly, propertyName, identifierName), pos)) + return result +} + +func (p *Parser) parseImportOrExportSpecifier(kind ast.Kind) (isTypeOnly bool, propertyName *ast.Node, name *ast.Node) { + // ImportSpecifier: + // BindingIdentifier + // ModuleExportName as BindingIdentifier + // ExportSpecifier: + // ModuleExportName + // ModuleExportName as ModuleExportName + // let checkIdentifierIsKeyword = isKeyword(token()) && !isIdentifier(); + // let checkIdentifierStart = scanner.getTokenStart(); + // let checkIdentifierEnd = scanner.getTokenEnd(); + canParseAsKeyword := true + disallowKeywords := kind == ast.KindImportSpecifier + var nameOk bool + name, nameOk = p.parseModuleExportName(disallowKeywords) + if name.Kind == ast.KindIdentifier && name.AsIdentifier().Text == "type" { + // If the first token of an import specifier is 'type', there are a lot of possibilities, + // especially if we see 'as' afterwards: + // + // import { type } from "mod"; - isTypeOnly: false, name: type + // import { type as } from "mod"; - isTypeOnly: true, name: as + // import { type as as } from "mod"; - isTypeOnly: false, name: as, propertyName: type + // import { type as as as } from "mod"; - isTypeOnly: true, name: as, propertyName: as + if p.token == ast.KindAsKeyword { + // { type as ...? } + firstAs := p.parseIdentifierName() + if p.token == ast.KindAsKeyword { + // { type as as ...? } + secondAs := p.parseIdentifierName() + if p.canParseModuleExportName() { + // { type as as something } + // { type as as "something" } + isTypeOnly = true + propertyName = firstAs + name, nameOk = p.parseModuleExportName(disallowKeywords) + canParseAsKeyword = false + } else { + // { type as as } + propertyName = name + name = secondAs + canParseAsKeyword = false + } + } else if p.canParseModuleExportName() { + // { type as something } + // { type as "something" } + propertyName = name + canParseAsKeyword = false + name, nameOk = p.parseModuleExportName(disallowKeywords) + } else { + // { type as } + isTypeOnly = true + name = firstAs + } + } else if p.canParseModuleExportName() { + // { type something ...? } + // { type "something" ...? } + isTypeOnly = true + name, nameOk = p.parseModuleExportName(disallowKeywords) + } + } + if canParseAsKeyword && p.token == ast.KindAsKeyword { + propertyName = name + p.parseExpected(ast.KindAsKeyword) + name, nameOk = p.parseModuleExportName(disallowKeywords) + } + + if !nameOk { + p.parseErrorAtRange(p.skipRangeTrivia(name.Loc), diagnostics.Identifier_expected) + } + + return isTypeOnly, propertyName, name +} + +func (p *Parser) canParseModuleExportName() bool { + return tokenIsIdentifierOrKeyword(p.token) || p.token == ast.KindStringLiteral +} + +func (p *Parser) parseModuleExportName(disallowKeywords bool) (node *ast.Node, nameOk bool) { + nameOk = true + + if p.token == ast.KindStringLiteral { + return p.parseLiteralExpression(false /*intern*/), nameOk + } + if disallowKeywords && ast.IsKeyword(p.token) && !p.isIdentifier() { + nameOk = false + } + return p.parseIdentifierName(), nameOk +} + +func (p *Parser) tryParseImportAttributes() *ast.Node { + if (p.token == ast.KindWithKeyword || p.token == ast.KindAssertKeyword) && !p.hasPrecedingLineBreak() { + return p.parseImportAttributes(p.token, false /*skipKeyword*/) + } + return nil +} + +func (p *Parser) parseExportAssignment(pos int, hasJSDoc bool, modifiers *ast.ModifierList) *ast.Node { + saveContextFlags := p.contextFlags + saveHasAwaitIdentifier := p.statementHasAwaitIdentifier + p.setContextFlags(ast.NodeFlagsAwaitContext, true) + isExportEquals := false + if p.parseOptional(ast.KindEqualsToken) { + isExportEquals = true + } else { + p.parseExpected(ast.KindDefaultKeyword) + } + expression := p.parseAssignmentExpressionOrHigher() + p.parseSemicolon() + p.contextFlags = saveContextFlags + p.statementHasAwaitIdentifier = saveHasAwaitIdentifier + result := p.finishNode(p.factory.NewExportAssignment(modifiers, isExportEquals, nil /*typeNode*/, expression), pos) + p.withJSDoc(result, hasJSDoc) + p.checkJSSyntax(result) + return result +} + +func (p *Parser) parseNamespaceExportDeclaration(pos int, hasJSDoc bool, modifiers *ast.ModifierList) *ast.Node { + p.parseExpected(ast.KindAsKeyword) + p.parseExpected(ast.KindNamespaceKeyword) + saveHasAwaitIdentifier := p.statementHasAwaitIdentifier + name := p.parseIdentifier() + p.statementHasAwaitIdentifier = saveHasAwaitIdentifier + p.parseSemicolon() + // NamespaceExportDeclaration nodes cannot have decorators or modifiers, we attach them here so we can report them in the grammar checker + result := p.finishNode(p.factory.NewNamespaceExportDeclaration(modifiers, name), pos) + p.withJSDoc(result, hasJSDoc) + return result +} + +func (p *Parser) parseExportDeclaration(pos int, hasJSDoc bool, modifiers *ast.ModifierList) *ast.Node { + saveContextFlags := p.contextFlags + saveHasAwaitIdentifier := p.statementHasAwaitIdentifier + p.setContextFlags(ast.NodeFlagsAwaitContext, true) + var exportClause *ast.Node + var moduleSpecifier *ast.Expression + var attributes *ast.Node + isTypeOnly := p.parseOptional(ast.KindTypeKeyword) + namespaceExportPos := p.nodePos() + if p.parseOptional(ast.KindAsteriskToken) { + if p.parseOptional(ast.KindAsKeyword) { + exportClause = p.parseNamespaceExport(namespaceExportPos) + } + p.parseExpected(ast.KindFromKeyword) + moduleSpecifier = p.parseModuleSpecifier() + } else { + exportClause = p.parseNamedExports() + // It is not uncommon to accidentally omit the 'from' keyword. Additionally, in editing scenarios, + // the 'from' keyword can be parsed as a named export when the export clause is unterminated (i.e. `export { from "moduleName";`) + // If we don't have a 'from' keyword, see if we have a string literal such that ASI won't take effect. + if p.token == ast.KindFromKeyword || (p.token == ast.KindStringLiteral && !p.hasPrecedingLineBreak()) { + p.parseExpected(ast.KindFromKeyword) + moduleSpecifier = p.parseModuleSpecifier() + } + } + if moduleSpecifier != nil && (p.token == ast.KindWithKeyword || p.token == ast.KindAssertKeyword) && !p.hasPrecedingLineBreak() { + attributes = p.parseImportAttributes(p.token, false /*skipKeyword*/) + } + p.parseSemicolon() + p.contextFlags = saveContextFlags + p.statementHasAwaitIdentifier = saveHasAwaitIdentifier + result := p.finishNode(p.factory.NewExportDeclaration(modifiers, isTypeOnly, exportClause, moduleSpecifier, attributes), pos) + p.withJSDoc(result, hasJSDoc) + p.checkJSSyntax(result) + return result +} + +func (p *Parser) parseNamespaceExport(pos int) *ast.Node { + exportName, _ := p.parseModuleExportName(false /*disallowKeywords*/) + return p.finishNode(p.factory.NewNamespaceExport(exportName), pos) +} + +func (p *Parser) parseNamedExports() *ast.Node { + pos := p.nodePos() + // NamedImports: + // { } + // { ImportsList } + // { ImportsList, } + exports := p.parseBracketedList(PCImportOrExportSpecifiers, (*Parser).parseExportSpecifier, ast.KindOpenBraceToken, ast.KindCloseBraceToken) + return p.finishNode(p.factory.NewNamedExports(exports), pos) +} + +func (p *Parser) parseExportSpecifier() *ast.Node { + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + isTypeOnly, propertyName, name := p.parseImportOrExportSpecifier(ast.KindExportSpecifier) + result := p.finishNode(p.factory.NewExportSpecifier(isTypeOnly, propertyName, name), pos) + p.withJSDoc(result, hasJSDoc) + p.checkJSSyntax(result) + return result +} + +// TYPES + +func (p *Parser) parseType() *ast.TypeNode { + saveContextFlags := p.contextFlags + p.setContextFlags(ast.NodeFlagsTypeExcludesFlags, false) + var typeNode *ast.TypeNode + if p.isStartOfFunctionTypeOrConstructorType() { + typeNode = p.parseFunctionOrConstructorType() + } else { + pos := p.nodePos() + typeNode = p.parseUnionTypeOrHigher() + if !p.inDisallowConditionalTypesContext() && !p.hasPrecedingLineBreak() && p.parseOptional(ast.KindExtendsKeyword) { + // The type following 'extends' is not permitted to be another conditional type + extendsType := doInContext(p, ast.NodeFlagsDisallowConditionalTypesContext, true, (*Parser).parseType) + p.parseExpected(ast.KindQuestionToken) + trueType := doInContext(p, ast.NodeFlagsDisallowConditionalTypesContext, false, (*Parser).parseType) + p.parseExpected(ast.KindColonToken) + falseType := doInContext(p, ast.NodeFlagsDisallowConditionalTypesContext, false, (*Parser).parseType) + conditionalType := p.factory.NewConditionalTypeNode(typeNode, extendsType, trueType, falseType) + p.finishNode(conditionalType, pos) + typeNode = conditionalType + } + } + p.contextFlags = saveContextFlags + return typeNode +} + +func (p *Parser) parseUnionTypeOrHigher() *ast.TypeNode { + return p.parseUnionOrIntersectionType(ast.KindBarToken, (*Parser).parseIntersectionTypeOrHigher) +} + +func (p *Parser) parseIntersectionTypeOrHigher() *ast.TypeNode { + return p.parseUnionOrIntersectionType(ast.KindAmpersandToken, (*Parser).parseTypeOperatorOrHigher) +} + +func (p *Parser) parseUnionOrIntersectionType(operator ast.Kind, parseConstituentType func(p *Parser) *ast.TypeNode) *ast.TypeNode { + pos := p.nodePos() + isUnionType := operator == ast.KindBarToken + hasLeadingOperator := p.parseOptional(operator) + var typeNode *ast.TypeNode + if hasLeadingOperator { + typeNode = p.parseFunctionOrConstructorTypeToError(isUnionType, parseConstituentType) + } else { + typeNode = parseConstituentType(p) + } + if p.token == operator || hasLeadingOperator { + types := make([]*ast.Node, 1, 8) + types[0] = typeNode + for p.parseOptional(operator) { + types = append(types, p.parseFunctionOrConstructorTypeToError(isUnionType, parseConstituentType)) + } + typeNode = p.createUnionOrIntersectionTypeNode(operator, p.newNodeList(core.NewTextRange(pos, p.nodePos()), p.nodeSlicePool.Clone(types))) + p.finishNode(typeNode, pos) + } + return typeNode +} + +func (p *Parser) createUnionOrIntersectionTypeNode(operator ast.Kind, types *ast.NodeList) *ast.Node { + switch operator { + case ast.KindBarToken: + return p.factory.NewUnionTypeNode(types) + case ast.KindAmpersandToken: + return p.factory.NewIntersectionTypeNode(types) + default: + panic("Unhandled case in createUnionOrIntersectionType") + } +} + +func (p *Parser) parseTypeOperatorOrHigher() *ast.TypeNode { + operator := p.token + switch operator { + case ast.KindKeyOfKeyword, ast.KindUniqueKeyword, ast.KindReadonlyKeyword: + return p.parseTypeOperator(operator) + case ast.KindInferKeyword: + return p.parseInferType() + } + return doInContext(p, ast.NodeFlagsDisallowConditionalTypesContext, false, (*Parser).parsePostfixTypeOrHigher) +} + +func (p *Parser) parseTypeOperator(operator ast.Kind) *ast.Node { + pos := p.nodePos() + p.parseExpected(operator) + return p.finishNode(p.factory.NewTypeOperatorNode(operator, p.parseTypeOperatorOrHigher()), pos) +} + +func (p *Parser) parseInferType() *ast.Node { + pos := p.nodePos() + p.parseExpected(ast.KindInferKeyword) + return p.finishNode(p.factory.NewInferTypeNode(p.parseTypeParameterOfInferType()), pos) +} + +func (p *Parser) parseTypeParameterOfInferType() *ast.Node { + pos := p.nodePos() + name := p.parseIdentifier() + constraint := p.tryParseConstraintOfInferType() + return p.finishNode(p.factory.NewTypeParameterDeclaration(nil /*modifiers*/, name, constraint, nil /*defaultType*/), pos) +} + +func (p *Parser) tryParseConstraintOfInferType() *ast.Node { + state := p.mark() + if p.parseOptional(ast.KindExtendsKeyword) { + constraint := doInContext(p, ast.NodeFlagsDisallowConditionalTypesContext, true, (*Parser).parseType) + if p.inDisallowConditionalTypesContext() || p.token != ast.KindQuestionToken { + return constraint + } + } + p.rewind(state) + return nil +} + +func (p *Parser) parsePostfixTypeOrHigher() *ast.Node { + pos := p.nodePos() + typeNode := p.parseNonArrayType() + for !p.hasPrecedingLineBreak() { + switch p.token { + case ast.KindExclamationToken: + p.nextToken() + typeNode = p.finishNode(p.factory.NewJSDocNonNullableType(typeNode), pos) + case ast.KindQuestionToken: + // If next token is start of a type we have a conditional type + if p.lookAhead((*Parser).nextIsStartOfType) { + return typeNode + } + p.nextToken() + typeNode = p.finishNode(p.factory.NewJSDocNullableType(typeNode), pos) + case ast.KindOpenBracketToken: + p.parseExpected(ast.KindOpenBracketToken) + if p.isStartOfType(false /*isStartOfParameter*/) { + indexType := p.parseType() + p.parseExpected(ast.KindCloseBracketToken) + typeNode = p.finishNode(p.factory.NewIndexedAccessTypeNode(typeNode, indexType), pos) + } else { + p.parseExpected(ast.KindCloseBracketToken) + typeNode = p.finishNode(p.factory.NewArrayTypeNode(typeNode), pos) + } + default: + return typeNode + } + } + return typeNode +} + +func (p *Parser) nextIsStartOfType() bool { + p.nextToken() + return p.isStartOfType(false /*inStartOfParameter*/) +} + +func (p *Parser) parseNonArrayType() *ast.Node { + switch p.token { + case ast.KindAnyKeyword, ast.KindUnknownKeyword, ast.KindStringKeyword, ast.KindNumberKeyword, ast.KindBigIntKeyword, + ast.KindSymbolKeyword, ast.KindBooleanKeyword, ast.KindUndefinedKeyword, ast.KindNeverKeyword, ast.KindObjectKeyword: + state := p.mark() + keywordTypeNode := p.parseKeywordTypeNode() + // If these are followed by a dot then parse these out as a dotted type reference instead + if p.token != ast.KindDotToken { + return keywordTypeNode + } + p.rewind(state) + return p.parseTypeReference() + case ast.KindAsteriskEqualsToken: + // If there is '*=', treat it as * followed by postfix = + p.scanner.ReScanAsteriskEqualsToken() + fallthrough + case ast.KindAsteriskToken: + return p.parseJSDocAllType() + case ast.KindQuestionQuestionToken: + // If there is '??', treat it as prefix-'?' in JSDoc type. + p.scanner.ReScanQuestionToken() + fallthrough + case ast.KindQuestionToken: + return p.parseJSDocNullableType() + case ast.KindExclamationToken: + return p.parseJSDocNonNullableType() + case ast.KindNoSubstitutionTemplateLiteral, ast.KindStringLiteral, ast.KindNumericLiteral, ast.KindBigIntLiteral, ast.KindTrueKeyword, + ast.KindFalseKeyword, ast.KindNullKeyword: + return p.parseLiteralTypeNode(false /*negative*/) + case ast.KindMinusToken: + if p.lookAhead((*Parser).nextTokenIsNumericOrBigIntLiteral) { + return p.parseLiteralTypeNode(true /*negative*/) + } + return p.parseTypeReference() + case ast.KindVoidKeyword: + return p.parseKeywordTypeNode() + case ast.KindThisKeyword: + thisKeyword := p.parseThisTypeNode() + if p.token == ast.KindIsKeyword && !p.hasPrecedingLineBreak() { + return p.parseThisTypePredicate(thisKeyword) + } + return thisKeyword + case ast.KindTypeOfKeyword: + if p.lookAhead((*Parser).nextIsStartOfTypeOfImportType) { + return p.parseImportType() + } + return p.parseTypeQuery() + case ast.KindOpenBraceToken: + if p.lookAhead((*Parser).nextIsStartOfMappedType) { + return p.parseMappedType() + } + return p.parseTypeLiteral() + case ast.KindOpenBracketToken: + return p.parseTupleType() + case ast.KindOpenParenToken: + return p.parseParenthesizedType() + case ast.KindImportKeyword: + return p.parseImportType() + case ast.KindAssertsKeyword: + if p.lookAhead((*Parser).nextTokenIsIdentifierOrKeywordOnSameLine) { + return p.parseAssertsTypePredicate() + } + return p.parseTypeReference() + case ast.KindTemplateHead: + return p.parseTemplateType() + default: + return p.parseTypeReference() + } +} + +func (p *Parser) parseKeywordTypeNode() *ast.Node { + pos := p.nodePos() + result := p.factory.NewKeywordTypeNode(p.token) + p.nextToken() + return p.finishNode(result, pos) +} + +func (p *Parser) parseThisTypeNode() *ast.Node { + pos := p.nodePos() + p.nextToken() + return p.finishNode(p.factory.NewThisTypeNode(), pos) +} + +func (p *Parser) parseThisTypePredicate(lhs *ast.Node) *ast.Node { + p.nextToken() + return p.finishNode(p.factory.NewTypePredicateNode(nil /*assertsModifier*/, lhs, p.parseType()), lhs.Pos()) +} + +func (p *Parser) parseJSDocAllType() *ast.Node { + pos := p.nodePos() + p.nextToken() + return p.finishNode(p.factory.NewJSDocAllType(), pos) +} + +func (p *Parser) parseJSDocNonNullableType() *ast.TypeNode { + pos := p.nodePos() + p.nextToken() + return p.finishNode(p.factory.NewJSDocNonNullableType(p.parseNonArrayType()), pos) +} + +func (p *Parser) parseJSDocNullableType() *ast.Node { + pos := p.nodePos() + // skip the ? + p.nextToken() + return p.finishNode(p.factory.NewJSDocNullableType(p.parseType()), pos) +} + +func (p *Parser) parseJSDocType() *ast.TypeNode { + p.scanner.SetSkipJSDocLeadingAsterisks(true) + pos := p.nodePos() + + hasDotDotDot := p.parseOptional(ast.KindDotDotDotToken) + t := p.parseTypeOrTypePredicate() + p.scanner.SetSkipJSDocLeadingAsterisks(false) + if hasDotDotDot { + t = p.finishNode(p.factory.NewJSDocVariadicType(t), pos) + } + if p.token == ast.KindEqualsToken { + p.nextToken() + return p.finishNode(p.factory.NewJSDocOptionalType(t), pos) + } + return t +} + +func (p *Parser) parseLiteralTypeNode(negative bool) *ast.Node { + pos := p.nodePos() + if negative { + p.nextToken() + } + var expression *ast.Expression + if p.token == ast.KindTrueKeyword || p.token == ast.KindFalseKeyword || p.token == ast.KindNullKeyword { + expression = p.parseKeywordExpression() + } else { + expression = p.parseLiteralExpression(false /*intern*/) + } + if negative { + expression = p.finishNode(p.factory.NewPrefixUnaryExpression(ast.KindMinusToken, expression), pos) + } + return p.finishNode(p.factory.NewLiteralTypeNode(expression), pos) +} + +func (p *Parser) parseTypeReference() *ast.Node { + pos := p.nodePos() + return p.finishNode(p.factory.NewTypeReferenceNode(p.parseEntityNameOfTypeReference(), p.parseTypeArgumentsOfTypeReference()), pos) +} + +func (p *Parser) parseEntityNameOfTypeReference() *ast.Node { + return p.parseEntityName(true /*allowReservedWords*/, diagnostics.Type_expected) +} + +func (p *Parser) parseEntityName(allowReservedWords bool, diagnosticMessage *diagnostics.Message) *ast.Node { + pos := p.nodePos() + var entity *ast.Node + if allowReservedWords { + entity = p.parseIdentifierNameWithDiagnostic(diagnosticMessage) + } else { + entity = p.parseIdentifierWithDiagnostic(diagnosticMessage, nil) + } + for p.parseOptional(ast.KindDotToken) { + if p.token == ast.KindLessThanToken { + // The entity is part of a JSDoc-style generic. We will use the gap between `typeName` and + // `typeArguments` to report it as a grammar error in the checker. + break + } + entity = p.finishNode(p.factory.NewQualifiedName(entity, p.parseRightSideOfDot(allowReservedWords, false /*allowPrivateIdentifiers*/, true /*allowUnicodeEscapeSequenceInIdentifierName*/)), pos) + } + return entity +} + +func (p *Parser) parseRightSideOfDot(allowIdentifierNames bool, allowPrivateIdentifiers bool, allowUnicodeEscapeSequenceInIdentifierName bool) *ast.Node { + // Technically a keyword is valid here as all identifiers and keywords are identifier names. + // However, often we'll encounter this in error situations when the identifier or keyword + // is actually starting another valid construct. + // + // So, we check for the following specific case: + // + // name. + // identifierOrKeyword identifierNameOrKeyword + // + // Note: the newlines are important here. For example, if that above code + // were rewritten into: + // + // name.identifierOrKeyword + // identifierNameOrKeyword + // + // Then we would consider it valid. That's because ASI would take effect and + // the code would be implicitly: "name.identifierOrKeyword; identifierNameOrKeyword". + // In the first case though, ASI will not take effect because there is not a + // line terminator after the identifier or keyword. + if p.hasPrecedingLineBreak() && tokenIsIdentifierOrKeyword(p.token) && p.lookAhead((*Parser).nextTokenIsIdentifierOrKeywordOnSameLine) { + // Report that we need an identifier. However, report it right after the dot, + // and not on the next token. This is because the next token might actually + // be an identifier and the error would be quite confusing. + p.parseErrorAt(p.nodePos(), p.nodePos(), diagnostics.Identifier_expected) + return p.createMissingIdentifier() + } + if p.token == ast.KindPrivateIdentifier { + node := p.parsePrivateIdentifier() + if allowPrivateIdentifiers { + return node + } + p.parseErrorAt(p.nodePos(), p.nodePos(), diagnostics.Identifier_expected) + return p.createMissingIdentifier() + } + if allowIdentifierNames { + if allowUnicodeEscapeSequenceInIdentifierName { + return p.parseIdentifierName() + } + return p.parseIdentifierNameErrorOnUnicodeEscapeSequence() + } + saveHasAwaitIdentifier := p.statementHasAwaitIdentifier + id := p.parseIdentifier() + p.statementHasAwaitIdentifier = saveHasAwaitIdentifier + return id +} + +func (p *Parser) newIdentifier(text string) *ast.Node { + p.identifierCount++ + id := p.factory.NewIdentifier(text) + if text == "await" { + p.statementHasAwaitIdentifier = true + } + return id +} + +func (p *Parser) createMissingIdentifier() *ast.Node { + return p.finishNode(p.newIdentifier(""), p.nodePos()) +} + +func (p *Parser) parsePrivateIdentifier() *ast.Node { + pos := p.nodePos() + text := p.scanner.TokenValue() + p.nextToken() + return p.finishNode(p.factory.NewPrivateIdentifier(p.internIdentifier(text)), pos) +} + +func (p *Parser) reScanLessThanToken() ast.Kind { + p.token = p.scanner.ReScanLessThanToken() + return p.token +} + +func (p *Parser) reScanGreaterThanToken() ast.Kind { + p.token = p.scanner.ReScanGreaterThanToken() + return p.token +} + +func (p *Parser) reScanSlashToken() ast.Kind { + p.token = p.scanner.ReScanSlashToken() + return p.token +} + +func (p *Parser) reScanTemplateToken(isTaggedTemplate bool) ast.Kind { + p.token = p.scanner.ReScanTemplateToken(isTaggedTemplate) + return p.token +} + +func (p *Parser) parseTypeArgumentsOfTypeReference() *ast.NodeList { + if !p.hasPrecedingLineBreak() && p.reScanLessThanToken() == ast.KindLessThanToken { + return p.parseTypeArguments() + } + return nil +} + +func (p *Parser) parseTypeArguments() *ast.NodeList { + if p.token == ast.KindLessThanToken { + return p.parseBracketedList(PCTypeArguments, (*Parser).parseType, ast.KindLessThanToken, ast.KindGreaterThanToken) + } + return nil +} + +func (p *Parser) nextIsStartOfTypeOfImportType() bool { + p.nextToken() + return p.token == ast.KindImportKeyword +} + +func (p *Parser) parseImportType() *ast.Node { + p.sourceFlags |= ast.NodeFlagsPossiblyContainsDynamicImport + pos := p.nodePos() + isTypeOf := p.parseOptional(ast.KindTypeOfKeyword) + p.parseExpected(ast.KindImportKeyword) + p.parseExpected(ast.KindOpenParenToken) + typeNode := p.parseType() + var attributes *ast.Node + if p.parseOptional(ast.KindCommaToken) { + openBracePosition := p.scanner.TokenStart() + p.parseExpected(ast.KindOpenBraceToken) + currentToken := p.token + if currentToken == ast.KindWithKeyword || currentToken == ast.KindAssertKeyword { + p.nextToken() + } else { + p.parseErrorAtCurrentToken(diagnostics.X_0_expected, scanner.TokenToString(ast.KindWithKeyword)) + } + p.parseExpected(ast.KindColonToken) + attributes = p.parseImportAttributes(currentToken, true /*skipKeyword*/) + p.parseOptional(ast.KindCommaToken) + if !p.parseExpected(ast.KindCloseBraceToken) { + if len(p.diagnostics) != 0 { + lastDiagnostic := p.diagnostics[len(p.diagnostics)-1] + if lastDiagnostic.Code() == diagnostics.X_0_expected.Code() { + related := ast.NewDiagnostic(nil, core.NewTextRange(openBracePosition, openBracePosition+1), diagnostics.The_parser_expected_to_find_a_1_to_match_the_0_token_here, "{", "}") + lastDiagnostic.AddRelatedInfo(related) + } + } + } + } + p.parseExpected(ast.KindCloseParenToken) + var qualifier *ast.Node + if p.parseOptional(ast.KindDotToken) { + qualifier = p.parseEntityNameOfTypeReference() + } + typeArguments := p.parseTypeArgumentsOfTypeReference() + return p.finishNode(p.factory.NewImportTypeNode(isTypeOf, typeNode, attributes, qualifier, typeArguments), pos) +} + +func (p *Parser) parseImportAttribute() *ast.Node { + pos := p.nodePos() + var name *ast.Node + if tokenIsIdentifierOrKeyword(p.token) { + name = p.parseIdentifierName() + } else if p.token == ast.KindStringLiteral { + name = p.parseLiteralExpression(false /*intern*/) + } + if name != nil { + p.parseExpected(ast.KindColonToken) + } else { + p.parseErrorAtCurrentToken(diagnostics.Identifier_or_string_literal_expected) + } + value := p.parseAssignmentExpressionOrHigher() + return p.finishNode(p.factory.NewImportAttribute(name, value), pos) +} + +func (p *Parser) parseImportAttributes(token ast.Kind, skipKeyword bool) *ast.Node { + pos := p.nodePos() + if !skipKeyword { + p.parseExpected(token) + } + var elements *ast.NodeList + var multiLine bool + openBracePosition := p.scanner.TokenStart() + if p.parseExpected(ast.KindOpenBraceToken) { + multiLine = p.hasPrecedingLineBreak() + elements = p.parseDelimitedList(PCImportAttributes, (*Parser).parseImportAttribute) + if !p.parseExpected(ast.KindCloseBraceToken) { + if len(p.diagnostics) != 0 { + lastDiagnostic := p.diagnostics[len(p.diagnostics)-1] + if lastDiagnostic.Code() == diagnostics.X_0_expected.Code() { + related := ast.NewDiagnostic(nil, core.NewTextRange(openBracePosition, openBracePosition+1), diagnostics.The_parser_expected_to_find_a_1_to_match_the_0_token_here, "{", "}") + lastDiagnostic.AddRelatedInfo(related) + } + } + } + } else { + elements = p.parseEmptyNodeList() + } + return p.finishNode(p.factory.NewImportAttributes(token, elements, multiLine), pos) +} + +func (p *Parser) parseTypeQuery() *ast.Node { + pos := p.nodePos() + p.parseExpected(ast.KindTypeOfKeyword) + entityName := p.parseEntityName(true /*allowReservedWords*/, nil) + // Make sure we perform ASI to prevent parsing the next line's type arguments as part of an instantiation expression + var typeArguments *ast.NodeList + if !p.hasPrecedingLineBreak() { + typeArguments = p.parseTypeArguments() + } + return p.finishNode(p.factory.NewTypeQueryNode(entityName, typeArguments), pos) +} + +func (p *Parser) nextIsStartOfMappedType() bool { + p.nextToken() + if p.token == ast.KindPlusToken || p.token == ast.KindMinusToken { + return p.nextToken() == ast.KindReadonlyKeyword + } + if p.token == ast.KindReadonlyKeyword { + p.nextToken() + } + return p.token == ast.KindOpenBracketToken && p.nextTokenIsIdentifier() && p.nextToken() == ast.KindInKeyword +} + +func (p *Parser) parseMappedType() *ast.Node { + pos := p.nodePos() + p.parseExpected(ast.KindOpenBraceToken) + var readonlyToken *ast.Node // ReadonlyKeyword | PlusToken | MinusToken + if p.token == ast.KindReadonlyKeyword || p.token == ast.KindPlusToken || p.token == ast.KindMinusToken { + readonlyToken = p.parseTokenNode() + if readonlyToken.Kind != ast.KindReadonlyKeyword { + p.parseExpected(ast.KindReadonlyKeyword) + } + } + p.parseExpected(ast.KindOpenBracketToken) + typeParameter := p.parseMappedTypeParameter() + var nameType *ast.TypeNode + if p.parseOptional(ast.KindAsKeyword) { + nameType = p.parseType() + } + p.parseExpected(ast.KindCloseBracketToken) + var questionToken *ast.Node // QuestionToken | PlusToken | MinusToken + if p.token == ast.KindQuestionToken || p.token == ast.KindPlusToken || p.token == ast.KindMinusToken { + questionToken = p.parseTokenNode() + if questionToken.Kind != ast.KindQuestionToken { + p.parseExpected(ast.KindQuestionToken) + } + } + typeNode := p.parseTypeAnnotation() + p.parseSemicolon() + members := p.parseList(PCTypeMembers, (*Parser).parseTypeMember) + p.parseExpected(ast.KindCloseBraceToken) + return p.finishNode(p.factory.NewMappedTypeNode(readonlyToken, typeParameter, nameType, questionToken, typeNode, members), pos) +} + +func (p *Parser) parseMappedTypeParameter() *ast.Node { + pos := p.nodePos() + name := p.parseIdentifierName() + p.parseExpected(ast.KindInKeyword) + typeNode := p.parseType() + return p.finishNode(p.factory.NewTypeParameterDeclaration(nil /*modifiers*/, name, typeNode, nil /*defaultType*/), pos) +} + +func (p *Parser) parseTypeMember() *ast.Node { + if p.token == ast.KindOpenParenToken || p.token == ast.KindLessThanToken { + return p.parseSignatureMember(ast.KindCallSignature) + } + if p.token == ast.KindNewKeyword && p.lookAhead((*Parser).nextTokenIsOpenParenOrLessThan) { + return p.parseSignatureMember(ast.KindConstructSignature) + } + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + modifiers := p.parseModifiers() + if p.parseContextualModifier(ast.KindGetKeyword) { + return p.parseAccessorDeclaration(pos, hasJSDoc, modifiers, ast.KindGetAccessor, ParseFlagsType) + } + if p.parseContextualModifier(ast.KindSetKeyword) { + return p.parseAccessorDeclaration(pos, hasJSDoc, modifiers, ast.KindSetAccessor, ParseFlagsType) + } + if p.isIndexSignature() { + return p.parseIndexSignatureDeclaration(pos, hasJSDoc, modifiers) + } + return p.parsePropertyOrMethodSignature(pos, hasJSDoc, modifiers) +} + +func (p *Parser) nextTokenIsOpenParenOrLessThan() bool { + p.nextToken() + return p.token == ast.KindOpenParenToken || p.token == ast.KindLessThanToken +} + +func (p *Parser) parseSignatureMember(kind ast.Kind) *ast.Node { + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + if kind == ast.KindConstructSignature { + p.parseExpected(ast.KindNewKeyword) + } + typeParameters := p.parseTypeParameters() + parameters := p.parseParameters(ParseFlagsType) + typeNode := p.parseReturnType(ast.KindColonToken /*isType*/, true) + p.parseTypeMemberSemicolon() + var result *ast.Node + if kind == ast.KindCallSignature { + result = p.factory.NewCallSignatureDeclaration(typeParameters, parameters, typeNode) + } else { + result = p.factory.NewConstructSignatureDeclaration(typeParameters, parameters, typeNode) + } + p.finishNode(result, pos) + p.withJSDoc(result, hasJSDoc) + return result +} + +func (p *Parser) parseTypeParameters() *ast.NodeList { + if p.token == ast.KindLessThanToken { + return p.parseBracketedList(PCTypeParameters, (*Parser).parseTypeParameter, ast.KindLessThanToken, ast.KindGreaterThanToken) + } + return nil +} + +func (p *Parser) parseTypeParameter() *ast.Node { + pos := p.nodePos() + modifiers := p.parseModifiersEx(false /*allowDecorators*/, true /*permitConstAsModifier*/, false /*stopOnStartOfClassStaticBlock*/) + name := p.parseIdentifier() + var constraint *ast.TypeNode + var expression *ast.Expression + if p.parseOptional(ast.KindExtendsKeyword) { + // It's not uncommon for people to write improper constraints to a generic. If the + // user writes a constraint that is an expression and not an actual type, then parse + // it out as an expression (so we can recover well), but report that a type is needed + // instead. + if p.isStartOfType(false /*inStartOfParameter*/) || !p.isStartOfExpression() { + constraint = p.parseType() + } else { + // It was not a type, and it looked like an expression. Parse out an expression + // here so we recover well. Note: it is important that we call parseUnaryExpression + // and not parseExpression here. If the user has: + // + // + // + // We do *not* want to consume the `>` as we're consuming the expression for "". + expression = p.parseUnaryExpressionOrHigher() + } + } + var defaultType *ast.TypeNode + if p.parseOptional(ast.KindEqualsToken) { + defaultType = p.parseType() + } + result := p.finishNode(p.factory.NewTypeParameterDeclaration(modifiers, name, constraint, defaultType), pos) + result.AsTypeParameter().Expression = expression + return result +} + +func (p *Parser) parseParameters(flags ParseFlags) *ast.NodeList { + // FormalParameters [Yield,Await]: (modified) + // [empty] + // FormalParameterList[?Yield,Await] + // + // FormalParameter[Yield,Await]: (modified) + // BindingElement[?Yield,Await] + // + // BindingElement [Yield,Await]: (modified) + // SingleNameBinding[?Yield,?Await] + // BindingPattern[?Yield,?Await]Initializer [In, ?Yield,?Await] opt + // + // SingleNameBinding [Yield,Await]: + // BindingIdentifier[?Yield,?Await]Initializer [In, ?Yield,?Await] opt + if p.parseExpected(ast.KindOpenParenToken) { + parameters := p.parseParametersWorker(flags, true /*allowAmbiguity*/) + p.parseExpected(ast.KindCloseParenToken) + return parameters + } + return p.parseEmptyNodeList() +} + +func (p *Parser) parseParametersWorker(flags ParseFlags, allowAmbiguity bool) *ast.NodeList { + // FormalParameters [Yield,Await]: (modified) + // [empty] + // FormalParameterList[?Yield,Await] + // + // FormalParameter[Yield,Await]: (modified) + // BindingElement[?Yield,Await] + // + // BindingElement [Yield,Await]: (modified) + // SingleNameBinding[?Yield,?Await] + // BindingPattern[?Yield,?Await]Initializer [In, ?Yield,?Await] opt + // + // SingleNameBinding [Yield,Await]: + // BindingIdentifier[?Yield,?Await]Initializer [In, ?Yield,?Await] opt + inAwaitContext := p.contextFlags&ast.NodeFlagsAwaitContext != 0 + saveContextFlags := p.contextFlags + p.setContextFlags(ast.NodeFlagsYieldContext, flags&ParseFlagsYield != 0) + p.setContextFlags(ast.NodeFlagsAwaitContext, flags&ParseFlagsAwait != 0) + parameters := p.parseDelimitedList(PCParameters, func(p *Parser) *ast.Node { + parameter := p.parseParameterEx(inAwaitContext, allowAmbiguity) + if parameter != nil && flags&ParseFlagsType == 0 { + p.checkJSSyntax(parameter) + } + return parameter + }) + p.contextFlags = saveContextFlags + return parameters +} + +func (p *Parser) parseParameter() *ast.Node { + return p.parseParameterEx(false /*inOuterAwaitContext*/, true /*allowAmbiguity*/) +} + +func (p *Parser) parseParameterEx(inOuterAwaitContext bool, allowAmbiguity bool) *ast.Node { + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + // FormalParameter [Yield,Await]: + // BindingElement[?Yield,?Await] + // Decorators are parsed in the outer [Await] context, the rest of the parameter is parsed in the function's [Await] context. + saveContextFlags := p.contextFlags + p.setContextFlags(ast.NodeFlagsAwaitContext, inOuterAwaitContext) + modifiers := p.parseModifiersEx(true /*allowDecorators*/, false /*permitConstAsModifier*/, false /*stopOnStartOfClassStaticBlock*/) + p.contextFlags = saveContextFlags + if p.token == ast.KindThisKeyword { + result := p.factory.NewParameterDeclaration( + modifiers, + nil, /*dotDotDotToken*/ + p.createIdentifier(true /*isIdentifier*/), + nil, /*questionToken*/ + p.parseTypeAnnotation(), + nil /*initializer*/) + if modifiers != nil { + p.parseErrorAtRange(modifiers.Nodes[0].Loc, diagnostics.Neither_decorators_nor_modifiers_may_be_applied_to_this_parameters) + } + p.withJSDoc(p.finishNode(result, pos), hasJSDoc) + return result + } + dotDotDotToken := p.parseOptionalToken(ast.KindDotDotDotToken) + if !allowAmbiguity && !p.isParameterNameStart() { + return nil + } + result := p.factory.NewParameterDeclaration( + modifiers, + dotDotDotToken, + p.parseNameOfParameter(modifiers), + p.parseOptionalToken(ast.KindQuestionToken), + p.parseTypeAnnotation(), + p.parseInitializer()) + p.withJSDoc(p.finishNode(result, pos), hasJSDoc) + return result +} + +func (p *Parser) isParameterNameStart() bool { + // Be permissive about await and yield by calling isBindingIdentifier instead of isIdentifier; disallowing + // them during a speculative parse leads to many more follow-on errors than allowing the function to parse then later + // complaining about the use of the keywords. + return p.isBindingIdentifier() || p.token == ast.KindOpenBracketToken || p.token == ast.KindOpenBraceToken +} + +func (p *Parser) parseNameOfParameter(modifiers *ast.ModifierList) *ast.Node { + // FormalParameter [Yield,Await]: + // BindingElement[?Yield,?Await] + name := p.parseIdentifierOrPatternWithDiagnostic(diagnostics.Private_identifiers_cannot_be_used_as_parameters) + if name.Loc.Len() == 0 && modifiers == nil && ast.IsModifierKind(p.token) { + // in cases like + // 'use strict' + // function foo(static) + // isParameter('static') == true, because of isModifier('static') + // however 'static' is not a legal identifier in a strict mode. + // so result of this function will be ParameterDeclaration (flags = 0, name = missing, type = undefined, initializer = undefined) + // and current token will not change => parsing of the enclosing parameter list will last till the end of time (or OOM) + // to avoid this we'll advance cursor to the next token. + p.nextToken() + } + return name +} + +func (p *Parser) parseReturnType(returnToken ast.Kind, isType bool) *ast.TypeNode { + if p.shouldParseReturnType(returnToken, isType) { + return doInContext(p, ast.NodeFlagsDisallowConditionalTypesContext, false, (*Parser).parseTypeOrTypePredicate) + } + return nil +} + +func (p *Parser) shouldParseReturnType(returnToken ast.Kind, isType bool) bool { + if returnToken == ast.KindEqualsGreaterThanToken { + p.parseExpected(returnToken) + return true + } else if p.parseOptional(ast.KindColonToken) { + return true + } else if isType && p.token == ast.KindEqualsGreaterThanToken { + // This is easy to get backward, especially in type contexts, so parse the type anyway + p.parseErrorAtCurrentToken(diagnostics.X_0_expected, scanner.TokenToString(ast.KindColonToken)) + p.nextToken() + return true + } + return false +} + +func (p *Parser) parseTypeOrTypePredicate() *ast.TypeNode { + if p.isIdentifier() { + state := p.mark() + pos := p.nodePos() + id := p.parseIdentifier() + if p.token == ast.KindIsKeyword && !p.hasPrecedingLineBreak() { + p.nextToken() + return p.finishNode(p.factory.NewTypePredicateNode(nil /*assertsModifier*/, id, p.parseType()), pos) + } + p.rewind(state) + } + return p.parseType() +} + +func (p *Parser) parseTypeMemberSemicolon() { + // We allow type members to be separated by commas or (possibly ASI) semicolons. + // First check if it was a comma. If so, we're done with the member. + if p.parseOptional(ast.KindCommaToken) { + return + } + // Didn't have a comma. We must have a (possible ASI) semicolon. + p.parseSemicolon() +} + +func (p *Parser) parseAccessorDeclaration(pos int, hasJSDoc bool, modifiers *ast.ModifierList, kind ast.Kind, flags ParseFlags) *ast.Node { + name := p.parsePropertyName() + typeParameters := p.parseTypeParameters() + parameters := p.parseParameters(ParseFlagsNone) + returnType := p.parseReturnType(ast.KindColonToken, false /*isType*/) + body := p.parseFunctionBlockOrSemicolon(flags, nil /*diagnosticMessage*/) + var result *ast.Node + // Keep track of `typeParameters` (for both) and `type` (for setters) if they were parsed those indicate grammar errors + if kind == ast.KindGetAccessor { + result = p.factory.NewGetAccessorDeclaration(modifiers, name, typeParameters, parameters, returnType, nil /*fullSignature*/, body) + } else { + result = p.factory.NewSetAccessorDeclaration(modifiers, name, typeParameters, parameters, returnType, nil /*fullSignature*/, body) + } + p.withJSDoc(p.finishNode(result, pos), hasJSDoc) + if flags&ParseFlagsType == 0 { + p.checkJSSyntax(result) + } + return result +} + +func (p *Parser) parsePropertyName() *ast.Node { + saveHasAwaitIdentifier := p.statementHasAwaitIdentifier + prop := p.parsePropertyNameWorker(true /*allowComputedPropertyNames*/) + p.statementHasAwaitIdentifier = saveHasAwaitIdentifier + return prop +} + +func (p *Parser) parsePropertyNameWorker(allowComputedPropertyNames bool) *ast.Node { + if p.token == ast.KindStringLiteral || p.token == ast.KindNumericLiteral || p.token == ast.KindBigIntLiteral { + literal := p.parseLiteralExpression(true /*intern*/) + return literal + } + if allowComputedPropertyNames && p.token == ast.KindOpenBracketToken { + return p.parseComputedPropertyName() + } + if p.token == ast.KindPrivateIdentifier { + return p.parsePrivateIdentifier() + } + return p.parseIdentifierName() +} + +func (p *Parser) parseComputedPropertyName() *ast.Node { + // PropertyName [Yield]: + // LiteralPropertyName + // ComputedPropertyName[?Yield] + pos := p.nodePos() + p.parseExpected(ast.KindOpenBracketToken) + // We parse any expression (including a comma expression). But the grammar + // says that only an assignment expression is allowed, so the grammar checker + // will error if it sees a comma expression. + expression := p.parseExpressionAllowIn() + p.parseExpected(ast.KindCloseBracketToken) + return p.finishNode(p.factory.NewComputedPropertyName(expression), pos) +} + +func (p *Parser) parseFunctionBlockOrSemicolon(flags ParseFlags, diagnosticMessage *diagnostics.Message) *ast.Node { + if p.token != ast.KindOpenBraceToken { + if flags&ParseFlagsType != 0 { + p.parseTypeMemberSemicolon() + return nil + } + if p.canParseSemicolon() { + p.parseSemicolon() + return nil + } + } + return p.parseFunctionBlock(flags, diagnosticMessage) +} + +func (p *Parser) parseFunctionBlock(flags ParseFlags, diagnosticMessage *diagnostics.Message) *ast.Node { + saveContextFlags := p.contextFlags + saveHasAwaitIdentifier := p.statementHasAwaitIdentifier + p.setContextFlags(ast.NodeFlagsYieldContext, flags&ParseFlagsYield != 0) + p.setContextFlags(ast.NodeFlagsAwaitContext, flags&ParseFlagsAwait != 0) + // We may be in a [Decorator] context when parsing a function expression or + // arrow function. The body of the function is not in [Decorator] context. + p.setContextFlags(ast.NodeFlagsDecoratorContext, false) + block := p.parseBlock(flags&ParseFlagsIgnoreMissingOpenBrace != 0, diagnosticMessage) + p.contextFlags = saveContextFlags + p.statementHasAwaitIdentifier = saveHasAwaitIdentifier + return block +} + +func (p *Parser) isIndexSignature() bool { + return p.token == ast.KindOpenBracketToken && p.lookAhead((*Parser).nextIsUnambiguouslyIndexSignature) +} + +func (p *Parser) nextIsUnambiguouslyIndexSignature() bool { + // The only allowed sequence is: + // + // [id: + // + // However, for error recovery, we also check the following cases: + // + // [... + // [id, + // [id?, + // [id?: + // [id?] + // [public id + // [private id + // [protected id + // [] + // + p.nextToken() + if p.token == ast.KindDotDotDotToken || p.token == ast.KindCloseBracketToken { + return true + } + if ast.IsModifierKind(p.token) { + p.nextToken() + if p.isIdentifier() { + return true + } + } else if !p.isIdentifier() { + return false + } else { + // Skip the identifier + p.nextToken() + } + // A colon signifies a well formed indexer + // A comma should be a badly formed indexer because comma expressions are not allowed + // in computed properties. + if p.token == ast.KindColonToken || p.token == ast.KindCommaToken { + return true + } + // Question mark could be an indexer with an optional property, + // or it could be a conditional expression in a computed property. + if p.token != ast.KindQuestionToken { + return false + } + // If any of the following tokens are after the question mark, it cannot + // be a conditional expression, so treat it as an indexer. + p.nextToken() + return p.token == ast.KindColonToken || p.token == ast.KindCommaToken || p.token == ast.KindCloseBracketToken +} + +func (p *Parser) parseIndexSignatureDeclaration(pos int, hasJSDoc bool, modifiers *ast.ModifierList) *ast.Node { + parameters := p.parseBracketedList(PCParameters, (*Parser).parseParameter, ast.KindOpenBracketToken, ast.KindCloseBracketToken) + typeNode := p.parseTypeAnnotation() + p.parseTypeMemberSemicolon() + result := p.finishNode(p.factory.NewIndexSignatureDeclaration(modifiers, parameters, typeNode), pos) + p.withJSDoc(result, hasJSDoc) + return result +} + +func (p *Parser) parsePropertyOrMethodSignature(pos int, hasJSDoc bool, modifiers *ast.ModifierList) *ast.Node { + name := p.parsePropertyName() + questionToken := p.parseOptionalToken(ast.KindQuestionToken) + var result *ast.Node + if p.token == ast.KindOpenParenToken || p.token == ast.KindLessThanToken { + // Method signatures don't exist in expression contexts. So they have neither + // [Yield] nor [Await] + typeParameters := p.parseTypeParameters() + parameters := p.parseParameters(ParseFlagsType) + returnType := p.parseReturnType(ast.KindColonToken /*isType*/, true) + result = p.factory.NewMethodSignatureDeclaration(modifiers, name, questionToken, typeParameters, parameters, returnType) + } else { + typeNode := p.parseTypeAnnotation() + // Although type literal properties cannot not have initializers, we attempt + // to parse an initializer so we can report in the checker that an interface + // property or type literal property cannot have an initializer. + var initializer *ast.Expression + if p.token == ast.KindEqualsToken { + initializer = p.parseInitializer() + } + result = p.factory.NewPropertySignatureDeclaration(modifiers, name, questionToken, typeNode, initializer) + } + p.parseTypeMemberSemicolon() + p.withJSDoc(p.finishNode(result, pos), hasJSDoc) + return result +} + +func (p *Parser) parseTypeLiteral() *ast.Node { + pos := p.nodePos() + result := p.finishNode(p.factory.NewTypeLiteralNode(p.parseObjectTypeMembers()), pos) + return result +} + +func (p *Parser) parseObjectTypeMembers() *ast.NodeList { + if p.parseExpected(ast.KindOpenBraceToken) { + members := p.parseList(PCTypeMembers, (*Parser).parseTypeMember) + p.parseExpected(ast.KindCloseBraceToken) + return members + } + return p.parseEmptyNodeList() +} + +func (p *Parser) parseTupleType() *ast.Node { + pos := p.nodePos() + return p.finishNode(p.factory.NewTupleTypeNode(p.parseBracketedList(PCTupleElementTypes, (*Parser).parseTupleElementNameOrTupleElementType, ast.KindOpenBracketToken, ast.KindCloseBracketToken)), pos) +} + +func (p *Parser) parseTupleElementNameOrTupleElementType() *ast.Node { + if p.lookAhead((*Parser).scanStartOfNamedTupleElement) { + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + dotDotDotToken := p.parseOptionalToken(ast.KindDotDotDotToken) + name := p.parseIdentifierName() + questionToken := p.parseOptionalToken(ast.KindQuestionToken) + p.parseExpected(ast.KindColonToken) + typeNode := p.parseTupleElementType() + result := p.finishNode(p.factory.NewNamedTupleMember(dotDotDotToken, name, questionToken, typeNode), pos) + p.withJSDoc(result, hasJSDoc) + return result + } + return p.parseTupleElementType() +} + +func (p *Parser) scanStartOfNamedTupleElement() bool { + if p.token == ast.KindDotDotDotToken { + return tokenIsIdentifierOrKeyword(p.nextToken()) && p.nextTokenIsColonOrQuestionColon() + } + return tokenIsIdentifierOrKeyword(p.token) && p.nextTokenIsColonOrQuestionColon() +} + +func (p *Parser) nextTokenIsColonOrQuestionColon() bool { + return p.nextToken() == ast.KindColonToken || p.token == ast.KindQuestionToken && p.nextToken() == ast.KindColonToken +} + +func (p *Parser) parseTupleElementType() *ast.TypeNode { + pos := p.nodePos() + if p.parseOptional(ast.KindDotDotDotToken) { + return p.finishNode(p.factory.NewRestTypeNode(p.parseType()), pos) + } + typeNode := p.parseType() + if ast.IsJSDocNullableType(typeNode) && typeNode.Pos() == typeNode.Type().Pos() { + node := p.factory.NewOptionalTypeNode(typeNode.Type()) + node.Flags = typeNode.Flags + node.Loc = typeNode.Loc + typeNode.Type().Parent = node + return node + } + return typeNode +} + +func (p *Parser) parseParenthesizedType() *ast.Node { + pos := p.nodePos() + p.parseExpected(ast.KindOpenParenToken) + typeNode := p.parseType() + p.parseExpected(ast.KindCloseParenToken) + return p.finishNode(p.factory.NewParenthesizedTypeNode(typeNode), pos) +} + +func (p *Parser) parseAssertsTypePredicate() *ast.TypeNode { + pos := p.nodePos() + assertsModifier := p.parseExpectedToken(ast.KindAssertsKeyword) + var parameterName *ast.Node + if p.token == ast.KindThisKeyword { + parameterName = p.parseThisTypeNode() + } else { + parameterName = p.parseIdentifier() + } + var typeNode *ast.TypeNode + if p.parseOptional(ast.KindIsKeyword) { + typeNode = p.parseType() + } + return p.finishNode(p.factory.NewTypePredicateNode(assertsModifier, parameterName, typeNode), pos) +} + +func (p *Parser) parseTemplateType() *ast.Node { + pos := p.nodePos() + return p.finishNode(p.factory.NewTemplateLiteralTypeNode(p.parseTemplateHead(false /*isTaggedTemplate*/), p.parseTemplateTypeSpans()), pos) +} + +func (p *Parser) parseTemplateHead(isTaggedTemplate bool) *ast.Node { + if !isTaggedTemplate && p.scanner.TokenFlags()&ast.TokenFlagsIsInvalid != 0 { + p.reScanTemplateToken(false /*isTaggedTemplate*/) + } + pos := p.nodePos() + result := p.factory.NewTemplateHead(p.scanner.TokenValue(), p.getTemplateLiteralRawText(2 /*endLength*/), p.scanner.TokenFlags()&ast.TokenFlagsTemplateLiteralLikeFlags) + p.nextToken() + return p.finishNode(result, pos) +} + +func (p *Parser) getTemplateLiteralRawText(endLength int) string { + tokenText := p.scanner.TokenText() + if p.scanner.TokenFlags()&ast.TokenFlagsUnterminated != 0 { + endLength = 0 + } + return tokenText[1 : len(tokenText)-endLength] +} + +func (p *Parser) parseTemplateTypeSpans() *ast.NodeList { + pos := p.nodePos() + var list []*ast.Node + for { + span := p.parseTemplateTypeSpan() + list = append(list, span) + if span.AsTemplateLiteralTypeSpan().Literal.Kind != ast.KindTemplateMiddle { + break + } + } + return p.newNodeList(core.NewTextRange(pos, p.nodePos()), list) +} + +func (p *Parser) parseTemplateTypeSpan() *ast.Node { + pos := p.nodePos() + return p.finishNode(p.factory.NewTemplateLiteralTypeSpan(p.parseType(), p.parseLiteralOfTemplateSpan(false /*isTaggedTemplate*/)), pos) +} + +func (p *Parser) parseLiteralOfTemplateSpan(isTaggedTemplate bool) *ast.Node { + if p.token == ast.KindCloseBraceToken { + p.reScanTemplateToken(isTaggedTemplate) + return p.parseTemplateMiddleOrTail() + } + p.parseErrorAtCurrentToken(diagnostics.X_0_expected, scanner.TokenToString(ast.KindCloseBraceToken)) + return p.finishNode(p.factory.NewTemplateTail("", "", ast.TokenFlagsNone), p.nodePos()) +} + +func (p *Parser) parseTemplateMiddleOrTail() *ast.Node { + pos := p.nodePos() + var result *ast.Node + if p.token == ast.KindTemplateMiddle { + result = p.factory.NewTemplateMiddle(p.scanner.TokenValue(), p.getTemplateLiteralRawText(2 /*endLength*/), p.scanner.TokenFlags()&ast.TokenFlagsTemplateLiteralLikeFlags) + } else { + result = p.factory.NewTemplateTail(p.scanner.TokenValue(), p.getTemplateLiteralRawText(1 /*endLength*/), p.scanner.TokenFlags()&ast.TokenFlagsTemplateLiteralLikeFlags) + } + p.nextToken() + return p.finishNode(result, pos) +} + +func (p *Parser) parseFunctionOrConstructorTypeToError(isInUnionType bool, parseConstituentType func(p *Parser) *ast.TypeNode) *ast.TypeNode { + // the function type and constructor type shorthand notation + // are not allowed directly in unions and intersections, but we'll + // try to parse them gracefully and issue a helpful message. + if p.isStartOfFunctionTypeOrConstructorType() { + typeNode := p.parseFunctionOrConstructorType() + var diagnostic *diagnostics.Message + if typeNode.Kind == ast.KindFunctionType { + diagnostic = core.IfElse(isInUnionType, + diagnostics.Function_type_notation_must_be_parenthesized_when_used_in_a_union_type, + diagnostics.Function_type_notation_must_be_parenthesized_when_used_in_an_intersection_type) + } else { + diagnostic = core.IfElse(isInUnionType, + diagnostics.Constructor_type_notation_must_be_parenthesized_when_used_in_a_union_type, + diagnostics.Constructor_type_notation_must_be_parenthesized_when_used_in_an_intersection_type) + } + p.parseErrorAtRange(typeNode.Loc, diagnostic) + return typeNode + } + return parseConstituentType(p) +} + +func (p *Parser) isStartOfFunctionTypeOrConstructorType() bool { + return p.token == ast.KindLessThanToken || + p.token == ast.KindOpenParenToken && p.lookAhead((*Parser).nextIsUnambiguouslyStartOfFunctionType) || + p.token == ast.KindNewKeyword || + p.token == ast.KindAbstractKeyword && p.lookAhead((*Parser).nextTokenIsNewKeyword) +} + +func (p *Parser) parseFunctionOrConstructorType() *ast.TypeNode { + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + modifiers := p.parseModifiersForConstructorType() + isConstructorType := p.parseOptional(ast.KindNewKeyword) + debug.Assert(modifiers == nil || isConstructorType, "Per isStartOfFunctionOrConstructorType, a function type cannot have modifiers.") + typeParameters := p.parseTypeParameters() + parameters := p.parseParameters(ParseFlagsType) + returnType := p.parseReturnType(ast.KindEqualsGreaterThanToken, false /*isType*/) + var result *ast.TypeNode + if isConstructorType { + result = p.factory.NewConstructorTypeNode(modifiers, typeParameters, parameters, returnType) + } else { + result = p.factory.NewFunctionTypeNode(typeParameters, parameters, returnType) + } + p.finishNode(result, pos) + p.withJSDoc(result, hasJSDoc) + return result +} + +func (p *Parser) parseModifiersForConstructorType() *ast.ModifierList { + if p.token == ast.KindAbstractKeyword { + pos := p.nodePos() + modifier := p.factory.NewModifier(p.token) + p.nextToken() + p.finishNode(modifier, pos) + return p.newModifierList(modifier.Loc, p.nodeSlicePool.NewSlice1(modifier)) + } + return nil +} + +func (p *Parser) nextTokenIsNewKeyword() bool { + return p.nextToken() == ast.KindNewKeyword +} + +func (p *Parser) nextIsUnambiguouslyStartOfFunctionType() bool { + p.nextToken() + if p.token == ast.KindCloseParenToken || p.token == ast.KindDotDotDotToken { + // ( ) + // ( ... + return true + } + if p.skipParameterStart() { + // We successfully skipped modifiers (if any) and an identifier or binding pattern, + // now see if we have something that indicates a parameter declaration + if p.token == ast.KindColonToken || p.token == ast.KindCommaToken || p.token == ast.KindQuestionToken || p.token == ast.KindEqualsToken { + // ( xxx : + // ( xxx , + // ( xxx ? + // ( xxx = + return true + } + if p.token == ast.KindCloseParenToken && p.nextToken() == ast.KindEqualsGreaterThanToken { + // ( xxx ) => + return true + } + } + return false +} + +func (p *Parser) skipParameterStart() bool { + if ast.IsModifierKind(p.token) { + // Skip modifiers + p.parseModifiers() + } + p.parseOptional(ast.KindDotDotDotToken) + if p.isIdentifier() || p.token == ast.KindThisKeyword { + p.nextToken() + return true + } + if p.token == ast.KindOpenBracketToken || p.token == ast.KindOpenBraceToken { + // Return true if we can parse an array or object binding pattern with no errors + previousErrorCount := len(p.diagnostics) + p.parseIdentifierOrPattern() + return previousErrorCount == len(p.diagnostics) + } + return false +} + +func (p *Parser) parseModifiers() *ast.ModifierList { + return p.parseModifiersEx(false, false, false) +} + +func (p *Parser) parseModifiersEx(allowDecorators bool, permitConstAsModifier bool, stopOnStartOfClassStaticBlock bool) *ast.ModifierList { + var hasLeadingModifier bool + var hasTrailingDecorator bool + var hasTrailingModifier bool + var hasStaticModifier bool + // Decorators should be contiguous in a list of modifiers but can potentially appear in two places (i.e., `[...leadingDecorators, ...leadingModifiers, ...trailingDecorators, ...trailingModifiers]`). + // The leading modifiers *should* only contain `export` and `default` when trailingDecorators are present, but we'll handle errors for any other leading modifiers in the checker. + // It is illegal to have both leadingDecorators and trailingDecorators, but we will report that as a grammar check in the checker. + // parse leading decorators + pos := p.nodePos() + list := make([]*ast.Node, 0, 16) + for { + if allowDecorators && p.token == ast.KindAtToken && !hasTrailingModifier { + decorator := p.parseDecorator() + list = append(list, decorator) + if hasLeadingModifier { + hasTrailingDecorator = true + } + } else { + modifier := p.tryParseModifier(hasStaticModifier, permitConstAsModifier, stopOnStartOfClassStaticBlock) + if modifier == nil { + break + } + if modifier.Kind == ast.KindStaticKeyword { + hasStaticModifier = true + } + list = append(list, modifier) + if hasTrailingDecorator { + hasTrailingModifier = true + } else { + hasLeadingModifier = true + } + } + } + if len(list) != 0 { + return p.newModifierList(core.NewTextRange(pos, p.nodePos()), p.nodeSlicePool.Clone(list)) + } + return nil +} + +func (p *Parser) parseDecorator() *ast.Node { + pos := p.nodePos() + p.parseExpected(ast.KindAtToken) + expression := doInContext(p, ast.NodeFlagsDecoratorContext, true, (*Parser).parseDecoratorExpression) + return p.finishNode(p.factory.NewDecorator(expression), pos) +} + +func (p *Parser) parseDecoratorExpression() *ast.Expression { + if p.inAwaitContext() && p.token == ast.KindAwaitKeyword { + // `@await` is disallowed in an [Await] context, but can cause parsing to go off the rails + // This simply parses the missing identifier and moves on. + pos := p.nodePos() + awaitExpression := p.parseIdentifierWithDiagnostic(diagnostics.Expression_expected, nil) + p.nextToken() + memberExpression := p.parseMemberExpressionRest(pos, awaitExpression /*allowOptionalChain*/, true) + return p.parseCallExpressionRest(pos, memberExpression) + } + return p.parseLeftHandSideExpressionOrHigher() +} + +func (p *Parser) tryParseModifier(hasSeenStaticModifier bool, permitConstAsModifier bool, stopOnStartOfClassStaticBlock bool) *ast.Node { + pos := p.nodePos() + kind := p.token + if p.token == ast.KindConstKeyword && permitConstAsModifier { + // We need to ensure that any subsequent modifiers appear on the same line + // so that when 'const' is a standalone declaration, we don't issue an error. + if !p.lookAhead((*Parser).nextTokenIsOnSameLineAndCanFollowModifier) { + return nil + } else { + p.nextToken() + } + } else if stopOnStartOfClassStaticBlock && p.token == ast.KindStaticKeyword && p.lookAhead((*Parser).nextTokenIsOpenBrace) { + return nil + } else if hasSeenStaticModifier && p.token == ast.KindStaticKeyword { + return nil + } else { + if !p.parseAnyContextualModifier() { + return nil + } + } + return p.finishNode(p.factory.NewModifier(kind), pos) +} + +func (p *Parser) parseContextualModifier(t ast.Kind) bool { + state := p.mark() + if p.token == t && p.nextTokenCanFollowModifier() { + return true + } + p.rewind(state) + return false +} + +func (p *Parser) parseAnyContextualModifier() bool { + state := p.mark() + if ast.IsModifierKind(p.token) && p.nextTokenCanFollowModifier() { + return true + } + p.rewind(state) + return false +} + +func (p *Parser) nextTokenCanFollowModifier() bool { + switch p.token { + case ast.KindConstKeyword: + // 'const' is only a modifier if followed by 'enum'. + return p.nextToken() == ast.KindEnumKeyword + case ast.KindExportKeyword: + p.nextToken() + if p.token == ast.KindDefaultKeyword { + return p.lookAhead((*Parser).nextTokenCanFollowDefaultKeyword) + } + if p.token == ast.KindTypeKeyword { + return p.lookAhead((*Parser).nextTokenCanFollowExportModifier) + } + return p.canFollowExportModifier() + case ast.KindDefaultKeyword: + return p.nextTokenCanFollowDefaultKeyword() + case ast.KindStaticKeyword: + p.nextToken() + return p.canFollowModifier() + case ast.KindGetKeyword, ast.KindSetKeyword: + p.nextToken() + return p.canFollowGetOrSetKeyword() + default: + return p.nextTokenIsOnSameLineAndCanFollowModifier() + } +} + +func (p *Parser) nextTokenCanFollowDefaultKeyword() bool { + switch p.nextToken() { + case ast.KindClassKeyword, ast.KindFunctionKeyword, ast.KindInterfaceKeyword, ast.KindAtToken: + return true + case ast.KindAbstractKeyword: + return p.lookAhead((*Parser).nextTokenIsClassKeywordOnSameLine) + case ast.KindAsyncKeyword: + return p.lookAhead((*Parser).nextTokenIsFunctionKeywordOnSameLine) + } + return false +} + +func (p *Parser) nextTokenIsIdentifierOrKeyword() bool { + return tokenIsIdentifierOrKeyword(p.nextToken()) +} + +func (p *Parser) nextTokenIsIdentifierOrKeywordOrGreaterThan() bool { + return tokenIsIdentifierOrKeywordOrGreaterThan(p.nextToken()) +} + +func (p *Parser) nextTokenIsIdentifierOrKeywordOnSameLine() bool { + return p.nextTokenIsIdentifierOrKeyword() && !p.hasPrecedingLineBreak() +} + +func (p *Parser) nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine() bool { + return (p.nextTokenIsIdentifierOrKeyword() || p.token == ast.KindNumericLiteral || p.token == ast.KindBigIntLiteral || p.token == ast.KindStringLiteral) && !p.hasPrecedingLineBreak() +} + +func (p *Parser) nextTokenIsClassKeywordOnSameLine() bool { + return p.nextToken() == ast.KindClassKeyword && !p.hasPrecedingLineBreak() +} + +func (p *Parser) nextTokenIsFunctionKeywordOnSameLine() bool { + return p.nextToken() == ast.KindFunctionKeyword && !p.hasPrecedingLineBreak() +} + +func (p *Parser) nextTokenCanFollowExportModifier() bool { + p.nextToken() + return p.canFollowExportModifier() +} + +func (p *Parser) canFollowExportModifier() bool { + return p.token == ast.KindAtToken || p.token != ast.KindAsteriskToken && p.token != ast.KindAsKeyword && p.token != ast.KindOpenBraceToken && p.canFollowModifier() +} + +func (p *Parser) canFollowModifier() bool { + return p.token == ast.KindOpenBracketToken || p.token == ast.KindOpenBraceToken || p.token == ast.KindAsteriskToken || p.token == ast.KindDotDotDotToken || p.isLiteralPropertyName() +} + +func (p *Parser) canFollowGetOrSetKeyword() bool { + return p.token == ast.KindOpenBracketToken || p.isLiteralPropertyName() +} + +func (p *Parser) nextTokenIsOnSameLineAndCanFollowModifier() bool { + p.nextToken() + if p.hasPrecedingLineBreak() { + return false + } + return p.canFollowModifier() +} + +func (p *Parser) nextTokenIsOpenBrace() bool { + return p.nextToken() == ast.KindOpenBraceToken +} + +func (p *Parser) parseExpression() *ast.Expression { + // Expression[in]: + // AssignmentExpression[in] + // Expression[in] , AssignmentExpression[in] + + // clear the decorator context when parsing Expression, as it should be unambiguous when parsing a decorator + saveContextFlags := p.contextFlags + p.contextFlags &= ^ast.NodeFlagsDecoratorContext + pos := p.nodePos() + expr := p.parseAssignmentExpressionOrHigher() + for { + operatorToken := p.parseOptionalToken(ast.KindCommaToken) + if operatorToken == nil { + break + } + expr = p.makeBinaryExpression(expr, operatorToken, p.parseAssignmentExpressionOrHigher(), pos) + } + p.contextFlags = saveContextFlags + return expr +} + +func (p *Parser) parseExpressionAllowIn() *ast.Expression { + return doInContext(p, ast.NodeFlagsDisallowInContext, false, (*Parser).parseExpression) +} + +func (p *Parser) parseAssignmentExpressionOrHigher() *ast.Expression { + return p.parseAssignmentExpressionOrHigherWorker(true /*allowReturnTypeInArrowFunction*/) +} + +func (p *Parser) parseAssignmentExpressionOrHigherWorker(allowReturnTypeInArrowFunction bool) *ast.Expression { + // AssignmentExpression[in,yield]: + // 1) ConditionalExpression[?in,?yield] + // 2) LeftHandSideExpression = AssignmentExpression[?in,?yield] + // 3) LeftHandSideExpression AssignmentOperator AssignmentExpression[?in,?yield] + // 4) ArrowFunctionExpression[?in,?yield] + // 5) AsyncArrowFunctionExpression[in,yield,await] + // 6) [+Yield] YieldExpression[?In] + // + // Note: for ease of implementation we treat productions '2' and '3' as the same thing. + // (i.e. they're both BinaryExpressions with an assignment operator in it). + // First, do the simple check if we have a YieldExpression (production '6'). + if p.isYieldExpression() { + return p.parseYieldExpression() + } + // Then, check if we have an arrow function (production '4' and '5') that starts with a parenthesized + // parameter list or is an async arrow function. + // AsyncArrowFunctionExpression: + // 1) async[no LineTerminator here]AsyncArrowBindingIdentifier[?Yield][no LineTerminator here]=>AsyncConciseBody[?In] + // 2) CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await][no LineTerminator here]=>AsyncConciseBody[?In] + // Production (1) of AsyncArrowFunctionExpression is parsed in "tryParseAsyncSimpleArrowFunctionExpression". + // And production (2) is parsed in "tryParseParenthesizedArrowFunctionExpression". + // + // If we do successfully parse arrow-function, we must *not* recurse for productions 1, 2 or 3. An ArrowFunction is + // not a LeftHandSideExpression, nor does it start a ConditionalExpression. So we are done + // with AssignmentExpression if we see one. + arrowExpression := p.tryParseParenthesizedArrowFunctionExpression(allowReturnTypeInArrowFunction) + if arrowExpression != nil { + return arrowExpression + } + arrowExpression = p.tryParseAsyncSimpleArrowFunctionExpression(allowReturnTypeInArrowFunction) + if arrowExpression != nil { + return arrowExpression + } + // arrowExpression2 := p.tryParseAsyncSimpleArrowFunctionExpression(allowReturnTypeInArrowFunction) + // if arrowExpression2 != nil { + // return arrowExpression2 + // } + // Now try to see if we're in production '1', '2' or '3'. A conditional expression can + // start with a LogicalOrExpression, while the assignment productions can only start with + // LeftHandSideExpressions. + // + // So, first, we try to just parse out a BinaryExpression. If we get something that is a + // LeftHandSide or higher, then we can try to parse out the assignment expression part. + // Otherwise, we try to parse out the conditional expression bit. We want to allow any + // binary expression here, so we pass in the 'lowest' precedence here so that it matches + // and consumes anything. + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + expr := p.parseBinaryExpressionOrHigher(ast.OperatorPrecedenceLowest) + // To avoid a look-ahead, we did not handle the case of an arrow function with a single un-parenthesized + // parameter ('x => ...') above. We handle it here by checking if the parsed expression was a single + // identifier and the current token is an arrow. + if expr.Kind == ast.KindIdentifier && p.token == ast.KindEqualsGreaterThanToken { + return p.parseSimpleArrowFunctionExpression(pos, expr, allowReturnTypeInArrowFunction, hasJSDoc, nil /*asyncModifier*/) + } + // Now see if we might be in cases '2' or '3'. + // If the expression was a LHS expression, and we have an assignment operator, then + // we're in '2' or '3'. Consume the assignment and return. + // + // Note: we call reScanGreaterToken so that we get an appropriately merged token + // for cases like `> > =` becoming `>>=` + if ast.IsLeftHandSideExpression(expr) && ast.IsAssignmentOperator(p.reScanGreaterThanToken()) { + return p.makeBinaryExpression(expr, p.parseTokenNode(), p.parseAssignmentExpressionOrHigherWorker(allowReturnTypeInArrowFunction), pos) + } + // It wasn't an assignment or a lambda. This is a conditional expression: + return p.parseConditionalExpressionRest(expr, pos, allowReturnTypeInArrowFunction) +} + +func (p *Parser) isYieldExpression() bool { + if p.token == ast.KindYieldKeyword { + // If we have a 'yield' keyword, and this is a context where yield expressions are + // allowed, then definitely parse out a yield expression. + if p.inYieldContext() { + return true + } + + // We're in a context where 'yield expr' is not allowed. However, if we can + // definitely tell that the user was trying to parse a 'yield expr' and not + // just a normal expr that start with a 'yield' identifier, then parse out + // a 'yield expr'. We can then report an error later that they are only + // allowed in generator expressions. + // + // for example, if we see 'yield(foo)', then we'll have to treat that as an + // invocation expression of something called 'yield'. However, if we have + // 'yield foo' then that is not legal as a normal expression, so we can + // definitely recognize this as a yield expression. + // + // for now we just check if the next token is an identifier. More heuristics + // can be added here later as necessary. We just need to make sure that we + // don't accidentally consume something legal. + return p.lookAhead((*Parser).nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine) + } + return false +} + +func (p *Parser) parseYieldExpression() *ast.Node { + pos := p.nodePos() + // YieldExpression[In] : + // yield + // yield [no LineTerminator here] [Lexical goal InputElementRegExp]AssignmentExpression[?In, Yield] + // yield [no LineTerminator here] * [Lexical goal InputElementRegExp]AssignmentExpression[?In, Yield] + p.nextToken() + var result *ast.Node + if !p.hasPrecedingLineBreak() && (p.token == ast.KindAsteriskToken || p.isStartOfExpression()) { + result = p.factory.NewYieldExpression(p.parseOptionalToken(ast.KindAsteriskToken), p.parseAssignmentExpressionOrHigher()) + } else { + // if the next token is not on the same line as yield. or we don't have an '*' or + // the start of an expression, then this is just a simple "yield" expression. + result = p.factory.NewYieldExpression(nil /*asteriskToken*/, nil /*expression*/) + } + return p.finishNode(result, pos) +} + +func (p *Parser) isParenthesizedArrowFunctionExpression() core.Tristate { + if p.token == ast.KindOpenParenToken || p.token == ast.KindLessThanToken || p.token == ast.KindAsyncKeyword { + state := p.mark() + result := p.nextIsParenthesizedArrowFunctionExpression() + p.rewind(state) + return result + } + if p.token == ast.KindEqualsGreaterThanToken { + // ERROR RECOVERY TWEAK: + // If we see a standalone => try to parse it as an arrow function expression as that's + // likely what the user intended to write. + return core.TSTrue + } + // Definitely not a parenthesized arrow function. + return core.TSFalse +} + +func (p *Parser) nextIsParenthesizedArrowFunctionExpression() core.Tristate { + if p.token == ast.KindAsyncKeyword { + p.nextToken() + if p.hasPrecedingLineBreak() { + return core.TSFalse + } + if p.token != ast.KindOpenParenToken && p.token != ast.KindLessThanToken { + return core.TSFalse + } + } + first := p.token + second := p.nextToken() + if first == ast.KindOpenParenToken { + if second == ast.KindCloseParenToken { + // Simple cases: "() =>", "(): ", and "() {". + // This is an arrow function with no parameters. + // The last one is not actually an arrow function, + // but this is probably what the user intended. + third := p.nextToken() + switch third { + case ast.KindEqualsGreaterThanToken, ast.KindColonToken, ast.KindOpenBraceToken: + return core.TSTrue + } + return core.TSFalse + } + // If encounter "([" or "({", this could be the start of a binding pattern. + // Examples: + // ([ x ]) => { } + // ({ x }) => { } + // ([ x ]) + // ({ x }) + if second == ast.KindOpenBracketToken || second == ast.KindOpenBraceToken { + return core.TSUnknown + } + // Simple case: "(..." + // This is an arrow function with a rest parameter. + if second == ast.KindDotDotDotToken { + return core.TSTrue + } + // Check for "(xxx yyy", where xxx is a modifier and yyy is an identifier. This + // isn't actually allowed, but we want to treat it as a lambda so we can provide + // a good error message. + if ast.IsModifierKind(second) && second != ast.KindAsyncKeyword && p.lookAhead((*Parser).nextTokenIsIdentifier) { + if p.nextToken() == ast.KindAsKeyword { + // https://github.com/microsoft/TypeScript/issues/44466 + return core.TSFalse + } + return core.TSTrue + } + // If we had "(" followed by something that's not an identifier, + // then this definitely doesn't look like a lambda. "this" is not + // valid, but we want to parse it and then give a semantic error. + if !p.isIdentifier() && second != ast.KindThisKeyword { + return core.TSFalse + } + switch p.nextToken() { + case ast.KindColonToken: + // If we have something like "(a:", then we must have a + // type-annotated parameter in an arrow function expression. + return core.TSTrue + case ast.KindQuestionToken: + p.nextToken() + // If we have "(a?:" or "(a?," or "(a?=" or "(a?)" then it is definitely a lambda. + if p.token == ast.KindColonToken || p.token == ast.KindCommaToken || p.token == ast.KindEqualsToken || p.token == ast.KindCloseParenToken { + return core.TSTrue + } + // Otherwise it is definitely not a lambda. + return core.TSFalse + case ast.KindCommaToken, ast.KindEqualsToken, ast.KindCloseParenToken: + // If we have "(a," or "(a=" or "(a)" this *could* be an arrow function + return core.TSUnknown + } + // It is definitely not an arrow function + return core.TSFalse + } else { + debug.Assert(first == ast.KindLessThanToken) + // If we have "<" not followed by an identifier, + // then this definitely is not an arrow function. + if !p.isIdentifier() && p.token != ast.KindConstKeyword { + return core.TSFalse + } + // JSX overrides + if p.languageVariant == core.LanguageVariantJSX { + isArrowFunctionInJsx := p.lookAhead(func(p *Parser) bool { + p.parseOptional(ast.KindConstKeyword) + third := p.nextToken() + if third == ast.KindExtendsKeyword { + fourth := p.nextToken() + switch fourth { + case ast.KindEqualsToken, ast.KindGreaterThanToken, ast.KindSlashToken: + return false + } + return true + } else if third == ast.KindCommaToken || third == ast.KindEqualsToken { + return true + } + return false + }) + if isArrowFunctionInJsx { + return core.TSTrue + } + return core.TSFalse + } + // This *could* be a parenthesized arrow function. + return core.TSUnknown + } +} + +func (p *Parser) tryParseParenthesizedArrowFunctionExpression(allowReturnTypeInArrowFunction bool) *ast.Node { + tristate := p.isParenthesizedArrowFunctionExpression() + if tristate == core.TSFalse { + // It's definitely not a parenthesized arrow function expression. + return nil + } + // If we definitely have an arrow function, then we can just parse one, not requiring a + // following => or { token. Otherwise, we *might* have an arrow function. Try to parse + // it out, but don't allow any ambiguity, and return 'undefined' if this could be an + // expression instead. + if tristate == core.TSTrue { + return p.parseParenthesizedArrowFunctionExpression(true /*allowAmbiguity*/, true /*allowReturnTypeInArrowFunction*/) + } + state := p.mark() + result := p.parsePossibleParenthesizedArrowFunctionExpression(allowReturnTypeInArrowFunction) + if result == nil { + p.rewind(state) + } + return result +} + +func (p *Parser) parseParenthesizedArrowFunctionExpression(allowAmbiguity bool, allowReturnTypeInArrowFunction bool) *ast.Node { + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + modifiers := p.parseModifiersForArrowFunction() + isAsync := modifierListHasAsync(modifiers) + signatureFlags := core.IfElse(isAsync, ParseFlagsAwait, ParseFlagsNone) + // Arrow functions are never generators. + // + // If we're speculatively parsing a signature for a parenthesized arrow function, then + // we have to have a complete parameter list. Otherwise we might see something like + // a => (b => c) + // And think that "(b =>" was actually a parenthesized arrow function with a missing + // close paren. + typeParameters := p.parseTypeParameters() + var parameters *ast.NodeList + if !p.parseExpected(ast.KindOpenParenToken) { + if !allowAmbiguity { + return nil + } + parameters = p.parseEmptyNodeList() + } else { + if !allowAmbiguity { + maybeParameters := p.parseParametersWorker(signatureFlags, allowAmbiguity) + if maybeParameters == nil { + return nil + } + parameters = maybeParameters + } else { + parameters = p.parseParametersWorker(signatureFlags, allowAmbiguity) + } + if !p.parseExpected(ast.KindCloseParenToken) && !allowAmbiguity { + return nil + } + } + hasReturnColon := p.token == ast.KindColonToken + returnType := p.parseReturnType(ast.KindColonToken /*isType*/, false) + if returnType != nil && !allowAmbiguity && typeHasArrowFunctionBlockingParseError(returnType) { + return nil + } + // Parsing a signature isn't enough. + // Parenthesized arrow signatures often look like other valid expressions. + // For instance: + // - "(x = 10)" is an assignment expression parsed as a signature with a default parameter value. + // - "(x,y)" is a comma expression parsed as a signature with two parameters. + // - "a ? (b): c" will have "(b):" parsed as a signature with a return type annotation. + // - "a ? (b): function() {}" will too, since function() is a valid JSDoc function type. + // - "a ? (b): (function() {})" as well, but inside of a parenthesized type with an arbitrary amount of nesting. + // + // So we need just a bit of lookahead to ensure that it can only be a signature. + unwrappedType := returnType + for unwrappedType != nil && unwrappedType.Kind == ast.KindParenthesizedType { + unwrappedType = unwrappedType.AsParenthesizedTypeNode().Type // Skip parens if need be + } + if !allowAmbiguity && p.token != ast.KindEqualsGreaterThanToken && p.token != ast.KindOpenBraceToken { + // Returning undefined here will cause our caller to rewind to where we started from. + return nil + } + // If we have an arrow, then try to parse the body. Even if not, try to parse if we + // have an opening brace, just in case we're in an error state. + lastToken := p.token + equalsGreaterThanToken := p.parseExpectedToken(ast.KindEqualsGreaterThanToken) + var body *ast.Node + if lastToken == ast.KindEqualsGreaterThanToken || lastToken == ast.KindOpenBraceToken { + body = p.parseArrowFunctionExpressionBody(isAsync, allowReturnTypeInArrowFunction) + } else { + body = p.parseIdentifier() + } + // Given: + // x ? y => ({ y }) : z => ({ z }) + // We try to parse the body of the first arrow function by looking at: + // ({ y }) : z => ({ z }) + // This is a valid arrow function with "z" as the return type. + // + // But, if we're in the true side of a conditional expression, this colon + // terminates the expression, so we cannot allow a return type if we aren't + // certain whether or not the preceding text was parsed as a parameter list. + // + // For example, + // a() ? (b: number, c?: string): void => d() : e + // is determined by isParenthesizedArrowFunctionExpression to unambiguously + // be an arrow expression, so we allow a return type. + if !allowReturnTypeInArrowFunction && hasReturnColon { + // However, if the arrow function we were able to parse is followed by another colon + // as in: + // a ? (x): string => x : null + // Then allow the arrow function, and treat the second colon as terminating + // the conditional expression. It's okay to do this because this code would + // be a syntax error in JavaScript (as the second colon shouldn't be there). + if p.token != ast.KindColonToken { + return nil + } + } + result := p.finishNode(p.factory.NewArrowFunction(modifiers, typeParameters, parameters, returnType, nil /*fullSignature*/, equalsGreaterThanToken, body), pos) + p.withJSDoc(result, hasJSDoc) + p.checkJSSyntax(result) + return result +} + +func (p *Parser) parseModifiersForArrowFunction() *ast.ModifierList { + if p.token == ast.KindAsyncKeyword { + pos := p.nodePos() + p.nextToken() + modifier := p.finishNode(p.factory.NewModifier(ast.KindAsyncKeyword), pos) + return p.newModifierList(modifier.Loc, p.nodeSlicePool.NewSlice1(modifier)) + } + return nil +} + +// If true, we should abort parsing an error function. +func typeHasArrowFunctionBlockingParseError(node *ast.TypeNode) bool { + switch node.Kind { + case ast.KindTypeReference: + return ast.NodeIsMissing(node.AsTypeReference().TypeName) + case ast.KindFunctionType, ast.KindConstructorType: + return typeHasArrowFunctionBlockingParseError(node.Type()) + case ast.KindParenthesizedType: + return typeHasArrowFunctionBlockingParseError(node.AsParenthesizedTypeNode().Type) + } + return false +} + +func (p *Parser) parseArrowFunctionExpressionBody(isAsync bool, allowReturnTypeInArrowFunction bool) *ast.Node { + if p.token == ast.KindOpenBraceToken { + return p.parseFunctionBlock(core.IfElse(isAsync, ParseFlagsAwait, ParseFlagsNone), nil /*diagnosticMessage*/) + } + if p.token != ast.KindSemicolonToken && p.token != ast.KindFunctionKeyword && p.token != ast.KindClassKeyword && p.isStartOfStatement() && !p.isStartOfExpressionStatement() { + // Check if we got a plain statement (i.e. no expression-statements, no function/class expressions/declarations) + // + // Here we try to recover from a potential error situation in the case where the + // user meant to supply a block. For example, if the user wrote: + // + // a => + // let v = 0; + // } + // + // they may be missing an open brace. Check to see if that's the case so we can + // try to recover better. If we don't do this, then the next close curly we see may end + // up preemptively closing the containing construct. + // + // Note: even when 'IgnoreMissingOpenBrace' is passed, parseBody will still error. + return p.parseFunctionBlock(ParseFlagsIgnoreMissingOpenBrace|core.IfElse(isAsync, ParseFlagsAwait, ParseFlagsNone), nil /*diagnosticMessage*/) + } + saveContextFlags := p.contextFlags + p.setContextFlags(ast.NodeFlagsAwaitContext, isAsync) + p.setContextFlags(ast.NodeFlagsYieldContext, false) + node := p.parseAssignmentExpressionOrHigherWorker(allowReturnTypeInArrowFunction) + p.contextFlags = saveContextFlags + return node +} + +func (p *Parser) isStartOfExpressionStatement() bool { + // As per the grammar, none of '{' or 'function' or 'class' can start an expression statement. + return p.token != ast.KindOpenBraceToken && p.token != ast.KindFunctionKeyword && p.token != ast.KindClassKeyword && p.token != ast.KindAtToken && p.isStartOfExpression() +} + +func (p *Parser) parsePossibleParenthesizedArrowFunctionExpression(allowReturnTypeInArrowFunction bool) *ast.Node { + tokenPos := p.scanner.TokenStart() + if p.notParenthesizedArrow.Has(tokenPos) { + return nil + } + result := p.parseParenthesizedArrowFunctionExpression(false /*allowAmbiguity*/, allowReturnTypeInArrowFunction) + if result == nil { + p.notParenthesizedArrow.Add(tokenPos) + } + return result +} + +func (p *Parser) tryParseAsyncSimpleArrowFunctionExpression(allowReturnTypeInArrowFunction bool) *ast.Node { + // We do a check here so that we won't be doing unnecessarily call to "lookAhead" + if p.token == ast.KindAsyncKeyword && p.lookAhead((*Parser).nextIsUnParenthesizedAsyncArrowFunction) { + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + asyncModifier := p.parseModifiersForArrowFunction() + expr := p.parseBinaryExpressionOrHigher(ast.OperatorPrecedenceLowest) + return p.parseSimpleArrowFunctionExpression(pos, expr, allowReturnTypeInArrowFunction, hasJSDoc, asyncModifier) + } + return nil +} + +func (p *Parser) nextIsUnParenthesizedAsyncArrowFunction() bool { + // AsyncArrowFunctionExpression: + // 1) async[no LineTerminator here]AsyncArrowBindingIdentifier[?Yield][no LineTerminator here]=>AsyncConciseBody[?In] + // 2) CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await][no LineTerminator here]=>AsyncConciseBody[?In] + if p.token == ast.KindAsyncKeyword { + p.nextToken() + // If the "async" is followed by "=>" token then it is not a beginning of an async arrow-function + // but instead a simple arrow-function which will be parsed inside "parseAssignmentExpressionOrHigher" + if p.hasPrecedingLineBreak() || p.token == ast.KindEqualsGreaterThanToken { + return false + } + // Check for un-parenthesized AsyncArrowFunction + expr := p.parseBinaryExpressionOrHigher(ast.OperatorPrecedenceLowest) + if !p.hasPrecedingLineBreak() && expr.Kind == ast.KindIdentifier && p.token == ast.KindEqualsGreaterThanToken { + return true + } + } + return false +} + +func (p *Parser) parseSimpleArrowFunctionExpression(pos int, identifier *ast.Node, allowReturnTypeInArrowFunction bool, hasJSDoc bool, asyncModifier *ast.ModifierList) *ast.Node { + debug.Assert(p.token == ast.KindEqualsGreaterThanToken, "parseSimpleArrowFunctionExpression should only have been called if we had a =>") + parameter := p.finishNode(p.factory.NewParameterDeclaration(nil /*modifiers*/, nil /*dotDotDotToken*/, identifier, nil /*questionToken*/, nil /*typeNode*/, nil /*initializer*/), identifier.Pos()) + parameters := p.newNodeList(parameter.Loc, []*ast.Node{parameter}) + equalsGreaterThanToken := p.parseExpectedToken(ast.KindEqualsGreaterThanToken) + body := p.parseArrowFunctionExpressionBody(asyncModifier != nil /*isAsync*/, allowReturnTypeInArrowFunction) + result := p.finishNode(p.factory.NewArrowFunction(asyncModifier, nil /*typeParameters*/, parameters, nil /*returnType*/, nil /*fullSignature*/, equalsGreaterThanToken, body), pos) + p.withJSDoc(result, hasJSDoc) + return result +} + +func (p *Parser) parseConditionalExpressionRest(leftOperand *ast.Expression, pos int, allowReturnTypeInArrowFunction bool) *ast.Expression { + // Note: we are passed in an expression which was produced from parseBinaryExpressionOrHigher. + questionToken := p.parseOptionalToken(ast.KindQuestionToken) + if questionToken == nil { + return leftOperand + } + // Note: we explicitly 'allowIn' in the whenTrue part of the condition expression, and + // we do not that for the 'whenFalse' part. + saveContextFlags := p.contextFlags + p.setContextFlags(ast.NodeFlagsDisallowInContext, false) + trueExpression := p.parseAssignmentExpressionOrHigherWorker(false /*allowReturnTypeInArrowFunction*/) + p.contextFlags = saveContextFlags + colonToken := p.parseExpectedToken(ast.KindColonToken) + var falseExpression *ast.Expression + if colonToken != nil { + falseExpression = p.parseAssignmentExpressionOrHigherWorker(allowReturnTypeInArrowFunction) + } else { + p.parseErrorAtCurrentToken(diagnostics.X_0_expected, scanner.TokenToString(ast.KindColonToken)) + falseExpression = p.createMissingIdentifier() + } + return p.finishNode(p.factory.NewConditionalExpression(leftOperand, questionToken, trueExpression, colonToken, falseExpression), pos) +} + +func (p *Parser) parseBinaryExpressionOrHigher(precedence ast.OperatorPrecedence) *ast.Expression { + pos := p.nodePos() + leftOperand := p.parseUnaryExpressionOrHigher() + return p.parseBinaryExpressionRest(precedence, leftOperand, pos) +} + +func (p *Parser) parseBinaryExpressionRest(precedence ast.OperatorPrecedence, leftOperand *ast.Expression, pos int) *ast.Expression { + for { + // We either have a binary operator here, or we're finished. We call + // reScanGreaterToken so that we merge token sequences like > and = into >= + p.reScanGreaterThanToken() + newPrecedence := ast.GetBinaryOperatorPrecedence(p.token) + // Check the precedence to see if we should "take" this operator + // - For left associative operator (all operator but **), consume the operator, + // recursively call the function below, and parse binaryExpression as a rightOperand + // of the caller if the new precedence of the operator is greater then or equal to the current precedence. + // For example: + // a - b - c; + // ^token; leftOperand = b. Return b to the caller as a rightOperand + // a * b - c + // ^token; leftOperand = b. Return b to the caller as a rightOperand + // a - b * c; + // ^token; leftOperand = b. Return b * c to the caller as a rightOperand + // - For right associative operator (**), consume the operator, recursively call the function + // and parse binaryExpression as a rightOperand of the caller if the new precedence of + // the operator is strictly grater than the current precedence + // For example: + // a ** b ** c; + // ^^token; leftOperand = b. Return b ** c to the caller as a rightOperand + // a - b ** c; + // ^^token; leftOperand = b. Return b ** c to the caller as a rightOperand + // a ** b - c + // ^token; leftOperand = b. Return b to the caller as a rightOperand + var consumeCurrentOperator bool + if p.token == ast.KindAsteriskAsteriskToken { + consumeCurrentOperator = newPrecedence >= precedence + } else { + consumeCurrentOperator = newPrecedence > precedence + } + if !consumeCurrentOperator { + break + } + if p.token == ast.KindInKeyword && p.inDisallowInContext() { + break + } + if p.token == ast.KindAsKeyword || p.token == ast.KindSatisfiesKeyword { + // Make sure we *do* perform ASI for constructs like this: + // var x = foo + // as (Bar) + // This should be parsed as an initialized variable, followed + // by a function call to 'as' with the argument 'Bar' + if p.hasPrecedingLineBreak() { + break + } else { + keywordKind := p.token + p.nextToken() + if keywordKind == ast.KindSatisfiesKeyword { + leftOperand = p.makeSatisfiesExpression(leftOperand, p.parseType()) + } else { + leftOperand = p.makeAsExpression(leftOperand, p.parseType()) + } + } + } else { + leftOperand = p.makeBinaryExpression(leftOperand, p.parseTokenNode(), p.parseBinaryExpressionOrHigher(newPrecedence), pos) + } + } + return leftOperand +} + +func (p *Parser) makeSatisfiesExpression(expression *ast.Expression, typeNode *ast.TypeNode) *ast.Node { + return p.checkJSSyntax(p.finishNode(p.factory.NewSatisfiesExpression(expression, typeNode), expression.Pos())) +} + +func (p *Parser) makeAsExpression(left *ast.Expression, right *ast.TypeNode) *ast.Node { + return p.checkJSSyntax(p.finishNode(p.factory.NewAsExpression(left, right), left.Pos())) +} + +func (p *Parser) makeBinaryExpression(left *ast.Expression, operatorToken *ast.Node, right *ast.Expression, pos int) *ast.Node { + return p.finishNode(p.factory.NewBinaryExpression(nil /*modifiers*/, left, nil /*typeNode*/, operatorToken, right), pos) +} + +func (p *Parser) parseUnaryExpressionOrHigher() *ast.Expression { + // ES7 UpdateExpression: + // 1) LeftHandSideExpression[?Yield] + // 2) LeftHandSideExpression[?Yield][no LineTerminator here]++ + // 3) LeftHandSideExpression[?Yield][no LineTerminator here]-- + // 4) ++UnaryExpression[?Yield] + // 5) --UnaryExpression[?Yield] + if p.isUpdateExpression() { + pos := p.nodePos() + updateExpression := p.parseUpdateExpression() + if p.token == ast.KindAsteriskAsteriskToken { + return p.parseBinaryExpressionRest(ast.GetBinaryOperatorPrecedence(p.token), updateExpression, pos) + } + return updateExpression + } + // ES7 UnaryExpression: + // 1) UpdateExpression[?yield] + // 2) delete UpdateExpression[?yield] + // 3) void UpdateExpression[?yield] + // 4) typeof UpdateExpression[?yield] + // 5) + UpdateExpression[?yield] + // 6) - UpdateExpression[?yield] + // 7) ~ UpdateExpression[?yield] + // 8) ! UpdateExpression[?yield] + unaryOperator := p.token + simpleUnaryExpression := p.parseSimpleUnaryExpression() + if p.token == ast.KindAsteriskAsteriskToken { + pos := scanner.SkipTrivia(p.sourceText, simpleUnaryExpression.Pos()) + end := simpleUnaryExpression.End() + if simpleUnaryExpression.Kind == ast.KindTypeAssertionExpression { + p.parseErrorAt(pos, end, diagnostics.A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses) + } else { + debug.Assert(isKeywordOrPunctuation(unaryOperator)) + p.parseErrorAt(pos, end, diagnostics.An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses, scanner.TokenToString(unaryOperator)) + } + } + return simpleUnaryExpression +} + +func (p *Parser) isUpdateExpression() bool { + switch p.token { + case ast.KindPlusToken, ast.KindMinusToken, ast.KindTildeToken, ast.KindExclamationToken, ast.KindDeleteKeyword, ast.KindTypeOfKeyword, ast.KindVoidKeyword, ast.KindAwaitKeyword: + return false + case ast.KindLessThanToken: + return p.languageVariant == core.LanguageVariantJSX + } + return true +} + +func (p *Parser) parseUpdateExpression() *ast.Expression { + pos := p.nodePos() + if p.token == ast.KindPlusPlusToken || p.token == ast.KindMinusMinusToken { + operator := p.token + p.nextToken() + return p.finishNode(p.factory.NewPrefixUnaryExpression(operator, p.parseLeftHandSideExpressionOrHigher()), pos) + } else if p.languageVariant == core.LanguageVariantJSX && p.token == ast.KindLessThanToken && p.lookAhead((*Parser).nextTokenIsIdentifierOrKeywordOrGreaterThan) { + // JSXElement is part of primaryExpression + return p.parseJsxElementOrSelfClosingElementOrFragment(true /*inExpressionContext*/, -1 /*topInvalidNodePosition*/, nil /*openingTag*/, false /*mustBeUnary*/) + } + expression := p.parseLeftHandSideExpressionOrHigher() + if (p.token == ast.KindPlusPlusToken || p.token == ast.KindMinusMinusToken) && !p.hasPrecedingLineBreak() { + operator := p.token + p.nextToken() + return p.finishNode(p.factory.NewPostfixUnaryExpression(expression, operator), pos) + } + return expression +} + +func (p *Parser) parseJsxElementOrSelfClosingElementOrFragment(inExpressionContext bool, topInvalidNodePosition int, openingTag *ast.Node, mustBeUnary bool) *ast.Expression { + pos := p.nodePos() + opening := p.parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext) + var result *ast.Expression + switch opening.Kind { + case ast.KindJsxOpeningElement: + children := p.parseJsxChildren(opening) + var closingElement *ast.Node + lastChild := core.LastOrNil(children.Nodes) + if lastChild != nil && lastChild.Kind == ast.KindJsxElement && + !tagNamesAreEquivalent(lastChild.AsJsxElement().OpeningElement.AsJsxOpeningElement().TagName, lastChild.AsJsxElement().ClosingElement.AsJsxClosingElement().TagName) && + tagNamesAreEquivalent(opening.AsJsxOpeningElement().TagName, lastChild.AsJsxElement().ClosingElement.AsJsxClosingElement().TagName) { + // when an unclosed JsxOpeningElement incorrectly parses its parent's JsxClosingElement, + // restructure (
(......
)) --> (
(......)
) + // (no need to error; the parent will error) + end := lastChild.AsJsxElement().OpeningElement.End() + missingIdentifier := p.finishNodeWithEnd(p.newIdentifier(""), end, end) + newClosingElement := p.finishNodeWithEnd(p.factory.NewJsxClosingElement(missingIdentifier), end, end) + newLast := p.finishNodeWithEnd( + p.factory.NewJsxElement(lastChild.AsJsxElement().OpeningElement, lastChild.AsJsxElement().Children, newClosingElement), + lastChild.AsJsxElement().OpeningElement.Pos(), + end, + ) + // force reset parent pointers from discarded parse result + if lastChild.AsJsxElement().OpeningElement != nil { + lastChild.AsJsxElement().OpeningElement.Parent = newLast + } + if lastChild.AsJsxElement().Children != nil { + for _, c := range lastChild.AsJsxElement().Children.Nodes { + c.Parent = newLast + } + } + newClosingElement.Parent = newLast + children = p.newNodeList(core.NewTextRange(children.Pos(), newLast.End()), append(children.Nodes[0:len(children.Nodes)-1], newLast)) + closingElement = lastChild.AsJsxElement().ClosingElement + } else { + closingElement = p.parseJsxClosingElement(opening, inExpressionContext) + if !tagNamesAreEquivalent(opening.AsJsxOpeningElement().TagName, closingElement.AsJsxClosingElement().TagName) { + if openingTag != nil && ast.IsJsxOpeningElement(openingTag) && tagNamesAreEquivalent(closingElement.AsJsxClosingElement().TagName, openingTag.AsJsxOpeningElement().TagName) { + // opening incorrectly matched with its parent's closing -- put error on opening + p.parseErrorAtRange(opening.AsJsxOpeningElement().TagName.Loc, diagnostics.JSX_element_0_has_no_corresponding_closing_tag, scanner.GetTextOfNodeFromSourceText(p.sourceText, opening.AsJsxOpeningElement().TagName, false /*includeTrivia*/)) + } else { + // other opening/closing mismatches -- put error on closing + p.parseErrorAtRange(closingElement.AsJsxClosingElement().TagName.Loc, diagnostics.Expected_corresponding_JSX_closing_tag_for_0, scanner.GetTextOfNodeFromSourceText(p.sourceText, opening.AsJsxOpeningElement().TagName, false /*includeTrivia*/)) + } + } + } + result = p.finishNode(p.factory.NewJsxElement(opening, children, closingElement), pos) + closingElement.Parent = result // force reset parent pointers from possibly discarded parse result + case ast.KindJsxOpeningFragment: + result = p.finishNode(p.factory.NewJsxFragment(opening, p.parseJsxChildren(opening), p.parseJsxClosingFragment(inExpressionContext)), pos) + case ast.KindJsxSelfClosingElement: + // Nothing else to do for self-closing elements + result = opening + default: + panic("Unhandled case in parseJsxElementOrSelfClosingElementOrFragment") + } + // If the user writes the invalid code '
' in an expression context (i.e. not wrapped in + // an enclosing tag), we'll naively try to parse ^ this as a 'less than' operator and the remainder of the tag + // as garbage, which will cause the formatter to badly mangle the JSX. Perform a speculative parse of a JSX + // element if we see a < token so that we can wrap it in a synthetic binary expression so the formatter + // does less damage and we can report a better error. + // Since JSX elements are invalid < operands anyway, this lookahead parse will only occur in error scenarios + // of one sort or another. + // If we are in a unary context, we can't do this recovery; the binary expression we return here is not + // a valid UnaryExpression and will cause problems later. + if !mustBeUnary && inExpressionContext && p.token == ast.KindLessThanToken { + topBadPos := topInvalidNodePosition + if topBadPos < 0 { + topBadPos = result.Pos() + } + invalidElement := p.parseJsxElementOrSelfClosingElementOrFragment( /*inExpressionContext*/ true, topBadPos, nil, false) + operatorToken := p.factory.NewToken(ast.KindCommaToken) + operatorToken.Loc = core.NewTextRange(invalidElement.Pos(), invalidElement.Pos()) + p.parseErrorAt(scanner.SkipTrivia(p.sourceText, topBadPos), invalidElement.End(), diagnostics.JSX_expressions_must_have_one_parent_element) + result = p.finishNode(p.factory.NewBinaryExpression(nil /*modifiers*/, result, nil /*typeNode*/, operatorToken, invalidElement), pos) + } + return result +} + +func (p *Parser) parseJsxChildren(openingTag *ast.Expression) *ast.NodeList { + pos := p.nodePos() + saveParsingContexts := p.parsingContexts + p.parsingContexts |= 1 << PCJsxChildren + var list []*ast.Node + for { + currentToken := p.scanner.ReScanJsxToken(true /*allowMultilineJsxText*/) + child := p.parseJsxChild(openingTag, currentToken) + if child == nil { + break + } + list = append(list, child) + if ast.IsJsxOpeningElement(openingTag) && child.Kind == ast.KindJsxElement && + !tagNamesAreEquivalent(child.AsJsxElement().OpeningElement.AsJsxOpeningElement().TagName, child.AsJsxElement().ClosingElement.AsJsxClosingElement().TagName) && + tagNamesAreEquivalent(openingTag.AsJsxOpeningElement().TagName, child.AsJsxElement().ClosingElement.AsJsxClosingElement().TagName) { + // stop after parsing a mismatched child like
...(
) in order to reattach the higher + break + } + } + p.parsingContexts = saveParsingContexts + return p.newNodeList(core.NewTextRange(pos, p.nodePos()), list) +} + +func (p *Parser) parseJsxChild(openingTag *ast.Node, token ast.Kind) *ast.Expression { + switch token { + case ast.KindEndOfFile: + // If we hit EOF, issue the error at the tag that lacks the closing element + // rather than at the end of the file (which is useless) + if ast.IsJsxOpeningFragment(openingTag) { + p.parseErrorAtRange(openingTag.Loc, diagnostics.JSX_fragment_has_no_corresponding_closing_tag) + } else { + // We want the error span to cover only 'Foo.Bar' in < Foo.Bar > + // or to cover only 'Foo' in < Foo > + tag := openingTag.AsJsxOpeningElement().TagName + start := min(scanner.SkipTrivia(p.sourceText, tag.Pos()), tag.End()) + p.parseErrorAt(start, tag.End(), diagnostics.JSX_element_0_has_no_corresponding_closing_tag, + scanner.GetTextOfNodeFromSourceText(p.sourceText, openingTag.AsJsxOpeningElement().TagName, false /*includeTrivia*/)) + } + return nil + case ast.KindLessThanSlashToken, ast.KindConflictMarkerTrivia: + return nil + case ast.KindJsxText, ast.KindJsxTextAllWhiteSpaces: + return p.parseJsxText() + case ast.KindOpenBraceToken: + return p.parseJsxExpression(false /*inExpressionContext*/) + case ast.KindLessThanToken: + return p.parseJsxElementOrSelfClosingElementOrFragment(false /*inExpressionContext*/, -1 /*topInvalidNodePosition*/, openingTag, false) + } + panic("Unhandled case in parseJsxChild") +} + +func (p *Parser) parseJsxText() *ast.Node { + pos := p.nodePos() + result := p.factory.NewJsxText(p.scanner.TokenValue(), p.token == ast.KindJsxTextAllWhiteSpaces) + p.scanJsxText() + return p.finishNode(result, pos) +} + +func (p *Parser) parseJsxExpression(inExpressionContext bool) *ast.Node { + pos := p.nodePos() + if !p.parseExpected(ast.KindOpenBraceToken) { + return nil + } + var dotDotDotToken *ast.Node + var expression *ast.Expression + if p.token != ast.KindCloseBraceToken { + if !inExpressionContext { + dotDotDotToken = p.parseOptionalToken(ast.KindDotDotDotToken) + } + // Only an AssignmentExpression is valid here per the JSX spec, + // but we can unambiguously parse a comma sequence and provide + // a better error message in grammar checking. + expression = p.parseExpression() + } + if inExpressionContext { + p.parseExpected(ast.KindCloseBraceToken) + } else if p.parseExpectedWithoutAdvancing(ast.KindCloseBraceToken) { + p.scanJsxText() + } + return p.finishNode(p.factory.NewJsxExpression(dotDotDotToken, expression), pos) +} + +func (p *Parser) scanJsxText() ast.Kind { + p.token = p.scanner.ScanJsxToken() + return p.token +} + +func (p *Parser) scanJsxIdentifier() ast.Kind { + p.token = p.scanner.ScanJsxIdentifier() + return p.token +} + +func (p *Parser) scanJsxAttributeValue() ast.Kind { + p.token = p.scanner.ScanJsxAttributeValue() + return p.token +} + +func (p *Parser) parseJsxClosingElement(open *ast.Node, inExpressionContext bool) *ast.Node { + pos := p.nodePos() + p.parseExpected(ast.KindLessThanSlashToken) + tagName := p.parseJsxElementName() + if p.parseExpectedWithDiagnostic(ast.KindGreaterThanToken, nil /*diagnosticMessage*/, false /*shouldAdvance*/) { + // manually advance the scanner in order to look for jsx text inside jsx + if inExpressionContext || !tagNamesAreEquivalent(open.AsJsxOpeningElement().TagName, tagName) { + p.nextToken() + } else { + p.scanJsxText() + } + } + return p.finishNode(p.factory.NewJsxClosingElement(tagName), pos) +} + +func (p *Parser) parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext bool) *ast.Expression { + pos := p.nodePos() + p.parseExpected(ast.KindLessThanToken) + if p.token == ast.KindGreaterThanToken { + // See below for explanation of scanJsxText + p.scanJsxText() + return p.finishNode(p.factory.NewJsxOpeningFragment(), pos) + } + tagName := p.parseJsxElementName() + var typeArguments *ast.NodeList + if p.contextFlags&ast.NodeFlagsJavaScriptFile == 0 { + typeArguments = p.parseTypeArguments() + } + attributes := p.parseJsxAttributes() + var result *ast.Expression + if p.token == ast.KindGreaterThanToken { + // Closing tag, so scan the immediately-following text with the JSX scanning instead + // of regular scanning to avoid treating illegal characters (e.g. '#') as immediate + // scanning errors + p.scanJsxText() + result = p.factory.NewJsxOpeningElement(tagName, typeArguments, attributes) + } else { + p.parseExpected(ast.KindSlashToken) + if p.parseExpectedWithoutAdvancing(ast.KindGreaterThanToken) { + if inExpressionContext { + p.nextToken() + } else { + p.scanJsxText() + } + } + result = p.factory.NewJsxSelfClosingElement(tagName, typeArguments, attributes) + } + return p.finishNode(result, pos) +} + +func (p *Parser) parseJsxElementName() *ast.Expression { + pos := p.nodePos() + // JsxElement can have name in the form of + // propertyAccessExpression + // primaryExpression in the form of an identifier and "this" keyword + // We can't just simply use parseLeftHandSideExpressionOrHigher because then we will start consider class,function etc as a keyword + // We only want to consider "this" as a primaryExpression + initialExpression := p.parseJsxTagName() + if ast.IsJsxNamespacedName(initialExpression) { + return initialExpression // `a:b.c` is invalid syntax, don't even look for the `.` if we parse `a:b`, and let `parseAttribute` report "unexpected :" instead. + } + expression := initialExpression + for p.parseOptional(ast.KindDotToken) { + expression = p.finishNode(p.factory.NewPropertyAccessExpression(expression, nil, p.parseRightSideOfDot(true /*allowIdentifierNames*/, false /*allowPrivateIdentifiers*/, false /*allowUnicodeEscapeSequenceInIdentifierName*/), ast.NodeFlagsNone), pos) + } + return expression +} + +func (p *Parser) parseJsxTagName() *ast.Expression { + pos := p.nodePos() + p.scanJsxIdentifier() + isThis := p.token == ast.KindThisKeyword + tagName := p.parseIdentifierNameErrorOnUnicodeEscapeSequence() + if p.parseOptional(ast.KindColonToken) { + p.scanJsxIdentifier() + return p.finishNode(p.factory.NewJsxNamespacedName(tagName, p.parseIdentifierNameErrorOnUnicodeEscapeSequence()), pos) + } + if isThis { + result := p.factory.NewKeywordExpression(ast.KindThisKeyword) + return p.finishNode(result, pos) + } + return tagName +} + +func (p *Parser) parseJsxAttributes() *ast.Node { + pos := p.nodePos() + return p.finishNode(p.factory.NewJsxAttributes(p.parseList(PCJsxAttributes, (*Parser).parseJsxAttribute)), pos) +} + +func (p *Parser) parseJsxAttribute() *ast.Node { + if p.token == ast.KindOpenBraceToken { + return p.parseJsxSpreadAttribute() + } + pos := p.nodePos() + return p.finishNode(p.factory.NewJsxAttribute(p.parseJsxAttributeName(), p.parseJsxAttributeValue()), pos) +} + +func (p *Parser) parseJsxSpreadAttribute() *ast.Node { + pos := p.nodePos() + p.parseExpected(ast.KindOpenBraceToken) + p.parseExpected(ast.KindDotDotDotToken) + expression := p.parseExpression() + p.parseExpected(ast.KindCloseBraceToken) + return p.finishNode(p.factory.NewJsxSpreadAttribute(expression), pos) +} + +func (p *Parser) parseJsxAttributeName() *ast.Node { + pos := p.nodePos() + p.scanJsxIdentifier() + attrName := p.parseIdentifierNameErrorOnUnicodeEscapeSequence() + if p.parseOptional(ast.KindColonToken) { + p.scanJsxIdentifier() + return p.finishNode(p.factory.NewJsxNamespacedName(attrName, p.parseIdentifierNameErrorOnUnicodeEscapeSequence()), pos) + } + return attrName +} + +func (p *Parser) parseJsxAttributeValue() *ast.Expression { + if p.token == ast.KindEqualsToken { + if p.scanJsxAttributeValue() == ast.KindStringLiteral { + return p.parseLiteralExpression(false /*intern*/) + } + if p.token == ast.KindOpenBraceToken { + return p.parseJsxExpression( /*inExpressionContext*/ true) + } + if p.token == ast.KindLessThanToken { + return p.parseJsxElementOrSelfClosingElementOrFragment(true /*inExpressionContext*/, -1, nil, false) + } + p.parseErrorAtCurrentToken(diagnostics.X_or_JSX_element_expected) + } + return nil +} + +func (p *Parser) parseJsxClosingFragment(inExpressionContext bool) *ast.Node { + pos := p.nodePos() + p.parseExpected(ast.KindLessThanSlashToken) + if p.parseExpectedWithDiagnostic(ast.KindGreaterThanToken, diagnostics.Expected_corresponding_closing_tag_for_JSX_fragment, false /*shouldAdvance*/) { + // manually advance the scanner in order to look for jsx text inside jsx + if inExpressionContext { + p.nextToken() + } else { + p.scanJsxText() + } + } + return p.finishNode(p.factory.NewJsxClosingFragment(), pos) +} + +func (p *Parser) parseSimpleUnaryExpression() *ast.Expression { + switch p.token { + case ast.KindPlusToken, ast.KindMinusToken, ast.KindTildeToken, ast.KindExclamationToken: + return p.parsePrefixUnaryExpression() + case ast.KindDeleteKeyword: + return p.parseDeleteExpression() + case ast.KindTypeOfKeyword: + return p.parseTypeOfExpression() + case ast.KindVoidKeyword: + return p.parseVoidExpression() + case ast.KindLessThanToken: + // Just like in parseUpdateExpression, we need to avoid parsing type assertions when + // in JSX and we see an expression like "+ bar". + if p.languageVariant == core.LanguageVariantJSX { + return p.parseJsxElementOrSelfClosingElementOrFragment(true /*inExpressionContext*/, -1 /*topInvalidNodePosition*/, nil /*openingTag*/, true /*mustBeUnary*/) + } + // // This is modified UnaryExpression grammar in TypeScript + // // UnaryExpression (modified): + // // < type > UnaryExpression + return p.parseTypeAssertion() + case ast.KindAwaitKeyword: + if p.isAwaitExpression() { + return p.parseAwaitExpression() + } + fallthrough + default: + return p.parseUpdateExpression() + } +} + +func (p *Parser) parsePrefixUnaryExpression() *ast.Node { + pos := p.nodePos() + operator := p.token + p.nextToken() + return p.finishNode(p.factory.NewPrefixUnaryExpression(operator, p.parseSimpleUnaryExpression()), pos) +} + +func (p *Parser) parseDeleteExpression() *ast.Node { + pos := p.nodePos() + p.nextToken() + return p.finishNode(p.factory.NewDeleteExpression(p.parseSimpleUnaryExpression()), pos) +} + +func (p *Parser) parseTypeOfExpression() *ast.Node { + pos := p.nodePos() + p.nextToken() + return p.finishNode(p.factory.NewTypeOfExpression(p.parseSimpleUnaryExpression()), pos) +} + +func (p *Parser) parseVoidExpression() *ast.Node { + pos := p.nodePos() + p.nextToken() + return p.finishNode(p.factory.NewVoidExpression(p.parseSimpleUnaryExpression()), pos) +} + +func (p *Parser) isAwaitExpression() bool { + if p.token == ast.KindAwaitKeyword { + if p.inAwaitContext() { + return true + } + // here we are using similar heuristics as 'isYieldExpression' + return p.lookAhead((*Parser).nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine) + } + return false +} + +func (p *Parser) parseAwaitExpression() *ast.Node { + pos := p.nodePos() + p.nextToken() + return p.finishNode(p.factory.NewAwaitExpression(p.parseSimpleUnaryExpression()), pos) +} + +func (p *Parser) parseTypeAssertion() *ast.Node { + debug.Assert(p.languageVariant != core.LanguageVariantJSX, "Type assertions should never be parsed in JSX; they should be parsed as comparisons or JSX elements/fragments.") + pos := p.nodePos() + p.parseExpected(ast.KindLessThanToken) + typeNode := p.parseType() + p.parseExpected(ast.KindGreaterThanToken) + expression := p.parseSimpleUnaryExpression() + return p.finishNode(p.factory.NewTypeAssertion(typeNode, expression), pos) +} + +func (p *Parser) parseLeftHandSideExpressionOrHigher() *ast.Expression { + // Original Ecma: + // LeftHandSideExpression: See 11.2 + // NewExpression + // CallExpression + // + // Our simplification: + // + // LeftHandSideExpression: See 11.2 + // MemberExpression + // CallExpression + // + // See comment in parseMemberExpressionOrHigher on how we replaced NewExpression with + // MemberExpression to make our lives easier. + // + // to best understand the below code, it's important to see how CallExpression expands + // out into its own productions: + // + // CallExpression: + // MemberExpression Arguments + // CallExpression Arguments + // CallExpression[Expression] + // CallExpression.IdentifierName + // import (AssignmentExpression) + // super Arguments + // super.IdentifierName + // + // Because of the recursion in these calls, we need to bottom out first. There are three + // bottom out states we can run into: 1) We see 'super' which must start either of + // the last two CallExpression productions. 2) We see 'import' which must start import call. + // 3)we have a MemberExpression which either completes the LeftHandSideExpression, + // or starts the beginning of the first four CallExpression productions. + pos := p.nodePos() + var expression *ast.Expression + if p.token == ast.KindImportKeyword { + if p.lookAhead((*Parser).nextTokenIsOpenParenOrLessThan) { + // We don't want to eagerly consume all import keyword as import call expression so we look ahead to find "(" + // For example: + // var foo3 = require("subfolder + // import * as foo1 from "module-from-node + // We want this import to be a statement rather than import call expression + p.sourceFlags |= ast.NodeFlagsPossiblyContainsDynamicImport + expression = p.parseKeywordExpression() + } else if p.lookAhead((*Parser).nextTokenIsDot) { + // This is an 'import.*' metaproperty (i.e. 'import.meta') + p.nextToken() // advance past the 'import' + p.nextToken() // advance past the dot + expression = p.finishNode(p.factory.NewMetaProperty(ast.KindImportKeyword, p.parseIdentifierName()), pos) + if expression.Text() == "defer" { + if p.token == ast.KindOpenParenToken || p.token == ast.KindLessThanToken { + p.sourceFlags |= ast.NodeFlagsPossiblyContainsDynamicImport + } + } else { + p.sourceFlags |= ast.NodeFlagsPossiblyContainsImportMeta + } + } else { + expression = p.parseMemberExpressionOrHigher() + } + } else if p.token == ast.KindSuperKeyword { + expression = p.parseSuperExpression() + } else { + expression = p.parseMemberExpressionOrHigher() + } + // Now, we *may* be complete. However, we might have consumed the start of a + // CallExpression or OptionalExpression. As such, we need to consume the rest + // of it here to be complete. + return p.parseCallExpressionRest(pos, expression) +} + +func (p *Parser) nextTokenIsDot() bool { + return p.nextToken() == ast.KindDotToken +} + +func (p *Parser) parseSuperExpression() *ast.Expression { + pos := p.nodePos() + expression := p.parseKeywordExpression() + if p.token == ast.KindLessThanToken { + startPos := p.nodePos() + typeArguments := p.tryParseTypeArgumentsInExpression() + if typeArguments != nil { + p.parseErrorAt(startPos, p.nodePos(), diagnostics.X_super_may_not_use_type_arguments) + if !p.isTemplateStartOfTaggedTemplate() { + expression = p.finishNode(p.factory.NewExpressionWithTypeArguments(expression, typeArguments), pos) + } + } + } + if p.token == ast.KindOpenParenToken || p.token == ast.KindDotToken || p.token == ast.KindOpenBracketToken { + return expression + } + // If we have seen "super" it must be followed by '(' or '.'. + // If it wasn't then just try to parse out a '.' and report an error. + p.parseErrorAtCurrentToken(diagnostics.X_super_must_be_followed_by_an_argument_list_or_member_access) + // private names will never work with `super` (`super.#foo`), but that's a semantic error, not syntactic + return p.finishNode(p.factory.NewPropertyAccessExpression(expression, nil /*questionDotToken*/, p.parseRightSideOfDot(true /*allowIdentifierNames*/, true /*allowPrivateIdentifiers*/, true /*allowUnicodeEscapeSequenceInIdentifierName*/), ast.NodeFlagsNone), pos) +} + +func (p *Parser) isTemplateStartOfTaggedTemplate() bool { + return p.token == ast.KindNoSubstitutionTemplateLiteral || p.token == ast.KindTemplateHead +} + +func (p *Parser) tryParseTypeArgumentsInExpression() *ast.NodeList { + // TypeArguments must not be parsed in JavaScript files to avoid ambiguity with binary operators. + state := p.mark() + if p.contextFlags&ast.NodeFlagsJavaScriptFile == 0 && p.reScanLessThanToken() == ast.KindLessThanToken { + p.nextToken() + typeArguments := p.parseDelimitedList(PCTypeArguments, (*Parser).parseType) + // If it doesn't have the closing `>` then it's definitely not an type argument list. + if p.reScanGreaterThanToken() == ast.KindGreaterThanToken { + p.nextToken() + // We successfully parsed a type argument list. The next token determines whether we want to + // treat it as such. If the type argument list is followed by `(` or a template literal, as in + // `f(42)`, we favor the type argument interpretation even though JavaScript would view + // it as a relational expression. + if p.canFollowTypeArgumentsInExpression() { + return typeArguments + } + } + } + p.rewind(state) + return nil +} + +func (p *Parser) canFollowTypeArgumentsInExpression() bool { + switch p.token { + // These tokens can follow a type argument list in a call expression: + // foo( + // foo `...` + // foo `...${100}...` + case ast.KindOpenParenToken, ast.KindNoSubstitutionTemplateLiteral, ast.KindTemplateHead: + return true + // A type argument list followed by `<` never makes sense, and a type argument list followed + // by `>` is ambiguous with a (re-scanned) `>>` operator, so we disqualify both. Also, in + // this context, `+` and `-` are unary operators, not binary operators. + case ast.KindLessThanToken, ast.KindGreaterThanToken, ast.KindPlusToken, ast.KindMinusToken: + return false + } + // We favor the type argument list interpretation when it is immediately followed by + // a line break, a binary operator, or something that can't start an expression. + return p.hasPrecedingLineBreak() || p.isBinaryOperator() || !p.isStartOfExpression() +} + +func (p *Parser) parseMemberExpressionOrHigher() *ast.Node { + // Note: to make our lives simpler, we decompose the NewExpression productions and + // place ObjectCreationExpression and FunctionExpression into PrimaryExpression. + // like so: + // + // PrimaryExpression : See 11.1 + // this + // Identifier + // Literal + // ArrayLiteral + // ObjectLiteral + // (Expression) + // FunctionExpression + // new MemberExpression Arguments? + // + // MemberExpression : See 11.2 + // PrimaryExpression + // MemberExpression[Expression] + // MemberExpression.IdentifierName + // + // CallExpression : See 11.2 + // MemberExpression + // CallExpression Arguments + // CallExpression[Expression] + // CallExpression.IdentifierName + // + // Technically this is ambiguous. i.e. CallExpression defines: + // + // CallExpression: + // CallExpression Arguments + // + // If you see: "new Foo()" + // + // Then that could be treated as a single ObjectCreationExpression, or it could be + // treated as the invocation of "new Foo". We disambiguate that in code (to match + // the original grammar) by making sure that if we see an ObjectCreationExpression + // we always consume arguments if they are there. So we treat "new Foo()" as an + // object creation only, and not at all as an invocation. Another way to think + // about this is that for every "new" that we see, we will consume an argument list if + // it is there as part of the *associated* object creation node. Any additional + // argument lists we see, will become invocation expressions. + // + // Because there are no other places in the grammar now that refer to FunctionExpression + // or ObjectCreationExpression, it is safe to push down into the PrimaryExpression + // production. + // + // Because CallExpression and MemberExpression are left recursive, we need to bottom out + // of the recursion immediately. So we parse out a primary expression to start with. + pos := p.nodePos() + expression := p.parsePrimaryExpression() + return p.parseMemberExpressionRest(pos, expression, true /*allowOptionalChain*/) +} + +func (p *Parser) parseMemberExpressionRest(pos int, expression *ast.Expression, allowOptionalChain bool) *ast.Expression { + for { + var questionDotToken *ast.Node + isPropertyAccess := false + if allowOptionalChain && p.isStartOfOptionalPropertyOrElementAccessChain() { + questionDotToken = p.parseExpectedToken(ast.KindQuestionDotToken) + isPropertyAccess = tokenIsIdentifierOrKeyword(p.token) + } else { + isPropertyAccess = p.parseOptional(ast.KindDotToken) + } + if isPropertyAccess { + expression = p.parsePropertyAccessExpressionRest(pos, expression, questionDotToken) + continue + } + // when in the [Decorator] context, we do not parse ElementAccess as it could be part of a ComputedPropertyName + if (questionDotToken != nil || !p.inDecoratorContext()) && p.parseOptional(ast.KindOpenBracketToken) { + expression = p.parseElementAccessExpressionRest(pos, expression, questionDotToken) + continue + } + if p.isTemplateStartOfTaggedTemplate() { + // Absorb type arguments into TemplateExpression when preceding expression is ExpressionWithTypeArguments + if questionDotToken == nil && ast.IsExpressionWithTypeArguments(expression) { + original := expression.AsExpressionWithTypeArguments() + expression = p.parseTaggedTemplateRest(pos, original.Expression, questionDotToken, original.TypeArguments) + p.unparseExpressionWithTypeArguments(original.Expression, original.TypeArguments, expression) + } else { + expression = p.parseTaggedTemplateRest(pos, expression, questionDotToken, nil /*typeArguments*/) + } + continue + } + if questionDotToken == nil { + if p.token == ast.KindExclamationToken && !p.hasPrecedingLineBreak() { + p.nextToken() + expression = p.checkJSSyntax(p.finishNode(p.factory.NewNonNullExpression(expression, ast.NodeFlagsNone), pos)) + continue + } + typeArguments := p.tryParseTypeArgumentsInExpression() + if typeArguments != nil { + expression = p.finishNode(p.factory.NewExpressionWithTypeArguments(expression, typeArguments), pos) + continue + } + } + return expression + } +} + +func (p *Parser) isStartOfOptionalPropertyOrElementAccessChain() bool { + return p.token == ast.KindQuestionDotToken && p.lookAhead((*Parser).nextTokenIsIdentifierOrKeywordOrOpenBracketOrTemplate) +} + +func (p *Parser) nextTokenIsIdentifierOrKeywordOrOpenBracketOrTemplate() bool { + p.nextToken() + return tokenIsIdentifierOrKeyword(p.token) || p.token == ast.KindOpenBracketToken || p.isTemplateStartOfTaggedTemplate() +} + +func (p *Parser) parsePropertyAccessExpressionRest(pos int, expression *ast.Expression, questionDotToken *ast.Node) *ast.Node { + name := p.parseRightSideOfDot(true /*allowIdentifierNames*/, true /*allowPrivateIdentifiers*/, true /*allowUnicodeEscapeSequenceInIdentifierName*/) + isOptionalChain := questionDotToken != nil || p.tryReparseOptionalChain(expression) + propertyAccess := p.factory.NewPropertyAccessExpression(expression, questionDotToken, name, core.IfElse(isOptionalChain, ast.NodeFlagsOptionalChain, ast.NodeFlagsNone)) + if isOptionalChain && ast.IsPrivateIdentifier(name) { + p.parseErrorAtRange(p.skipRangeTrivia(name.Loc), diagnostics.An_optional_chain_cannot_contain_private_identifiers) + } + if ast.IsExpressionWithTypeArguments(expression) { + typeArguments := expression.AsExpressionWithTypeArguments().TypeArguments + if typeArguments != nil { + loc := core.NewTextRange(typeArguments.Pos()-1, scanner.SkipTrivia(p.sourceText, typeArguments.End())+1) + p.parseErrorAtRange(loc, diagnostics.An_instantiation_expression_cannot_be_followed_by_a_property_access) + } + } + return p.finishNode(propertyAccess, pos) +} + +func (p *Parser) tryReparseOptionalChain(node *ast.Expression) bool { + if node.Flags&ast.NodeFlagsOptionalChain != 0 { + return true + } + // check for an optional chain in a non-null expression + if ast.IsNonNullExpression(node) { + expr := node.AsNonNullExpression().Expression + for ast.IsNonNullExpression(expr) && expr.Flags&ast.NodeFlagsOptionalChain == 0 { + expr = expr.AsNonNullExpression().Expression + } + if expr.Flags&ast.NodeFlagsOptionalChain != 0 { + // this is part of an optional chain. Walk down from `node` to `expression` and set the flag. + for ast.IsNonNullExpression(node) { + node.Flags |= ast.NodeFlagsOptionalChain + node = node.AsNonNullExpression().Expression + } + return true + } + } + return false +} + +func (p *Parser) parseElementAccessExpressionRest(pos int, expression *ast.Expression, questionDotToken *ast.Node) *ast.Node { + var argumentExpression *ast.Expression + if p.token == ast.KindCloseBracketToken { + p.parseErrorAt(p.nodePos(), p.nodePos(), diagnostics.An_element_access_expression_should_take_an_argument) + argumentExpression = p.createMissingIdentifier() + } else { + argument := p.parseExpressionAllowIn() + switch argument.Kind { + case ast.KindStringLiteral: + argument.AsStringLiteral().Text = p.internIdentifier(argument.AsStringLiteral().Text) + case ast.KindNoSubstitutionTemplateLiteral: + argument.AsNoSubstitutionTemplateLiteral().Text = p.internIdentifier(argument.AsNoSubstitutionTemplateLiteral().Text) + case ast.KindNumericLiteral: + argument.AsNumericLiteral().Text = p.internIdentifier(argument.AsNumericLiteral().Text) + } + argumentExpression = argument + } + p.parseExpected(ast.KindCloseBracketToken) + isOptionalChain := questionDotToken != nil || p.tryReparseOptionalChain(expression) + return p.finishNode(p.factory.NewElementAccessExpression(expression, questionDotToken, argumentExpression, core.IfElse(isOptionalChain, ast.NodeFlagsOptionalChain, ast.NodeFlagsNone)), pos) +} + +func (p *Parser) parseCallExpressionRest(pos int, expression *ast.Expression) *ast.Expression { + for { + expression = p.parseMemberExpressionRest(pos, expression /*allowOptionalChain*/, true) + var typeArguments *ast.NodeList + questionDotToken := p.parseOptionalToken(ast.KindQuestionDotToken) + if questionDotToken != nil { + typeArguments = p.tryParseTypeArgumentsInExpression() + if p.isTemplateStartOfTaggedTemplate() { + expression = p.parseTaggedTemplateRest(pos, expression, questionDotToken, typeArguments) + continue + } + } + if typeArguments != nil || p.token == ast.KindOpenParenToken { + // Absorb type arguments into CallExpression when preceding expression is ExpressionWithTypeArguments + if questionDotToken == nil && expression.Kind == ast.KindExpressionWithTypeArguments { + typeArguments = expression.AsExpressionWithTypeArguments().TypeArguments + expression = expression.AsExpressionWithTypeArguments().Expression + } + inner := expression + argumentList := p.parseArgumentList() + isOptionalChain := questionDotToken != nil || p.tryReparseOptionalChain(expression) + expression = p.checkJSSyntax(p.finishNode(p.factory.NewCallExpression(expression, questionDotToken, typeArguments, argumentList, core.IfElse(isOptionalChain, ast.NodeFlagsOptionalChain, ast.NodeFlagsNone)), pos)) + p.unparseExpressionWithTypeArguments(inner, typeArguments, expression) + continue + } + if questionDotToken != nil { + // We parsed `?.` but then failed to parse anything, so report a missing identifier here. + p.parseErrorAtCurrentToken(diagnostics.Identifier_expected) + name := p.createMissingIdentifier() + expression = p.finishNode(p.factory.NewPropertyAccessExpression(expression, questionDotToken, name, ast.NodeFlagsOptionalChain), pos) + } + break + } + return expression +} + +func (p *Parser) parseArgumentList() *ast.NodeList { + p.parseExpected(ast.KindOpenParenToken) + result := p.parseDelimitedList(PCArgumentExpressions, (*Parser).parseArgumentExpression) + p.parseExpected(ast.KindCloseParenToken) + return result +} + +func (p *Parser) parseArgumentExpression() *ast.Expression { + return doInContext(p, ast.NodeFlagsDisallowInContext|ast.NodeFlagsDecoratorContext, false, (*Parser).parseArgumentOrArrayLiteralElement) +} + +func (p *Parser) parseArgumentOrArrayLiteralElement() *ast.Expression { + switch p.token { + case ast.KindDotDotDotToken: + return p.parseSpreadElement() + case ast.KindCommaToken: + return p.finishNode(p.factory.NewOmittedExpression(), p.nodePos()) + } + return p.parseAssignmentExpressionOrHigher() +} + +func (p *Parser) parseSpreadElement() *ast.Node { + pos := p.nodePos() + p.parseExpected(ast.KindDotDotDotToken) + expression := p.parseAssignmentExpressionOrHigher() + return p.finishNode(p.factory.NewSpreadElement(expression), pos) +} + +func (p *Parser) parseTaggedTemplateRest(pos int, tag *ast.Expression, questionDotToken *ast.Node, typeArguments *ast.NodeList) *ast.Node { + var template *ast.Expression + if p.token == ast.KindNoSubstitutionTemplateLiteral { + p.reScanTemplateToken(true /*isTaggedTemplate*/) + template = p.parseLiteralExpression(false /*intern*/) + } else { + template = p.parseTemplateExpression(true /*isTaggedTemplate*/) + } + isOptionalChain := questionDotToken != nil || tag.Flags&ast.NodeFlagsOptionalChain != 0 + return p.checkJSSyntax(p.finishNode(p.factory.NewTaggedTemplateExpression(tag, questionDotToken, typeArguments, template, core.IfElse(isOptionalChain, ast.NodeFlagsOptionalChain, ast.NodeFlagsNone)), pos)) +} + +func (p *Parser) parseTemplateExpression(isTaggedTemplate bool) *ast.Expression { + pos := p.nodePos() + return p.finishNode(p.factory.NewTemplateExpression(p.parseTemplateHead(isTaggedTemplate), p.parseTemplateSpans(isTaggedTemplate)), pos) +} + +func (p *Parser) parseTemplateSpans(isTaggedTemplate bool) *ast.NodeList { + pos := p.nodePos() + var list []*ast.Node + for { + span := p.parseTemplateSpan(isTaggedTemplate) + list = append(list, span) + if span.AsTemplateSpan().Literal.Kind != ast.KindTemplateMiddle { + break + } + } + return p.newNodeList(core.NewTextRange(pos, p.nodePos()), list) +} + +func (p *Parser) parseTemplateSpan(isTaggedTemplate bool) *ast.Node { + pos := p.nodePos() + expression := p.parseExpressionAllowIn() + literal := p.parseLiteralOfTemplateSpan(isTaggedTemplate) + return p.finishNode(p.factory.NewTemplateSpan(expression, literal), pos) +} + +func (p *Parser) parsePrimaryExpression() *ast.Expression { + switch p.token { + case ast.KindNoSubstitutionTemplateLiteral: + if p.scanner.TokenFlags()&ast.TokenFlagsIsInvalid != 0 { + p.reScanTemplateToken(false /*isTaggedTemplate*/) + } + fallthrough + case ast.KindNumericLiteral, ast.KindBigIntLiteral, ast.KindStringLiteral: + return p.parseLiteralExpression(false /*intern*/) + case ast.KindThisKeyword, ast.KindSuperKeyword, ast.KindNullKeyword, ast.KindTrueKeyword, ast.KindFalseKeyword: + return p.parseKeywordExpression() + case ast.KindOpenParenToken: + return p.parseParenthesizedExpression() + case ast.KindOpenBracketToken: + return p.parseArrayLiteralExpression() + case ast.KindOpenBraceToken: + return p.parseObjectLiteralExpression() + case ast.KindAsyncKeyword: + // Async arrow functions are parsed earlier in parseAssignmentExpressionOrHigher. + // If we encounter `async [no LineTerminator here] function` then this is an async + // function; otherwise, its an identifier. + if !p.lookAhead((*Parser).nextTokenIsFunctionKeywordOnSameLine) { + break + } + return p.parseFunctionExpression() + case ast.KindAtToken: + return p.parseDecoratedExpression() + case ast.KindClassKeyword: + return p.parseClassExpression() + case ast.KindFunctionKeyword: + return p.parseFunctionExpression() + case ast.KindNewKeyword: + return p.parseNewExpressionOrNewDotTarget() + case ast.KindSlashToken, ast.KindSlashEqualsToken: + if p.reScanSlashToken() == ast.KindRegularExpressionLiteral { + return p.parseLiteralExpression(false /*intern*/) + } + case ast.KindTemplateHead: + return p.parseTemplateExpression(false /*isTaggedTemplate*/) + case ast.KindPrivateIdentifier: + return p.parsePrivateIdentifier() + } + return p.parseIdentifierWithDiagnostic(diagnostics.Expression_expected, nil) +} + +func (p *Parser) parseParenthesizedExpression() *ast.Expression { + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + p.parseExpected(ast.KindOpenParenToken) + expression := p.parseExpressionAllowIn() + p.parseExpected(ast.KindCloseParenToken) + result := p.finishNode(p.factory.NewParenthesizedExpression(expression), pos) + p.withJSDoc(result, hasJSDoc) + return result +} + +func (p *Parser) parseArrayLiteralExpression() *ast.Expression { + pos := p.nodePos() + openBracketPosition := p.scanner.TokenStart() + openBracketParsed := p.parseExpected(ast.KindOpenBracketToken) + multiLine := p.hasPrecedingLineBreak() + elements := p.parseDelimitedList(PCArrayLiteralMembers, (*Parser).parseArgumentOrArrayLiteralElement) + p.parseExpectedMatchingBrackets(ast.KindOpenBracketToken, ast.KindCloseBracketToken, openBracketParsed, openBracketPosition) + return p.finishNode(p.factory.NewArrayLiteralExpression(elements, multiLine), pos) +} + +func (p *Parser) parseObjectLiteralExpression() *ast.Expression { + pos := p.nodePos() + openBracePosition := p.scanner.TokenStart() + openBraceParsed := p.parseExpected(ast.KindOpenBraceToken) + multiLine := p.hasPrecedingLineBreak() + properties := p.parseDelimitedList(PCObjectLiteralMembers, (*Parser).parseObjectLiteralElement) + p.parseExpectedMatchingBrackets(ast.KindOpenBraceToken, ast.KindCloseBraceToken, openBraceParsed, openBracePosition) + return p.finishNode(p.factory.NewObjectLiteralExpression(properties, multiLine), pos) +} + +func (p *Parser) parseObjectLiteralElement() *ast.Node { + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + if p.parseOptional(ast.KindDotDotDotToken) { + expression := p.parseAssignmentExpressionOrHigher() + result := p.finishNode(p.factory.NewSpreadAssignment(expression), pos) + p.withJSDoc(result, hasJSDoc) + return result + } + modifiers := p.parseModifiersEx(true /*allowDecorators*/, false /*permitConstAsModifier*/, false /*stopOnStartOfClassStaticBlock*/) + if p.parseContextualModifier(ast.KindGetKeyword) { + return p.parseAccessorDeclaration(pos, hasJSDoc, modifiers, ast.KindGetAccessor, ParseFlagsNone) + } + if p.parseContextualModifier(ast.KindSetKeyword) { + return p.parseAccessorDeclaration(pos, hasJSDoc, modifiers, ast.KindSetAccessor, ParseFlagsNone) + } + asteriskToken := p.parseOptionalToken(ast.KindAsteriskToken) + tokenIsIdentifier := p.isIdentifier() + name := p.parsePropertyName() + // Disallowing of optional property assignments and definite assignment assertion happens in the grammar checker. + postfixToken := p.parseOptionalToken(ast.KindQuestionToken) + // Decorators, Modifiers, questionToken, and exclamationToken are not supported by property assignments and are reported in the grammar checker + if postfixToken == nil { + postfixToken = p.parseOptionalToken(ast.KindExclamationToken) + } + if asteriskToken != nil || p.token == ast.KindOpenParenToken || p.token == ast.KindLessThanToken { + return p.parseMethodDeclaration(pos, hasJSDoc, modifiers, asteriskToken, name, postfixToken, nil /*diagnosticMessage*/) + } + // check if it is short-hand property assignment or normal property assignment + // NOTE: if token is EqualsToken it is interpreted as CoverInitializedName production + // CoverInitializedName[Yield] : + // IdentifierReference[?Yield] Initializer[In, ?Yield] + // this is necessary because ObjectLiteral productions are also used to cover grammar for ObjectAssignmentPattern + var node *ast.Node + isShorthandPropertyAssignment := tokenIsIdentifier && p.token != ast.KindColonToken + if isShorthandPropertyAssignment { + equalsToken := p.parseOptionalToken(ast.KindEqualsToken) + var initializer *ast.Expression + if equalsToken != nil { + initializer = doInContext(p, ast.NodeFlagsDisallowInContext, false, (*Parser).parseAssignmentExpressionOrHigher) + } + node = p.factory.NewShorthandPropertyAssignment(modifiers, name, postfixToken, nil /*typeNode*/, equalsToken, initializer) + } else { + p.parseExpected(ast.KindColonToken) + initializer := doInContext(p, ast.NodeFlagsDisallowInContext, false, (*Parser).parseAssignmentExpressionOrHigher) + node = p.factory.NewPropertyAssignment(modifiers, name, postfixToken, nil /*typeNode*/, initializer) + } + p.finishNode(node, pos) + p.withJSDoc(node, hasJSDoc) + return node +} + +func (p *Parser) parseFunctionExpression() *ast.Expression { + // GeneratorExpression: + // function* BindingIdentifier [Yield][opt](FormalParameters[Yield]){ GeneratorBody } + // + // FunctionExpression: + // function BindingIdentifier[opt](FormalParameters){ FunctionBody } + saveContexFlags := p.contextFlags + p.setContextFlags(ast.NodeFlagsDecoratorContext, false) + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + modifiers := p.parseModifiers() + p.parseExpected(ast.KindFunctionKeyword) + asteriskToken := p.parseOptionalToken(ast.KindAsteriskToken) + isGenerator := asteriskToken != nil + isAsync := modifierListHasAsync(modifiers) + signatureFlags := core.IfElse(isGenerator, ParseFlagsYield, ParseFlagsNone) | core.IfElse(isAsync, ParseFlagsAwait, ParseFlagsNone) + var name *ast.Node + switch { + case isGenerator && isAsync: + name = doInContext(p, ast.NodeFlagsYieldContext|ast.NodeFlagsAwaitContext, true, (*Parser).parseOptionalBindingIdentifier) + case isGenerator: + name = doInContext(p, ast.NodeFlagsYieldContext, true, (*Parser).parseOptionalBindingIdentifier) + case isAsync: + name = doInContext(p, ast.NodeFlagsAwaitContext, true, (*Parser).parseOptionalBindingIdentifier) + default: + name = p.parseOptionalBindingIdentifier() + } + typeParameters := p.parseTypeParameters() + parameters := p.parseParameters(signatureFlags) + returnType := p.parseReturnType(ast.KindColonToken, false /*isType*/) + body := p.parseFunctionBlock(signatureFlags, nil /*diagnosticMessage*/) + p.contextFlags = saveContexFlags + result := p.factory.NewFunctionExpression(modifiers, asteriskToken, name, typeParameters, parameters, returnType, nil /*fullSignature*/, body) + p.finishNode(result, pos) + p.withJSDoc(result, hasJSDoc) + p.checkJSSyntax(result) + return result +} + +func (p *Parser) parseOptionalBindingIdentifier() *ast.Node { + if p.isBindingIdentifier() { + return p.parseBindingIdentifier() + } + return nil +} + +func (p *Parser) parseDecoratedExpression() *ast.Expression { + pos := p.nodePos() + hasJSDoc := p.hasPrecedingJSDocComment() + modifiers := p.parseModifiersEx(true /*allowDecorators*/, false /*permitConstAsModifier*/, false /*stopOnStartOfClassStaticBlock*/) + if p.token == ast.KindClassKeyword { + return p.parseClassDeclarationOrExpression(pos, hasJSDoc, modifiers, ast.KindClassExpression) + } + p.parseErrorAt(p.nodePos(), p.nodePos(), diagnostics.Expression_expected) + return p.finishNode(p.factory.NewMissingDeclaration(modifiers), pos) +} + +func (p *Parser) unparseExpressionWithTypeArguments(expression *ast.Node, typeArguments *ast.NodeList, result *ast.Node) { + // force overwrite the `.Parent` of the expression and type arguments to erase the fact that they may have originally been parsed as an ExpressionWithTypeArguments and be parented to such + if expression != nil { + expression.Parent = result + } + if typeArguments != nil { + for _, a := range typeArguments.Nodes { + a.Parent = result + } + } +} + +func (p *Parser) parseNewExpressionOrNewDotTarget() *ast.Node { + pos := p.nodePos() + p.parseExpected(ast.KindNewKeyword) + if p.parseOptional(ast.KindDotToken) { + name := p.parseIdentifierName() + return p.finishNode(p.factory.NewMetaProperty(ast.KindNewKeyword, name), pos) + } + expressionPos := p.nodePos() + expression := p.parseMemberExpressionRest(expressionPos, p.parsePrimaryExpression(), false /*allowOptionalChain*/) + var typeArguments *ast.NodeList + // Absorb type arguments into NewExpression when preceding expression is ExpressionWithTypeArguments + if expression.Kind == ast.KindExpressionWithTypeArguments { + typeArguments = expression.AsExpressionWithTypeArguments().TypeArguments + expression = expression.AsExpressionWithTypeArguments().Expression + } + if p.token == ast.KindQuestionDotToken { + p.parseErrorAtCurrentToken(diagnostics.Invalid_optional_chain_from_new_expression_Did_you_mean_to_call_0, scanner.GetTextOfNodeFromSourceText(p.sourceText, expression, false /*includeTrivia*/)) + } + var argumentList *ast.NodeList + if p.token == ast.KindOpenParenToken { + argumentList = p.parseArgumentList() + } + result := p.checkJSSyntax(p.finishNode(p.factory.NewNewExpression(expression, typeArguments, argumentList), pos)) + p.unparseExpressionWithTypeArguments(expression, typeArguments, result) + return result +} + +func (p *Parser) parseKeywordExpression() *ast.Node { + pos := p.nodePos() + result := p.factory.NewKeywordExpression(p.token) + p.nextToken() + return p.finishNode(result, pos) +} + +func (p *Parser) parseLiteralExpression(intern bool) *ast.Node { + pos := p.nodePos() + text := p.scanner.TokenValue() + if intern { + text = p.internIdentifier(text) + } + tokenFlags := p.scanner.TokenFlags() + var result *ast.Node + switch p.token { + case ast.KindStringLiteral: + result = p.factory.NewStringLiteral(text) + result.AsStringLiteral().TokenFlags |= tokenFlags & ast.TokenFlagsStringLiteralFlags + case ast.KindNumericLiteral: + result = p.factory.NewNumericLiteral(text) + result.AsNumericLiteral().TokenFlags |= tokenFlags & ast.TokenFlagsNumericLiteralFlags + case ast.KindBigIntLiteral: + result = p.factory.NewBigIntLiteral(text) + result.AsBigIntLiteral().TokenFlags |= tokenFlags & ast.TokenFlagsNumericLiteralFlags + case ast.KindRegularExpressionLiteral: + result = p.factory.NewRegularExpressionLiteral(text) + result.AsRegularExpressionLiteral().TokenFlags |= tokenFlags & ast.TokenFlagsRegularExpressionLiteralFlags + case ast.KindNoSubstitutionTemplateLiteral: + result = p.factory.NewNoSubstitutionTemplateLiteral(text) + result.AsNoSubstitutionTemplateLiteral().TokenFlags |= tokenFlags & ast.TokenFlagsTemplateLiteralLikeFlags + default: + panic("Unhandled case in parseLiteralExpression") + } + p.nextToken() + return p.finishNode(result, pos) +} + +func (p *Parser) parseIdentifierNameErrorOnUnicodeEscapeSequence() *ast.Node { + if p.scanner.HasUnicodeEscape() || p.scanner.HasExtendedUnicodeEscape() { + p.parseErrorAtCurrentToken(diagnostics.Unicode_escape_sequence_cannot_appear_here) + } + return p.createIdentifier(tokenIsIdentifierOrKeyword(p.token)) +} + +func (p *Parser) parseBindingIdentifier() *ast.Node { + return p.parseBindingIdentifierWithDiagnostic(nil) +} + +func (p *Parser) parseBindingIdentifierWithDiagnostic(privateIdentifierDiagnosticMessage *diagnostics.Message) *ast.Node { + saveHasAwaitIdentifier := p.statementHasAwaitIdentifier + id := p.createIdentifierWithDiagnostic(p.isBindingIdentifier(), nil /*diagnosticMessage*/, privateIdentifierDiagnosticMessage) + p.statementHasAwaitIdentifier = saveHasAwaitIdentifier + return id +} + +func (p *Parser) parseIdentifierName() *ast.Node { + return p.parseIdentifierNameWithDiagnostic(nil) +} + +func (p *Parser) parseIdentifierNameWithDiagnostic(diagnosticMessage *diagnostics.Message) *ast.Node { + return p.createIdentifierWithDiagnostic(tokenIsIdentifierOrKeyword(p.token), diagnosticMessage, nil) +} + +func (p *Parser) parseIdentifier() *ast.Node { + return p.parseIdentifierWithDiagnostic(nil, nil) +} + +func (p *Parser) parseIdentifierWithDiagnostic(diagnosticMessage *diagnostics.Message, privateIdentifierDiagnosticMessage *diagnostics.Message) *ast.Node { + return p.createIdentifierWithDiagnostic(p.isIdentifier(), diagnosticMessage, privateIdentifierDiagnosticMessage) +} + +func (p *Parser) createIdentifier(isIdentifier bool) *ast.Node { + return p.createIdentifierWithDiagnostic(isIdentifier, nil, nil) +} + +func (p *Parser) createIdentifierWithDiagnostic(isIdentifier bool, diagnosticMessage *diagnostics.Message, privateIdentifierDiagnosticMessage *diagnostics.Message) *ast.Node { + if isIdentifier { + var pos int + if p.scanner.HasPrecedingJSDocLeadingAsterisks() { + pos = p.scanner.TokenStart() + } else { + pos = p.nodePos() + } + text := p.scanner.TokenValue() + p.nextTokenWithoutCheck() + return p.finishNode(p.newIdentifier(p.internIdentifier(text)), pos) + } + if p.token == ast.KindPrivateIdentifier { + if privateIdentifierDiagnosticMessage != nil { + p.parseErrorAtCurrentToken(privateIdentifierDiagnosticMessage) + } else { + p.parseErrorAtCurrentToken(diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies) + } + return p.createIdentifier(true /*isIdentifier*/) + } + if diagnosticMessage != nil { + p.parseErrorAtCurrentToken(diagnosticMessage) + } else if isReservedWord(p.token) { + p.parseErrorAtCurrentToken(diagnostics.Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here, p.scanner.TokenText()) + } else { + p.parseErrorAtCurrentToken(diagnostics.Identifier_expected) + } + return p.createMissingIdentifier() +} + +func (p *Parser) internIdentifier(text string) string { + if identifier, ok := p.identifiers[text]; ok { + return identifier + } + identifier := text + if p.identifiers == nil { + p.identifiers = make(map[string]string) + } + p.identifiers[identifier] = identifier + return identifier +} + +func (p *Parser) newNodeList(loc core.TextRange, nodes []*ast.Node) *ast.NodeList { + list := p.factory.NewNodeList(nodes) + list.Loc = loc + return list +} + +func (p *Parser) newModifierList(loc core.TextRange, nodes []*ast.Node) *ast.ModifierList { + list := p.factory.NewModifierList(nodes) + list.Loc = loc + return list +} + +func (p *Parser) finishNode(node *ast.Node, pos int) *ast.Node { + return p.finishNodeWithEnd(node, pos, p.nodePos()) +} + +func (p *Parser) finishNodeWithEnd(node *ast.Node, pos int, end int) *ast.Node { + node.Loc = core.NewTextRange(pos, end) + node.Flags |= p.contextFlags + if p.hasParseError { + node.Flags |= ast.NodeFlagsThisNodeHasError + p.hasParseError = false + } + p.overrideParentInImmediateChildren(node) + return node +} + +func (p *Parser) overrideParentInImmediateChildren(node *ast.Node) { + p.currentParent = node + node.ForEachChild(p.setParentFromContext) + p.currentParent = nil +} + +func (p *Parser) nextTokenIsSlash() bool { + return p.nextToken() == ast.KindSlashToken +} + +func (p *Parser) scanTypeMemberStart() bool { + // Return true if we have the start of a signature member + if p.token == ast.KindOpenParenToken || p.token == ast.KindLessThanToken || p.token == ast.KindGetKeyword || p.token == ast.KindSetKeyword { + return true + } + idToken := false + // Eat up all modifiers, but hold on to the last one in case it is actually an identifier + for ast.IsModifierKind(p.token) { + idToken = true + p.nextToken() + } + // Index signatures and computed property names are type members + if p.token == ast.KindOpenBracketToken { + return true + } + // Try to get the first property-like token following all modifiers + if p.isLiteralPropertyName() { + idToken = true + p.nextToken() + } + // If we were able to get any potential identifier, check that it is + // the start of a member declaration + if idToken { + return p.token == ast.KindOpenParenToken || p.token == ast.KindLessThanToken || p.token == ast.KindQuestionToken || p.token == ast.KindColonToken || p.token == ast.KindCommaToken || p.canParseSemicolon() + } + return false +} + +func (p *Parser) scanClassMemberStart() bool { + idToken := ast.KindUnknown + if p.token == ast.KindAtToken { + return true + } + // Eat up all modifiers, but hold on to the last one in case it is actually an identifier. + for ast.IsModifierKind(p.token) { + idToken = p.token + // If the idToken is a class modifier (protected, private, public, and static), it is + // certain that we are starting to parse class member. This allows better error recovery + // Example: + // public foo() ... // true + // public @dec blah ... // true; we will then report an error later + // export public ... // true; we will then report an error later + if ast.IsClassMemberModifier(idToken) { + return true + } + p.nextToken() + } + if p.token == ast.KindAsteriskToken { + return true + } + // Try to get the first property-like token following all modifiers. + // This can either be an identifier or the 'get' or 'set' keywords. + if p.isLiteralPropertyName() { + idToken = p.token + p.nextToken() + } + // Index signatures and computed properties are class members; we can parse. + if p.token == ast.KindOpenBracketToken { + return true + } + // If we were able to get any potential identifier... + if idToken != ast.KindUnknown { + // If we have a non-keyword identifier, or if we have an accessor, then it's safe to parse. + if !ast.IsKeyword(idToken) || idToken == ast.KindSetKeyword || idToken == ast.KindGetKeyword { + return true + } + // If it *is* a keyword, but not an accessor, check a little farther along + // to see if it should actually be parsed as a class member. + switch p.token { + case ast.KindOpenParenToken, // Method declaration + ast.KindLessThanToken, // Generic Method declaration + ast.KindExclamationToken, // Non-null assertion on property name + ast.KindColonToken, // Type Annotation for declaration + ast.KindEqualsToken, // Initializer for declaration + ast.KindQuestionToken: // Not valid, but permitted so that it gets caught later on. + return true + } + // Covers + // - Semicolons (declaration termination) + // - Closing braces (end-of-class, must be declaration) + // - End-of-files (not valid, but permitted so that it gets caught later on) + // - Line-breaks (enabling *automatic semicolon insertion*) + return p.canParseSemicolon() + } + return false +} + +func (p *Parser) canParseSemicolon() bool { + // If there's a real semicolon, then we can always parse it out. + // We can parse out an optional semicolon in ASI cases in the following cases. + return p.token == ast.KindSemicolonToken || p.token == ast.KindCloseBraceToken || p.token == ast.KindEndOfFile || p.hasPrecedingLineBreak() +} + +func (p *Parser) tryParseSemicolon() bool { + if !p.canParseSemicolon() { + return false + } + if p.token == ast.KindSemicolonToken { + // consume the semicolon if it was explicitly provided. + p.nextToken() + } + return true +} + +func (p *Parser) parseSemicolon() bool { + return p.tryParseSemicolon() || p.parseExpected(ast.KindSemicolonToken) +} + +func (p *Parser) isLiteralPropertyName() bool { + return tokenIsIdentifierOrKeyword(p.token) || p.token == ast.KindStringLiteral || p.token == ast.KindNumericLiteral || p.token == ast.KindBigIntLiteral +} + +func (p *Parser) isStartOfStatement() bool { + switch p.token { + // 'catch' and 'finally' do not actually indicate that the code is part of a statement, + // however, we say they are here so that we may gracefully parse them and error later. + case ast.KindAtToken, ast.KindSemicolonToken, ast.KindOpenBraceToken, ast.KindVarKeyword, ast.KindLetKeyword, + ast.KindUsingKeyword, ast.KindFunctionKeyword, ast.KindClassKeyword, ast.KindEnumKeyword, ast.KindIfKeyword, + ast.KindDoKeyword, ast.KindWhileKeyword, ast.KindForKeyword, ast.KindContinueKeyword, ast.KindBreakKeyword, + ast.KindReturnKeyword, ast.KindWithKeyword, ast.KindSwitchKeyword, ast.KindThrowKeyword, ast.KindTryKeyword, + ast.KindDebuggerKeyword, ast.KindCatchKeyword, ast.KindFinallyKeyword: + return true + case ast.KindImportKeyword: + return p.isStartOfDeclaration() || p.isNextTokenOpenParenOrLessThanOrDot() + case ast.KindConstKeyword, ast.KindExportKeyword: + return p.isStartOfDeclaration() + case ast.KindAsyncKeyword, ast.KindDeclareKeyword, ast.KindInterfaceKeyword, ast.KindModuleKeyword, ast.KindNamespaceKeyword, + ast.KindTypeKeyword, ast.KindGlobalKeyword, ast.KindDeferKeyword: + // When these don't start a declaration, they're an identifier in an expression statement + return true + case ast.KindAccessorKeyword, ast.KindPublicKeyword, ast.KindPrivateKeyword, ast.KindProtectedKeyword, ast.KindStaticKeyword, + ast.KindReadonlyKeyword: + // When these don't start a declaration, they may be the start of a class member if an identifier + // immediately follows. Otherwise they're an identifier in an expression statement. + return p.isStartOfDeclaration() || !p.lookAhead((*Parser).nextTokenIsIdentifierOrKeywordOnSameLine) + + default: + return p.isStartOfExpression() + } +} + +func (p *Parser) isStartOfDeclaration() bool { + return p.lookAhead((*Parser).scanStartOfDeclaration) +} + +func (p *Parser) scanStartOfDeclaration() bool { + for { + switch p.token { + case ast.KindVarKeyword, ast.KindLetKeyword, ast.KindConstKeyword, ast.KindFunctionKeyword, ast.KindClassKeyword, + ast.KindEnumKeyword: + return true + case ast.KindUsingKeyword: + return p.isUsingDeclaration() + case ast.KindAwaitKeyword: + return p.isAwaitUsingDeclaration() + // 'declare', 'module', 'namespace', 'interface'* and 'type' are all legal JavaScript identifiers; + // however, an identifier cannot be followed by another identifier on the same line. This is what we + // count on to parse out the respective declarations. For instance, we exploit this to say that + // + // namespace n + // + // can be none other than the beginning of a namespace declaration, but need to respect that JavaScript sees + // + // namespace + // n + // + // as the identifier 'namespace' on one line followed by the identifier 'n' on another. + // We need to look one token ahead to see if it permissible to try parsing a declaration. + // + // *Note*: 'interface' is actually a strict mode reserved word. So while + // + // "use strict" + // interface + // I {} + // + // could be legal, it would add complexity for very little gain. + case ast.KindInterfaceKeyword, ast.KindTypeKeyword, ast.KindDeferKeyword: + return p.nextTokenIsIdentifierOnSameLine() + case ast.KindModuleKeyword, ast.KindNamespaceKeyword: + return p.nextTokenIsIdentifierOrStringLiteralOnSameLine() + case ast.KindAbstractKeyword, ast.KindAccessorKeyword, ast.KindAsyncKeyword, ast.KindDeclareKeyword, ast.KindPrivateKeyword, + ast.KindProtectedKeyword, ast.KindPublicKeyword, ast.KindReadonlyKeyword: + previousToken := p.token + p.nextToken() + // ASI takes effect for this modifier. + if p.hasPrecedingLineBreak() { + return false + } + if previousToken == ast.KindDeclareKeyword && p.token == ast.KindTypeKeyword { + // If we see 'declare type', then commit to parsing a type alias. parseTypeAliasDeclaration will + // report Line_break_not_permitted_here if needed. + return true + } + continue + case ast.KindGlobalKeyword: + p.nextToken() + return p.token == ast.KindOpenBraceToken || p.token == ast.KindIdentifier || p.token == ast.KindExportKeyword + case ast.KindImportKeyword: + p.nextToken() + return p.token == ast.KindDeferKeyword || p.token == ast.KindStringLiteral || p.token == ast.KindAsteriskToken || p.token == ast.KindOpenBraceToken || tokenIsIdentifierOrKeyword(p.token) + case ast.KindExportKeyword: + p.nextToken() + if p.token == ast.KindEqualsToken || p.token == ast.KindAsteriskToken || p.token == ast.KindOpenBraceToken || + p.token == ast.KindDefaultKeyword || p.token == ast.KindAsKeyword || p.token == ast.KindAtToken { + return true + } + if p.token == ast.KindTypeKeyword { + p.nextToken() + return p.token == ast.KindAsteriskToken || p.token == ast.KindOpenBraceToken || p.isIdentifier() && !p.hasPrecedingLineBreak() + } + continue + case ast.KindStaticKeyword: + p.nextToken() + continue + } + return false + } +} + +func (p *Parser) isStartOfExpression() bool { + if p.isStartOfLeftHandSideExpression() { + return true + } + switch p.token { + case ast.KindPlusToken, ast.KindMinusToken, ast.KindTildeToken, ast.KindExclamationToken, ast.KindDeleteKeyword, + ast.KindTypeOfKeyword, ast.KindVoidKeyword, ast.KindPlusPlusToken, ast.KindMinusMinusToken, ast.KindLessThanToken, + ast.KindAwaitKeyword, ast.KindYieldKeyword, ast.KindPrivateIdentifier, ast.KindAtToken: + // Yield/await always starts an expression. Either it is an identifier (in which case + // it is definitely an expression). Or it's a keyword (either because we're in + // a generator or async function, or in strict mode (or both)) and it started a yield or await expression. + return true + } + // Error tolerance. If we see the start of some binary operator, we consider + // that the start of an expression. That way we'll parse out a missing identifier, + // give a good message about an identifier being missing, and then consume the + // rest of the binary expression. + if p.isBinaryOperator() { + return true + } + return p.isIdentifier() +} + +func (p *Parser) isStartOfLeftHandSideExpression() bool { + switch p.token { + case ast.KindThisKeyword, ast.KindSuperKeyword, ast.KindNullKeyword, ast.KindTrueKeyword, ast.KindFalseKeyword, + ast.KindNumericLiteral, ast.KindBigIntLiteral, ast.KindStringLiteral, ast.KindNoSubstitutionTemplateLiteral, ast.KindTemplateHead, + ast.KindOpenParenToken, ast.KindOpenBracketToken, ast.KindOpenBraceToken, ast.KindFunctionKeyword, ast.KindClassKeyword, + ast.KindNewKeyword, ast.KindSlashToken, ast.KindSlashEqualsToken, ast.KindIdentifier: + return true + case ast.KindImportKeyword: + return p.isNextTokenOpenParenOrLessThanOrDot() + } + return p.isIdentifier() +} + +func (p *Parser) isStartOfType(inStartOfParameter bool) bool { + switch p.token { + case ast.KindAnyKeyword, ast.KindUnknownKeyword, ast.KindStringKeyword, ast.KindNumberKeyword, ast.KindBigIntKeyword, + ast.KindBooleanKeyword, ast.KindReadonlyKeyword, ast.KindSymbolKeyword, ast.KindUniqueKeyword, ast.KindVoidKeyword, + ast.KindUndefinedKeyword, ast.KindNullKeyword, ast.KindThisKeyword, ast.KindTypeOfKeyword, ast.KindNeverKeyword, + ast.KindOpenBraceToken, ast.KindOpenBracketToken, ast.KindLessThanToken, ast.KindBarToken, ast.KindAmpersandToken, + ast.KindNewKeyword, ast.KindStringLiteral, ast.KindNumericLiteral, ast.KindBigIntLiteral, ast.KindTrueKeyword, + ast.KindFalseKeyword, ast.KindObjectKeyword, ast.KindAsteriskToken, ast.KindQuestionToken, ast.KindExclamationToken, + ast.KindDotDotDotToken, ast.KindInferKeyword, ast.KindImportKeyword, ast.KindAssertsKeyword, ast.KindNoSubstitutionTemplateLiteral, + ast.KindTemplateHead: + return true + case ast.KindFunctionKeyword: + return !inStartOfParameter + case ast.KindMinusToken: + return !inStartOfParameter && p.lookAhead((*Parser).nextTokenIsNumericOrBigIntLiteral) + case ast.KindOpenParenToken: + // Only consider '(' the start of a type if followed by ')', '...', an identifier, a modifier, + // or something that starts a type. We don't want to consider things like '(1)' a type. + return !inStartOfParameter && p.lookAhead((*Parser).nextIsParenthesizedOrFunctionType) + } + return p.isIdentifier() +} + +func (p *Parser) nextTokenIsNumericOrBigIntLiteral() bool { + p.nextToken() + return p.token == ast.KindNumericLiteral || p.token == ast.KindBigIntLiteral +} + +func (p *Parser) nextIsParenthesizedOrFunctionType() bool { + p.nextToken() + return p.token == ast.KindCloseParenToken || p.isStartOfParameter(false /*isJSDocParameter*/) || p.isStartOfType(false /*inStartOfParameter*/) +} + +func (p *Parser) isStartOfParameter(isJSDocParameter bool) bool { + return p.token == ast.KindDotDotDotToken || + p.isBindingIdentifierOrPrivateIdentifierOrPattern() || + ast.IsModifierKind(p.token) || + p.token == ast.KindAtToken || + p.isStartOfType(!isJSDocParameter /*inStartOfParameter*/) +} + +func (p *Parser) isBindingIdentifierOrPrivateIdentifierOrPattern() bool { + return p.token == ast.KindOpenBraceToken || p.token == ast.KindOpenBracketToken || p.token == ast.KindPrivateIdentifier || p.isBindingIdentifier() +} + +func (p *Parser) isNextTokenOpenParenOrLessThanOrDot() bool { + return p.lookAhead((*Parser).nextTokenIsOpenParenOrLessThanOrDot) +} + +func (p *Parser) nextTokenIsOpenParenOrLessThanOrDot() bool { + switch p.nextToken() { + case ast.KindOpenParenToken, ast.KindLessThanToken, ast.KindDotToken: + return true + } + return false +} + +func (p *Parser) nextTokenIsIdentifierOnSameLine() bool { + p.nextToken() + return p.isIdentifier() && !p.hasPrecedingLineBreak() +} + +func (p *Parser) nextTokenIsIdentifierOrStringLiteralOnSameLine() bool { + p.nextToken() + return (p.isIdentifier() || p.token == ast.KindStringLiteral) && !p.hasPrecedingLineBreak() +} + +// Ignore strict mode flag because we will report an error in type checker instead. +func (p *Parser) isIdentifier() bool { + if p.token == ast.KindIdentifier { + return true + } + // If we have a 'yield' keyword, and we're in the [yield] context, then 'yield' is + // considered a keyword and is not an identifier. + // If we have a 'await' keyword, and we're in the [Await] context, then 'await' is + // considered a keyword and is not an identifier. + if p.token == ast.KindYieldKeyword && p.inYieldContext() || p.token == ast.KindAwaitKeyword && p.inAwaitContext() { + return false + } + return p.token > ast.KindLastReservedWord +} + +func (p *Parser) isBindingIdentifier() bool { + // `let await`/`let yield` in [Yield] or [Await] are allowed here and disallowed in the binder. + return p.token == ast.KindIdentifier || p.token > ast.KindLastReservedWord +} + +func (p *Parser) isImportAttributeName() bool { + return tokenIsIdentifierOrKeyword(p.token) || p.token == ast.KindStringLiteral +} + +func (p *Parser) isBinaryOperator() bool { + if p.inDisallowInContext() && p.token == ast.KindInKeyword { + return false + } + return ast.GetBinaryOperatorPrecedence(p.token) != ast.OperatorPrecedenceInvalid +} + +func (p *Parser) isValidHeritageClauseObjectLiteral() bool { + return p.lookAhead((*Parser).nextIsValidHeritageClauseObjectLiteral) +} + +func (p *Parser) nextIsValidHeritageClauseObjectLiteral() bool { + if p.nextToken() == ast.KindCloseBraceToken { + // if we see "extends {}" then only treat the {} as what we're extending (and not + // the class body) if we have: + // + // extends {} { + // extends {}, + // extends {} extends + // extends {} implements + next := p.nextToken() + return next == ast.KindCommaToken || next == ast.KindOpenBraceToken || next == ast.KindExtendsKeyword || next == ast.KindImplementsKeyword + } + return true +} + +func (p *Parser) isHeritageClause() bool { + return p.token == ast.KindExtendsKeyword || p.token == ast.KindImplementsKeyword +} + +func (p *Parser) isHeritageClauseExtendsOrImplementsKeyword() bool { + return p.isHeritageClause() && p.lookAhead((*Parser).nextIsStartOfExpression) +} + +func (p *Parser) nextIsStartOfExpression() bool { + p.nextToken() + return p.isStartOfExpression() +} + +func (p *Parser) isUsingDeclaration() bool { + // 'using' always starts a lexical declaration if followed by an identifier. We also eagerly parse + // |ObjectBindingPattern| so that we can report a grammar error during check. We don't parse out + // |ArrayBindingPattern| since it potentially conflicts with element access (i.e., `using[x]`). + return p.lookAhead(func(p *Parser) bool { + return p.nextTokenIsBindingIdentifierOrStartOfDestructuringOnSameLine( /*disallowOf*/ false) + }) +} + +func (p *Parser) nextTokenIsEqualsOrSemicolonOrColonToken() bool { + p.nextToken() + return p.token == ast.KindEqualsToken || p.token == ast.KindSemicolonToken || p.token == ast.KindColonToken +} + +func (p *Parser) nextTokenIsBindingIdentifierOrStartOfDestructuringOnSameLine(disallowOf bool) bool { + p.nextToken() + if disallowOf && p.token == ast.KindOfKeyword { + return p.lookAhead((*Parser).nextTokenIsEqualsOrSemicolonOrColonToken) + } + return p.isBindingIdentifier() || p.token == ast.KindOpenBraceToken && !p.hasPrecedingLineBreak() +} + +func (p *Parser) nextTokenIsBindingIdentifierOrStartOfDestructuringOnSameLineDisallowOf() bool { + return p.nextTokenIsBindingIdentifierOrStartOfDestructuringOnSameLine( /*disallowOf*/ true) +} + +func (p *Parser) isAwaitUsingDeclaration() bool { + return p.lookAhead((*Parser).nextIsUsingKeywordThenBindingIdentifierOrStartOfObjectDestructuringOnSameLine) +} + +func (p *Parser) nextIsUsingKeywordThenBindingIdentifierOrStartOfObjectDestructuringOnSameLine() bool { + return p.nextToken() == ast.KindUsingKeyword && p.nextTokenIsBindingIdentifierOrStartOfDestructuringOnSameLine( /*disallowOf*/ false) +} + +func (p *Parser) nextTokenIsTokenStringLiteral() bool { + return p.nextToken() == ast.KindStringLiteral +} + +func (p *Parser) setContextFlags(flags ast.NodeFlags, value bool) { + if value { + p.contextFlags |= flags + } else { + p.contextFlags &= ^flags + } +} + +func doInContext[T any](p *Parser, flags ast.NodeFlags, value bool, f func(p *Parser) T) T { + saveContextFlags := p.contextFlags + p.setContextFlags(flags, value) + result := f(p) + p.contextFlags = saveContextFlags + return result +} + +func (p *Parser) inYieldContext() bool { + return p.contextFlags&ast.NodeFlagsYieldContext != 0 +} + +func (p *Parser) inDisallowInContext() bool { + return p.contextFlags&ast.NodeFlagsDisallowInContext != 0 +} + +func (p *Parser) inDisallowConditionalTypesContext() bool { + return p.contextFlags&ast.NodeFlagsDisallowConditionalTypesContext != 0 +} + +func (p *Parser) inDecoratorContext() bool { + return p.contextFlags&ast.NodeFlagsDecoratorContext != 0 +} + +func (p *Parser) inAwaitContext() bool { + return p.contextFlags&ast.NodeFlagsAwaitContext != 0 +} + +func (p *Parser) skipRangeTrivia(textRange core.TextRange) core.TextRange { + return core.NewTextRange(scanner.SkipTrivia(p.sourceText, textRange.Pos()), textRange.End()) +} + +func isReservedWord(token ast.Kind) bool { + return ast.KindFirstReservedWord <= token && token <= ast.KindLastReservedWord +} + +func tagNamesAreEquivalent(lhs *ast.Expression, rhs *ast.Expression) bool { + if lhs.Kind != rhs.Kind { + return false + } + switch lhs.Kind { + case ast.KindIdentifier: + return lhs.AsIdentifier().Text == rhs.AsIdentifier().Text + case ast.KindThisKeyword: + return true + case ast.KindJsxNamespacedName: + return lhs.AsJsxNamespacedName().Namespace.AsIdentifier().Text == rhs.AsJsxNamespacedName().Namespace.AsIdentifier().Text && + lhs.AsJsxNamespacedName().Name().AsIdentifier().Text == rhs.AsJsxNamespacedName().Name().AsIdentifier().Text + case ast.KindPropertyAccessExpression: + return lhs.AsPropertyAccessExpression().Name().Text() == rhs.AsPropertyAccessExpression().Name().Text() && + tagNamesAreEquivalent(lhs.AsPropertyAccessExpression().Expression, rhs.AsPropertyAccessExpression().Expression) + } + panic("Unhandled case in tagNamesAreEquivalent") +} + +func attachFileToDiagnostics(diagnostics []*ast.Diagnostic, file *ast.SourceFile) []*ast.Diagnostic { + for _, d := range diagnostics { + d.SetFile(file) + for _, r := range d.RelatedInformation() { + r.SetFile(file) + } + } + return diagnostics +} + +func getCommentPragmas(f *ast.NodeFactory, sourceText string) (pragmas []ast.Pragma) { + for commentRange := range scanner.GetLeadingCommentRanges(f, sourceText, 0) { + comment := sourceText[commentRange.Pos():commentRange.End()] + pragmas = append(pragmas, extractPragmas(commentRange, comment)...) + } + return pragmas +} + +func extractPragmas(commentRange ast.CommentRange, text string) []ast.Pragma { + if commentRange.Kind == ast.KindSingleLineCommentTrivia { + pos := 2 + tripleSlash := match(text, pos, "/") + if tripleSlash { + pos++ + } + pos = skipBlanks(text, pos) + if tripleSlash && match(text, pos, "<") { + tagName := extractName(text, pos+1) + if tagName != "reference" { + return nil + } + pos += 10 + args := make(map[string]ast.PragmaArgument) + for { + pos = skipBlanks(text, pos) + if match(text, pos, "/>") { + break + } + argName := extractName(text, pos) + if argName == "" { + break + } + pos = skipBlanks(text, pos+len(argName)) + if !match(text, pos, "=") { + break + } + pos = skipBlanks(text, pos+1) + value, ok := extractQuotedString(text, pos) + if !ok { + break + } + args[argName] = ast.PragmaArgument{ + Name: argName, + Value: value, + TextRange: core.NewTextRange(commentRange.Pos()+pos+1, commentRange.Pos()+pos+1+len(value)), + } + pos += len(value) + 2 + } + return []ast.Pragma{{ + CommentRange: commentRange, + Name: "reference", + Args: args, + }} + } + if match(text, pos, "@") { + pos++ + pragmaName := extractName(text, pos) + if !(pragmaName == "ts-check" || pragmaName == "ts-nocheck") { + return nil + } + return []ast.Pragma{{ + CommentRange: commentRange, + Name: pragmaName, + }} + } + } + if commentRange.Kind == ast.KindMultiLineCommentTrivia { + text = strings.TrimSuffix(text, "*/") + pos := 2 + var pragmas []ast.Pragma + for { + if pos = skipTo(text, pos, "@"); pos < 0 { + break + } + pragmaName := extractName(text, pos+1) + if !(pragmaName == "jsx" || pragmaName == "jsxfrag" || pragmaName == "jsximportsource" || pragmaName == "jsxruntime") { + break + } + start := skipBlanks(text, pos+len(pragmaName)+1) + pos = skipNonBlanks(text, start) + if pos == start { + break + } + args := make(map[string]ast.PragmaArgument, 1) + args["factory"] = ast.PragmaArgument{ + Name: "factory", + Value: text[start:pos], + TextRange: core.NewTextRange(commentRange.Pos()+start, commentRange.Pos()+pos), + } + pragmas = append(pragmas, ast.Pragma{ + CommentRange: commentRange, + Name: pragmaName, + Args: args, + }) + } + return pragmas + } + return nil +} + +func match(text string, pos int, s string) bool { + return strings.HasPrefix(text[pos:], s) +} + +func skipBlanks(text string, pos int) int { + for pos < len(text) && (text[pos] == ' ' || text[pos] == '\t') { + pos++ + } + return pos +} + +func skipNonBlanks(text string, pos int) int { + for pos < len(text) && (text[pos] != ' ' && text[pos] != '\t' && text[pos] != '\r' && text[pos] != '\n') { + pos++ + } + return pos +} + +func skipTo(text string, pos int, s string) int { + i := strings.Index(text[pos:], s) + if i < 0 { + return -1 + } + return pos + i +} + +func extractName(text string, pos int) string { + start := pos + for pos < len(text) && (text[pos] >= 'A' && text[pos] <= 'Z' || text[pos] >= 'a' && text[pos] <= 'z' || text[pos] == '-') { + pos++ + } + return strings.ToLower(text[start:pos]) +} + +func extractQuotedString(text string, pos int) (string, bool) { + if pos == len(text) { + return "", false + } + quote := text[pos] + if quote != '\'' && quote != '"' { + return "", false + } + pos++ + start := pos + for pos < len(text) && text[pos] != quote { + pos++ + } + if pos == len(text) { + return "", false + } + return text[start:pos], true +} + +func (p *Parser) processPragmasIntoFields(context *ast.SourceFile) { + context.CheckJsDirective = nil + context.ReferencedFiles = nil + context.TypeReferenceDirectives = nil + context.LibReferenceDirectives = nil + // context.AmdDependencies = nil + for _, pragma := range context.Pragmas { + switch pragma.Name { + case "reference": + types, typesOk := pragma.Args["types"] + lib, libOk := pragma.Args["lib"] + path, pathOk := pragma.Args["path"] + resolutionMode, resolutionModeOk := pragma.Args["resolution-mode"] + preserve, preserveOk := pragma.Args["preserve"] + noDefaultLib, noDefaultLibOk := pragma.Args["no-default-lib"] + switch { + case noDefaultLibOk && noDefaultLib.Value == "true": + // Ignored. + case typesOk: + var parsed core.ResolutionMode + if resolutionModeOk { + parsed = parseResolutionMode(resolutionMode.Value, resolutionMode.Pos(), resolutionMode.End() /*, reportDiagnostic*/) + } + context.TypeReferenceDirectives = append(context.TypeReferenceDirectives, &ast.FileReference{ + TextRange: types.TextRange, + FileName: types.Value, + ResolutionMode: parsed, + Preserve: preserveOk && preserve.Value == "true", + }) + case libOk: + context.LibReferenceDirectives = append(context.LibReferenceDirectives, &ast.FileReference{ + TextRange: lib.TextRange, + FileName: lib.Value, + Preserve: preserveOk && preserve.Value == "true", + }) + case pathOk: + context.ReferencedFiles = append(context.ReferencedFiles, &ast.FileReference{ + TextRange: path.TextRange, + FileName: path.Value, + Preserve: preserveOk && preserve.Value == "true", + }) + default: + p.parseErrorAtRange(pragma.TextRange, diagnostics.Invalid_reference_directive_syntax) + } + case "ts-check", "ts-nocheck": + // _last_ of either nocheck or check in a file is the "winner" + for _, directive := range context.Pragmas { + if context.CheckJsDirective == nil || directive.TextRange.Pos() > context.CheckJsDirective.Range.Pos() { + context.CheckJsDirective = &ast.CheckJsDirective{ + Enabled: directive.Name == "ts-check", + Range: directive.CommentRange, + } + } + } + case "jsx", "jsxfrag", "jsximportsource", "jsxruntime": + // Nothing to do here + default: + panic("Unhandled pragma kind: " + pragma.Name) + } + } +} + +func parseResolutionMode(mode string, pos int, end int /*reportDiagnostic: PragmaDiagnosticReporter*/) (resolutionKind core.ResolutionMode) { + if mode == "import" { + resolutionKind = core.ModuleKindESNext + } + if mode == "require" { + resolutionKind = core.ModuleKindCommonJS + } + return resolutionKind + // reportDiagnostic(pos, end - pos, Diagnostics.resolution_mode_should_be_either_require_or_import); + // return undefined; +} + +func (p *Parser) jsErrorAtRange(loc core.TextRange, message *diagnostics.Message, args ...any) { + p.jsDiagnostics = append(p.jsDiagnostics, ast.NewDiagnostic(nil, core.NewTextRange(scanner.SkipTrivia(p.sourceText, loc.Pos()), loc.End()), message, args...)) +} + +func (p *Parser) checkJSSyntax(node *ast.Node) *ast.Node { + if node.Flags&ast.NodeFlagsJavaScriptFile == 0 || node.Flags&(ast.NodeFlagsJSDoc|ast.NodeFlagsReparsed) != 0 { + return node + } + switch node.Kind { + case ast.KindParameter, ast.KindPropertyDeclaration, ast.KindMethodDeclaration: + if token := node.PostfixToken(); token != nil && token.Flags&ast.NodeFlagsReparsed == 0 && ast.IsQuestionToken(token) { + p.jsErrorAtRange(token.Loc, diagnostics.The_0_modifier_can_only_be_used_in_TypeScript_files, "?") + } + fallthrough + case ast.KindMethodSignature, ast.KindConstructor, ast.KindGetAccessor, ast.KindSetAccessor, ast.KindFunctionExpression, + ast.KindFunctionDeclaration, ast.KindArrowFunction, ast.KindVariableDeclaration, ast.KindIndexSignature: + if ast.IsFunctionLike(node) && node.Body() == nil { + p.jsErrorAtRange(node.Loc, diagnostics.Signature_declarations_can_only_be_used_in_TypeScript_files) + } else if t := node.Type(); t != nil && t.Flags&ast.NodeFlagsReparsed == 0 { + p.jsErrorAtRange(t.Loc, diagnostics.Type_annotations_can_only_be_used_in_TypeScript_files) + } + case ast.KindImportDeclaration: + if clause := node.AsImportDeclaration().ImportClause; clause != nil && clause.IsTypeOnly() { + p.jsErrorAtRange(node.Loc, diagnostics.X_0_declarations_can_only_be_used_in_TypeScript_files, "import type") + } + case ast.KindExportDeclaration: + if node.IsTypeOnly() { + p.jsErrorAtRange(node.Loc, diagnostics.X_0_declarations_can_only_be_used_in_TypeScript_files, "export type") + } + case ast.KindImportSpecifier: + if node.IsTypeOnly() { + p.jsErrorAtRange(node.Loc, diagnostics.X_0_declarations_can_only_be_used_in_TypeScript_files, "import...type") + } + case ast.KindExportSpecifier: + if node.IsTypeOnly() { + p.jsErrorAtRange(node.Loc, diagnostics.X_0_declarations_can_only_be_used_in_TypeScript_files, "export...type") + } + case ast.KindImportEqualsDeclaration: + p.jsErrorAtRange(node.Loc, diagnostics.X_import_can_only_be_used_in_TypeScript_files) + case ast.KindExportAssignment: + if node.AsExportAssignment().IsExportEquals { + p.jsErrorAtRange(node.Loc, diagnostics.X_export_can_only_be_used_in_TypeScript_files) + } + case ast.KindHeritageClause: + if node.AsHeritageClause().Token == ast.KindImplementsKeyword { + p.jsErrorAtRange(node.Loc, diagnostics.X_implements_clauses_can_only_be_used_in_TypeScript_files) + } + case ast.KindInterfaceDeclaration: + p.jsErrorAtRange(node.Name().Loc, diagnostics.X_0_declarations_can_only_be_used_in_TypeScript_files, "interface") + case ast.KindModuleDeclaration: + p.jsErrorAtRange(node.Name().Loc, diagnostics.X_0_declarations_can_only_be_used_in_TypeScript_files, scanner.TokenToString(node.AsModuleDeclaration().Keyword)) + case ast.KindTypeAliasDeclaration: + p.jsErrorAtRange(node.Name().Loc, diagnostics.Type_aliases_can_only_be_used_in_TypeScript_files) + case ast.KindEnumDeclaration: + p.jsErrorAtRange(node.Name().Loc, diagnostics.X_0_declarations_can_only_be_used_in_TypeScript_files, "enum") + case ast.KindNonNullExpression: + p.jsErrorAtRange(node.Loc, diagnostics.Non_null_assertions_can_only_be_used_in_TypeScript_files) + case ast.KindAsExpression: + p.jsErrorAtRange(node.Type().Loc, diagnostics.Type_assertion_expressions_can_only_be_used_in_TypeScript_files) + case ast.KindSatisfiesExpression: + p.jsErrorAtRange(node.Type().Loc, diagnostics.Type_satisfaction_expressions_can_only_be_used_in_TypeScript_files) + } + // Check absence of type parameters, type arguments and non-JavaScript modifiers + switch node.Kind { + case ast.KindClassDeclaration, ast.KindClassExpression, ast.KindMethodDeclaration, ast.KindConstructor, ast.KindGetAccessor, + ast.KindSetAccessor, ast.KindFunctionExpression, ast.KindFunctionDeclaration, ast.KindArrowFunction: + if list := node.TypeParameterList(); list != nil && core.Some(list.Nodes, func(n *ast.Node) bool { return n.Flags&ast.NodeFlagsReparsed == 0 }) { + p.jsErrorAtRange(list.Loc, diagnostics.Type_parameter_declarations_can_only_be_used_in_TypeScript_files) + } + fallthrough + case ast.KindVariableStatement, ast.KindPropertyDeclaration: + if modifiers := node.Modifiers(); modifiers != nil { + for _, modifier := range modifiers.Nodes { + if modifier.Flags&ast.NodeFlagsReparsed == 0 && modifier.Kind != ast.KindDecorator && ast.ModifierToFlag(modifier.Kind)&ast.ModifierFlagsJavaScript == 0 { + p.jsErrorAtRange(modifier.Loc, diagnostics.The_0_modifier_can_only_be_used_in_TypeScript_files, scanner.TokenToString(modifier.Kind)) + } + } + } + case ast.KindParameter: + if core.Some(node.ModifierNodes(), ast.IsModifier) { + p.jsErrorAtRange(node.Modifiers().Loc, diagnostics.Parameter_modifiers_can_only_be_used_in_TypeScript_files) + } + case ast.KindCallExpression, ast.KindNewExpression, ast.KindExpressionWithTypeArguments, ast.KindJsxSelfClosingElement, + ast.KindJsxOpeningElement, ast.KindTaggedTemplateExpression: + if list := node.TypeArgumentList(); list != nil && core.Some(list.Nodes, func(n *ast.Node) bool { return n.Flags&ast.NodeFlagsReparsed == 0 }) { + p.jsErrorAtRange(list.Loc, diagnostics.Type_arguments_can_only_be_used_in_TypeScript_files) + } + } + return node +} diff --git a/kitcom/internal/tsgo/parser/references.go b/kitcom/internal/tsgo/parser/references.go new file mode 100644 index 0000000..b46cc5a --- /dev/null +++ b/kitcom/internal/tsgo/parser/references.go @@ -0,0 +1,74 @@ +package parser + +import ( + "strings" + + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/ast" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/core" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/tspath" +) + +func collectExternalModuleReferences(file *ast.SourceFile) { + for _, node := range file.Statements.Nodes { + collectModuleReferences(file, node, false /*inAmbientModule*/) + } + + if file.Flags&ast.NodeFlagsPossiblyContainsDynamicImport != 0 || ast.IsInJSFile(file.AsNode()) { + ast.ForEachDynamicImportOrRequireCall(file /*includeTypeSpaceImports*/, true /*requireStringLiteralLikeArgument*/, true, func(node *ast.Node, moduleSpecifier *ast.Expression) bool { + ast.SetImportsOfSourceFile(file, append(file.Imports(), moduleSpecifier)) + return false + }) + } +} + +func collectModuleReferences(file *ast.SourceFile, node *ast.Statement, inAmbientModule bool) { + if ast.IsAnyImportOrReExport(node) { + moduleNameExpr := ast.GetExternalModuleName(node) + // TypeScript 1.0 spec (April 2014): 12.1.6 + // An ExternalImportDeclaration in an AmbientExternalModuleDeclaration may reference other external modules + // only through top - level external module names. Relative external module names are not permitted. + if moduleNameExpr != nil && ast.IsStringLiteral(moduleNameExpr) { + moduleName := moduleNameExpr.AsStringLiteral().Text + if moduleName != "" && (!inAmbientModule || !tspath.IsExternalModuleNameRelative(moduleName)) { + ast.SetImportsOfSourceFile(file, append(file.Imports(), moduleNameExpr)) + // !!! removed `&& p.currentNodeModulesDepth == 0` + if file.UsesUriStyleNodeCoreModules != core.TSTrue && !file.IsDeclarationFile { + if strings.HasPrefix(moduleName, "node:") && !core.ExclusivelyPrefixedNodeCoreModules[moduleName] { + // Presence of `node:` prefix takes precedence over unprefixed node core modules + file.UsesUriStyleNodeCoreModules = core.TSTrue + } else if file.UsesUriStyleNodeCoreModules == core.TSUnknown && core.UnprefixedNodeCoreModules[moduleName] { + // Avoid `unprefixedNodeCoreModules.has` for every import + file.UsesUriStyleNodeCoreModules = core.TSFalse + } + } + } + } + return + } + if ast.IsModuleDeclaration(node) && ast.IsAmbientModule(node) && (inAmbientModule || ast.HasSyntacticModifier(node, ast.ModifierFlagsAmbient) || file.IsDeclarationFile) { + nameText := node.AsModuleDeclaration().Name().Text() + // Ambient module declarations can be interpreted as augmentations for some existing external modules. + // This will happen in two cases: + // - if current file is external module then module augmentation is a ambient module declaration defined in the top level scope + // - if current file is not external module then module augmentation is an ambient module declaration with non-relative module name + // immediately nested in top level ambient module declaration . + if ast.IsExternalModule(file) || (inAmbientModule && !tspath.IsExternalModuleNameRelative(nameText)) { + file.ModuleAugmentations = append(file.ModuleAugmentations, node.AsModuleDeclaration().Name()) + } else if !inAmbientModule { + if file.IsDeclarationFile { + // for global .d.ts files record name of ambient module + file.AmbientModuleNames = append(file.AmbientModuleNames, nameText) + } + // An AmbientExternalModuleDeclaration declares an external module. + // This type of declaration is permitted only in the global module. + // The StringLiteral must specify a top - level external module name. + // Relative external module names are not permitted + // NOTE: body of ambient module is always a module block, if it exists + if node.AsModuleDeclaration().Body != nil { + for _, statement := range node.AsModuleDeclaration().Body.AsModuleBlock().Statements.Nodes { + collectModuleReferences(file, statement, true /*inAmbientModule*/) + } + } + } + } +} diff --git a/kitcom/internal/tsgo/parser/reparser.go b/kitcom/internal/tsgo/parser/reparser.go new file mode 100644 index 0000000..f7a46b9 --- /dev/null +++ b/kitcom/internal/tsgo/parser/reparser.go @@ -0,0 +1,619 @@ +package parser + +import ( + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/ast" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/core" +) + +func (p *Parser) finishReparsedNode(node *ast.Node, locationNode *ast.Node) { + node.Flags = p.contextFlags | ast.NodeFlagsReparsed + node.Loc = locationNode.Loc + p.overrideParentInImmediateChildren(node) +} + +func (p *Parser) finishMutatedNode(node *ast.Node) { + p.overrideParentInImmediateChildren(node) +} + +func (p *Parser) reparseCommonJS(node *ast.Node, jsdoc []*ast.Node) { + if p.scriptKind != core.ScriptKindJS && p.scriptKind != core.ScriptKindJSX { + return + } + if node.Kind != ast.KindExpressionStatement || node.AsExpressionStatement().Expression.Kind != ast.KindBinaryExpression { + return + } + bin := node.AsExpressionStatement().Expression.AsBinaryExpression() + kind := ast.GetAssignmentDeclarationKind(bin) + var export *ast.Node + switch kind { + case ast.JSDeclarationKindModuleExports: + export = p.factory.NewJSExportAssignment(nil, p.factory.DeepCloneReparse(bin.Right)) + case ast.JSDeclarationKindExportsProperty: + mod := p.factory.NewModifier(ast.KindExportKeyword) + mod.Flags = p.contextFlags | ast.NodeFlagsReparsed + mod.Loc = bin.Loc + // TODO: Name can sometimes be a string literal, so downstream code needs to handle this + export = p.factory.NewCommonJSExport( + p.newModifierList(bin.Loc, p.nodeSlicePool.NewSlice1(mod)), + p.factory.DeepCloneReparse(ast.GetElementOrPropertyAccessName(bin.Left)), + nil, /*typeNode*/ + p.factory.DeepCloneReparse(bin.Right)) + } + if export != nil { + p.reparseList = append(p.reparseList, export) + p.commonJSModuleIndicator = export + p.reparseTags(export, jsdoc) + p.finishReparsedNode(export, bin.AsNode()) + } +} + +// Hosted tags find a host and add their children to the correct location under the host. +// Unhosted tags add synthetic nodes to the reparse list. +func (p *Parser) reparseTags(parent *ast.Node, jsDoc []*ast.Node) { + for _, j := range jsDoc { + isLast := j == jsDoc[len(jsDoc)-1] + tags := j.AsJSDoc().Tags + if tags == nil { + continue + } + for _, tag := range tags.Nodes { + if parent.Kind != ast.KindCommonJSExport && parent.Kind != ast.KindJSExportAssignment { + p.reparseUnhosted(tag, parent, j) + } + if isLast { + p.reparseHosted(tag, parent, j) + } + } + } +} + +func (p *Parser) reparseUnhosted(tag *ast.Node, parent *ast.Node, jsDoc *ast.Node) { + switch tag.Kind { + case ast.KindJSDocTypedefTag: + // !!! Don't mark typedefs as exported if they are not in a module + typeExpression := tag.AsJSDocTypedefTag().TypeExpression + if typeExpression == nil { + break + } + export := p.factory.NewModifier(ast.KindExportKeyword) + export.Loc = tag.Loc + export.Flags = p.contextFlags | ast.NodeFlagsReparsed + modifiers := p.newModifierList(export.Loc, p.nodeSlicePool.NewSlice1(export)) + + typeAlias := p.factory.NewJSTypeAliasDeclaration(modifiers, p.factory.DeepCloneReparse(tag.AsJSDocTypedefTag().Name()), nil, nil) + typeAlias.AsTypeAliasDeclaration().TypeParameters = p.gatherTypeParameters(jsDoc, tag) + var t *ast.Node + switch typeExpression.Kind { + case ast.KindJSDocTypeExpression: + t = p.factory.DeepCloneReparse(typeExpression.Type()) + case ast.KindJSDocTypeLiteral: + t = p.reparseJSDocTypeLiteral(typeExpression) + default: + panic("typedef tag type expression should be a name reference or a type expression" + typeExpression.Kind.String()) + } + typeAlias.AsTypeAliasDeclaration().Type = t + p.finishReparsedNode(typeAlias, tag) + p.reparseList = append(p.reparseList, typeAlias) + case ast.KindJSDocCallbackTag: + callbackTag := tag.AsJSDocCallbackTag() + if callbackTag.TypeExpression == nil { + break + } + + export := p.factory.NewModifier(ast.KindExportKeyword) + export.Loc = tag.Loc + export.Flags = p.contextFlags | ast.NodeFlagsReparsed + modifiers := p.newModifierList(export.Loc, p.nodeSlicePool.NewSlice1(export)) + functionType := p.reparseJSDocSignature(callbackTag.TypeExpression, tag, jsDoc, tag, nil) + + typeAlias := p.factory.NewJSTypeAliasDeclaration(modifiers, p.factory.DeepCloneReparse(callbackTag.FullName), nil, functionType) + typeAlias.AsTypeAliasDeclaration().TypeParameters = p.gatherTypeParameters(jsDoc, tag) + p.finishReparsedNode(typeAlias, tag) + p.reparseList = append(p.reparseList, typeAlias) + case ast.KindJSDocImportTag: + importTag := tag.AsJSDocImportTag() + if importTag.ImportClause == nil { + break + } + importClause := p.factory.DeepCloneReparse(importTag.ImportClause) + importClause.AsImportClause().PhaseModifier = ast.KindTypeKeyword + importDeclaration := p.factory.NewJSImportDeclaration( + p.factory.DeepCloneReparseModifiers(importTag.Modifiers()), + importClause, + p.factory.DeepCloneReparse(importTag.ModuleSpecifier), + p.factory.DeepCloneReparse(importTag.Attributes), + ) + p.finishReparsedNode(importDeclaration, tag) + p.reparseList = append(p.reparseList, importDeclaration) + case ast.KindJSDocOverloadTag: + if fun, ok := getFunctionLikeHost(parent); ok { + p.reparseList = append(p.reparseList, p.reparseJSDocSignature(tag.AsJSDocOverloadTag().TypeExpression, fun, jsDoc, tag, fun.Modifiers())) + } + } +} + +func (p *Parser) reparseJSDocSignature(jsSignature *ast.Node, fun *ast.Node, jsDoc *ast.Node, tag *ast.Node, modifiers *ast.ModifierList) *ast.Node { + var signature *ast.Node + clonedModifiers := p.factory.DeepCloneReparseModifiers(modifiers) + switch fun.Kind { + case ast.KindFunctionDeclaration, ast.KindFunctionExpression, ast.KindArrowFunction: + signature = p.factory.NewFunctionDeclaration(clonedModifiers, nil, p.factory.DeepCloneReparse(fun.Name()), nil, nil, nil, nil, nil) + case ast.KindMethodDeclaration, ast.KindMethodSignature: + signature = p.factory.NewMethodDeclaration(clonedModifiers, nil, p.factory.DeepCloneReparse(fun.Name()), nil, nil, nil, nil, nil, nil) + case ast.KindConstructor: + signature = p.factory.NewConstructorDeclaration(clonedModifiers, nil, nil, nil, nil, nil) + case ast.KindJSDocCallbackTag: + signature = p.factory.NewFunctionTypeNode(nil, nil, nil) + default: + panic("Unexpected kind " + fun.Kind.String()) + } + + if tag.Kind != ast.KindJSDocCallbackTag { + signature.FunctionLikeData().TypeParameters = p.gatherTypeParameters(jsDoc, tag) + } + parameters := p.nodeSlicePool.NewSlice(0) + for _, param := range jsSignature.Parameters() { + var parameter *ast.Node + if param.Kind == ast.KindJSDocThisTag { + thisTag := param.AsJSDocThisTag() + thisIdent := p.factory.NewIdentifier("this") + thisIdent.Loc = thisTag.Loc + thisIdent.Flags = p.contextFlags | ast.NodeFlagsReparsed + parameter = p.factory.NewParameterDeclaration(nil, nil, thisIdent, nil, nil, nil) + if thisTag.TypeExpression != nil { + parameter.AsParameterDeclaration().Type = p.factory.DeepCloneReparse(thisTag.TypeExpression.Type()) + } + } else { + jsparam := param.AsJSDocParameterOrPropertyTag() + var dotDotDotToken *ast.Node + var paramType *ast.TypeNode + + if jsparam.TypeExpression != nil { + if jsparam.TypeExpression.Type().Kind == ast.KindJSDocVariadicType { + dotDotDotToken = p.factory.NewToken(ast.KindDotDotDotToken) + dotDotDotToken.Loc = jsparam.Loc + dotDotDotToken.Flags = p.contextFlags | ast.NodeFlagsReparsed + + variadicType := jsparam.TypeExpression.Type().AsJSDocVariadicType() + paramType = p.reparseJSDocTypeLiteral(variadicType.Type) + } else { + paramType = p.reparseJSDocTypeLiteral(jsparam.TypeExpression.Type()) + } + } + + parameter = p.factory.NewParameterDeclaration(nil, dotDotDotToken, p.factory.DeepCloneReparse(jsparam.Name()), p.makeQuestionIfOptional(jsparam), paramType, nil) + } + p.finishReparsedNode(parameter, param) + parameters = append(parameters, parameter) + } + signature.FunctionLikeData().Parameters = p.newNodeList(jsSignature.AsJSDocSignature().Parameters.Loc, parameters) + + if jsSignature.Type() != nil && jsSignature.Type().AsJSDocReturnTag().TypeExpression != nil { + signature.FunctionLikeData().Type = p.factory.DeepCloneReparse(jsSignature.Type().AsJSDocReturnTag().TypeExpression.Type()) + } + loc := jsSignature + if tag.Kind == ast.KindJSDocOverloadTag { + loc = tag.AsJSDocOverloadTag().TagName + } + p.finishReparsedNode(signature, loc) + return signature +} + +func (p *Parser) reparseJSDocTypeLiteral(t *ast.TypeNode) *ast.Node { + if t == nil { + return nil + } + if t.Kind == ast.KindJSDocTypeLiteral { + jstypeliteral := t.AsJSDocTypeLiteral() + isArrayType := jstypeliteral.IsArrayType + properties := p.nodeSlicePool.NewSlice(0) + for _, prop := range jstypeliteral.JSDocPropertyTags { + jsprop := prop.AsJSDocParameterOrPropertyTag() + name := prop.Name() + if name.Kind == ast.KindQualifiedName { + name = name.AsQualifiedName().Right + } + property := p.factory.NewPropertySignatureDeclaration(nil, p.factory.DeepCloneReparse(name), p.makeQuestionIfOptional(jsprop), nil, nil) + if jsprop.TypeExpression != nil { + property.AsPropertySignatureDeclaration().Type = p.reparseJSDocTypeLiteral(jsprop.TypeExpression.Type()) + } + p.finishReparsedNode(property, prop) + properties = append(properties, property) + } + t = p.factory.NewTypeLiteralNode(p.newNodeList(jstypeliteral.Loc, properties)) + if isArrayType { + p.finishReparsedNode(t, jstypeliteral.AsNode()) + t = p.factory.NewArrayTypeNode(t) + } + p.finishReparsedNode(t, jstypeliteral.AsNode()) + } + return p.factory.DeepCloneReparse(t) +} + +func (p *Parser) gatherTypeParameters(j *ast.Node, tagWithTypeParameters *ast.Node) *ast.NodeList { + var typeParameters []*ast.Node + pos := -1 + endPos := -1 + firstTemplate := true + // type parameters only apply to the tag or node they occur before, so record a place to stop + start := 0 + for i, other := range j.AsJSDoc().Tags.Nodes { + if other == tagWithTypeParameters { + break + } + if other.Kind == ast.KindJSDocTypedefTag || other.Kind == ast.KindJSDocCallbackTag || other.Kind == ast.KindJSDocOverloadTag { + start = i + 1 + } + } + for i, tag := range j.AsJSDoc().Tags.Nodes { + if tag == tagWithTypeParameters { + break + } + if i < start || tag.Kind != ast.KindJSDocTemplateTag { + continue + } + if firstTemplate { + pos = tag.Pos() + firstTemplate = false + } + endPos = tag.End() + + constraint := tag.AsJSDocTemplateTag().Constraint + firstTypeParameter := true + for _, tp := range tag.TypeParameters() { + var reparse *ast.Node + if constraint != nil && firstTypeParameter { + reparse = p.factory.NewTypeParameterDeclaration( + p.factory.DeepCloneReparseModifiers(tp.Modifiers()), + p.factory.DeepCloneReparse(tp.Name()), + p.factory.DeepCloneReparse(constraint.Type()), + p.factory.DeepCloneReparse(tp.AsTypeParameter().DefaultType), + ) + p.finishReparsedNode(reparse, tp) + } else { + reparse = p.factory.DeepCloneReparse(tp) + } + if typeParameters == nil { + typeParameters = p.nodeSlicePool.NewSlice(0) + } + typeParameters = append(typeParameters, reparse) + firstTypeParameter = false + } + } + if len(typeParameters) == 0 { + return nil + } else { + return p.newNodeList(core.NewTextRange(pos, endPos), typeParameters) + } +} + +func (p *Parser) reparseHosted(tag *ast.Node, parent *ast.Node, jsDoc *ast.Node) { + switch tag.Kind { + case ast.KindJSDocTypeTag: + switch parent.Kind { + case ast.KindVariableStatement: + if parent.AsVariableStatement().DeclarationList != nil { + for _, declaration := range parent.AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes { + if declaration.Type() == nil && tag.AsJSDocTypeTag().TypeExpression != nil { + declaration.AsMutable().SetType(p.factory.DeepCloneReparse(tag.AsJSDocTypeTag().TypeExpression.Type())) + p.finishMutatedNode(declaration) + return + } + } + } + case ast.KindVariableDeclaration, + ast.KindCommonJSExport, ast.KindExportAssignment, ast.KindJSExportAssignment, + ast.KindPropertyDeclaration, ast.KindPropertyAssignment, ast.KindShorthandPropertyAssignment: + if parent.Type() == nil && tag.AsJSDocTypeTag().TypeExpression != nil { + parent.AsMutable().SetType(p.factory.DeepCloneReparse(tag.AsJSDocTypeTag().TypeExpression.Type())) + p.finishMutatedNode(parent) + return + } + case ast.KindParameter: + if parent.Type() == nil && tag.AsJSDocTypeTag().TypeExpression != nil { + parent.AsMutable().SetType(p.reparseJSDocTypeLiteral(tag.AsJSDocTypeTag().TypeExpression.Type())) + p.finishMutatedNode(parent) + return + } + case ast.KindExpressionStatement: + if parent.AsExpressionStatement().Expression.Kind == ast.KindBinaryExpression { + bin := parent.AsExpressionStatement().Expression.AsBinaryExpression() + if kind := ast.GetAssignmentDeclarationKind(bin); kind != ast.JSDeclarationKindNone && tag.AsJSDocTypeTag().TypeExpression != nil { + bin.AsMutable().SetType(p.factory.DeepCloneReparse(tag.AsJSDocTypeTag().TypeExpression.Type())) + p.finishMutatedNode(bin.AsNode()) + return + } + } + case ast.KindReturnStatement, ast.KindParenthesizedExpression: + if tag.AsJSDocTypeTag().TypeExpression != nil { + parent.AsMutable().SetExpression(p.makeNewCast( + p.factory.DeepCloneReparse(tag.AsJSDocTypeTag().TypeExpression.Type()), + p.factory.DeepCloneReparse(parent.Expression()), + true /*isAssertion*/)) + p.finishMutatedNode(parent) + return + } + } + if fun, ok := getFunctionLikeHost(parent); ok { + noTypedParams := core.Every(fun.Parameters(), func(param *ast.Node) bool { return param.Type() == nil }) + if fun.Type() == nil && noTypedParams && tag.AsJSDocTypeTag().TypeExpression != nil { + fun.FunctionLikeData().FullSignature = p.factory.DeepCloneReparse(tag.AsJSDocTypeTag().TypeExpression.Type()) + p.finishMutatedNode(fun) + } + } + case ast.KindJSDocSatisfiesTag: + switch parent.Kind { + case ast.KindVariableStatement: + if parent.AsVariableStatement().DeclarationList != nil { + for _, declaration := range parent.AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes { + if declaration.Initializer() != nil && tag.AsJSDocSatisfiesTag().TypeExpression != nil { + declaration.AsMutable().SetInitializer(p.makeNewCast( + p.factory.DeepCloneReparse(tag.AsJSDocSatisfiesTag().TypeExpression.Type()), + p.factory.DeepCloneReparse(declaration.Initializer()), + false /*isAssertion*/)) + p.finishMutatedNode(declaration) + break + } + } + } + case ast.KindVariableDeclaration, + ast.KindCommonJSExport, + ast.KindPropertyDeclaration, ast.KindPropertyAssignment, ast.KindShorthandPropertyAssignment: + if parent.Initializer() != nil && tag.AsJSDocSatisfiesTag().TypeExpression != nil { + parent.AsMutable().SetInitializer(p.makeNewCast( + p.factory.DeepCloneReparse(tag.AsJSDocSatisfiesTag().TypeExpression.Type()), + p.factory.DeepCloneReparse(parent.Initializer()), + false /*isAssertion*/)) + p.finishMutatedNode(parent) + } + case ast.KindReturnStatement, ast.KindParenthesizedExpression, + ast.KindExportAssignment, ast.KindJSExportAssignment: + if parent.Expression() != nil && tag.AsJSDocSatisfiesTag().TypeExpression != nil { + parent.AsMutable().SetExpression(p.makeNewCast( + p.factory.DeepCloneReparse(tag.AsJSDocSatisfiesTag().TypeExpression.Type()), + p.factory.DeepCloneReparse(parent.Expression()), + false /*isAssertion*/)) + p.finishMutatedNode(parent) + } + case ast.KindExpressionStatement: + if parent.AsExpressionStatement().Expression.Kind == ast.KindBinaryExpression { + bin := parent.AsExpressionStatement().Expression.AsBinaryExpression() + if kind := ast.GetAssignmentDeclarationKind(bin); kind != ast.JSDeclarationKindNone && tag.AsJSDocSatisfiesTag().TypeExpression != nil { + bin.Right = p.makeNewCast( + p.factory.DeepCloneReparse(tag.AsJSDocSatisfiesTag().TypeExpression.Type()), + p.factory.DeepCloneReparse(bin.Right), + false /*isAssertion*/) + p.finishMutatedNode(bin.AsNode()) + } + } + } + case ast.KindJSDocTemplateTag: + if fun, ok := getFunctionLikeHost(parent); ok { + if fun.TypeParameters() == nil { + fun.FunctionLikeData().TypeParameters = p.gatherTypeParameters(jsDoc, nil /*tagWithTypeParameters*/) + p.finishMutatedNode(fun) + } + } else if parent.Kind == ast.KindClassDeclaration { + class := parent.AsClassDeclaration() + if class.TypeParameters == nil { + class.TypeParameters = p.gatherTypeParameters(jsDoc, nil /*tagWithTypeParameters*/) + p.finishMutatedNode(parent) + } + } else if parent.Kind == ast.KindClassExpression { + class := parent.AsClassExpression() + if class.TypeParameters == nil { + class.TypeParameters = p.gatherTypeParameters(jsDoc, nil /*tagWithTypeParameters*/) + p.finishMutatedNode(parent) + } + } + case ast.KindJSDocParameterTag: + if fun, ok := getFunctionLikeHost(parent); ok { + parameterTag := tag.AsJSDocParameterOrPropertyTag() + if param, ok := findMatchingParameter(fun, parameterTag, jsDoc); ok { + if param.Type == nil && parameterTag.TypeExpression != nil { + param.AsParameterDeclaration().Type = p.reparseJSDocTypeLiteral(parameterTag.TypeExpression.Type()) + } + if param.QuestionToken == nil && param.Initializer == nil { + if question := p.makeQuestionIfOptional(parameterTag); question != nil { + param.QuestionToken = question + } + } + p.finishMutatedNode(param.AsNode()) + } + } + case ast.KindJSDocThisTag: + if fun, ok := getFunctionLikeHost(parent); ok { + params := fun.Parameters() + if len(params) == 0 || params[0].Name().Kind != ast.KindThisKeyword { + thisParam := p.factory.NewParameterDeclaration( + nil, /* decorators */ + nil, /* modifiers */ + p.factory.NewIdentifier("this"), + nil, /* questionToken */ + nil, /* type */ + nil, /* initializer */ + ) + if tag.AsJSDocThisTag().TypeExpression != nil { + thisParam.AsParameterDeclaration().Type = p.factory.DeepCloneReparse(tag.AsJSDocThisTag().TypeExpression.Type()) + } + p.finishReparsedNode(thisParam, tag.AsJSDocThisTag().TagName) + + newParams := p.nodeSlicePool.NewSlice(len(params) + 1) + newParams[0] = thisParam + for i, param := range params { + newParams[i+1] = param + } + + fun.FunctionLikeData().Parameters = p.newNodeList(thisParam.Loc, newParams) + p.finishMutatedNode(fun) + } + } + case ast.KindJSDocReturnTag: + if fun, ok := getFunctionLikeHost(parent); ok { + if fun.Type() == nil && tag.AsJSDocReturnTag().TypeExpression != nil { + fun.FunctionLikeData().Type = p.factory.DeepCloneReparse(tag.AsJSDocReturnTag().TypeExpression.Type()) + p.finishMutatedNode(fun) + } + } + case ast.KindJSDocReadonlyTag, ast.KindJSDocPrivateTag, ast.KindJSDocPublicTag, ast.KindJSDocProtectedTag, ast.KindJSDocOverrideTag: + if parent.Kind == ast.KindExpressionStatement { + parent = parent.AsExpressionStatement().Expression + } + switch parent.Kind { + case ast.KindPropertyDeclaration, ast.KindMethodDeclaration, ast.KindGetAccessor, ast.KindSetAccessor, ast.KindBinaryExpression: + var keyword ast.Kind + switch tag.Kind { + case ast.KindJSDocReadonlyTag: + keyword = ast.KindReadonlyKeyword + case ast.KindJSDocPrivateTag: + keyword = ast.KindPrivateKeyword + case ast.KindJSDocPublicTag: + keyword = ast.KindPublicKeyword + case ast.KindJSDocProtectedTag: + keyword = ast.KindProtectedKeyword + case ast.KindJSDocOverrideTag: + keyword = ast.KindOverrideKeyword + } + modifier := p.factory.NewModifier(keyword) + modifier.Loc = tag.Loc + modifier.Flags = p.contextFlags | ast.NodeFlagsReparsed + var nodes []*ast.Node + var loc core.TextRange + if parent.Modifiers() == nil { + nodes = p.nodeSlicePool.NewSlice(1) + nodes[0] = modifier + loc = tag.Loc + } else { + nodes = append(parent.Modifiers().Nodes, modifier) + loc = parent.Modifiers().Loc + } + parent.AsMutable().SetModifiers(p.newModifierList(loc, nodes)) + p.finishMutatedNode(parent) + } + case ast.KindJSDocImplementsTag: + if class := getClassLikeData(parent); class != nil { + implementsTag := tag.AsJSDocImplementsTag() + + if class.HeritageClauses != nil { + if implementsClause := core.Find(class.HeritageClauses.Nodes, func(node *ast.Node) bool { + return node.AsHeritageClause().Token == ast.KindImplementsKeyword + }); implementsClause != nil { + implementsClause.AsHeritageClause().Types.Nodes = append(implementsClause.AsHeritageClause().Types.Nodes, p.factory.DeepCloneReparse(implementsTag.ClassName)) + p.finishMutatedNode(implementsClause) + return + } + } + typesList := p.newNodeList(implementsTag.ClassName.Loc, p.nodeSlicePool.NewSlice1(p.factory.DeepCloneReparse(implementsTag.ClassName))) + + heritageClause := p.factory.NewHeritageClause(ast.KindImplementsKeyword, typesList) + p.finishReparsedNode(heritageClause, implementsTag.ClassName) + + if class.HeritageClauses == nil { + heritageClauses := p.newNodeList(implementsTag.ClassName.Loc, p.nodeSlicePool.NewSlice1(heritageClause)) + class.HeritageClauses = heritageClauses + } else { + class.HeritageClauses.Nodes = append(class.HeritageClauses.Nodes, heritageClause) + } + p.finishMutatedNode(parent) + } + case ast.KindJSDocAugmentsTag: + if class := getClassLikeData(parent); class != nil && class.HeritageClauses != nil { + if extendsClause := core.Find(class.HeritageClauses.Nodes, func(node *ast.Node) bool { + return node.AsHeritageClause().Token == ast.KindExtendsKeyword + }); extendsClause != nil && len(extendsClause.AsHeritageClause().Types.Nodes) == 1 { + target := extendsClause.AsHeritageClause().Types.Nodes[0].AsExpressionWithTypeArguments() + source := tag.AsJSDocAugmentsTag().ClassName.AsExpressionWithTypeArguments() + if ast.HasSamePropertyAccessName(target.Expression, source.Expression) { + if target.TypeArguments == nil && source.TypeArguments != nil { + newArguments := p.nodeSlicePool.NewSlice(len(source.TypeArguments.Nodes)) + for i, arg := range source.TypeArguments.Nodes { + newArguments[i] = p.factory.DeepCloneReparse(arg) + } + target.TypeArguments = p.newNodeList(source.TypeArguments.Loc, newArguments) + p.finishMutatedNode(target.AsNode()) + } + } + } + } + } +} + +func (p *Parser) makeQuestionIfOptional(parameter *ast.JSDocParameterTag) *ast.Node { + var questionToken *ast.Node + if parameter.IsBracketed || parameter.TypeExpression != nil && parameter.TypeExpression.Type().Kind == ast.KindJSDocOptionalType { + questionToken = p.factory.NewToken(ast.KindQuestionToken) + questionToken.Loc = parameter.Loc + questionToken.Flags = p.contextFlags | ast.NodeFlagsReparsed + } + return questionToken +} + +func findMatchingParameter(fun *ast.Node, parameterTag *ast.JSDocParameterTag, jsDoc *ast.Node) (*ast.ParameterDeclaration, bool) { + tagIndex := -1 + paramCount := -1 + for _, tag := range jsDoc.AsJSDoc().Tags.Nodes { + if tag.Kind == ast.KindJSDocParameterTag { + paramCount++ + if tag.AsJSDocParameterOrPropertyTag() == parameterTag { + tagIndex = paramCount + break + } + } + } + for parameterIndex, parameter := range fun.Parameters() { + if parameter.Name().Kind == ast.KindIdentifier { + if parameterTag.Name().Kind == ast.KindIdentifier && parameter.Name().Text() == parameterTag.Name().Text() { + return parameter.AsParameterDeclaration(), true + } + } else if parameterIndex == tagIndex { + return parameter.AsParameterDeclaration(), true + } + } + return nil, false +} + +func getFunctionLikeHost(host *ast.Node) (*ast.Node, bool) { + fun := host + if host.Kind == ast.KindVariableStatement && host.AsVariableStatement().DeclarationList != nil { + for _, declaration := range host.AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes { + if ast.IsFunctionLike(declaration.Initializer()) { + fun = declaration.Initializer() + break + } + } + } else if host.Kind == ast.KindPropertyAssignment { + fun = host.AsPropertyAssignment().Initializer + } else if host.Kind == ast.KindPropertyDeclaration { + fun = host.AsPropertyDeclaration().Initializer + } else if host.Kind == ast.KindExportAssignment { + fun = host.AsExportAssignment().Expression + } else if host.Kind == ast.KindReturnStatement { + fun = host.AsReturnStatement().Expression + } + if ast.IsFunctionLike(fun) { + return fun, true + } + return nil, false +} + +func (p *Parser) makeNewCast(t *ast.TypeNode, e *ast.Node, isAssertion bool) *ast.Node { + var assert *ast.Node + if isAssertion { + assert = p.factory.NewAsExpression(e, t) + } else { + assert = p.factory.NewSatisfiesExpression(e, t) + } + p.finishReparsedNode(assert, e) + return assert +} + +func getClassLikeData(parent *ast.Node) *ast.ClassLikeBase { + var class *ast.ClassLikeBase + switch parent.Kind { + case ast.KindClassDeclaration: + class = parent.AsClassDeclaration().ClassLikeData() + case ast.KindClassExpression: + class = parent.AsClassExpression().ClassLikeData() + } + return class +} diff --git a/kitcom/internal/tsgo/parser/types.go b/kitcom/internal/tsgo/parser/types.go new file mode 100644 index 0000000..6711894 --- /dev/null +++ b/kitcom/internal/tsgo/parser/types.go @@ -0,0 +1,14 @@ +package parser + +// ParseFlags + +type ParseFlags uint32 + +const ( + ParseFlagsNone ParseFlags = 0 + ParseFlagsYield ParseFlags = 1 << 0 + ParseFlagsAwait ParseFlags = 1 << 1 + ParseFlagsType ParseFlags = 1 << 2 + ParseFlagsIgnoreMissingOpenBrace ParseFlags = 1 << 4 + ParseFlagsJSDoc ParseFlags = 1 << 5 +) diff --git a/kitcom/internal/tsgo/parser/utilities.go b/kitcom/internal/tsgo/parser/utilities.go new file mode 100644 index 0000000..a16468f --- /dev/null +++ b/kitcom/internal/tsgo/parser/utilities.go @@ -0,0 +1,54 @@ +package parser + +import ( + "slices" + + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/ast" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/core" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/scanner" +) + +func getLanguageVariant(scriptKind core.ScriptKind) core.LanguageVariant { + switch scriptKind { + case core.ScriptKindTSX, core.ScriptKindJSX, core.ScriptKindJS, core.ScriptKindJSON: + // .tsx and .jsx files are treated as jsx language variant. + return core.LanguageVariantJSX + } + return core.LanguageVariantStandard +} + +func tokenIsIdentifierOrKeyword(token ast.Kind) bool { + return token >= ast.KindIdentifier +} + +func tokenIsIdentifierOrKeywordOrGreaterThan(token ast.Kind) bool { + return token == ast.KindGreaterThanToken || tokenIsIdentifierOrKeyword(token) +} + +func GetJSDocCommentRanges(f *ast.NodeFactory, commentRanges []ast.CommentRange, node *ast.Node, text string) []ast.CommentRange { + switch node.Kind { + case ast.KindParameter, ast.KindTypeParameter, ast.KindFunctionExpression, ast.KindArrowFunction, ast.KindParenthesizedExpression, ast.KindVariableDeclaration, ast.KindExportSpecifier: + for commentRange := range scanner.GetTrailingCommentRanges(f, text, node.Pos()) { + commentRanges = append(commentRanges, commentRange) + } + for commentRange := range scanner.GetLeadingCommentRanges(f, text, node.Pos()) { + commentRanges = append(commentRanges, commentRange) + } + default: + for commentRange := range scanner.GetLeadingCommentRanges(f, text, node.Pos()) { + commentRanges = append(commentRanges, commentRange) + } + } + // Keep if the comment starts with '/**' but not if it is '/**/' + return slices.DeleteFunc(commentRanges, func(comment ast.CommentRange) bool { + return comment.End() > node.End() || text[comment.Pos()+1] != '*' || text[comment.Pos()+2] != '*' || text[comment.Pos()+3] == '/' + }) +} + +func isKeywordOrPunctuation(token ast.Kind) bool { + return ast.IsKeywordKind(token) || ast.IsPunctuationKind(token) +} + +func isJSDocLikeText(text string) bool { + return len(text) >= 4 && text[1] == '*' && text[2] == '*' && text[3] != '/' +} diff --git a/kitcom/internal/tsgo/repo/paths.go b/kitcom/internal/tsgo/repo/paths.go new file mode 100644 index 0000000..237a8d0 --- /dev/null +++ b/kitcom/internal/tsgo/repo/paths.go @@ -0,0 +1,63 @@ +package repo + +import ( + "os" + "path/filepath" + "runtime" + "sync" +) + +var ( + RootPath string + TypeScriptSubmodulePath string + TestDataPath string +) + +func init() { + _, filename, _, ok := runtime.Caller(0) + if !ok { + panic("could not get current filename") + } + filename = filepath.FromSlash(filename) // runtime.Caller always returns forward slashes; https://go.dev/issues/3335, https://go.dev/cl/603275 + RootPath = findGoMod(filepath.Dir(filename)) + TypeScriptSubmodulePath = filepath.Join(RootPath, "_submodules", "TypeScript") + TestDataPath = filepath.Join(RootPath, "testdata") +} + +func findGoMod(dir string) string { + root := filepath.VolumeName(dir) + for dir != root { + if _, err := os.Stat(filepath.Join(dir, "go.mod")); err == nil { + return dir + } + dir = filepath.Dir(dir) + } + panic("could not find go.mod") +} + +var typeScriptSubmoduleExists = sync.OnceValue(func() bool { + p := filepath.Join(TypeScriptSubmodulePath, "package.json") + if _, err := os.Stat(p); err != nil { + if os.IsNotExist(err) { + return false + } + panic(err) + } + return true +}) + +func TypeScriptSubmoduleExists() bool { + return typeScriptSubmoduleExists() +} + +type skippable interface { + Helper() + Skipf(format string, args ...any) +} + +func SkipIfNoTypeScriptSubmodule(t skippable) { + t.Helper() + if !typeScriptSubmoduleExists() { + t.Skipf("TypeScript submodule does not exist") + } +} diff --git a/kitcom/internal/tsgo/scanner/scanner.go b/kitcom/internal/tsgo/scanner/scanner.go new file mode 100644 index 0000000..4ba98cb --- /dev/null +++ b/kitcom/internal/tsgo/scanner/scanner.go @@ -0,0 +1,2619 @@ +package scanner + +import ( + "fmt" + "iter" + "maps" + "strconv" + "strings" + "unicode" + "unicode/utf8" + + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/ast" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/core" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/debug" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/diagnostics" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/jsnum" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/stringutil" +) + +type EscapeSequenceScanningFlags int32 + +const ( + EscapeSequenceScanningFlagsString EscapeSequenceScanningFlags = 1 << 0 + EscapeSequenceScanningFlagsReportErrors EscapeSequenceScanningFlags = 1 << 1 + EscapeSequenceScanningFlagsRegularExpression EscapeSequenceScanningFlags = 1 << 2 + EscapeSequenceScanningFlagsAnnexB EscapeSequenceScanningFlags = 1 << 3 + EscapeSequenceScanningFlagsAnyUnicodeMode EscapeSequenceScanningFlags = 1 << 4 + EscapeSequenceScanningFlagsAtomEscape EscapeSequenceScanningFlags = 1 << 5 + EscapeSequenceScanningFlagsReportInvalidEscapeErrors EscapeSequenceScanningFlags = EscapeSequenceScanningFlagsRegularExpression | EscapeSequenceScanningFlagsReportErrors + EscapeSequenceScanningFlagsAllowExtendedUnicodeEscape EscapeSequenceScanningFlags = EscapeSequenceScanningFlagsString | EscapeSequenceScanningFlagsAnyUnicodeMode +) + +type ErrorCallback func(diagnostic *diagnostics.Message, start, length int, args ...any) + +var textToKeyword = map[string]ast.Kind{ + "abstract": ast.KindAbstractKeyword, + "accessor": ast.KindAccessorKeyword, + "any": ast.KindAnyKeyword, + "as": ast.KindAsKeyword, + "asserts": ast.KindAssertsKeyword, + "assert": ast.KindAssertKeyword, + "bigint": ast.KindBigIntKeyword, + "boolean": ast.KindBooleanKeyword, + "break": ast.KindBreakKeyword, + "case": ast.KindCaseKeyword, + "catch": ast.KindCatchKeyword, + "class": ast.KindClassKeyword, + "continue": ast.KindContinueKeyword, + "const": ast.KindConstKeyword, + "constructor": ast.KindConstructorKeyword, + "debugger": ast.KindDebuggerKeyword, + "declare": ast.KindDeclareKeyword, + "default": ast.KindDefaultKeyword, + "defer": ast.KindDeferKeyword, + "delete": ast.KindDeleteKeyword, + "do": ast.KindDoKeyword, + "else": ast.KindElseKeyword, + "enum": ast.KindEnumKeyword, + "export": ast.KindExportKeyword, + "extends": ast.KindExtendsKeyword, + "false": ast.KindFalseKeyword, + "finally": ast.KindFinallyKeyword, + "for": ast.KindForKeyword, + "from": ast.KindFromKeyword, + "function": ast.KindFunctionKeyword, + "get": ast.KindGetKeyword, + "if": ast.KindIfKeyword, + "immediate": ast.KindImmediateKeyword, + "implements": ast.KindImplementsKeyword, + "import": ast.KindImportKeyword, + "in": ast.KindInKeyword, + "infer": ast.KindInferKeyword, + "instanceof": ast.KindInstanceOfKeyword, + "interface": ast.KindInterfaceKeyword, + "intrinsic": ast.KindIntrinsicKeyword, + "is": ast.KindIsKeyword, + "keyof": ast.KindKeyOfKeyword, + "let": ast.KindLetKeyword, + "module": ast.KindModuleKeyword, + "namespace": ast.KindNamespaceKeyword, + "never": ast.KindNeverKeyword, + "new": ast.KindNewKeyword, + "null": ast.KindNullKeyword, + "number": ast.KindNumberKeyword, + "object": ast.KindObjectKeyword, + "package": ast.KindPackageKeyword, + "private": ast.KindPrivateKeyword, + "protected": ast.KindProtectedKeyword, + "public": ast.KindPublicKeyword, + "override": ast.KindOverrideKeyword, + "out": ast.KindOutKeyword, + "readonly": ast.KindReadonlyKeyword, + "require": ast.KindRequireKeyword, + "global": ast.KindGlobalKeyword, + "return": ast.KindReturnKeyword, + "satisfies": ast.KindSatisfiesKeyword, + "set": ast.KindSetKeyword, + "static": ast.KindStaticKeyword, + "string": ast.KindStringKeyword, + "super": ast.KindSuperKeyword, + "switch": ast.KindSwitchKeyword, + "symbol": ast.KindSymbolKeyword, + "this": ast.KindThisKeyword, + "throw": ast.KindThrowKeyword, + "true": ast.KindTrueKeyword, + "try": ast.KindTryKeyword, + "type": ast.KindTypeKeyword, + "typeof": ast.KindTypeOfKeyword, + "undefined": ast.KindUndefinedKeyword, + "unique": ast.KindUniqueKeyword, + "unknown": ast.KindUnknownKeyword, + "using": ast.KindUsingKeyword, + "var": ast.KindVarKeyword, + "void": ast.KindVoidKeyword, + "while": ast.KindWhileKeyword, + "with": ast.KindWithKeyword, + "yield": ast.KindYieldKeyword, + "async": ast.KindAsyncKeyword, + "await": ast.KindAwaitKeyword, + "of": ast.KindOfKeyword, +} + +var textToToken = func() map[string]ast.Kind { + m := map[string]ast.Kind{ + "{": ast.KindOpenBraceToken, + "}": ast.KindCloseBraceToken, + "(": ast.KindOpenParenToken, + ")": ast.KindCloseParenToken, + "[": ast.KindOpenBracketToken, + "]": ast.KindCloseBracketToken, + ".": ast.KindDotToken, + "...": ast.KindDotDotDotToken, + ";": ast.KindSemicolonToken, + ",": ast.KindCommaToken, + "<": ast.KindLessThanToken, + ">": ast.KindGreaterThanToken, + "<=": ast.KindLessThanEqualsToken, + ">=": ast.KindGreaterThanEqualsToken, + "==": ast.KindEqualsEqualsToken, + "!=": ast.KindExclamationEqualsToken, + "===": ast.KindEqualsEqualsEqualsToken, + "!==": ast.KindExclamationEqualsEqualsToken, + "=>": ast.KindEqualsGreaterThanToken, + "+": ast.KindPlusToken, + "-": ast.KindMinusToken, + "**": ast.KindAsteriskAsteriskToken, + "*": ast.KindAsteriskToken, + "/": ast.KindSlashToken, + "%": ast.KindPercentToken, + "++": ast.KindPlusPlusToken, + "--": ast.KindMinusMinusToken, + "<<": ast.KindLessThanLessThanToken, + ">": ast.KindGreaterThanGreaterThanToken, + ">>>": ast.KindGreaterThanGreaterThanGreaterThanToken, + "&": ast.KindAmpersandToken, + "|": ast.KindBarToken, + "^": ast.KindCaretToken, + "!": ast.KindExclamationToken, + "~": ast.KindTildeToken, + "&&": ast.KindAmpersandAmpersandToken, + "||": ast.KindBarBarToken, + "?": ast.KindQuestionToken, + "??": ast.KindQuestionQuestionToken, + "?.": ast.KindQuestionDotToken, + ":": ast.KindColonToken, + "=": ast.KindEqualsToken, + "+=": ast.KindPlusEqualsToken, + "-=": ast.KindMinusEqualsToken, + "*=": ast.KindAsteriskEqualsToken, + "**=": ast.KindAsteriskAsteriskEqualsToken, + "/=": ast.KindSlashEqualsToken, + "%=": ast.KindPercentEqualsToken, + "<<=": ast.KindLessThanLessThanEqualsToken, + ">>=": ast.KindGreaterThanGreaterThanEqualsToken, + ">>>=": ast.KindGreaterThanGreaterThanGreaterThanEqualsToken, + "&=": ast.KindAmpersandEqualsToken, + "|=": ast.KindBarEqualsToken, + "^=": ast.KindCaretEqualsToken, + "||=": ast.KindBarBarEqualsToken, + "&&=": ast.KindAmpersandAmpersandEqualsToken, + "??=": ast.KindQuestionQuestionEqualsToken, + "@": ast.KindAtToken, + "#": ast.KindHashToken, + "`": ast.KindBacktickToken, + } + maps.Copy(m, textToKeyword) + return m +}() + +// Generated by scripts/regenerate-unicode-identifier-parts.mjs on node v22.1.0 with unicode 15.1 +// based on http://www.unicode.org/reports/tr31/ and https://www.ecma-international.org/ecma-262/6.0/#sec-names-and-keywords +// unicodeESNextIdentifierStart corresponds to the ID_Start and Other_ID_Start property, and +// unicodeESNextIdentifierPart corresponds to ID_Continue, Other_ID_Continue, plus ID_Start and Other_ID_Start +var ( + unicodeESNextIdentifierStart = []rune{65, 90, 97, 122, 170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 880, 884, 886, 887, 890, 893, 895, 895, 902, 902, 904, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1162, 1327, 1329, 1366, 1369, 1369, 1376, 1416, 1488, 1514, 1519, 1522, 1568, 1610, 1646, 1647, 1649, 1747, 1749, 1749, 1765, 1766, 1774, 1775, 1786, 1788, 1791, 1791, 1808, 1808, 1810, 1839, 1869, 1957, 1969, 1969, 1994, 2026, 2036, 2037, 2042, 2042, 2048, 2069, 2074, 2074, 2084, 2084, 2088, 2088, 2112, 2136, 2144, 2154, 2160, 2183, 2185, 2190, 2208, 2249, 2308, 2361, 2365, 2365, 2384, 2384, 2392, 2401, 2417, 2432, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2493, 2493, 2510, 2510, 2524, 2525, 2527, 2529, 2544, 2545, 2556, 2556, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654, 2674, 2676, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2749, 2749, 2768, 2768, 2784, 2785, 2809, 2809, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2929, 2929, 2947, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3024, 3024, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3129, 3133, 3133, 3160, 3162, 3165, 3165, 3168, 3169, 3200, 3200, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3261, 3261, 3293, 3294, 3296, 3297, 3313, 3314, 3332, 3340, 3342, 3344, 3346, 3386, 3389, 3389, 3406, 3406, 3412, 3414, 3423, 3425, 3450, 3455, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3585, 3632, 3634, 3635, 3648, 3654, 3713, 3714, 3716, 3716, 3718, 3722, 3724, 3747, 3749, 3749, 3751, 3760, 3762, 3763, 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3807, 3840, 3840, 3904, 3911, 3913, 3948, 3976, 3980, 4096, 4138, 4159, 4159, 4176, 4181, 4186, 4189, 4193, 4193, 4197, 4198, 4206, 4208, 4213, 4225, 4238, 4238, 4256, 4293, 4295, 4295, 4301, 4301, 4304, 4346, 4348, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4992, 5007, 5024, 5109, 5112, 5117, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5880, 5888, 5905, 5919, 5937, 5952, 5969, 5984, 5996, 5998, 6000, 6016, 6067, 6103, 6103, 6108, 6108, 6176, 6264, 6272, 6312, 6314, 6314, 6320, 6389, 6400, 6430, 6480, 6509, 6512, 6516, 6528, 6571, 6576, 6601, 6656, 6678, 6688, 6740, 6823, 6823, 6917, 6963, 6981, 6988, 7043, 7072, 7086, 7087, 7098, 7141, 7168, 7203, 7245, 7247, 7258, 7293, 7296, 7304, 7312, 7354, 7357, 7359, 7401, 7404, 7406, 7411, 7413, 7414, 7418, 7418, 7424, 7615, 7680, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8305, 8305, 8319, 8319, 8336, 8348, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8472, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11492, 11499, 11502, 11506, 11507, 11520, 11557, 11559, 11559, 11565, 11565, 11568, 11623, 11631, 11631, 11648, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 12293, 12295, 12321, 12329, 12337, 12341, 12344, 12348, 12353, 12438, 12443, 12447, 12449, 12538, 12540, 12543, 12549, 12591, 12593, 12686, 12704, 12735, 12784, 12799, 13312, 19903, 19968, 42124, 42192, 42237, 42240, 42508, 42512, 42527, 42538, 42539, 42560, 42606, 42623, 42653, 42656, 42735, 42775, 42783, 42786, 42888, 42891, 42954, 42960, 42961, 42963, 42963, 42965, 42969, 42994, 43009, 43011, 43013, 43015, 43018, 43020, 43042, 43072, 43123, 43138, 43187, 43250, 43255, 43259, 43259, 43261, 43262, 43274, 43301, 43312, 43334, 43360, 43388, 43396, 43442, 43471, 43471, 43488, 43492, 43494, 43503, 43514, 43518, 43520, 43560, 43584, 43586, 43588, 43595, 43616, 43638, 43642, 43642, 43646, 43695, 43697, 43697, 43701, 43702, 43705, 43709, 43712, 43712, 43714, 43714, 43739, 43741, 43744, 43754, 43762, 43764, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43824, 43866, 43868, 43881, 43888, 44002, 44032, 55203, 55216, 55238, 55243, 55291, 63744, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65136, 65140, 65142, 65276, 65313, 65338, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500, 65536, 65547, 65549, 65574, 65576, 65594, 65596, 65597, 65599, 65613, 65616, 65629, 65664, 65786, 65856, 65908, 66176, 66204, 66208, 66256, 66304, 66335, 66349, 66378, 66384, 66421, 66432, 66461, 66464, 66499, 66504, 66511, 66513, 66517, 66560, 66717, 66736, 66771, 66776, 66811, 66816, 66855, 66864, 66915, 66928, 66938, 66940, 66954, 66956, 66962, 66964, 66965, 66967, 66977, 66979, 66993, 66995, 67001, 67003, 67004, 67072, 67382, 67392, 67413, 67424, 67431, 67456, 67461, 67463, 67504, 67506, 67514, 67584, 67589, 67592, 67592, 67594, 67637, 67639, 67640, 67644, 67644, 67647, 67669, 67680, 67702, 67712, 67742, 67808, 67826, 67828, 67829, 67840, 67861, 67872, 67897, 67968, 68023, 68030, 68031, 68096, 68096, 68112, 68115, 68117, 68119, 68121, 68149, 68192, 68220, 68224, 68252, 68288, 68295, 68297, 68324, 68352, 68405, 68416, 68437, 68448, 68466, 68480, 68497, 68608, 68680, 68736, 68786, 68800, 68850, 68864, 68899, 69248, 69289, 69296, 69297, 69376, 69404, 69415, 69415, 69424, 69445, 69488, 69505, 69552, 69572, 69600, 69622, 69635, 69687, 69745, 69746, 69749, 69749, 69763, 69807, 69840, 69864, 69891, 69926, 69956, 69956, 69959, 69959, 69968, 70002, 70006, 70006, 70019, 70066, 70081, 70084, 70106, 70106, 70108, 70108, 70144, 70161, 70163, 70187, 70207, 70208, 70272, 70278, 70280, 70280, 70282, 70285, 70287, 70301, 70303, 70312, 70320, 70366, 70405, 70412, 70415, 70416, 70419, 70440, 70442, 70448, 70450, 70451, 70453, 70457, 70461, 70461, 70480, 70480, 70493, 70497, 70656, 70708, 70727, 70730, 70751, 70753, 70784, 70831, 70852, 70853, 70855, 70855, 71040, 71086, 71128, 71131, 71168, 71215, 71236, 71236, 71296, 71338, 71352, 71352, 71424, 71450, 71488, 71494, 71680, 71723, 71840, 71903, 71935, 71942, 71945, 71945, 71948, 71955, 71957, 71958, 71960, 71983, 71999, 71999, 72001, 72001, 72096, 72103, 72106, 72144, 72161, 72161, 72163, 72163, 72192, 72192, 72203, 72242, 72250, 72250, 72272, 72272, 72284, 72329, 72349, 72349, 72368, 72440, 72704, 72712, 72714, 72750, 72768, 72768, 72818, 72847, 72960, 72966, 72968, 72969, 72971, 73008, 73030, 73030, 73056, 73061, 73063, 73064, 73066, 73097, 73112, 73112, 73440, 73458, 73474, 73474, 73476, 73488, 73490, 73523, 73648, 73648, 73728, 74649, 74752, 74862, 74880, 75075, 77712, 77808, 77824, 78895, 78913, 78918, 82944, 83526, 92160, 92728, 92736, 92766, 92784, 92862, 92880, 92909, 92928, 92975, 92992, 92995, 93027, 93047, 93053, 93071, 93760, 93823, 93952, 94026, 94032, 94032, 94099, 94111, 94176, 94177, 94179, 94179, 94208, 100343, 100352, 101589, 101632, 101640, 110576, 110579, 110581, 110587, 110589, 110590, 110592, 110882, 110898, 110898, 110928, 110930, 110933, 110933, 110948, 110951, 110960, 111355, 113664, 113770, 113776, 113788, 113792, 113800, 113808, 113817, 119808, 119892, 119894, 119964, 119966, 119967, 119970, 119970, 119973, 119974, 119977, 119980, 119982, 119993, 119995, 119995, 119997, 120003, 120005, 120069, 120071, 120074, 120077, 120084, 120086, 120092, 120094, 120121, 120123, 120126, 120128, 120132, 120134, 120134, 120138, 120144, 120146, 120485, 120488, 120512, 120514, 120538, 120540, 120570, 120572, 120596, 120598, 120628, 120630, 120654, 120656, 120686, 120688, 120712, 120714, 120744, 120746, 120770, 120772, 120779, 122624, 122654, 122661, 122666, 122928, 122989, 123136, 123180, 123191, 123197, 123214, 123214, 123536, 123565, 123584, 123627, 124112, 124139, 124896, 124902, 124904, 124907, 124909, 124910, 124912, 124926, 124928, 125124, 125184, 125251, 125259, 125259, 126464, 126467, 126469, 126495, 126497, 126498, 126500, 126500, 126503, 126503, 126505, 126514, 126516, 126519, 126521, 126521, 126523, 126523, 126530, 126530, 126535, 126535, 126537, 126537, 126539, 126539, 126541, 126543, 126545, 126546, 126548, 126548, 126551, 126551, 126553, 126553, 126555, 126555, 126557, 126557, 126559, 126559, 126561, 126562, 126564, 126564, 126567, 126570, 126572, 126578, 126580, 126583, 126585, 126588, 126590, 126590, 126592, 126601, 126603, 126619, 126625, 126627, 126629, 126633, 126635, 126651, 131072, 173791, 173824, 177977, 177984, 178205, 178208, 183969, 183984, 191456, 191472, 192093, 194560, 195101, 196608, 201546, 201552, 205743} + unicodeESNextIdentifierPart = []rune{48, 57, 65, 90, 95, 95, 97, 122, 170, 170, 181, 181, 183, 183, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 768, 884, 886, 887, 890, 893, 895, 895, 902, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1155, 1159, 1162, 1327, 1329, 1366, 1369, 1369, 1376, 1416, 1425, 1469, 1471, 1471, 1473, 1474, 1476, 1477, 1479, 1479, 1488, 1514, 1519, 1522, 1552, 1562, 1568, 1641, 1646, 1747, 1749, 1756, 1759, 1768, 1770, 1788, 1791, 1791, 1808, 1866, 1869, 1969, 1984, 2037, 2042, 2042, 2045, 2045, 2048, 2093, 2112, 2139, 2144, 2154, 2160, 2183, 2185, 2190, 2200, 2273, 2275, 2403, 2406, 2415, 2417, 2435, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2492, 2500, 2503, 2504, 2507, 2510, 2519, 2519, 2524, 2525, 2527, 2531, 2534, 2545, 2556, 2556, 2558, 2558, 2561, 2563, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2620, 2620, 2622, 2626, 2631, 2632, 2635, 2637, 2641, 2641, 2649, 2652, 2654, 2654, 2662, 2677, 2689, 2691, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2748, 2757, 2759, 2761, 2763, 2765, 2768, 2768, 2784, 2787, 2790, 2799, 2809, 2815, 2817, 2819, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2876, 2884, 2887, 2888, 2891, 2893, 2901, 2903, 2908, 2909, 2911, 2915, 2918, 2927, 2929, 2929, 2946, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3006, 3010, 3014, 3016, 3018, 3021, 3024, 3024, 3031, 3031, 3046, 3055, 3072, 3084, 3086, 3088, 3090, 3112, 3114, 3129, 3132, 3140, 3142, 3144, 3146, 3149, 3157, 3158, 3160, 3162, 3165, 3165, 3168, 3171, 3174, 3183, 3200, 3203, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3260, 3268, 3270, 3272, 3274, 3277, 3285, 3286, 3293, 3294, 3296, 3299, 3302, 3311, 3313, 3315, 3328, 3340, 3342, 3344, 3346, 3396, 3398, 3400, 3402, 3406, 3412, 3415, 3423, 3427, 3430, 3439, 3450, 3455, 3457, 3459, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3530, 3530, 3535, 3540, 3542, 3542, 3544, 3551, 3558, 3567, 3570, 3571, 3585, 3642, 3648, 3662, 3664, 3673, 3713, 3714, 3716, 3716, 3718, 3722, 3724, 3747, 3749, 3749, 3751, 3773, 3776, 3780, 3782, 3782, 3784, 3790, 3792, 3801, 3804, 3807, 3840, 3840, 3864, 3865, 3872, 3881, 3893, 3893, 3895, 3895, 3897, 3897, 3902, 3911, 3913, 3948, 3953, 3972, 3974, 3991, 3993, 4028, 4038, 4038, 4096, 4169, 4176, 4253, 4256, 4293, 4295, 4295, 4301, 4301, 4304, 4346, 4348, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4957, 4959, 4969, 4977, 4992, 5007, 5024, 5109, 5112, 5117, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5880, 5888, 5909, 5919, 5940, 5952, 5971, 5984, 5996, 5998, 6000, 6002, 6003, 6016, 6099, 6103, 6103, 6108, 6109, 6112, 6121, 6155, 6157, 6159, 6169, 6176, 6264, 6272, 6314, 6320, 6389, 6400, 6430, 6432, 6443, 6448, 6459, 6470, 6509, 6512, 6516, 6528, 6571, 6576, 6601, 6608, 6618, 6656, 6683, 6688, 6750, 6752, 6780, 6783, 6793, 6800, 6809, 6823, 6823, 6832, 6845, 6847, 6862, 6912, 6988, 6992, 7001, 7019, 7027, 7040, 7155, 7168, 7223, 7232, 7241, 7245, 7293, 7296, 7304, 7312, 7354, 7357, 7359, 7376, 7378, 7380, 7418, 7424, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8204, 8205, 8255, 8256, 8276, 8276, 8305, 8305, 8319, 8319, 8336, 8348, 8400, 8412, 8417, 8417, 8421, 8432, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8472, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11492, 11499, 11507, 11520, 11557, 11559, 11559, 11565, 11565, 11568, 11623, 11631, 11631, 11647, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 11744, 11775, 12293, 12295, 12321, 12335, 12337, 12341, 12344, 12348, 12353, 12438, 12441, 12447, 12449, 12543, 12549, 12591, 12593, 12686, 12704, 12735, 12784, 12799, 13312, 19903, 19968, 42124, 42192, 42237, 42240, 42508, 42512, 42539, 42560, 42607, 42612, 42621, 42623, 42737, 42775, 42783, 42786, 42888, 42891, 42954, 42960, 42961, 42963, 42963, 42965, 42969, 42994, 43047, 43052, 43052, 43072, 43123, 43136, 43205, 43216, 43225, 43232, 43255, 43259, 43259, 43261, 43309, 43312, 43347, 43360, 43388, 43392, 43456, 43471, 43481, 43488, 43518, 43520, 43574, 43584, 43597, 43600, 43609, 43616, 43638, 43642, 43714, 43739, 43741, 43744, 43759, 43762, 43766, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43824, 43866, 43868, 43881, 43888, 44010, 44012, 44013, 44016, 44025, 44032, 55203, 55216, 55238, 55243, 55291, 63744, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65024, 65039, 65056, 65071, 65075, 65076, 65101, 65103, 65136, 65140, 65142, 65276, 65296, 65305, 65313, 65338, 65343, 65343, 65345, 65370, 65381, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500, 65536, 65547, 65549, 65574, 65576, 65594, 65596, 65597, 65599, 65613, 65616, 65629, 65664, 65786, 65856, 65908, 66045, 66045, 66176, 66204, 66208, 66256, 66272, 66272, 66304, 66335, 66349, 66378, 66384, 66426, 66432, 66461, 66464, 66499, 66504, 66511, 66513, 66517, 66560, 66717, 66720, 66729, 66736, 66771, 66776, 66811, 66816, 66855, 66864, 66915, 66928, 66938, 66940, 66954, 66956, 66962, 66964, 66965, 66967, 66977, 66979, 66993, 66995, 67001, 67003, 67004, 67072, 67382, 67392, 67413, 67424, 67431, 67456, 67461, 67463, 67504, 67506, 67514, 67584, 67589, 67592, 67592, 67594, 67637, 67639, 67640, 67644, 67644, 67647, 67669, 67680, 67702, 67712, 67742, 67808, 67826, 67828, 67829, 67840, 67861, 67872, 67897, 67968, 68023, 68030, 68031, 68096, 68099, 68101, 68102, 68108, 68115, 68117, 68119, 68121, 68149, 68152, 68154, 68159, 68159, 68192, 68220, 68224, 68252, 68288, 68295, 68297, 68326, 68352, 68405, 68416, 68437, 68448, 68466, 68480, 68497, 68608, 68680, 68736, 68786, 68800, 68850, 68864, 68903, 68912, 68921, 69248, 69289, 69291, 69292, 69296, 69297, 69373, 69404, 69415, 69415, 69424, 69456, 69488, 69509, 69552, 69572, 69600, 69622, 69632, 69702, 69734, 69749, 69759, 69818, 69826, 69826, 69840, 69864, 69872, 69881, 69888, 69940, 69942, 69951, 69956, 69959, 69968, 70003, 70006, 70006, 70016, 70084, 70089, 70092, 70094, 70106, 70108, 70108, 70144, 70161, 70163, 70199, 70206, 70209, 70272, 70278, 70280, 70280, 70282, 70285, 70287, 70301, 70303, 70312, 70320, 70378, 70384, 70393, 70400, 70403, 70405, 70412, 70415, 70416, 70419, 70440, 70442, 70448, 70450, 70451, 70453, 70457, 70459, 70468, 70471, 70472, 70475, 70477, 70480, 70480, 70487, 70487, 70493, 70499, 70502, 70508, 70512, 70516, 70656, 70730, 70736, 70745, 70750, 70753, 70784, 70853, 70855, 70855, 70864, 70873, 71040, 71093, 71096, 71104, 71128, 71133, 71168, 71232, 71236, 71236, 71248, 71257, 71296, 71352, 71360, 71369, 71424, 71450, 71453, 71467, 71472, 71481, 71488, 71494, 71680, 71738, 71840, 71913, 71935, 71942, 71945, 71945, 71948, 71955, 71957, 71958, 71960, 71989, 71991, 71992, 71995, 72003, 72016, 72025, 72096, 72103, 72106, 72151, 72154, 72161, 72163, 72164, 72192, 72254, 72263, 72263, 72272, 72345, 72349, 72349, 72368, 72440, 72704, 72712, 72714, 72758, 72760, 72768, 72784, 72793, 72818, 72847, 72850, 72871, 72873, 72886, 72960, 72966, 72968, 72969, 72971, 73014, 73018, 73018, 73020, 73021, 73023, 73031, 73040, 73049, 73056, 73061, 73063, 73064, 73066, 73102, 73104, 73105, 73107, 73112, 73120, 73129, 73440, 73462, 73472, 73488, 73490, 73530, 73534, 73538, 73552, 73561, 73648, 73648, 73728, 74649, 74752, 74862, 74880, 75075, 77712, 77808, 77824, 78895, 78912, 78933, 82944, 83526, 92160, 92728, 92736, 92766, 92768, 92777, 92784, 92862, 92864, 92873, 92880, 92909, 92912, 92916, 92928, 92982, 92992, 92995, 93008, 93017, 93027, 93047, 93053, 93071, 93760, 93823, 93952, 94026, 94031, 94087, 94095, 94111, 94176, 94177, 94179, 94180, 94192, 94193, 94208, 100343, 100352, 101589, 101632, 101640, 110576, 110579, 110581, 110587, 110589, 110590, 110592, 110882, 110898, 110898, 110928, 110930, 110933, 110933, 110948, 110951, 110960, 111355, 113664, 113770, 113776, 113788, 113792, 113800, 113808, 113817, 113821, 113822, 118528, 118573, 118576, 118598, 119141, 119145, 119149, 119154, 119163, 119170, 119173, 119179, 119210, 119213, 119362, 119364, 119808, 119892, 119894, 119964, 119966, 119967, 119970, 119970, 119973, 119974, 119977, 119980, 119982, 119993, 119995, 119995, 119997, 120003, 120005, 120069, 120071, 120074, 120077, 120084, 120086, 120092, 120094, 120121, 120123, 120126, 120128, 120132, 120134, 120134, 120138, 120144, 120146, 120485, 120488, 120512, 120514, 120538, 120540, 120570, 120572, 120596, 120598, 120628, 120630, 120654, 120656, 120686, 120688, 120712, 120714, 120744, 120746, 120770, 120772, 120779, 120782, 120831, 121344, 121398, 121403, 121452, 121461, 121461, 121476, 121476, 121499, 121503, 121505, 121519, 122624, 122654, 122661, 122666, 122880, 122886, 122888, 122904, 122907, 122913, 122915, 122916, 122918, 122922, 122928, 122989, 123023, 123023, 123136, 123180, 123184, 123197, 123200, 123209, 123214, 123214, 123536, 123566, 123584, 123641, 124112, 124153, 124896, 124902, 124904, 124907, 124909, 124910, 124912, 124926, 124928, 125124, 125136, 125142, 125184, 125259, 125264, 125273, 126464, 126467, 126469, 126495, 126497, 126498, 126500, 126500, 126503, 126503, 126505, 126514, 126516, 126519, 126521, 126521, 126523, 126523, 126530, 126530, 126535, 126535, 126537, 126537, 126539, 126539, 126541, 126543, 126545, 126546, 126548, 126548, 126551, 126551, 126553, 126553, 126555, 126555, 126557, 126557, 126559, 126559, 126561, 126562, 126564, 126564, 126567, 126570, 126572, 126578, 126580, 126583, 126585, 126588, 126590, 126590, 126592, 126601, 126603, 126619, 126625, 126627, 126629, 126633, 126635, 126651, 130032, 130041, 131072, 173791, 173824, 177977, 177984, 178205, 178208, 183969, 183984, 191456, 191472, 192093, 194560, 195101, 196608, 201546, 201552, 205743, 917760, 917999} +) + +type ScannerState struct { + pos int // Current position in text (and ending position of current token) + fullStartPos int // Starting position of current token including preceding whitespace + tokenStart int // Starting position of non-whitespace part of current token + token ast.Kind // Kind of current token + tokenValue string // Parsed value of current token + tokenFlags ast.TokenFlags // Flags for current token + commentDirectives []ast.CommentDirective + skipJSDocLeadingAsterisks int // Leading asterisks to skip when scanning types inside JSDoc. Should be 0 outside JSDoc +} + +type Scanner struct { + text string + languageVariant core.LanguageVariant + onError ErrorCallback + skipTrivia bool + JSDocParsingMode ast.JSDocParsingMode + scriptKind core.ScriptKind + ScannerState + + numberCache map[string]string + hexNumberCache map[string]string + hexDigitCache map[string]string +} + +func defaultScanner() Scanner { + // Using a function rather than a global is intentional; this function is + // inlined as pure code (zeroing + moves), whereas a global requires write + // barriers since the memory is mutable. + return Scanner{skipTrivia: true} +} + +func NewScanner() *Scanner { + s := defaultScanner() + return &s +} + +func (s *Scanner) Reset() { + numberCache := cleared(s.numberCache) + hexNumberCache := cleared(s.hexNumberCache) + hexDigitCache := cleared(s.hexDigitCache) + *s = defaultScanner() + s.numberCache = numberCache + s.hexNumberCache = hexNumberCache + s.hexDigitCache = hexDigitCache +} + +func cleared[M ~map[K]V, K comparable, V any](m M) M { + clear(m) + return m +} + +func (s *Scanner) Text() string { + return s.text +} + +func (s *Scanner) Token() ast.Kind { + return s.token +} + +func (s *Scanner) TokenFlags() ast.TokenFlags { + return s.tokenFlags +} + +func (s *Scanner) TokenFullStart() int { + return s.fullStartPos +} + +func (s *Scanner) TokenStart() int { + return s.tokenStart +} + +func (s *Scanner) TokenEnd() int { + return s.pos +} + +func (s *Scanner) TokenText() string { + return s.text[s.tokenStart:s.pos] +} + +func (s *Scanner) TokenValue() string { + return s.tokenValue +} + +func (s *Scanner) TokenRange() core.TextRange { + return core.NewTextRange(s.tokenStart, s.pos) +} + +func (s *Scanner) CommentDirectives() []ast.CommentDirective { + return s.commentDirectives +} + +func (s *Scanner) Mark() ScannerState { + return s.ScannerState +} + +func (s *Scanner) Rewind(state ScannerState) { + s.ScannerState = state +} + +func (s *Scanner) ResetPos(pos int) { + if pos < 0 { + panic("Cannot reset token state to negative position") + } + s.pos = pos + s.fullStartPos = pos + s.tokenStart = pos +} + +func (s *Scanner) ResetTokenState(pos int) { + s.ResetPos(pos) + s.token = ast.KindUnknown + s.tokenValue = "" + s.tokenFlags = ast.TokenFlagsNone +} + +func (scanner *Scanner) SetSkipJSDocLeadingAsterisks(skip bool) { + if skip { + scanner.skipJSDocLeadingAsterisks += 1 + } else { + scanner.skipJSDocLeadingAsterisks += -1 + } +} + +func (scanner *Scanner) SetSkipTrivia(skip bool) { + scanner.skipTrivia = skip +} + +func (s *Scanner) HasUnicodeEscape() bool { + return s.tokenFlags&ast.TokenFlagsUnicodeEscape != 0 +} + +func (s *Scanner) HasExtendedUnicodeEscape() bool { + return s.tokenFlags&ast.TokenFlagsExtendedUnicodeEscape != 0 +} + +func (s *Scanner) HasPrecedingLineBreak() bool { + return s.tokenFlags&ast.TokenFlagsPrecedingLineBreak != 0 +} + +func (s *Scanner) HasPrecedingJSDocComment() bool { + return s.tokenFlags&ast.TokenFlagsPrecedingJSDocComment != 0 +} + +func (s *Scanner) HasPrecedingJSDocLeadingAsterisks() bool { + return s.tokenFlags&ast.TokenFlagsPrecedingJSDocLeadingAsterisks != 0 +} + +func (s *Scanner) SetText(text string) { + s.text = text + s.ScannerState = ScannerState{} +} + +func (s *Scanner) SetOnError(errorCallback ErrorCallback) { + s.onError = errorCallback +} + +func (s *Scanner) SetScriptKind(scriptKind core.ScriptKind) { + s.scriptKind = scriptKind +} + +func (s *Scanner) SetJSDocParsingMode(kind ast.JSDocParsingMode) { + s.JSDocParsingMode = kind +} + +func (s *Scanner) SetLanguageVariant(languageVariant core.LanguageVariant) { + s.languageVariant = languageVariant +} + +func (s *Scanner) error(diagnostic *diagnostics.Message) { + s.errorAt(diagnostic, s.pos, 0) +} + +func (s *Scanner) errorAt(diagnostic *diagnostics.Message, pos int, length int, args ...any) { + if s.onError != nil { + s.onError(diagnostic, pos, length, args...) + } +} + +// NOTE: even though this returns a rune, it only decodes the current byte. +// It must be checked against utf8.RuneSelf to verify that a call to charAndSize +// is not needed. +func (s *Scanner) char() rune { + if s.pos < len(s.text) { + return rune(s.text[s.pos]) + } + return -1 +} + +// NOTE: this returns a rune, but only decodes the byte at the offset. +func (s *Scanner) charAt(offset int) rune { + if s.pos+offset < len(s.text) { + return rune(s.text[s.pos+offset]) + } + return -1 +} + +func (s *Scanner) charAndSize() (rune, int) { + return utf8.DecodeRuneInString(s.text[s.pos:]) +} + +func (s *Scanner) shouldParseJSDoc() bool { + switch s.JSDocParsingMode { + case ast.JSDocParsingModeParseAll: + return true + case ast.JSDocParsingModeParseNone: + return false + } + if s.scriptKind != core.ScriptKindTS && s.scriptKind != core.ScriptKindTSX { + // If outside of TS, we need JSDoc to get any type info. + return true + } + if s.JSDocParsingMode == ast.JSDocParsingModeParseForTypeInfo { + // If we're in TS, but we don't need to produce reliable errors, + // we don't need to parse to find @see or @link. + return false + } + text := s.text[s.fullStartPos:s.pos] + for { + i := strings.IndexByte(text, '@') + if i < 0 { + break + } + text = text[i+1:] + if strings.HasPrefix(text, "see") || strings.HasPrefix(text, "link") { + return true + } + } + return false +} + +func (s *Scanner) Scan() ast.Kind { + s.fullStartPos = s.pos + s.tokenFlags = ast.TokenFlagsNone + for { + s.tokenStart = s.pos + ch := s.char() + + switch ch { + case '\t', '\v', '\f', ' ': + s.pos++ + if s.skipTrivia { + continue + } + for { + ch, size := s.charAndSize() + if !stringutil.IsWhiteSpaceSingleLine(ch) { + break + } + s.pos += size + } + s.token = ast.KindWhitespaceTrivia + case '\n', '\r': + s.tokenFlags |= ast.TokenFlagsPrecedingLineBreak + if s.skipTrivia { + s.pos++ + continue + } + if ch == '\r' && s.charAt(1) == '\n' { + s.pos += 2 + } else { + s.pos++ + } + s.token = ast.KindNewLineTrivia + case '!': + if s.charAt(1) == '=' { + if s.charAt(2) == '=' { + s.pos += 3 + s.token = ast.KindExclamationEqualsEqualsToken + } else { + s.pos += 2 + s.token = ast.KindExclamationEqualsToken + } + } else { + s.pos++ + s.token = ast.KindExclamationToken + } + case '"', '\'': + s.tokenValue = s.scanString(false /*jsxAttributeString*/) + s.token = ast.KindStringLiteral + case '`': + s.token = s.scanTemplateAndSetTokenValue(false /*shouldEmitInvalidEscapeError*/) + case '%': + if s.charAt(1) == '=' { + s.pos += 2 + s.token = ast.KindPercentEqualsToken + } else { + s.pos++ + s.token = ast.KindPercentToken + } + case '&': + if s.charAt(1) == '&' { + if s.charAt(2) == '=' { + s.pos += 3 + s.token = ast.KindAmpersandAmpersandEqualsToken + } else { + s.pos += 2 + s.token = ast.KindAmpersandAmpersandToken + } + } else if s.charAt(1) == '=' { + s.pos += 2 + s.token = ast.KindAmpersandEqualsToken + } else { + s.pos++ + s.token = ast.KindAmpersandToken + } + case '(': + s.pos++ + s.token = ast.KindOpenParenToken + case ')': + s.pos++ + s.token = ast.KindCloseParenToken + case '*': + if s.charAt(1) == '=' { + s.pos += 2 + s.token = ast.KindAsteriskEqualsToken + } else if s.charAt(1) == '*' { + if s.charAt(2) == '=' { + s.pos += 3 + s.token = ast.KindAsteriskAsteriskEqualsToken + } else { + s.pos += 2 + s.token = ast.KindAsteriskAsteriskToken + } + } else { + s.pos++ + if s.skipJSDocLeadingAsterisks != 0 && + (s.tokenFlags&ast.TokenFlagsPrecedingJSDocLeadingAsterisks) == 0 && + (s.tokenFlags&ast.TokenFlagsPrecedingLineBreak) != 0 { + s.tokenFlags |= ast.TokenFlagsPrecedingJSDocLeadingAsterisks + continue + } + s.token = ast.KindAsteriskToken + } + case '+': + if s.charAt(1) == '=' { + s.pos += 2 + s.token = ast.KindPlusEqualsToken + } else if s.charAt(1) == '+' { + s.pos += 2 + s.token = ast.KindPlusPlusToken + } else { + s.pos++ + s.token = ast.KindPlusToken + } + case ',': + s.pos++ + s.token = ast.KindCommaToken + case '-': + if s.charAt(1) == '=' { + s.pos += 2 + s.token = ast.KindMinusEqualsToken + } else if s.charAt(1) == '-' { + s.pos += 2 + s.token = ast.KindMinusMinusToken + } else { + s.pos++ + s.token = ast.KindMinusToken + } + case '.': + if stringutil.IsDigit(s.charAt(1)) { + s.token = s.scanNumber() + } else if s.charAt(1) == '.' && s.charAt(2) == '.' { + s.pos += 3 + s.token = ast.KindDotDotDotToken + } else { + s.pos++ + s.token = ast.KindDotToken + } + case '/': + // Single-line comment + if s.charAt(1) == '/' { + s.pos += 2 + + for { + ch1, size := s.charAndSize() + if size == 0 || stringutil.IsLineBreak(ch1) { + break + } + s.pos += size + } + + s.processCommentDirective(s.tokenStart, s.pos, false) + + if s.skipTrivia { + continue + } + s.token = ast.KindSingleLineCommentTrivia + return s.token + } + // Multi-line comment + if s.charAt(1) == '*' { + s.pos += 2 + isJSDoc := s.char() == '*' && s.charAt(1) != '/' + + commentClosed := false + lastLineStart := s.tokenStart + for { + ch1, size := s.charAndSize() + if size == 0 { + break + } + + if ch1 == '*' && s.charAt(1) == '/' { + s.pos += 2 + commentClosed = true + break + } + + s.pos += size + + if stringutil.IsLineBreak(ch1) { + lastLineStart = s.pos + s.tokenFlags |= ast.TokenFlagsPrecedingLineBreak + } + } + + if isJSDoc && s.shouldParseJSDoc() { + s.tokenFlags |= ast.TokenFlagsPrecedingJSDocComment + } + + s.processCommentDirective(lastLineStart, s.pos, true) + + if !commentClosed { + s.error(diagnostics.Asterisk_Slash_expected) + } + + if s.skipTrivia { + continue + } + + if !commentClosed { + s.tokenFlags |= ast.TokenFlagsUnterminated + } + s.token = ast.KindMultiLineCommentTrivia + return s.token + } + if s.charAt(1) == '=' { + s.pos += 2 + s.token = ast.KindSlashEqualsToken + } else { + s.pos++ + s.token = ast.KindSlashToken + } + case '0': + if s.charAt(1) == 'X' || s.charAt(1) == 'x' { + start := s.pos + s.pos += 2 + digits := s.scanHexDigits(1, true, true) + if digits == "" { + s.error(diagnostics.Hexadecimal_digit_expected) + digits = "0" + } + if s.hexNumberCache == nil { + s.hexNumberCache = make(map[string]string) + } + if cachedValue, ok := s.hexNumberCache[digits]; ok { + s.tokenValue = cachedValue + } else { + rawText := s.text[start:s.pos] + if strings.HasPrefix(rawText, "0x") && rawText[2:] == digits { + s.tokenValue = rawText + } else { + s.tokenValue = "0x" + digits + } + s.hexNumberCache[digits] = s.tokenValue + } + s.tokenFlags |= ast.TokenFlagsHexSpecifier + s.token = s.scanBigIntSuffix() + break + } + if s.charAt(1) == 'B' || s.charAt(1) == 'b' { + s.pos += 2 + digits := s.scanBinaryOrOctalDigits(2) + if digits == "" { + s.error(diagnostics.Binary_digit_expected) + digits = "0" + } + s.tokenValue = "0b" + digits + s.tokenFlags |= ast.TokenFlagsBinarySpecifier + s.token = s.scanBigIntSuffix() + break + } + if s.charAt(1) == 'O' || s.charAt(1) == 'o' { + s.pos += 2 + digits := s.scanBinaryOrOctalDigits(8) + if digits == "" { + s.error(diagnostics.Octal_digit_expected) + digits = "0" + } + s.tokenValue = "0o" + digits + s.tokenFlags |= ast.TokenFlagsOctalSpecifier + s.token = s.scanBigIntSuffix() + break + } + fallthrough + case '1', '2', '3', '4', '5', '6', '7', '8', '9': + s.token = s.scanNumber() + case ':': + s.pos++ + s.token = ast.KindColonToken + case ';': + s.pos++ + s.token = ast.KindSemicolonToken + case '<': + if isConflictMarkerTrivia(s.text, s.pos) { + s.pos = scanConflictMarkerTrivia(s.text, s.pos, s.errorAt) + if s.skipTrivia { + continue + } else { + s.token = ast.KindConflictMarkerTrivia + return s.token + } + } + if s.charAt(1) == '<' { + if s.charAt(2) == '=' { + s.pos += 3 + s.token = ast.KindLessThanLessThanEqualsToken + } else { + s.pos += 2 + s.token = ast.KindLessThanLessThanToken + } + } else if s.charAt(1) == '=' { + s.pos += 2 + s.token = ast.KindLessThanEqualsToken + } else if s.languageVariant == core.LanguageVariantJSX && s.charAt(1) == '/' && s.charAt(2) != '*' { + s.pos += 2 + s.token = ast.KindLessThanSlashToken + } else { + s.pos++ + s.token = ast.KindLessThanToken + } + case '=': + if isConflictMarkerTrivia(s.text, s.pos) { + s.pos = scanConflictMarkerTrivia(s.text, s.pos, s.errorAt) + if s.skipTrivia { + continue + } else { + s.token = ast.KindConflictMarkerTrivia + return s.token + } + } + if s.charAt(1) == '=' { + if s.charAt(2) == '=' { + s.pos += 3 + s.token = ast.KindEqualsEqualsEqualsToken + } else { + s.pos += 2 + s.token = ast.KindEqualsEqualsToken + } + } else if s.charAt(1) == '>' { + s.pos += 2 + s.token = ast.KindEqualsGreaterThanToken + } else { + s.pos++ + s.token = ast.KindEqualsToken + } + case '>': + if isConflictMarkerTrivia(s.text, s.pos) { + s.pos = scanConflictMarkerTrivia(s.text, s.pos, s.errorAt) + if s.skipTrivia { + continue + } else { + s.token = ast.KindConflictMarkerTrivia + return s.token + } + } + s.pos++ + s.token = ast.KindGreaterThanToken + case '?': + if s.charAt(1) == '.' && !stringutil.IsDigit(s.charAt(2)) { + s.pos += 2 + s.token = ast.KindQuestionDotToken + } else if s.charAt(1) == '?' { + if s.charAt(2) == '=' { + s.pos += 3 + s.token = ast.KindQuestionQuestionEqualsToken + } else { + s.pos += 2 + s.token = ast.KindQuestionQuestionToken + } + } else { + s.pos++ + s.token = ast.KindQuestionToken + } + case '[': + s.pos++ + s.token = ast.KindOpenBracketToken + case ']': + s.pos++ + s.token = ast.KindCloseBracketToken + case '^': + if s.charAt(1) == '=' { + s.pos += 2 + s.token = ast.KindCaretEqualsToken + } else { + s.pos++ + s.token = ast.KindCaretToken + } + case '{': + s.pos++ + s.token = ast.KindOpenBraceToken + case '|': + if isConflictMarkerTrivia(s.text, s.pos) { + s.pos = scanConflictMarkerTrivia(s.text, s.pos, s.errorAt) + if s.skipTrivia { + continue + } else { + s.token = ast.KindConflictMarkerTrivia + return s.token + } + } + if s.charAt(1) == '|' { + if s.charAt(2) == '=' { + s.pos += 3 + s.token = ast.KindBarBarEqualsToken + } else { + s.pos += 2 + s.token = ast.KindBarBarToken + } + } else if s.charAt(1) == '=' { + s.pos += 2 + s.token = ast.KindBarEqualsToken + } else { + s.pos++ + s.token = ast.KindBarToken + } + case '}': + s.pos++ + s.token = ast.KindCloseBraceToken + case '~': + s.pos++ + s.token = ast.KindTildeToken + case '@': + s.pos++ + s.token = ast.KindAtToken + case '\\': + cp := s.peekUnicodeEscape() + if cp >= 0 && IsIdentifierStart(cp) { + s.tokenValue = string(s.scanUnicodeEscape(true)) + s.scanIdentifierParts() + s.token = GetIdentifierToken(s.tokenValue) + } else { + s.scanInvalidCharacter() + } + case '#': + if s.charAt(1) == '!' { + if s.pos == 0 { + s.pos += 2 + for ch, size := s.charAndSize(); size > 0 && !stringutil.IsLineBreak(ch); ch, size = s.charAndSize() { + s.pos += size + } + continue + } + s.errorAt(diagnostics.X_can_only_be_used_at_the_start_of_a_file, s.pos, 2) + s.pos++ + s.token = ast.KindUnknown + break + } + if s.charAt(1) == '\\' { + s.pos++ + cp := s.peekUnicodeEscape() + if cp >= 0 && IsIdentifierStart(cp) { + s.tokenValue = "#" + string(s.scanUnicodeEscape(true)) + s.scanIdentifierParts() + s.token = ast.KindPrivateIdentifier + break + } + s.pos-- + } + if !s.scanIdentifier(1) { + s.errorAt(diagnostics.Invalid_character, s.pos-1, 1) + s.tokenValue = "#" + } + s.token = ast.KindPrivateIdentifier + default: + if ch < 0 { + s.token = ast.KindEndOfFile + break + } + if s.scanIdentifier(0) { + s.token = GetIdentifierToken(s.tokenValue) + break + } + ch, size := s.charAndSize() + if ch == utf8.RuneError && size == 1 { + s.errorAt(diagnostics.File_appears_to_be_binary, 0, 0) + s.pos = len(s.text) + s.token = ast.KindNonTextFileMarkerTrivia + break + } + if stringutil.IsWhiteSpaceSingleLine(ch) { + s.pos += size + + // If we get here and it's not 0x0085 (nextLine), then we're handling non-ASCII whitespace. + // Handle skipTrivia like we do in the space case above. + if ch == 0x0085 || s.skipTrivia { + continue + } + + for { + ch, size = s.charAndSize() + if !stringutil.IsWhiteSpaceSingleLine(ch) { + break + } + s.pos += size + } + s.token = ast.KindWhitespaceTrivia + return s.token + } + if stringutil.IsLineBreak(ch) { + s.tokenFlags |= ast.TokenFlagsPrecedingLineBreak + s.pos += size + continue + } + s.scanInvalidCharacter() + } + return s.token + } +} + +func (s *Scanner) processCommentDirective(start int, end int, multiline bool) { + // Skip starting slashes and whitespace + pos := start + if multiline { + // Skip whitespace + for pos < end && (s.text[pos] == ' ' || s.text[pos] == '\t') { + pos++ + } + // Skip combinations of / and * + for pos < end && (s.text[pos] == '/' || s.text[pos] == '*') { + pos++ + } + } else { + // Skip opening // + pos += 2 + // Skip another / if present + for pos < end && s.text[pos] == '/' { + pos++ + } + } + // Skip whitespace + for pos < end && (s.text[pos] == ' ' || s.text[pos] == '\t') { + pos++ + } + // Directive must start with '@' + if !(pos < end && s.text[pos] == '@') { + return + } + pos++ + var kind ast.CommentDirectiveKind + switch { + case strings.HasPrefix(s.text[pos:], "ts-expect-error"): + kind = ast.CommentDirectiveKindExpectError + case strings.HasPrefix(s.text[pos:], "ts-ignore"): + kind = ast.CommentDirectiveKindIgnore + default: + return + } + s.commentDirectives = append(s.commentDirectives, ast.CommentDirective{Loc: core.NewTextRange(start, end), Kind: kind}) +} + +func (s *Scanner) ReScanLessThanToken() ast.Kind { + if s.token == ast.KindLessThanLessThanToken { + s.pos = s.tokenStart + 1 + s.token = ast.KindLessThanToken + } + return s.token +} + +func (s *Scanner) ReScanGreaterThanToken() ast.Kind { + if s.token == ast.KindGreaterThanToken { + s.pos = s.tokenStart + 1 + if s.char() == '>' { + if s.charAt(1) == '>' { + if s.charAt(2) == '=' { + s.pos += 3 + s.token = ast.KindGreaterThanGreaterThanGreaterThanEqualsToken + } else { + s.pos += 2 + s.token = ast.KindGreaterThanGreaterThanGreaterThanToken + } + } else if s.charAt(1) == '=' { + s.pos += 2 + s.token = ast.KindGreaterThanGreaterThanEqualsToken + } else { + s.pos++ + s.token = ast.KindGreaterThanGreaterThanToken + } + } else if s.char() == '=' { + s.pos++ + s.token = ast.KindGreaterThanEqualsToken + } + } + return s.token +} + +func (s *Scanner) ReScanTemplateToken(isTaggedTemplate bool) ast.Kind { + s.pos = s.tokenStart + s.token = s.scanTemplateAndSetTokenValue(!isTaggedTemplate) + return s.token +} + +func (s *Scanner) ReScanAsteriskEqualsToken() ast.Kind { + if s.token != ast.KindAsteriskEqualsToken { + panic("'ReScanAsteriskEqualsToken' should only be called on a '*='") + } + s.pos = s.tokenStart + 1 + s.token = ast.KindEqualsToken + return s.token +} + +// !!! https://github.com/microsoft/TypeScript/pull/55600 +func (s *Scanner) ReScanSlashToken() ast.Kind { + if s.token == ast.KindSlashToken || s.token == ast.KindSlashEqualsToken { + s.pos = s.tokenStart + 1 + startOfRegExpBody := s.pos + inEscape := false + inCharacterClass := false + loop: + for { + ch, size := s.charAndSize() + // If we reach the end of a file, or hit a newline, then this is an unterminated + // regex. Report error and return what we have so far. + switch { + case size == 0 || stringutil.IsLineBreak(ch): + s.tokenFlags |= ast.TokenFlagsUnterminated + break loop + case inEscape: + // Parsing an escape character; + // reset the flag and just advance to the next char. + inEscape = false + case ch == '/' && !inCharacterClass: + // A slash within a character class is permissible, + // but in general it signals the end of the regexp literal. + break loop + case ch == '[': + inCharacterClass = true + case ch == '\\': + inEscape = true + case ch == ']': + inCharacterClass = false + } + s.pos += size + } + if s.tokenFlags&ast.TokenFlagsUnterminated != 0 { + // Search for the nearest unbalanced bracket for better recovery. Since the expression is + // invalid anyways, we take nested square brackets into consideration for the best guess. + endOfRegExpBody := s.pos + s.pos = startOfRegExpBody + inEscape = false + characterClassDepth := 0 + inDecimalQuantifier := false + groupDepth := 0 + for s.pos < endOfRegExpBody { + ch, size := s.charAndSize() + if inEscape { + inEscape = false + } else if ch == '\\' { + inEscape = true + } else if ch == '[' { + characterClassDepth++ + } else if ch == ']' && characterClassDepth != 0 { + characterClassDepth-- + } else if characterClassDepth == 0 { + if ch == '{' { + inDecimalQuantifier = true + } else if ch == '}' && inDecimalQuantifier { + inDecimalQuantifier = false + } else if !inDecimalQuantifier { + if ch == '(' { + groupDepth++ + } else if ch == ')' && groupDepth != 0 { + groupDepth-- + } else if ch == ')' || ch == ']' || ch == '}' { + // We encountered an unbalanced bracket outside a character class. Treat this position as the end of regex. + break + } + } + } + s.pos += size + } + // Whitespaces and semicolons at the end are not likely to be part of the regex + for { + ch, size := utf8.DecodeLastRuneInString(s.text[:s.pos]) + if stringutil.IsWhiteSpaceLike(ch) || ch == ';' { + s.pos -= size + } else { + break + } + } + s.errorAt(diagnostics.Unterminated_regular_expression_literal, s.tokenStart, s.pos-s.tokenStart) + } else { + // Consume the slash character + s.pos++ + for { + ch, size := s.charAndSize() + if size == 0 || !IsIdentifierPart(ch) { + break + } + s.pos += size + } + } + s.tokenValue = s.text[s.tokenStart:s.pos] + s.token = ast.KindRegularExpressionLiteral + } + return s.token +} + +func (s *Scanner) ReScanJsxToken(allowMultilineJsxText bool) ast.Kind { + s.pos = s.fullStartPos + s.tokenStart = s.fullStartPos + s.token = s.ScanJsxTokenEx(allowMultilineJsxText) + return s.token +} + +func (s *Scanner) ReScanHashToken() ast.Kind { + if s.token == ast.KindPrivateIdentifier { + s.pos = s.tokenStart + 1 + s.token = ast.KindHashToken + } + return s.token +} + +func (s *Scanner) ReScanQuestionToken() ast.Kind { + if s.token != ast.KindQuestionQuestionToken { + panic("'reScanQuestionToken' should only be called on a '??'") + } + s.pos = s.tokenStart + 1 + s.token = ast.KindQuestionToken + return s.token +} + +func (s *Scanner) ScanJsxToken() ast.Kind { + return s.ScanJsxTokenEx(true /*allowMultilineJsxText*/) +} + +func (s *Scanner) ScanJsxTokenEx(allowMultilineJsxText bool) ast.Kind { + s.fullStartPos = s.pos + s.tokenStart = s.pos + ch := s.char() + switch { + case ch < 0: + s.token = ast.KindEndOfFile + case ch == '<': + if s.charAt(1) == '/' { + s.pos += 2 + s.token = ast.KindLessThanSlashToken + } else { + s.pos++ + s.token = ast.KindLessThanToken + } + case ch == '{': + s.pos++ + s.token = ast.KindOpenBraceToken + default: + // First non-whitespace character on this line. + firstNonWhitespace := 0 + // These initial values are special because the first line is: + // firstNonWhitespace = 0 to indicate that we want leading whitespace + for { + ch, size := s.charAndSize() + if size == 0 || ch == '{' { + break + } + if ch == '<' { + if isConflictMarkerTrivia(s.text, s.pos) { + s.pos = scanConflictMarkerTrivia(s.text, s.pos, s.errorAt) + s.token = ast.KindConflictMarkerTrivia + return s.token + } + break + } + if ch == '>' { + s.errorAt(diagnostics.Unexpected_token_Did_you_mean_or_gt, s.pos, 1) + } else if ch == '}' { + s.errorAt(diagnostics.Unexpected_token_Did_you_mean_or_rbrace, s.pos, 1) + } + // FirstNonWhitespace is 0, then we only see whitespaces so far. If we see a linebreak, we want to ignore that whitespaces. + // i.e (- : whitespace) + //
---- + //
becomes
+ // + //
----
becomes
----
+ if stringutil.IsLineBreak(ch) && firstNonWhitespace == 0 { + firstNonWhitespace = -1 + } else if !allowMultilineJsxText && stringutil.IsLineBreak(ch) && firstNonWhitespace > 0 { + // Stop JsxText on each line during formatting. This allows the formatter to + // indent each line correctly. + break + } else if !stringutil.IsWhiteSpaceLike(ch) { + firstNonWhitespace = s.pos + } + s.pos += size + } + s.tokenValue = s.text[s.fullStartPos:s.pos] + s.token = ast.KindJsxText + if firstNonWhitespace == -1 { + s.token = ast.KindJsxTextAllWhiteSpaces + } + } + return s.token +} + +// Scans a JSX identifier; these differ from normal identifiers in that they allow dashes +func (s *Scanner) ScanJsxIdentifier() ast.Kind { + if tokenIsIdentifierOrKeyword(s.token) { + // An identifier or keyword has already been parsed - check for a `-` or a single instance of `:` and then append it and + // everything after it to the token + // Do note that this means that `scanJsxIdentifier` effectively _mutates_ the visible token without advancing to a new token + // Any caller should be expecting this behavior and should only read the pos or token value after calling it. + for { + ch := s.char() + if ch < 0 { + break + } + if ch == '-' { + s.tokenValue += "-" + s.pos++ + continue + } + oldPos := s.pos + s.tokenValue += s.scanIdentifierParts() // reuse `scanIdentifierParts` so unicode escapes are handled + if s.pos == oldPos { + break + } + } + s.token = GetIdentifierToken(s.tokenValue) + } + return s.token +} + +func (s *Scanner) ScanJsxAttributeValue() ast.Kind { + s.fullStartPos = s.pos + switch s.char() { + case '"', '\'': + s.tokenValue = s.scanString(true /*jsxAttributeString*/) + s.token = ast.KindStringLiteral + return s.token + default: + // If this scans anything other than `{`, it's a parse error. + return s.Scan() + } +} + +func (s *Scanner) ReScanJsxAttributeValue() ast.Kind { + s.pos = s.fullStartPos + s.tokenStart = s.fullStartPos + return s.ScanJsxAttributeValue() +} + +/** In addition to the usual JSDoc ast.Kinds, can also return ast.KindJSDocCommentTextToken */ +func (s *Scanner) ScanJSDocCommentTextToken(inBackticks bool) ast.Kind { + s.fullStartPos = s.pos + s.tokenFlags = ast.TokenFlagsNone + if s.pos >= len(s.text) { + s.token = ast.KindEndOfFile + return s.token + } + s.tokenStart = s.pos + for ch, size := s.charAndSize(); s.pos < len(s.text) && !stringutil.IsLineBreak(ch) && ch != '`'; ch, size = s.charAndSize() { + if !inBackticks { + if ch == '{' { + break + } else if ch == '@' && s.pos >= 0 { + // @ doesn't start a new tag inside ``, and elsewhere, only after whitespace and before non-whitespace + previous, _ := utf8.DecodeLastRuneInString(s.text[:s.pos]) + if stringutil.IsWhiteSpaceSingleLine(previous) { + if s.pos+size >= len(s.text) { + // EOF counts as non-whitespace + break + } + next, _ := utf8.DecodeRuneInString(s.text[s.pos+size:]) + if !stringutil.IsWhiteSpaceLike(next) { + break + } + } + } + } + s.pos += size + } + if s.pos == s.tokenStart { + return s.ScanJSDocToken() + } + s.tokenValue = s.text[s.tokenStart:s.pos] + s.token = ast.KindJSDocCommentTextToken + return s.token +} + +func (s *Scanner) ScanJSDocToken() ast.Kind { + s.fullStartPos = s.pos + s.tokenFlags = ast.TokenFlagsNone + if s.pos >= len(s.text) { + s.token = ast.KindEndOfFile + return s.token + } + + s.tokenStart = s.pos + ch, size := s.charAndSize() + s.pos += size + switch ch { + case '\t', '\v', '\f', ' ': + for ch2, size2 := s.charAndSize(); size2 > 0 && stringutil.IsWhiteSpaceSingleLine(ch2); ch2, size2 = s.charAndSize() { + s.pos += size2 + } + s.token = ast.KindWhitespaceTrivia + return s.token + case '@': + s.token = ast.KindAtToken + return s.token + case '\r': + if s.char() == '\n' { + s.pos++ + } + fallthrough + case '\n': + s.tokenFlags |= ast.TokenFlagsPrecedingLineBreak + s.token = ast.KindNewLineTrivia + return s.token + case '*': + s.token = ast.KindAsteriskToken + return s.token + case '{': + s.token = ast.KindOpenBraceToken + return s.token + case '}': + s.token = ast.KindCloseBraceToken + return s.token + case '[': + s.token = ast.KindOpenBracketToken + return s.token + case ']': + s.token = ast.KindCloseBracketToken + return s.token + case '(': + s.token = ast.KindOpenParenToken + return s.token + case ')': + s.token = ast.KindCloseParenToken + return s.token + case '<': + s.token = ast.KindLessThanToken + return s.token + case '>': + s.token = ast.KindGreaterThanToken + return s.token + case '=': + s.token = ast.KindEqualsToken + return s.token + case ',': + s.token = ast.KindCommaToken + return s.token + case '.': + s.token = ast.KindDotToken + return s.token + case '`': + s.token = ast.KindBacktickToken + return s.token + case '#': + s.token = ast.KindHashToken + return s.token + case '\\': + s.pos-- + cp := s.peekUnicodeEscape() + if cp >= 0 && IsIdentifierStart(cp) { + s.tokenValue = string(s.scanUnicodeEscape(true)) + s.scanIdentifierParts() + s.token = GetIdentifierToken(s.tokenValue) + } else { + s.scanInvalidCharacter() + } + return s.token + } + + if IsIdentifierStart(ch) { + char := ch + for { + if s.pos >= len(s.text) { + break + } + char, size = s.charAndSize() + if !IsIdentifierPart(char) && char != '-' { + break + } + s.pos += size + } + s.tokenValue = s.text[s.tokenStart:s.pos] + if char == '\\' { + s.tokenValue += s.scanIdentifierParts() + } + s.token = GetIdentifierToken(s.tokenValue) + return s.token + } else { + s.token = ast.KindUnknown + return s.token + } +} + +func (s *Scanner) scanIdentifier(prefixLength int) bool { + start := s.pos + s.pos += prefixLength + ch := s.char() + // Fast path for simple ASCII identifiers + if stringutil.IsASCIILetter(ch) || ch == '_' || ch == '$' { + for { + s.pos++ + ch = s.char() + if !(isWordCharacter(ch) || ch == '$') { + break + } + } + if ch < utf8.RuneSelf && ch != '\\' { + s.tokenValue = s.text[start:s.pos] + return true + } + s.pos = start + prefixLength + } + ch, size := s.charAndSize() + if IsIdentifierStart(ch) { + for { + s.pos += size + ch, size = s.charAndSize() + if !IsIdentifierPart(ch) { + break + } + } + s.tokenValue = s.text[start:s.pos] + if ch == '\\' { + s.tokenValue += s.scanIdentifierParts() + } + return true + } + return false +} + +func (s *Scanner) scanIdentifierParts() string { + var sb strings.Builder + start := s.pos + for { + ch, size := s.charAndSize() + if IsIdentifierPart(ch) { + s.pos += size + continue + } + if ch == '\\' { + escaped := s.peekUnicodeEscape() + if escaped >= 0 && IsIdentifierPart(escaped) { + sb.WriteString(s.text[start:s.pos]) + sb.WriteRune(s.scanUnicodeEscape(true)) + start = s.pos + continue + } + } + break + } + sb.WriteString(s.text[start:s.pos]) + return sb.String() +} + +func (s *Scanner) scanString(jsxAttributeString bool) string { + quote := s.char() + if quote == '\'' { + s.tokenFlags |= ast.TokenFlagsSingleQuote + } + s.pos++ + // Fast path for simple strings without escape sequences. + strLen := strings.IndexRune(s.text[s.pos:], quote) + if strLen == 0 { + s.pos++ + return "" + } + if strLen > 0 { + str := s.text[s.pos : s.pos+strLen] + if !jsxAttributeString && !strings.ContainsAny(str, "\r\n\\") { + s.pos += strLen + 1 + return str + } + } + var sb strings.Builder + start := s.pos + for { + ch := s.char() + if ch < 0 { + sb.WriteString(s.text[start:s.pos]) + s.tokenFlags |= ast.TokenFlagsUnterminated + s.error(diagnostics.Unterminated_string_literal) + break + } + if ch == quote { + sb.WriteString(s.text[start:s.pos]) + s.pos++ + break + } + if ch == '\\' && !jsxAttributeString { + sb.WriteString(s.text[start:s.pos]) + sb.WriteString(s.scanEscapeSequence(EscapeSequenceScanningFlagsString | EscapeSequenceScanningFlagsReportErrors)) + start = s.pos + continue + } + if (ch == '\n' || ch == '\r') && !jsxAttributeString { + sb.WriteString(s.text[start:s.pos]) + s.tokenFlags |= ast.TokenFlagsUnterminated + s.error(diagnostics.Unterminated_string_literal) + break + } + s.pos++ + } + return sb.String() +} + +func (s *Scanner) scanTemplateAndSetTokenValue(shouldEmitInvalidEscapeError bool) ast.Kind { + startedWithBacktick := s.char() == '`' + s.pos++ + start := s.pos + parts := make([]string, 0, 4) + var token ast.Kind + for { + ch := s.char() + if ch < 0 || ch == '`' { + parts = append(parts, s.text[start:s.pos]) + if ch == '`' { + s.pos++ + } else { + s.tokenFlags |= ast.TokenFlagsUnterminated + s.error(diagnostics.Unterminated_template_literal) + } + token = core.IfElse(startedWithBacktick, ast.KindNoSubstitutionTemplateLiteral, ast.KindTemplateTail) + break + } + if ch == '$' && s.charAt(1) == '{' { + parts = append(parts, s.text[start:s.pos]) + s.pos += 2 + token = core.IfElse(startedWithBacktick, ast.KindTemplateHead, ast.KindTemplateMiddle) + break + } + if ch == '\\' { + parts = append(parts, s.text[start:s.pos]) + parts = append(parts, s.scanEscapeSequence(EscapeSequenceScanningFlagsString|core.IfElse(shouldEmitInvalidEscapeError, EscapeSequenceScanningFlagsReportErrors, 0))) + start = s.pos + continue + } + // Speculated ECMAScript 6 Spec 11.8.6.1: + // and LineTerminatorSequences are normalized to for Template Values + if ch == '\r' { + parts = append(parts, s.text[start:s.pos]) + s.pos++ + if s.char() == '\n' { + s.pos++ + } + parts = append(parts, "\n") + start = s.pos + continue + } + s.pos++ + } + s.tokenValue = strings.Join(parts, "") + return token +} + +func (s *Scanner) scanEscapeSequence(flags EscapeSequenceScanningFlags) string { + start := s.pos + s.pos++ + ch := s.char() + if ch < 0 { + s.error(diagnostics.Unexpected_end_of_text) + return "" + } + s.pos++ + switch ch { + case '0': + // Although '0' preceding any digit is treated as LegacyOctalEscapeSequence, + // '\08' should separately be interpreted as '\0' + '8'. + if !stringutil.IsDigit(s.char()) { + return "\x00" + } + // '\01', '\011' + fallthrough + case '1', '2', '3': + // '\1', '\17', '\177' + if stringutil.IsOctalDigit(s.char()) { + s.pos++ + } + // '\17', '\177' + fallthrough + case '4', '5', '6', '7': + // '\4', '\47' but not '\477' + if stringutil.IsOctalDigit(s.char()) { + s.pos++ + } + // '\47' + s.tokenFlags |= ast.TokenFlagsContainsInvalidEscape + if flags&EscapeSequenceScanningFlagsReportInvalidEscapeErrors != 0 { + code, _ := strconv.ParseInt(s.text[start+1:s.pos], 8, 32) + if flags&EscapeSequenceScanningFlagsRegularExpression != 0 && flags&EscapeSequenceScanningFlagsAtomEscape == 0 && ch != '0' { + s.errorAt(diagnostics.Octal_escape_sequences_and_backreferences_are_not_allowed_in_a_character_class_If_this_was_intended_as_an_escape_sequence_use_the_syntax_0_instead, start, s.pos-start, fmt.Sprintf("%02x", code)) + } else { + s.errorAt(diagnostics.Octal_escape_sequences_are_not_allowed_Use_the_syntax_0, start, s.pos-start, "\\x"+fmt.Sprintf("%02x", code)) + } + return string(rune(code)) + } + return s.text[start:s.pos] + case '8', '9': + // the invalid '\8' and '\9' + s.tokenFlags |= ast.TokenFlagsContainsInvalidEscape + if flags&EscapeSequenceScanningFlagsReportInvalidEscapeErrors != 0 { + if flags&EscapeSequenceScanningFlagsRegularExpression != 0 && flags&EscapeSequenceScanningFlagsAtomEscape == 0 { + s.errorAt(diagnostics.Decimal_escape_sequences_and_backreferences_are_not_allowed_in_a_character_class, start, s.pos-start) + } else { + s.errorAt(diagnostics.Escape_sequence_0_is_not_allowed, start, s.pos-start, s.text[start:s.pos]) + } + return string(ch) + } + return s.text[start:s.pos] + case 'b': + return "\b" + case 't': + return "\t" + case 'n': + return "\n" + case 'v': + return "\v" + case 'f': + return "\f" + case 'r': + return "\r" + case '\'': + return "'" + case '"': + return "\"" + case 'u': + // '\uDDDD' and '\U{DDDDDD}' + s.pos -= 2 + codePoint := s.scanUnicodeEscape(flags&EscapeSequenceScanningFlagsReportInvalidEscapeErrors != 0) + if codePoint < 0 { + return s.text[start:s.pos] + } + return string(codePoint) + case 'x': + // '\xDD' + for ; s.pos < start+4; s.pos++ { + if !stringutil.IsHexDigit(s.char()) { + s.tokenFlags |= ast.TokenFlagsContainsInvalidEscape + if flags&EscapeSequenceScanningFlagsReportInvalidEscapeErrors != 0 { + s.error(diagnostics.Hexadecimal_digit_expected) + } + return s.text[start:s.pos] + } + } + s.tokenFlags |= ast.TokenFlagsHexEscape + escapedValue, _ := strconv.ParseInt(s.text[start+2:s.pos], 16, 32) + return string(rune(escapedValue)) + case '\r': + // when encountering a LineContinuation (i.e. a backslash and a line terminator sequence), + // the line terminator is interpreted to be "the empty code unit sequence". + if s.char() == '\n' { + s.pos++ + } + fallthrough + case '\n': + // case CharacterCodes.lineSeparator !!! + // case CharacterCodes.paragraphSeparator !!! + return "" + default: + if flags&EscapeSequenceScanningFlagsAnyUnicodeMode != 0 || flags&EscapeSequenceScanningFlagsRegularExpression != 0 && flags&EscapeSequenceScanningFlagsAnnexB == 0 && IsIdentifierPart(ch) { + s.errorAt(diagnostics.This_character_cannot_be_escaped_in_a_regular_expression, s.pos-2, 2) + } + return string(ch) + } +} + +// Known to be at \u +func (s *Scanner) scanUnicodeEscape(shouldEmitInvalidEscapeError bool) rune { + s.pos += 2 + start := s.pos + extended := s.char() == '{' + var hexDigits string + if extended { + s.pos++ + s.tokenFlags |= ast.TokenFlagsExtendedUnicodeEscape + hexDigits = s.scanHexDigits(1, true, false) + } else { + s.tokenFlags |= ast.TokenFlagsUnicodeEscape + hexDigits = s.scanHexDigits(4, false, false) + } + if hexDigits == "" { + s.tokenFlags |= ast.TokenFlagsContainsInvalidEscape + if shouldEmitInvalidEscapeError { + s.error(diagnostics.Hexadecimal_digit_expected) + } + return -1 + } + hexValue, _ := strconv.ParseInt(hexDigits, 16, 32) + if extended { + if hexValue > 0x10FFFF { + s.tokenFlags |= ast.TokenFlagsContainsInvalidEscape + if shouldEmitInvalidEscapeError { + s.errorAt(diagnostics.An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive, start+1, s.pos-start-1) + } + return -1 + } + if s.char() != '}' { + s.tokenFlags |= ast.TokenFlagsContainsInvalidEscape + if shouldEmitInvalidEscapeError { + s.error(diagnostics.Unterminated_Unicode_escape_sequence) + } + return -1 + } + s.pos++ + } + return rune(hexValue) +} + +// Current character is known to be a backslash. Check for Unicode escape of the form '\uXXXX' +// or '\u{XXXXXX}' and return code point value if valid Unicode escape is found. Otherwise return -1. +func (s *Scanner) peekUnicodeEscape() rune { + if s.charAt(1) == 'u' { + savePos := s.pos + saveTokenFlags := s.tokenFlags + codePoint := s.scanUnicodeEscape(false) + s.pos = savePos + s.tokenFlags = saveTokenFlags + return codePoint + } + return -1 +} + +func (s *Scanner) scanNumber() ast.Kind { + start := s.pos + var fixedPart string + if s.char() == '0' { + s.pos++ + if s.char() == '_' { + s.tokenFlags |= ast.TokenFlagsContainsSeparator | ast.TokenFlagsContainsInvalidSeparator + s.errorAt(diagnostics.Numeric_separators_are_not_allowed_here, s.pos, 1) + s.pos = start + fixedPart = s.scanNumberFragment() + } else { + digits, isOctal := s.scanDigits() + if digits == "" { + fixedPart = "0" + } else if !isOctal { + s.tokenFlags |= ast.TokenFlagsContainsLeadingZero + fixedPart = digits + } else { + s.tokenValue = jsnum.FromString(digits).String() + s.tokenFlags |= ast.TokenFlagsOctal + withMinus := s.token == ast.KindMinusToken + literal := core.IfElse(withMinus, "-", "") + "0o" + s.tokenValue + if withMinus { + start-- + } + s.errorAt(diagnostics.Octal_literals_are_not_allowed_Use_the_syntax_0, start, s.pos-start, literal) + return ast.KindNumericLiteral + } + } + } else { + fixedPart = s.scanNumberFragment() + } + fixedPartEnd := s.pos + fractionalPart := "" + exponentPreamble := "" + exponentPart := "" + if s.char() == '.' { + s.pos++ + fractionalPart = s.scanNumberFragment() + } + end := s.pos + if s.char() == 'E' || s.char() == 'e' { + s.pos++ + s.tokenFlags |= ast.TokenFlagsScientific + if s.char() == '+' || s.char() == '-' { + s.pos++ + } + startNumericPart := s.pos + exponentPart = s.scanNumberFragment() + if exponentPart == "" { + s.error(diagnostics.Digit_expected) + } else { + exponentPreamble = s.text[end:startNumericPart] + end = s.pos + } + } + if s.tokenFlags&ast.TokenFlagsContainsSeparator != 0 { + s.tokenValue = fixedPart + if fractionalPart != "" { + s.tokenValue += "." + fractionalPart + } + if exponentPart != "" { + s.tokenValue += exponentPreamble + exponentPart + } + } else { + s.tokenValue = s.text[start:end] + } + if s.tokenFlags&ast.TokenFlagsContainsLeadingZero != 0 { + s.errorAt(diagnostics.Decimals_with_leading_zeros_are_not_allowed, start, s.pos-start) + s.tokenValue = jsnum.FromString(s.tokenValue).String() + return ast.KindNumericLiteral + } + var result ast.Kind + if fixedPartEnd == s.pos { + result = s.scanBigIntSuffix() + } else { + s.tokenValue = jsnum.FromString(s.tokenValue).String() + result = ast.KindNumericLiteral + } + ch, _ := s.charAndSize() + if IsIdentifierStart(ch) { + idStart := s.pos + id := s.scanIdentifierParts() + if result != ast.KindBigIntLiteral && len(id) == 1 && s.text[idStart] == 'n' { + if s.tokenFlags&ast.TokenFlagsScientific != 0 { + s.errorAt(diagnostics.A_bigint_literal_cannot_use_exponential_notation, start, s.pos-start) + return result + } + if fixedPartEnd < idStart { + s.errorAt(diagnostics.A_bigint_literal_must_be_an_integer, start, s.pos-start) + return result + } + } + s.errorAt(diagnostics.An_identifier_or_keyword_cannot_immediately_follow_a_numeric_literal, idStart, s.pos-idStart) + s.pos = idStart + } + return result +} + +func (s *Scanner) scanNumberFragment() string { + start := s.pos + allowSeparator := false + isPreviousTokenSeparator := false + result := "" + for { + ch := s.char() + if ch == '_' { + s.tokenFlags |= ast.TokenFlagsContainsSeparator + if allowSeparator { + allowSeparator = false + isPreviousTokenSeparator = true + result += s.text[start:s.pos] + } else { + s.tokenFlags |= ast.TokenFlagsContainsInvalidSeparator + if isPreviousTokenSeparator { + s.errorAt(diagnostics.Multiple_consecutive_numeric_separators_are_not_permitted, s.pos, 1) + } else { + s.errorAt(diagnostics.Numeric_separators_are_not_allowed_here, s.pos, 1) + } + } + s.pos++ + start = s.pos + continue + } + if stringutil.IsDigit(ch) { + allowSeparator = true + isPreviousTokenSeparator = false + s.pos++ + continue + } + break + } + if isPreviousTokenSeparator { + s.tokenFlags |= ast.TokenFlagsContainsInvalidSeparator + s.errorAt(diagnostics.Numeric_separators_are_not_allowed_here, s.pos-1, 1) + } + return result + s.text[start:s.pos] +} + +func (s *Scanner) scanDigits() (string, bool) { + start := s.pos + isOctal := true + for stringutil.IsDigit(s.char()) { + if !stringutil.IsOctalDigit(s.char()) { + isOctal = false + } + s.pos++ + } + return s.text[start:s.pos], isOctal +} + +func (s *Scanner) scanHexDigits(minCount int, scanAsManyAsPossible bool, canHaveSeparators bool) string { + digitCount := 0 + start := s.pos + allowSeparator := false + isPreviousTokenSeparator := false + for digitCount < minCount || scanAsManyAsPossible { + ch := s.char() + if stringutil.IsHexDigit(ch) { + allowSeparator = canHaveSeparators + isPreviousTokenSeparator = false + digitCount++ + } else if canHaveSeparators && ch == '_' { + s.tokenFlags |= ast.TokenFlagsContainsSeparator + if allowSeparator { + allowSeparator = false + isPreviousTokenSeparator = true + } else if isPreviousTokenSeparator { + s.errorAt(diagnostics.Multiple_consecutive_numeric_separators_are_not_permitted, s.pos, 1) + } else { + s.errorAt(diagnostics.Numeric_separators_are_not_allowed_here, s.pos, 1) + } + } else { + break + } + s.pos++ + } + if isPreviousTokenSeparator { + s.errorAt(diagnostics.Numeric_separators_are_not_allowed_here, s.pos-1, 1) + } + if digitCount < minCount { + return "" + } + digits := s.text[start:s.pos] + if s.hexDigitCache == nil { + s.hexDigitCache = make(map[string]string) + } + if cached, ok := s.hexDigitCache[digits]; ok { + return cached + } else { + original := digits + if s.tokenFlags&ast.TokenFlagsContainsSeparator != 0 { + digits = strings.ReplaceAll(digits, "_", "") + } + digits = strings.ToLower(digits) // standardize hex literals to lowercase + s.hexDigitCache[original] = digits + return digits + } +} + +func (s *Scanner) scanBinaryOrOctalDigits(base int32) string { + var sb strings.Builder + allowSeparator := false + isPreviousTokenSeparator := false + for { + ch := s.char() + if stringutil.IsDigit(ch) && ch-'0' < base { + sb.WriteByte(byte(ch)) + allowSeparator = true + isPreviousTokenSeparator = false + } else if ch == '_' { + s.tokenFlags |= ast.TokenFlagsContainsSeparator + if allowSeparator { + allowSeparator = false + isPreviousTokenSeparator = true + } else if isPreviousTokenSeparator { + s.errorAt(diagnostics.Multiple_consecutive_numeric_separators_are_not_permitted, s.pos, 1) + } else { + s.errorAt(diagnostics.Numeric_separators_are_not_allowed_here, s.pos, 1) + } + } else { + break + } + s.pos++ + } + if isPreviousTokenSeparator { + s.errorAt(diagnostics.Numeric_separators_are_not_allowed_here, s.pos-1, 1) + } + return sb.String() +} + +func (s *Scanner) scanBigIntSuffix() ast.Kind { + if s.char() == 'n' { + s.tokenValue += "n" + if s.tokenFlags&ast.TokenFlagsBinaryOrOctalSpecifier != 0 { + s.tokenValue = jsnum.ParsePseudoBigInt(s.tokenValue) + "n" + } + s.pos++ + return ast.KindBigIntLiteral + } + if s.numberCache == nil { + s.numberCache = make(map[string]string) + } + if cached, ok := s.numberCache[s.tokenValue]; ok { + s.tokenValue = cached + } else { + tokenValue := jsnum.FromString(s.tokenValue).String() + if tokenValue == s.tokenValue { + tokenValue = s.tokenValue + } + s.numberCache[s.tokenValue] = tokenValue + s.tokenValue = tokenValue + } + return ast.KindNumericLiteral +} + +func (s *Scanner) scanInvalidCharacter() { + _, size := s.charAndSize() + s.errorAt(diagnostics.Invalid_character, s.pos, size) + s.pos += size + s.token = ast.KindUnknown +} + +func GetIdentifierToken(str string) ast.Kind { + if len(str) >= 2 && len(str) <= 12 && str[0] >= 'a' && str[0] <= 'z' { + keyword := textToKeyword[str] + if keyword != ast.KindUnknown { + return keyword + } + } + return ast.KindIdentifier +} + +func IsValidIdentifier(s string) bool { + if len(s) == 0 { + return false + } + for i, ch := range s { + if i == 0 && !IsIdentifierStart(ch) || i != 0 && !IsIdentifierPart(ch) { + return false + } + } + return true +} + +// Section 6.1.4 +func isWordCharacter(ch rune) bool { + return stringutil.IsASCIILetter(ch) || stringutil.IsDigit(ch) || ch == '_' +} + +func IsIdentifierStart(ch rune) bool { + return stringutil.IsASCIILetter(ch) || ch == '_' || ch == '$' || ch >= utf8.RuneSelf && isUnicodeIdentifierStart(ch) +} + +func IsIdentifierPart(ch rune) bool { + return IsIdentifierPartEx(ch, core.LanguageVariantStandard) +} + +func IsIdentifierPartEx(ch rune, languageVariant core.LanguageVariant) bool { + return isWordCharacter(ch) || ch == '$' || + ch >= utf8.RuneSelf && isUnicodeIdentifierPart(ch) || + languageVariant == core.LanguageVariantJSX && (ch == '-' || ch == ':') // "-" and ":" are valid in JSX Identifiers +} + +func isUnicodeIdentifierStart(ch rune) bool { + return isInUnicodeRanges(ch, unicodeESNextIdentifierStart) +} + +func isUnicodeIdentifierPart(ch rune) bool { + return isInUnicodeRanges(ch, unicodeESNextIdentifierPart) +} + +func isInUnicodeRanges(cp rune, ranges []rune) bool { + // Bail out quickly if it couldn't possibly be in the map + if cp < ranges[0] { + return false + } + // Perform binary search in one of the Unicode range maps + lo := 0 + hi := len(ranges) + for lo+1 < hi { + mid := lo + (hi-lo)/2 + // mid has to be even to catch beginning of a range + mid -= mid % 2 + if ranges[mid] <= cp && cp <= ranges[mid+1] { + return true + } + if cp < ranges[mid] { + hi = mid + } else { + lo = mid + 2 + } + } + return false +} + +var tokenToText map[ast.Kind]string + +func init() { + tokenToText = make(map[ast.Kind]string, len(textToToken)) + for text, key := range textToToken { + tokenToText[key] = text + } +} + +func TokenToString(token ast.Kind) string { + return tokenToText[token] +} + +func StringToToken(s string) ast.Kind { + kind, ok := textToToken[s] + if ok { + return kind + } + return ast.KindUnknown +} + +func GetViableKeywordSuggestions() []string { + result := make([]string, 0, len(textToKeyword)) + for text := range textToKeyword { + if len(text) > 2 { + result = append(result, text) + } + } + return result +} + +func couldStartTrivia(text string, pos int) bool { + // Keep in sync with skipTrivia + switch ch := text[pos]; ch { + // Characters that could start normal trivia + case '\r', '\n', '\t', '\v', '\f', ' ', '/', + // Characters that could start conflict marker trivia + '<', '|', '=', '>': + return true + case '#': + // Only if its the beginning can we have #! trivia + return pos == 0 + default: + return ch > maxAsciiCharacter + } +} + +type SkipTriviaOptions struct { + StopAfterLineBreak bool + StopAtComments bool + InJSDoc bool +} + +func SkipTrivia(text string, pos int) int { + return SkipTriviaEx(text, pos, nil) +} + +func SkipTriviaEx(text string, pos int, options *SkipTriviaOptions) int { + if ast.PositionIsSynthesized(pos) { + return pos + } + if options == nil { + options = &SkipTriviaOptions{} + } + + textLen := len(text) + canConsumeStar := false + // Keep in sync with couldStartTrivia + for { + ch, size := utf8.DecodeRuneInString(text[pos:]) + switch ch { + case '\r': + if pos+1 < textLen && text[pos+1] == '\n' { + pos++ + } + fallthrough + case '\n': + pos++ + if options.StopAfterLineBreak { + return pos + } + canConsumeStar = options.InJSDoc + continue + case '\t', '\v', '\f', ' ': + pos++ + continue + case '/': + if options.StopAtComments { + break + } + if pos+1 < textLen { + if text[pos+1] == '/' { + pos += 2 + for pos < textLen { + ch, size := utf8.DecodeRuneInString(text[pos:]) + if stringutil.IsLineBreak(ch) { + break + } + pos += size + } + canConsumeStar = false + continue + } + if text[pos+1] == '*' { + pos += 2 + for pos < textLen { + if text[pos] == '*' && (pos+1 < textLen) && text[pos+1] == '/' { + pos += 2 + break + } + _, size := utf8.DecodeRuneInString(text[pos:]) + pos += size + } + canConsumeStar = false + continue + } + } + case '<', '|', '=', '>': + if isConflictMarkerTrivia(text, pos) { + pos = scanConflictMarkerTrivia(text, pos, nil) + canConsumeStar = false + continue + } + case '#': + if pos == 0 && isShebangTrivia(text, pos) { + pos = scanShebangTrivia(text, pos) + canConsumeStar = false + continue + } + case '*': + if canConsumeStar { + pos++ + canConsumeStar = false + continue + } + default: + if ch > rune(maxAsciiCharacter) && stringutil.IsWhiteSpaceLike(ch) { + pos += size + continue + } + } + return pos + } +} + +// All conflict markers consist of the same character repeated seven times. If it is +// a <<<<<<< or >>>>>>> marker then it is also followed by a space. +var ( + mergeConflictMarkerLength = len("<<<<<<<") + maxAsciiCharacter byte = 127 +) + +func isConflictMarkerTrivia(text string, pos int) bool { + if pos < 0 { + panic("pos < 0") + } + + // Conflict markers must be at the start of a line. + var prev rune + if pos >= 2 { + prev, _ = utf8.DecodeLastRuneInString(text[:pos-2]) + } + if pos == 0 || stringutil.IsLineBreak(prev) || pos >= 1 && stringutil.IsLineBreak(rune(text[pos-1])) { + ch := text[pos] + + if (pos + mergeConflictMarkerLength) < len(text) { + for i := range mergeConflictMarkerLength { + if text[pos+i] != ch { + return false + } + } + + return ch == '=' || text[pos+mergeConflictMarkerLength] == ' ' + } + } + + return false +} + +func scanConflictMarkerTrivia(text string, pos int, reportError func(diag *diagnostics.Message, pos int, length int, args ...any)) int { + if reportError != nil { + reportError(diagnostics.Merge_conflict_marker_encountered, pos, mergeConflictMarkerLength) + } + ch, size := utf8.DecodeRuneInString(text[pos:]) + length := len(text) + + if ch == '<' || ch == '>' { + for pos < length && !stringutil.IsLineBreak(ch) { + pos += size + ch, size = utf8.DecodeRuneInString(text[pos:]) + } + } else { + if ch != '|' && ch != '=' { + panic("Assertion failed: ch must be either '|' or '='") + } + // Consume everything from the start of a ||||||| or ======= marker to the start + // of the next ======= or >>>>>>> marker. + for pos < length { + currentChar := text[pos] + if (currentChar == '=' || currentChar == '>') && rune(currentChar) != ch && isConflictMarkerTrivia(text, pos) { + break + } + + pos++ + } + } + + return pos +} + +func isShebangTrivia(text string, pos int) bool { + if len(text) < 2 { + return false + } + if pos != 0 { + panic("Shebangs check must only be done at the start of the file") + } + return text[0] == '#' && text[1] == '!' +} + +func scanShebangTrivia(text string, pos int) int { + pos += 2 + for pos < len(text) { + ch, size := utf8.DecodeRuneInString(text[pos:]) + if stringutil.IsLineBreak(ch) { + break + } + pos += size + } + return pos +} + +func GetShebang(text string) string { + if !isShebangTrivia(text, 0) { + return "" + } + + end := scanShebangTrivia(text, 0) + return text[:end] +} + +func GetScannerForSourceFile(sourceFile *ast.SourceFile, pos int) *Scanner { + s := NewScanner() + s.text = sourceFile.Text() + s.pos = pos + s.languageVariant = sourceFile.LanguageVariant + s.Scan() + return s +} + +func ScanTokenAtPosition(sourceFile *ast.SourceFile, pos int) ast.Kind { + s := GetScannerForSourceFile(sourceFile, pos) + return s.token +} + +func GetRangeOfTokenAtPosition(sourceFile *ast.SourceFile, pos int) core.TextRange { + s := GetScannerForSourceFile(sourceFile, pos) + return core.NewTextRange(s.tokenStart, s.pos) +} + +func GetTokenPosOfNode(node *ast.Node, sourceFile *ast.SourceFile, includeJSDoc bool) int { + // With nodes that have no width (i.e. 'Missing' nodes), we actually *don't* + // want to skip trivia because this will launch us forward to the next token. + if ast.NodeIsMissing(node) { + return node.Pos() + } + if ast.IsJSDocNode(node) || node.Kind == ast.KindJsxText { + // JsxText cannot actually contain comments, even though the scanner will think it sees comments + return SkipTriviaEx(sourceFile.Text(), node.Pos(), &SkipTriviaOptions{StopAtComments: true}) + } + if includeJSDoc && len(node.JSDoc(sourceFile)) > 0 { + return GetTokenPosOfNode(node.JSDoc(sourceFile)[0], sourceFile, false /*includeJSDoc*/) + } + return SkipTriviaEx(sourceFile.Text(), node.Pos(), &SkipTriviaOptions{InJSDoc: node.Flags&ast.NodeFlagsJSDoc != 0}) +} + +func getErrorRangeForArrowFunction(sourceFile *ast.SourceFile, node *ast.Node) core.TextRange { + pos := SkipTrivia(sourceFile.Text(), node.Pos()) + body := node.AsArrowFunction().Body + if body != nil && body.Kind == ast.KindBlock { + startLine, _ := GetECMALineAndCharacterOfPosition(sourceFile, body.Pos()) + endLine, _ := GetECMALineAndCharacterOfPosition(sourceFile, body.End()) + if startLine < endLine { + // The arrow function spans multiple lines, + // make the error span be the first line, inclusive. + return core.NewTextRange(pos, GetECMAEndLinePosition(sourceFile, startLine)) + } + } + return core.NewTextRange(pos, node.End()) +} + +func GetErrorRangeForNode(sourceFile *ast.SourceFile, node *ast.Node) core.TextRange { + errorNode := node + switch node.Kind { + case ast.KindSourceFile: + pos := SkipTrivia(sourceFile.Text(), 0) + if pos == len(sourceFile.Text()) { + return core.NewTextRange(0, 0) + } + return GetRangeOfTokenAtPosition(sourceFile, pos) + // This list is a work in progress. Add missing node kinds to improve their error spans + case ast.KindFunctionDeclaration, ast.KindMethodDeclaration: + if node.Flags&ast.NodeFlagsReparsed != 0 { + errorNode = node + break + } + fallthrough + case ast.KindVariableDeclaration, ast.KindBindingElement, ast.KindClassDeclaration, ast.KindClassExpression, ast.KindInterfaceDeclaration, + ast.KindModuleDeclaration, ast.KindEnumDeclaration, ast.KindEnumMember, ast.KindFunctionExpression, + ast.KindGetAccessor, ast.KindSetAccessor, ast.KindTypeAliasDeclaration, ast.KindJSTypeAliasDeclaration, ast.KindPropertyDeclaration, + ast.KindPropertySignature, ast.KindNamespaceImport: + errorNode = ast.GetNameOfDeclaration(node) + case ast.KindArrowFunction: + return getErrorRangeForArrowFunction(sourceFile, node) + case ast.KindCaseClause, ast.KindDefaultClause: + start := SkipTrivia(sourceFile.Text(), node.Pos()) + end := node.End() + statements := node.AsCaseOrDefaultClause().Statements.Nodes + if len(statements) != 0 { + end = statements[0].Pos() + } + return core.NewTextRange(start, end) + case ast.KindReturnStatement, ast.KindYieldExpression: + pos := SkipTrivia(sourceFile.Text(), node.Pos()) + return GetRangeOfTokenAtPosition(sourceFile, pos) + case ast.KindSatisfiesExpression: + pos := SkipTrivia(sourceFile.Text(), node.AsSatisfiesExpression().Expression.End()) + return GetRangeOfTokenAtPosition(sourceFile, pos) + case ast.KindConstructor: + if node.Flags&ast.NodeFlagsReparsed != 0 { + errorNode = node + break + } + scanner := GetScannerForSourceFile(sourceFile, node.Pos()) + start := scanner.TokenStart() + for scanner.Token() != ast.KindConstructorKeyword && scanner.Token() != ast.KindStringLiteral && scanner.Token() != ast.KindEndOfFile { + scanner.Scan() + } + return core.NewTextRange(start, scanner.TokenEnd()) + // !!! + // case KindJSDocSatisfiesTag: + // pos := scanner.SkipTrivia(sourceFile.Text(), node.tagName.pos) + // return scanner.GetRangeOfTokenAtPosition(sourceFile, pos) + } + if errorNode == nil { + // If we don't have a better node, then just set the error on the first token of + // construct. + return GetRangeOfTokenAtPosition(sourceFile, node.Pos()) + } + pos := errorNode.Pos() + if !ast.NodeIsMissing(errorNode) && !ast.IsJsxText(errorNode) { + pos = SkipTrivia(sourceFile.Text(), pos) + } + return core.NewTextRange(pos, errorNode.End()) +} + +func ComputeLineOfPosition(lineStarts []core.TextPos, pos int) int { + low := 0 + high := len(lineStarts) - 1 + for low <= high { + middle := low + ((high - low) >> 1) + value := int(lineStarts[middle]) + if value < pos { + low = middle + 1 + } else if value > pos { + high = middle - 1 + } else { + return middle + } + } + return low - 1 +} + +func GetECMALineStarts(sourceFile ast.SourceFileLike) []core.TextPos { + return sourceFile.ECMALineMap() +} + +func GetECMALineAndCharacterOfPosition(sourceFile ast.SourceFileLike, pos int) (line int, character int) { + lineMap := GetECMALineStarts(sourceFile) + line = ComputeLineOfPosition(lineMap, pos) + character = utf8.RuneCountInString(sourceFile.Text()[lineMap[line]:pos]) + return line, character +} + +func GetECMAEndLinePosition(sourceFile *ast.SourceFile, line int) int { + pos := int(GetECMALineStarts(sourceFile)[line]) + for { + ch, size := utf8.DecodeRuneInString(sourceFile.Text()[pos:]) + if size == 0 || stringutil.IsLineBreak(ch) { + return pos + } + pos += size + } +} + +func GetECMAPositionOfLineAndCharacter(sourceFile *ast.SourceFile, line int, character int) int { + return ComputePositionOfLineAndCharacter(GetECMALineStarts(sourceFile), line, character) +} + +func ComputePositionOfLineAndCharacter(lineStarts []core.TextPos, line int, character int) int { + return ComputePositionOfLineAndCharacterEx(lineStarts, line, character, nil, false) +} + +func ComputePositionOfLineAndCharacterEx(lineStarts []core.TextPos, line int, character int, text *string, allowEdits bool) int { + if line < 0 || line >= len(lineStarts) { + if allowEdits { + // Clamp line to nearest allowable value + if line < 0 { + line = 0 + } else if line >= len(lineStarts) { + line = len(lineStarts) - 1 + } + } else { + panic(fmt.Sprintf("Bad line number. Line: %d, lineStarts.length: %d.", line, len(lineStarts))) + } + } + + res := int(lineStarts[line]) + character + + if allowEdits { + // Clamp to nearest allowable values to allow the underlying to be edited without crashing (accuracy is lost, instead) + // TODO: Somehow track edits between file as it was during the creation of sourcemap we have and the current file and + // apply them to the computed position to improve accuracy + if line+1 < len(lineStarts) && res > int(lineStarts[line+1]) { + return int(lineStarts[line+1]) + } + if text != nil && res > len(*text) { + return len(*text) + } + return res + } + if line < len(lineStarts)-1 && res >= int(lineStarts[line+1]) { + panic("Computed position is beyond that of the following line.") + } else if text != nil { + debug.Assert(res <= len(*text)) // Allow single character overflow for trailing newline + } + return res +} + +func GetLeadingCommentRanges(f *ast.NodeFactory, text string, pos int) iter.Seq[ast.CommentRange] { + return iterateCommentRanges(f, text, pos, false) +} + +func GetTrailingCommentRanges(f *ast.NodeFactory, text string, pos int) iter.Seq[ast.CommentRange] { + return iterateCommentRanges(f, text, pos, true) +} + +/* +Returns an iterator over each comment range following the provided position. +Single-line comment ranges include the leading double-slash characters but not the ending +line break. Multi-line comment ranges include the leading slash-asterisk and trailing +asterisk-slash characters. +*/ +func iterateCommentRanges(f *ast.NodeFactory, text string, pos int, trailing bool) iter.Seq[ast.CommentRange] { + return func(yield func(ast.CommentRange) bool) { + var pendingPos int + var pendingEnd int + var pendingKind ast.Kind + var pendingHasTrailingNewLine bool + hasPendingCommentRange := false + collecting := trailing + if pos == 0 { + collecting = true + if isShebangTrivia(text, pos) { + pos = scanShebangTrivia(text, pos) + } + } + scan: + for pos >= 0 && pos < len(text) { + ch, size := utf8.DecodeRuneInString(text[pos:]) + switch ch { + case '\r': + if pos+1 < len(text) && text[pos+1] == '\n' { + pos++ + } + fallthrough + case '\n': + pos++ + if trailing { + break scan + } + + collecting = true + if hasPendingCommentRange { + pendingHasTrailingNewLine = true + } + + continue + case '\t', '\v', '\f', ' ': + pos++ + continue + case '/': + var nextChar byte + if pos+1 < len(text) { + nextChar = text[pos+1] + } + hasTrailingNewLine := false + if nextChar == '/' || nextChar == '*' { + var kind ast.Kind + if nextChar == '/' { + kind = ast.KindSingleLineCommentTrivia + } else { + kind = ast.KindMultiLineCommentTrivia + } + + startPos := pos + pos += 2 + if nextChar == '/' { + for pos < len(text) { + c, s := utf8.DecodeRuneInString(text[pos:]) + if stringutil.IsLineBreak(c) { + hasTrailingNewLine = true + break + } + pos += s + } + } else { + for pos < len(text) { + c, s := utf8.DecodeRuneInString(text[pos:]) + if c == '*' && pos+1 < len(text) && text[pos+1] == '/' { + pos += 2 + break + } + pos += s + } + } + + if collecting { + if hasPendingCommentRange { + if !yield(f.NewCommentRange(pendingKind, pendingPos, pendingEnd, pendingHasTrailingNewLine)) { + return + } + } + + pendingPos = startPos + pendingEnd = pos + pendingKind = kind + pendingHasTrailingNewLine = hasTrailingNewLine + hasPendingCommentRange = true + } + + continue + } + break scan + default: + if ch > unicode.MaxASCII && (stringutil.IsWhiteSpaceLike(ch)) { + if hasPendingCommentRange && stringutil.IsLineBreak(ch) { + pendingHasTrailingNewLine = true + } + pos += size + continue + } + break scan + } + } + + if hasPendingCommentRange { + yield(f.NewCommentRange(pendingKind, pendingPos, pendingEnd, pendingHasTrailingNewLine)) + } + } +} diff --git a/kitcom/internal/tsgo/scanner/utilities.go b/kitcom/internal/tsgo/scanner/utilities.go new file mode 100644 index 0000000..0232526 --- /dev/null +++ b/kitcom/internal/tsgo/scanner/utilities.go @@ -0,0 +1,67 @@ +package scanner + +import ( + "strings" + "unicode/utf8" + + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/ast" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/core" +) + +func tokenIsIdentifierOrKeyword(token ast.Kind) bool { + return token >= ast.KindIdentifier +} + +func IdentifierToKeywordKind(node *ast.Identifier) ast.Kind { + return textToKeyword[node.Text] +} + +func GetSourceTextOfNodeFromSourceFile(sourceFile *ast.SourceFile, node *ast.Node, includeTrivia bool) string { + return GetTextOfNodeFromSourceText(sourceFile.Text(), node, includeTrivia) +} + +func GetTextOfNodeFromSourceText(sourceText string, node *ast.Node, includeTrivia bool) string { + if ast.NodeIsMissing(node) { + return "" + } + pos := node.Pos() + if !includeTrivia { + pos = SkipTrivia(sourceText, pos) + } + text := sourceText[pos:node.End()] + // if (isJSDocTypeExpressionOrChild(node)) { + // // strip space + asterisk at line start + // text = text.split(/\r\n|\n|\r/).map(line => line.replace(/^\s*\*/, "").trimStart()).join("\n"); + // } + return text +} + +func GetTextOfNode(node *ast.Node) string { + return GetSourceTextOfNodeFromSourceFile(ast.GetSourceFileOfNode(node), node, false /*includeTrivia*/) +} + +func DeclarationNameToString(name *ast.Node) string { + if name == nil || name.Pos() == name.End() { + return "(Missing)" + } + return GetTextOfNode(name) +} + +func IsIdentifierText(name string, languageVariant core.LanguageVariant) bool { + ch, size := utf8.DecodeRuneInString(name) + if !IsIdentifierStart(ch) { + return false + } + for i := size; i < len(name); { + ch, size = utf8.DecodeRuneInString(name[i:]) + if !IsIdentifierPartEx(ch, languageVariant) { + return false + } + i += size + } + return true +} + +func IsIntrinsicJsxName(name string) bool { + return len(name) != 0 && (name[0] >= 'a' && name[0] <= 'z' || strings.ContainsRune(name, '-')) +} diff --git a/kitcom/internal/tsgo/stringutil/compare.go b/kitcom/internal/tsgo/stringutil/compare.go new file mode 100644 index 0000000..0fb1cd3 --- /dev/null +++ b/kitcom/internal/tsgo/stringutil/compare.go @@ -0,0 +1,120 @@ +package stringutil + +import ( + "strings" + "unicode" + "unicode/utf8" +) + +func EquateStringCaseInsensitive(a, b string) bool { + // !!! + // return a == b || strings.ToUpper(a) == strings.ToUpper(b) + return strings.EqualFold(a, b) +} + +func EquateStringCaseSensitive(a, b string) bool { + return a == b +} + +func GetStringEqualityComparer(ignoreCase bool) func(a, b string) bool { + if ignoreCase { + return EquateStringCaseInsensitive + } + return EquateStringCaseSensitive +} + +type Comparison = int + +const ( + ComparisonLessThan Comparison = -1 + ComparisonEqual Comparison = 0 + ComparisonGreaterThan Comparison = 1 +) + +func CompareStringsCaseInsensitive(a string, b string) Comparison { + if a == b { + return ComparisonEqual + } + for { + ca, sa := utf8.DecodeRuneInString(a) + cb, sb := utf8.DecodeRuneInString(b) + if sa == 0 { + if sb == 0 { + return ComparisonEqual + } + return ComparisonLessThan + } + if sb == 0 { + return ComparisonGreaterThan + } + lca := unicode.ToLower(ca) + lcb := unicode.ToLower(cb) + if lca != lcb { + if lca < lcb { + return ComparisonLessThan + } + return ComparisonGreaterThan + } + a = a[sa:] + b = b[sb:] + } +} + +func CompareStringsCaseSensitive(a string, b string) Comparison { + return strings.Compare(a, b) +} + +func GetStringComparer(ignoreCase bool) func(a, b string) Comparison { + if ignoreCase { + return CompareStringsCaseInsensitive + } + return CompareStringsCaseSensitive +} + +func HasPrefix(s string, prefix string, caseSensitive bool) bool { + if caseSensitive { + return strings.HasPrefix(s, prefix) + } + if len(prefix) > len(s) { + return false + } + return strings.EqualFold(s[0:len(prefix)], prefix) +} + +func HasSuffix(s string, suffix string, caseSensitive bool) bool { + if caseSensitive { + return strings.HasSuffix(s, suffix) + } + if len(suffix) > len(s) { + return false + } + return strings.EqualFold(s[len(s)-len(suffix):], suffix) +} + +func CompareStringsCaseInsensitiveThenSensitive(a, b string) Comparison { + cmp := CompareStringsCaseInsensitive(a, b) + if cmp != ComparisonEqual { + return cmp + } + return CompareStringsCaseSensitive(a, b) +} + +// CompareStringsCaseInsensitiveEslintCompatible performs a case-insensitive comparison +// using toLowerCase() instead of toUpperCase() for ESLint compatibility. +// +// `CompareStringsCaseInsensitive` transforms letters to uppercase for unicode reasons, +// while eslint's `sort-imports` rule transforms letters to lowercase. Which one you choose +// affects the relative order of letters and ASCII characters 91-96, of which `_` is a +// valid character in an identifier. So if we used `CompareStringsCaseInsensitive` for +// import sorting, TypeScript and eslint would disagree about the correct case-insensitive +// sort order for `__String` and `Foo`. Since eslint's whole job is to create consistency +// by enforcing nitpicky details like this, it makes way more sense for us to just adopt +// their convention so users can have auto-imports without making eslint angry. +func CompareStringsCaseInsensitiveEslintCompatible(a, b string) Comparison { + if a == b { + return ComparisonEqual + } + a = strings.ToLower(a) + b = strings.ToLower(b) + return strings.Compare(a, b) +} diff --git a/kitcom/internal/tsgo/stringutil/format.go b/kitcom/internal/tsgo/stringutil/format.go new file mode 100644 index 0000000..3c52e36 --- /dev/null +++ b/kitcom/internal/tsgo/stringutil/format.go @@ -0,0 +1,19 @@ +package stringutil + +import ( + "fmt" + "regexp" + "strconv" +) + +var placeholderRegexp = regexp.MustCompile(`{(\d+)}`) + +func Format(text string, args []any) string { + return placeholderRegexp.ReplaceAllStringFunc(text, func(match string) string { + index, err := strconv.ParseInt(match[1:len(match)-1], 10, 0) + if err != nil || int(index) >= len(args) { + panic("Invalid formatting placeholder") + } + return fmt.Sprintf("%v", args[int(index)]) + }) +} diff --git a/kitcom/internal/tsgo/stringutil/util.go b/kitcom/internal/tsgo/stringutil/util.go new file mode 100644 index 0000000..629846a --- /dev/null +++ b/kitcom/internal/tsgo/stringutil/util.go @@ -0,0 +1,240 @@ +// Package stringutil Exports common rune utilities for parsing and emitting javascript +package stringutil + +import ( + "net/url" + "regexp" + "strings" + "unicode" + "unicode/utf8" +) + +func IsWhiteSpaceLike(ch rune) bool { + return IsWhiteSpaceSingleLine(ch) || IsLineBreak(ch) +} + +func IsWhiteSpaceSingleLine(ch rune) bool { + // Note: nextLine is in the Zs space, and should be considered to be a whitespace. + // It is explicitly not a line-break as it isn't in the exact set specified by EcmaScript. + switch ch { + case + ' ', // space + '\t', // tab + '\v', // verticalTab + '\f', // formFeed + 0x0085, // nextLine + 0x00A0, // nonBreakingSpace + 0x1680, // ogham + 0x2000, // enQuad + 0x2001, // emQuad + 0x2002, // enSpace + 0x2003, // emSpace + 0x2004, // threePerEmSpace + 0x2005, // fourPerEmSpace + 0x2006, // sixPerEmSpace + 0x2007, // figureSpace + 0x2008, // punctuationEmSpace + 0x2009, // thinSpace + 0x200A, // hairSpace + 0x200B, // zeroWidthSpace + 0x202F, // narrowNoBreakSpace + 0x205F, // mathematicalSpace + 0x3000, // ideographicSpace + 0xFEFF: // byteOrderMark + return true + } + return false +} + +func IsLineBreak(ch rune) bool { + // ES5 7.3: + // The ECMAScript line terminator characters are listed in Table 3. + // Table 3: Line Terminator Characters + // Code Unit Value Name Formal Name + // \u000A Line Feed + // \u000D Carriage Return + // \u2028 Line separator + // \u2029 Paragraph separator + // Only the characters in Table 3 are treated as line terminators. Other new line or line + // breaking characters are treated as white space but not as line terminators. + switch ch { + case + '\n', // lineFeed + '\r', // carriageReturn + 0x2028, // lineSeparator + 0x2029: // paragraphSeparator + return true + } + return false +} + +func IsDigit(ch rune) bool { + return ch >= '0' && ch <= '9' +} + +func IsOctalDigit(ch rune) bool { + return ch >= '0' && ch <= '7' +} + +func IsHexDigit(ch rune) bool { + return ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'F' || ch >= 'a' && ch <= 'f' +} + +func IsASCIILetter(ch rune) bool { + return ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z' +} + +func SplitLines(text string) []string { + lines := make([]string, 0, strings.Count(text, "\n")+1) // preallocate + start := 0 + pos := 0 + for pos < len(text) { + switch text[pos] { + case '\r': + if pos+1 < len(text) && text[pos+1] == '\n' { + lines = append(lines, text[start:pos]) + pos += 2 + start = pos + continue + } + fallthrough + case '\n': + lines = append(lines, text[start:pos]) + pos++ + start = pos + continue + } + pos++ + } + if start < len(text) { + lines = append(lines, text[start:]) + } + return lines +} + +func GuessIndentation(lines []string) int { + const MAX_SMI_X86 int = 0x3fff_ffff + indentation := MAX_SMI_X86 + for _, line := range lines { + if len(line) == 0 { + continue + } + i := 0 + for i < len(line) && i < indentation { + ch, size := utf8.DecodeRuneInString(line[i:]) + if !IsWhiteSpaceLike(ch) { + break + } + i += size + } + if i < indentation { + indentation = i + } + if indentation == 0 { + return 0 + } + } + if indentation == MAX_SMI_X86 { + return 0 + } + return indentation +} + +// https://tc39.es/ecma262/multipage/global-object.html#sec-encodeuri-uri +func EncodeURI(s string) string { + var builder strings.Builder + start := 0 + pos := indexAny(s, ";/?:@&=+$,#", 0) + for pos >= 0 { + builder.WriteString(url.QueryEscape(s[start:pos])) + builder.WriteString(s[pos : pos+1]) + start = pos + 1 + pos = indexAny(s, ";/?:@&=+$,#", start) + } + if start < len(s) { + builder.WriteString(url.QueryEscape(s[start:])) + } + return builder.String() +} + +func indexAny(s, chars string, start int) int { + if start < 0 || start >= len(s) { + return -1 + } + index := strings.IndexAny(s[start:], chars) + if index < 0 { + return -1 + } + return start + index +} + +func getByteOrderMarkLength(text string) int { + if len(text) >= 1 { + ch0 := text[0] + if ch0 == 0xfe { + if len(text) >= 2 && text[1] == 0xff { + return 2 // utf16be + } + return 0 + } + if ch0 == 0xff { + if len(text) >= 2 && text[1] == 0xfe { + return 2 // utf16le + } + return 0 + } + if ch0 == 0xef { + if len(text) >= 3 && text[1] == 0xbb && text[2] == 0xbf { + return 3 // utf8 + } + return 0 + } + } + return 0 +} + +func RemoveByteOrderMark(text string) string { + length := getByteOrderMarkLength(text) + if length > 0 { + return text[length:] + } + return text +} + +func AddUTF8ByteOrderMark(text string) string { + if getByteOrderMarkLength(text) == 0 { + return "\xEF\xBB\xBF" + text + } + return text +} + +func StripQuotes(name string) string { + firstChar, _ := utf8.DecodeRuneInString(name) + lastChar, _ := utf8.DecodeLastRuneInString(name) + if firstChar == lastChar && (firstChar == '\'' || firstChar == '"' || firstChar == '`') { + return name[1 : len(name)-1] + } + return name +} + +var matchSlashSomething = regexp.MustCompile(`\.`) + +func matchSlashReplacer(in string) string { + return in[1:] +} + +func UnquoteString(str string) string { + // strconv.Unquote is insufficient as that only handles a single character inside single quotes, as those are character literals in go + inner := StripQuotes(str) + // In strada we do str.replace(/\\./g, s => s.substring(1)) - which is to say, replace all backslash-something with just something + // That's replicated here faithfully, but it seems wrong! This should probably be an actual unquote operation? + return matchSlashSomething.ReplaceAllStringFunc(inner, matchSlashReplacer) +} + +func LowerFirstChar(str string) string { + char, size := utf8.DecodeRuneInString(str) + if size > 0 { + return string(unicode.ToLower(char)) + str[size:] + } + return str +} diff --git a/kitcom/internal/tsgo/tspath/extension.go b/kitcom/internal/tsgo/tspath/extension.go new file mode 100644 index 0000000..1b4422e --- /dev/null +++ b/kitcom/internal/tsgo/tspath/extension.go @@ -0,0 +1,178 @@ +package tspath + +import ( + "path/filepath" + "slices" + "strings" +) + +const ( + ExtensionTs = ".ts" + ExtensionTsx = ".tsx" + ExtensionDts = ".d.ts" + ExtensionJs = ".js" + ExtensionJsx = ".jsx" + ExtensionJson = ".json" + ExtensionTsBuildInfo = ".tsbuildinfo" + ExtensionMjs = ".mjs" + ExtensionMts = ".mts" + ExtensionDmts = ".d.mts" + ExtensionCjs = ".cjs" + ExtensionCts = ".cts" + ExtensionDcts = ".d.cts" +) + +var ( + supportedDeclarationExtensions = []string{ExtensionDts, ExtensionDcts, ExtensionDmts} + supportedTSImplementationExtensions = []string{ExtensionTs, ExtensionTsx, ExtensionMts, ExtensionCts} + supportedTSExtensionsForExtractExtension = []string{ExtensionDts, ExtensionDcts, ExtensionDmts, ExtensionTs, ExtensionTsx, ExtensionMts, ExtensionCts} + AllSupportedExtensions = [][]string{{ExtensionTs, ExtensionTsx, ExtensionDts, ExtensionJs, ExtensionJsx}, {ExtensionCts, ExtensionDcts, ExtensionCjs}, {ExtensionMts, ExtensionDmts, ExtensionMjs}} + SupportedTSExtensions = [][]string{{ExtensionTs, ExtensionTsx, ExtensionDts}, {ExtensionCts, ExtensionDcts}, {ExtensionMts, ExtensionDmts}} + SupportedTSExtensionsFlat = []string{ExtensionTs, ExtensionTsx, ExtensionDts, ExtensionCts, ExtensionDcts, ExtensionMts, ExtensionDmts} + SupportedJSExtensions = [][]string{{ExtensionJs, ExtensionJsx}, {ExtensionMjs}, {ExtensionCjs}} + SupportedJSExtensionsFlat = []string{ExtensionJs, ExtensionJsx, ExtensionMjs, ExtensionCjs} + AllSupportedExtensionsWithJson = slices.Concat(AllSupportedExtensions, [][]string{{ExtensionJson}}) + SupportedTSExtensionsWithJson = slices.Concat(SupportedTSExtensions, [][]string{{ExtensionJson}}) + SupportedTSExtensionsWithJsonFlat = slices.Concat(SupportedTSExtensionsFlat, []string{ExtensionJson}) + ExtensionsNotSupportingExtensionlessResolution = []string{ExtensionMts, ExtensionDmts, ExtensionMjs, ExtensionCts, ExtensionDcts, ExtensionCjs} +) + +func ExtensionIsTs(ext string) bool { + return ext == ExtensionTs || ext == ExtensionTsx || ext == ExtensionDts || ext == ExtensionMts || ext == ExtensionDmts || ext == ExtensionCts || ext == ExtensionDcts || len(ext) >= 7 && ext[:3] == ".d." && ext[len(ext)-3:] == ".ts" +} + +var extensionsToRemove = []string{ExtensionDts, ExtensionDmts, ExtensionDcts, ExtensionMjs, ExtensionMts, ExtensionCjs, ExtensionCts, ExtensionTs, ExtensionJs, ExtensionTsx, ExtensionJsx, ExtensionJson} + +func RemoveFileExtension(path string) string { + // Remove any known extension even if it has more than one dot + for _, ext := range extensionsToRemove { + if strings.HasSuffix(path, ext) { + return path[:len(path)-len(ext)] + } + } + // Otherwise just remove single dot extension, if any + return path[:len(path)-len(filepath.Ext(path))] //nolint:forbidigo +} + +func TryGetExtensionFromPath(p string) string { + for _, ext := range extensionsToRemove { + if FileExtensionIs(p, ext) { + return ext + } + } + return "" +} + +func RemoveExtension(path string, extension string) string { + return path[:len(path)-len(extension)] +} + +func FileExtensionIsOneOf(path string, extensions []string) bool { + for _, ext := range extensions { + if FileExtensionIs(path, ext) { + return true + } + } + return false +} + +func TryExtractTSExtension(fileName string) string { + for _, ext := range supportedTSExtensionsForExtractExtension { + if FileExtensionIs(fileName, ext) { + return ext + } + } + return "" +} + +func HasTSFileExtension(path string) bool { + return FileExtensionIsOneOf(path, SupportedTSExtensionsFlat) +} + +func HasImplementationTSFileExtension(path string) bool { + return FileExtensionIsOneOf(path, supportedTSImplementationExtensions) && !IsDeclarationFileName(path) +} + +func HasJSFileExtension(path string) bool { + return FileExtensionIsOneOf(path, SupportedJSExtensionsFlat) +} + +func HasJSONFileExtension(path string) bool { + return FileExtensionIs(path, ExtensionJson) +} + +func IsDeclarationFileName(fileName string) bool { + return GetDeclarationFileExtension(fileName) != "" +} + +func ExtensionIsOneOf(ext string, extensions []string) bool { + return slices.Contains(extensions, ext) +} + +func GetDeclarationFileExtension(fileName string) string { + base := GetBaseFileName(fileName) + for _, ext := range supportedDeclarationExtensions { + if strings.HasSuffix(base, ext) { + return ext + } + } + if strings.HasSuffix(base, ExtensionTs) { + index := strings.Index(base, ".d.") + if index >= 0 { + return base[index:] + } + } + return "" +} + +func GetDeclarationEmitExtensionForPath(path string) string { + switch { + case FileExtensionIsOneOf(path, []string{ExtensionMjs, ExtensionMts}): + return ExtensionDmts + case FileExtensionIsOneOf(path, []string{ExtensionCjs, ExtensionCts}): + return ExtensionDcts + case FileExtensionIsOneOf(path, []string{ExtensionJson}): + return `.d.json.ts` // Drive-by redefinition of json declaration file output name so if it's ever enabled, it behaves well + default: + return ExtensionDts + } +} + +// changeAnyExtension changes the extension of a path to the provided extension if it has one of the provided extensions. +// +// changeAnyExtension("/path/to/file.ext", ".js", ".ext") === "/path/to/file.js" +// changeAnyExtension("/path/to/file.ext", ".js", ".ts") === "/path/to/file.ext" +// changeAnyExtension("/path/to/file.ext", ".js", [".ext", ".ts"]) === "/path/to/file.js" +func changeAnyExtension(path string, ext string, extensions []string, ignoreCase bool) string { + pathext := GetAnyExtensionFromPath(path, extensions, ignoreCase) + if pathext != "" { + result := path[:len(path)-len(pathext)] + if strings.HasPrefix(ext, ".") { + return result + ext + } else { + return result + "." + ext + } + } + return path +} + +func ChangeExtension(path string, newExtension string) string { + return changeAnyExtension(path, newExtension, extensionsToRemove /*ignoreCase*/, false) +} + +// Like `changeAnyExtension`, but declaration file extensions are recognized +// and replaced starting from the `.d`. +// +// changeAnyExtension("file.d.ts", ".js") === "file.d.js" +// changeFullExtension("file.d.ts", ".js") === "file.js" +func ChangeFullExtension(path string, newExtension string) string { + declarationExtension := GetDeclarationFileExtension(path) + if declarationExtension != "" { + ext := newExtension + if !strings.HasPrefix(ext, ".") { + ext = "." + ext + } + return path[:len(path)-len(declarationExtension)] + ext + } + return ChangeExtension(path, newExtension) +} diff --git a/kitcom/internal/tsgo/tspath/ignoredpaths.go b/kitcom/internal/tsgo/tspath/ignoredpaths.go new file mode 100644 index 0000000..78f3957 --- /dev/null +++ b/kitcom/internal/tsgo/tspath/ignoredpaths.go @@ -0,0 +1,14 @@ +package tspath + +import "strings" + +var ignoredPaths = []string{"/node_modules/.", "/.git", "/.#"} + +func ContainsIgnoredPath(path string) bool { + for _, p := range ignoredPaths { + if strings.Contains(path, p) { + return true + } + } + return false +} diff --git a/kitcom/internal/tsgo/tspath/path.go b/kitcom/internal/tsgo/tspath/path.go new file mode 100644 index 0000000..f652923 --- /dev/null +++ b/kitcom/internal/tsgo/tspath/path.go @@ -0,0 +1,1129 @@ +package tspath + +import ( + "cmp" + "slices" + "strings" + "unicode" + + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/stringutil" +) + +type Path string + +// Internally, we represent paths as strings with '/' as the directory separator. +// When we make system calls (eg: LanguageServiceHost.getDirectory()), +// we expect the host to correctly handle paths in our specified format. +const ( + DirectorySeparator = '/' + urlSchemeSeparator = "://" +) + +//// Path Tests + +// Determines whether a byte corresponds to `/` or `\`. +func isAnyDirectorySeparator(char byte) bool { + return char == '/' || char == '\\' +} + +// Determines whether a path starts with a URL scheme (e.g. starts with `http://`, `ftp://`, `file://`, etc.). +func IsUrl(path string) bool { + return GetEncodedRootLength(path) < 0 +} + +// Determines whether a path is an absolute disk path (e.g. starts with `/`, or a dos path +// like `c:`, `c:\` or `c:/`). +func IsRootedDiskPath(path string) bool { + return GetEncodedRootLength(path) > 0 +} + +// Determines whether a path consists only of a path root. +func IsDiskPathRoot(path string) bool { + rootLength := GetEncodedRootLength(path) + return rootLength > 0 && rootLength == len(path) +} + +// Determines whether a path starts with an absolute path component (i.e. `/`, `c:/`, `file://`, etc.). +// +// ``` +// // POSIX +// PathIsAbsolute("/path/to/file.ext") === true +// // DOS +// PathIsAbsolute("c:/path/to/file.ext") === true +// // URL +// PathIsAbsolute("file:///path/to/file.ext") === true +// // Non-absolute +// PathIsAbsolute("path/to/file.ext") === false +// PathIsAbsolute("./path/to/file.ext") === false +// ``` +func PathIsAbsolute(path string) bool { + return GetEncodedRootLength(path) != 0 +} + +func HasTrailingDirectorySeparator(path string) bool { + return len(path) > 0 && isAnyDirectorySeparator(path[len(path)-1]) +} + +// Combines paths. If a path is absolute, it replaces any previous path. Relative paths are not simplified. +// +// ``` +// // Non-rooted +// CombinePaths("path", "to", "file.ext") === "path/to/file.ext" +// CombinePaths("path", "dir", "..", "to", "file.ext") === "path/dir/../to/file.ext" +// // POSIX +// CombinePaths("/path", "to", "file.ext") === "/path/to/file.ext" +// CombinePaths("/path", "/to", "file.ext") === "/to/file.ext" +// // DOS +// CombinePaths("c:/path", "to", "file.ext") === "c:/path/to/file.ext" +// CombinePaths("c:/path", "c:/to", "file.ext") === "c:/to/file.ext" +// // URL +// CombinePaths("file:///path", "to", "file.ext") === "file:///path/to/file.ext" +// CombinePaths("file:///path", "file:///to", "file.ext") === "file:///to/file.ext" +// ``` +func CombinePaths(firstPath string, paths ...string) string { + // TODO (drosen): There is potential for a fast path here. + // In the case where we find the last absolute path and just path.Join from there. + firstPath = NormalizeSlashes(firstPath) + + var b strings.Builder + size := len(firstPath) + len(paths) + for _, p := range paths { + size += len(p) + } + b.Grow(size) + + b.WriteString(firstPath) + + // To provide a way to "set" the path, keep track of the start and then slice. + // This will waste some memory each time we do it, but saving memory is more common. + start := 0 + result := func() string { + return b.String()[start:] + } + setResult := func(value string) { + start = b.Len() + b.WriteString(value) + } + + for _, trailingPath := range paths { + if trailingPath == "" { + continue + } + trailingPath = NormalizeSlashes(trailingPath) + if result() == "" || GetRootLength(trailingPath) != 0 { + // `trailingPath` is absolute. + setResult(trailingPath) + } else { + if !HasTrailingDirectorySeparator(result()) { + b.WriteByte(DirectorySeparator) + } + b.WriteString(trailingPath) + } + } + return result() +} + +func GetPathComponents(path string, currentDirectory string) []string { + path = CombinePaths(currentDirectory, path) + return pathComponents(path, GetRootLength(path)) +} + +func pathComponents(path string, rootLength int) []string { + root := path[:rootLength] + rest := strings.Split(path[rootLength:], "/") + if len(rest) > 0 && rest[len(rest)-1] == "" { + rest = rest[:len(rest)-1] + } + return append([]string{root}, rest...) +} + +func IsVolumeCharacter(char byte) bool { + return char >= 'a' && char <= 'z' || char >= 'A' && char <= 'Z' +} + +func getFileUrlVolumeSeparatorEnd(url string, start int) int { + if len(url) <= start { + return -1 + } + ch0 := url[start] + if ch0 == ':' { + return start + 1 + } + if ch0 == '%' && len(url) > start+2 && url[start+1] == '3' { + ch2 := url[start+2] + if ch2 == 'a' || ch2 == 'A' { + return start + 3 + } + } + return -1 +} + +func GetEncodedRootLength(path string) int { + ln := len(path) + if ln == 0 { + return 0 + } + ch0 := path[0] + + // POSIX or UNC + if ch0 == '/' || ch0 == '\\' { + if ln == 1 || path[1] != ch0 { + return 1 // POSIX: "/" (or non-normalized "\") + } + + offset := 2 + p1 := strings.IndexByte(path[offset:], ch0) + if p1 < 0 { + return ln // UNC: "//server" or "\\server" + } + + return p1 + offset + 1 // UNC: "//server/" or "\\server\" + } + + // DOS + if IsVolumeCharacter(ch0) && ln > 1 && path[1] == ':' { + if ln == 2 { + return 2 // DOS: "c:" (but not "c:d") + } + ch2 := path[2] + if ch2 == '/' || ch2 == '\\' { + return 3 // DOS: "c:/" or "c:\" + } + } + + // Untitled paths (e.g., "^/untitled/ts-nul-authority/Untitled-1") + if ch0 == '^' && ln > 1 && path[1] == '/' { + return 2 // Untitled: "^/" + } + + // URL + schemeEnd := strings.Index(path, urlSchemeSeparator) + if schemeEnd != -1 { + authorityStart := schemeEnd + len(urlSchemeSeparator) + authorityLength := strings.Index(path[authorityStart:], "/") + if authorityLength != -1 { // URL: "file:///", "file://server/", "file://server/path" + authorityEnd := authorityStart + authorityLength + + // For local "file" URLs, include the leading DOS volume (if present). + // Per https://www.ietf.org/rfc/rfc1738.txt, a host of "" or "localhost" is a + // special case interpreted as "the machine from which the URL is being interpreted". + scheme := path[:schemeEnd] + authority := path[authorityStart:authorityEnd] + if scheme == "file" && (authority == "" || authority == "localhost") && (len(path) > authorityEnd+2) && IsVolumeCharacter(path[authorityEnd+1]) { + volumeSeparatorEnd := getFileUrlVolumeSeparatorEnd(path, authorityEnd+2) + if volumeSeparatorEnd != -1 { + if volumeSeparatorEnd == len(path) { + // URL: "file:///c:", "file://localhost/c:", "file:///c$3a", "file://localhost/c%3a" + // but not "file:///c:d" or "file:///c%3ad" + return ^volumeSeparatorEnd + } + if path[volumeSeparatorEnd] == '/' { + // URL: "file:///c:/", "file://localhost/c:/", "file:///c%3a/", "file://localhost/c%3a/" + return ^(volumeSeparatorEnd + 1) + } + } + } + return ^(authorityEnd + 1) // URL: "file://server/", "http://server/" + } + return ^ln // URL: "file://server", "http://server" + } + + // relative + return 0 +} + +func GetRootLength(path string) int { + rootLength := GetEncodedRootLength(path) + if rootLength < 0 { + return ^rootLength + } + return rootLength +} + +func GetDirectoryPath(path string) string { + path = NormalizeSlashes(path) + + // If the path provided is itself a root, then return it. + rootLength := GetRootLength(path) + if rootLength == len(path) { + return path + } + + // return the leading portion of the path up to the last (non-terminal) directory separator + // but not including any trailing directory separator. + path = RemoveTrailingDirectorySeparator(path) + return path[:max(rootLength, strings.LastIndex(path, "/"))] +} + +func (p Path) GetDirectoryPath() Path { + return Path(GetDirectoryPath(string(p))) +} + +func GetPathFromPathComponents(pathComponents []string) string { + if len(pathComponents) == 0 { + return "" + } + + root := pathComponents[0] + if root != "" { + root = EnsureTrailingDirectorySeparator(root) + } + + return root + strings.Join(pathComponents[1:], "/") +} + +func NormalizeSlashes(path string) string { + return strings.ReplaceAll(path, "\\", "/") +} + +func reducePathComponents(components []string) []string { + if len(components) == 0 { + return []string{} + } + reduced := []string{components[0]} + for i := 1; i < len(components); i++ { + component := components[i] + if component == "" { + continue + } + if component == "." { + continue + } + if component == ".." { + if len(reduced) > 1 { + if reduced[len(reduced)-1] != ".." { + reduced = reduced[:len(reduced)-1] + continue + } + } else if reduced[0] != "" { + continue + } + } + reduced = append(reduced, component) + } + return reduced +} + +// Combines and resolves paths. If a path is absolute, it replaces any previous path. Any +// `.` and `..` path components are resolved. Trailing directory separators are preserved. +// +// ```go +// resolvePath("/path", "to", "file.ext") == "path/to/file.ext" +// resolvePath("/path", "to", "file.ext/") == "path/to/file.ext/" +// resolvePath("/path", "dir", "..", "to", "file.ext") == "path/to/file.ext" +// ``` +func ResolvePath(path string, paths ...string) string { + var combinedPath string + if len(paths) > 0 { + combinedPath = CombinePaths(path, paths...) + } else { + combinedPath = NormalizeSlashes(path) + } + return NormalizePath(combinedPath) +} + +func ResolveTripleslashReference(moduleName string, containingFile string) string { + basePath := GetDirectoryPath(containingFile) + if IsRootedDiskPath(moduleName) { + return NormalizePath(moduleName) + } + return NormalizePath(CombinePaths(basePath, moduleName)) +} + +func GetNormalizedPathComponents(path string, currentDirectory string) []string { + return reducePathComponents(GetPathComponents(path, currentDirectory)) +} + +func GetNormalizedAbsolutePath(fileName string, currentDirectory string) string { + rootLength := GetRootLength(fileName) + if rootLength == 0 && currentDirectory != "" { + fileName = CombinePaths(currentDirectory, fileName) + } else { + // CombinePaths normalizes slashes, so not necessary in other branch + fileName = NormalizeSlashes(fileName) + } + rootLength = GetRootLength(fileName) + + if simpleNormalized, ok := simpleNormalizePath(fileName); ok { + length := len(simpleNormalized) + if length > rootLength { + return RemoveTrailingDirectorySeparator(simpleNormalized) + } + if length == rootLength && rootLength != 0 { + return EnsureTrailingDirectorySeparator(simpleNormalized) + } + return simpleNormalized + } + + length := len(fileName) + root := fileName[:rootLength] + // `normalized` is only initialized once `fileName` is determined to be non-normalized. + // `changed` is set at the same time. + var changed bool + var normalized string + var segmentStart int + index := rootLength + normalizedUpTo := index + seenNonDotDotSegment := rootLength != 0 + for index < length { + // At beginning of segment + segmentStart = index + ch := fileName[index] + for ch == '/' { + index++ + if index < length { + ch = fileName[index] + } else { + break + } + } + if index > segmentStart { + // Seen superfluous separator + if !changed { + normalized = fileName[:max(rootLength, segmentStart-1)] + changed = true + } + if index == length { + break + } + segmentStart = index + } + // Past any superfluous separators + segmentEnd := strings.IndexByte(fileName[index+1:], '/') + if segmentEnd == -1 { + segmentEnd = length + } else { + segmentEnd += index + 1 + } + segmentLength := segmentEnd - segmentStart + if segmentLength == 1 && fileName[index] == '.' { + // "." segment (skip) + if !changed { + normalized = fileName[:normalizedUpTo] + changed = true + } + } else if segmentLength == 2 && fileName[index] == '.' && fileName[index+1] == '.' { + // ".." segment + if !seenNonDotDotSegment { + if changed { + if len(normalized) == rootLength { + normalized += ".." + } else { + normalized += "/.." + } + } else { + normalizedUpTo = index + 2 + } + } else if !changed { + if normalizedUpTo-1 >= 0 { + normalized = fileName[:max(rootLength, strings.LastIndexByte(fileName[:normalizedUpTo-1], '/'))] + } else { + normalized = fileName[:normalizedUpTo] + } + changed = true + seenNonDotDotSegment = (len(normalized) != rootLength || rootLength != 0) && normalized != ".." && !strings.HasSuffix(normalized, "/..") + } else { + lastSlash := strings.LastIndexByte(normalized, '/') + if lastSlash != -1 { + normalized = normalized[:max(rootLength, lastSlash)] + } else { + normalized = root + } + seenNonDotDotSegment = (len(normalized) != rootLength || rootLength != 0) && normalized != ".." && !strings.HasSuffix(normalized, "/..") + } + } else if changed { + if len(normalized) != rootLength { + normalized += "/" + } + seenNonDotDotSegment = true + normalized += fileName[segmentStart:segmentEnd] + } else { + seenNonDotDotSegment = true + normalizedUpTo = segmentEnd + } + index = segmentEnd + 1 + } + if changed { + return normalized + } + if length > rootLength { + return RemoveTrailingDirectorySeparators(fileName) + } + if length == rootLength { + return EnsureTrailingDirectorySeparator(fileName) + } + return fileName +} + +func simpleNormalizePath(path string) (string, bool) { + // Most paths don't require normalization + if !hasRelativePathSegment(path) { + return path, true + } + // Some paths only require cleanup of `/./` or leading `./` + simplified := strings.ReplaceAll(path, "/./", "/") + trimmed := strings.TrimPrefix(simplified, "./") + if trimmed != path && !hasRelativePathSegment(trimmed) && !(trimmed != simplified && strings.HasPrefix(trimmed, "/")) { + // If we trimmed a leading "./" and the path now starts with "/", we changed the meaning + path = trimmed + return path, true + } + return "", false +} + +// hasRelativePathSegment reports whether p contains ".", "..", "./", "../", "/.", "/..", "//", "/./", or "/../". +func hasRelativePathSegment(p string) bool { + n := len(p) + if n == 0 { + return false + } + + if p == "." || p == ".." { + return true + } + + // Leading "./" OR "../" + if p[0] == '.' { + if n >= 2 && p[1] == '/' { + return true + } + // Leading "../" + if n >= 3 && p[1] == '.' && p[2] == '/' { + return true + } + } + // Trailing "/." OR "/.." + if p[n-1] == '.' { + if n >= 2 && p[n-2] == '/' { + return true + } + if n >= 3 && p[n-2] == '.' && p[n-3] == '/' { + return true + } + } + + // Now look for any `//` or `/./` or `/../` + + prevSlash := false + segLen := 0 // length of current segment since last slash + dotCount := 0 // consecutive dots at start of the current segment; -1 => not only dots + + for i := range n { + c := p[i] + if c == '/' { + // "//" + if prevSlash { + return true + } + // "/./" or "/../" + if (segLen == 1 && dotCount == 1) || (segLen == 2 && dotCount == 2) { + return true + } + prevSlash = true + segLen = 0 + dotCount = 0 + continue + } + + if c == '.' { + if dotCount >= 0 { + dotCount++ + } + } else { + dotCount = -1 + } + segLen++ + prevSlash = false + } + + // Trailing "/." or "/.." + return (segLen == 1 && dotCount == 1) || (segLen == 2 && dotCount == 2) +} + +func NormalizePath(path string) string { + path = NormalizeSlashes(path) + if normalized, ok := simpleNormalizePath(path); ok { + return normalized + } + normalized := GetNormalizedAbsolutePath(path, "") + if normalized != "" && HasTrailingDirectorySeparator(path) { + normalized = EnsureTrailingDirectorySeparator(normalized) + } + return normalized +} + +func GetCanonicalFileName(fileName string, useCaseSensitiveFileNames bool) string { + if useCaseSensitiveFileNames { + return fileName + } + return ToFileNameLowerCase(fileName) +} + +// We convert the file names to lower case as key for file name on case insensitive file system +// While doing so we need to handle special characters (eg \u0130) to ensure that we dont convert +// it to lower case, fileName with its lowercase form can exist along side it. +// Handle special characters and make those case sensitive instead +// +// |-#--|-Unicode--|-Char code-|-Desc-------------------------------------------------------------------| +// | 1. | i | 105 | Ascii i | +// | 2. | I | 73 | Ascii I | +// |-------- Special characters ------------------------------------------------------------------------| +// | 3. | \u0130 | 304 | Upper case I with dot above | +// | 4. | i,\u0307 | 105,775 | i, followed by 775: Lower case of (3rd item) | +// | 5. | I,\u0307 | 73,775 | I, followed by 775: Upper case of (4th item), lower case is (4th item) | +// | 6. | \u0131 | 305 | Lower case i without dot, upper case is I (2nd item) | +// | 7. | \u00DF | 223 | Lower case sharp s | +// +// Because item 3 is special where in its lowercase character has its own +// upper case form we cant convert its case. +// Rest special characters are either already in lower case format or +// they have corresponding upper case character so they dont need special handling + +func ToFileNameLowerCase(fileName string) string { + const IWithDot = '\u0130' + + ascii := true + needsLower := false + fileNameLen := len(fileName) + for i := range fileNameLen { + c := fileName[i] + if c >= 0x80 { + ascii = false + break + } + if 'A' <= c && c <= 'Z' { + needsLower = true + } + } + if ascii { + if !needsLower { + return fileName + } + b := make([]byte, fileNameLen) + for i := range fileNameLen { + c := fileName[i] + if 'A' <= c && c <= 'Z' { + c += 'a' - 'A' // +32 + } + b[i] = c + } + return string(b) + } + + return strings.Map(func(r rune) rune { + if r == IWithDot { + return r + } + return unicode.ToLower(r) + }, fileName) +} + +func ToPath(fileName string, basePath string, useCaseSensitiveFileNames bool) Path { + var nonCanonicalizedPath string + if IsRootedDiskPath(fileName) { + nonCanonicalizedPath = NormalizePath(fileName) + } else { + nonCanonicalizedPath = GetNormalizedAbsolutePath(fileName, basePath) + } + return Path(GetCanonicalFileName(nonCanonicalizedPath, useCaseSensitiveFileNames)) +} + +func RemoveTrailingDirectorySeparator(path string) string { + if HasTrailingDirectorySeparator(path) { + return path[:len(path)-1] + } + return path +} + +func (p Path) RemoveTrailingDirectorySeparator() Path { + return Path(RemoveTrailingDirectorySeparator(string(p))) +} + +func RemoveTrailingDirectorySeparators(path string) string { + for HasTrailingDirectorySeparator(path) { + path = RemoveTrailingDirectorySeparator(path) + } + return path +} + +func EnsureTrailingDirectorySeparator(path string) string { + if !HasTrailingDirectorySeparator(path) { + return path + "/" + } + + return path +} + +func (p Path) EnsureTrailingDirectorySeparator() Path { + return Path(EnsureTrailingDirectorySeparator(string(p))) +} + +//// Relative Paths + +func GetPathComponentsRelativeTo(from string, to string, options ComparePathsOptions) []string { + fromComponents := reducePathComponents(GetPathComponents(from, options.CurrentDirectory)) + toComponents := reducePathComponents(GetPathComponents(to, options.CurrentDirectory)) + + start := 0 + maxCommonComponents := min(len(fromComponents), len(toComponents)) + stringEqualer := options.getEqualityComparer() + for ; start < maxCommonComponents; start++ { + fromComponent := fromComponents[start] + toComponent := toComponents[start] + if start == 0 { + if !stringutil.EquateStringCaseInsensitive(fromComponent, toComponent) { + break + } + } else { + if !stringEqualer(fromComponent, toComponent) { + break + } + } + } + + if start == 0 { + return toComponents + } + + numDotDotSlashes := len(fromComponents) - start + result := make([]string, 1+numDotDotSlashes+len(toComponents)-start) + + result[0] = "" + i := 1 + // Add all the relative components until we hit a common directory. + for range numDotDotSlashes { + result[i] = ".." + i++ + } + // Now add all the remaining components of the "to" path. + for _, component := range toComponents[start:] { + result[i] = component + i++ + } + + return result +} + +func GetRelativePathFromDirectory(fromDirectory string, to string, options ComparePathsOptions) string { + if (GetRootLength(fromDirectory) > 0) != (GetRootLength(to) > 0) { + panic("paths must either both be absolute or both be relative") + } + pathComponents := GetPathComponentsRelativeTo(fromDirectory, to, options) + return GetPathFromPathComponents(pathComponents) +} + +func GetRelativePathFromFile(from string, to string, options ComparePathsOptions) string { + return EnsurePathIsNonModuleName(GetRelativePathFromDirectory(GetDirectoryPath(from), to, options)) +} + +func ConvertToRelativePath(absoluteOrRelativePath string, options ComparePathsOptions) string { + if !IsRootedDiskPath(absoluteOrRelativePath) { + return absoluteOrRelativePath + } + + return GetRelativePathToDirectoryOrUrl(options.CurrentDirectory, absoluteOrRelativePath, false /*isAbsolutePathAnUrl*/, options) +} + +func GetRelativePathToDirectoryOrUrl(directoryPathOrUrl string, relativeOrAbsolutePath string, isAbsolutePathAnUrl bool, options ComparePathsOptions) string { + pathComponents := GetPathComponentsRelativeTo( + directoryPathOrUrl, + relativeOrAbsolutePath, + options, + ) + + firstComponent := pathComponents[0] + if isAbsolutePathAnUrl && IsRootedDiskPath(firstComponent) { + var prefix string + if firstComponent[0] == DirectorySeparator { + prefix = "file://" + } else { + prefix = "file:///" + } + pathComponents[0] = prefix + firstComponent + } + + return GetPathFromPathComponents(pathComponents) +} + +// Gets the portion of a path following the last (non-terminal) separator (`/`). +// Semantics align with NodeJS's `path.basename` except that we support URL's as well. +// If the base name has any one of the provided extensions, it is removed. +// +// // POSIX +// GetBaseFileName("/path/to/file.ext") == "file.ext" +// GetBaseFileName("/path/to/") == "to" +// GetBaseFileName("/") == "" +// // DOS +// GetBaseFileName("c:/path/to/file.ext") == "file.ext" +// GetBaseFileName("c:/path/to/") == "to" +// GetBaseFileName("c:/") == "" +// GetBaseFileName("c:") == "" +// // URL +// GetBaseFileName("http://typescriptlang.org/path/to/file.ext") == "file.ext" +// GetBaseFileName("http://typescriptlang.org/path/to/") == "to" +// GetBaseFileName("http://typescriptlang.org/") == "" +// GetBaseFileName("http://typescriptlang.org") == "" +// GetBaseFileName("file://server/path/to/file.ext") == "file.ext" +// GetBaseFileName("file://server/path/to/") == "to" +// GetBaseFileName("file://server/") == "" +// GetBaseFileName("file://server") == "" +// GetBaseFileName("file:///path/to/file.ext") == "file.ext" +// GetBaseFileName("file:///path/to/") == "to" +// GetBaseFileName("file:///") == "" +// GetBaseFileName("file://") == "" +func GetBaseFileName(path string) string { + path = NormalizeSlashes(path) + + // if the path provided is itself the root, then it has no file name. + rootLength := GetRootLength(path) + if rootLength == len(path) { + return "" + } + + // return the trailing portion of the path starting after the last (non-terminal) directory + // separator but not including any trailing directory separator. + path = RemoveTrailingDirectorySeparator(path) + return path[max(GetRootLength(path), strings.LastIndex(path, string(DirectorySeparator))+1):] +} + +// Gets the file extension for a path. +// If extensions are provided, gets the file extension for a path, provided it is one of the provided extensions. +// +// GetAnyExtensionFromPath("/path/to/file.ext", nil, false) == ".ext" +// GetAnyExtensionFromPath("/path/to/file.ext/", nil, false) == ".ext" +// GetAnyExtensionFromPath("/path/to/file", nil, false) == "" +// GetAnyExtensionFromPath("/path/to.ext/file", nil, false) == "" +// GetAnyExtensionFromPath("/path/to/file.ext", ".ext", true) === ".ext" +// GetAnyExtensionFromPath("/path/to/file.js", ".ext", true) === "" +// GetAnyExtensionFromPath("/path/to/file.js", [".ext", ".js"], true) === ".js" +// GetAnyExtensionFromPath("/path/to/file.ext", ".EXT", false) === "" +func GetAnyExtensionFromPath(path string, extensions []string, ignoreCase bool) string { + // Retrieves any string from the final "." onwards from a base file name. + // Unlike extensionFromPath, which throws an exception on unrecognized extensions. + if len(extensions) > 0 { + return getAnyExtensionFromPathWorker(RemoveTrailingDirectorySeparator(path), extensions, stringutil.GetStringEqualityComparer(ignoreCase)) + } + + baseFileName := GetBaseFileName(path) + extensionIndex := strings.LastIndex(baseFileName, ".") + if extensionIndex >= 0 { + return baseFileName[extensionIndex:] + } + return "" +} + +func getAnyExtensionFromPathWorker(path string, extensions []string, stringEqualityComparer func(a, b string) bool) string { + for _, extension := range extensions { + result := tryGetExtensionFromPath(path, extension, stringEqualityComparer) + if result != "" { + return result + } + } + return "" +} + +func tryGetExtensionFromPath(path string, extension string, stringEqualityComparer func(a, b string) bool) string { + if !strings.HasPrefix(extension, ".") { + extension = "." + extension + } + if len(path) >= len(extension) && path[len(path)-len(extension)] == '.' { + pathExtension := path[len(path)-len(extension):] + if stringEqualityComparer(pathExtension, extension) { + return pathExtension + } + } + return "" +} + +func PathIsRelative(path string) bool { + // True if path is ".", "..", or starts with "./", "../", ".\\", or "..\\". + + if path == "." || path == ".." { + return true + } + + if len(path) >= 2 && path[0] == '.' && (path[1] == '/' || path[1] == '\\') { + return true + } + + if len(path) >= 3 && path[0] == '.' && path[1] == '.' && (path[2] == '/' || path[2] == '\\') { + return true + } + + return false +} + +// EnsurePathIsNonModuleName ensures a path is either absolute (prefixed with `/` or `c:`) or dot-relative (prefixed +// with `./` or `../`) so as not to be confused with an unprefixed module name. +func EnsurePathIsNonModuleName(path string) string { + if !PathIsAbsolute(path) && !PathIsRelative(path) { + return "./" + path + } + return path +} + +func IsExternalModuleNameRelative(moduleName string) bool { + // TypeScript 1.0 spec (April 2014): 11.2.1 + // An external module name is "relative" if the first term is "." or "..". + // Update: We also consider a path like `C:\foo.ts` "relative" because we do not search for it in `node_modules` or treat it as an ambient module. + return PathIsRelative(moduleName) || IsRootedDiskPath(moduleName) +} + +type ComparePathsOptions struct { + UseCaseSensitiveFileNames bool + CurrentDirectory string +} + +func (o ComparePathsOptions) GetComparer() func(a, b string) int { + return stringutil.GetStringComparer(!o.UseCaseSensitiveFileNames) +} + +func (o ComparePathsOptions) getEqualityComparer() func(a, b string) bool { + return stringutil.GetStringEqualityComparer(!o.UseCaseSensitiveFileNames) +} + +func ComparePaths(a string, b string, options ComparePathsOptions) int { + a = CombinePaths(options.CurrentDirectory, a) + b = CombinePaths(options.CurrentDirectory, b) + + if a == b { + return 0 + } + if a == "" { + return -1 + } + if b == "" { + return 1 + } + + // NOTE: Performance optimization - shortcut if the root segments differ as there would be no + // need to perform path reduction. + aRoot := a[:GetRootLength(a)] + bRoot := b[:GetRootLength(b)] + result := stringutil.CompareStringsCaseInsensitive(aRoot, bRoot) + if result != 0 { + return result + } + + // NOTE: Performance optimization - shortcut if there are no relative path segments in + // the non-root portion of the path + aRest := a[len(aRoot):] + bRest := b[len(bRoot):] + if !hasRelativePathSegment(aRest) && !hasRelativePathSegment(bRest) { + return options.GetComparer()(aRest, bRest) + } + + // The path contains a relative path segment. Normalize the paths and perform a slower component + // by component comparison. + aComponents := reducePathComponents(GetPathComponents(a, "")) + bComponents := reducePathComponents(GetPathComponents(b, "")) + sharedLength := min(len(aComponents), len(bComponents)) + for i := 1; i < sharedLength; i++ { + result := options.GetComparer()(aComponents[i], bComponents[i]) + if result != 0 { + return result + } + } + return cmp.Compare(len(aComponents), len(bComponents)) +} + +func ComparePathsCaseSensitive(a string, b string, currentDirectory string) int { + return ComparePaths(a, b, ComparePathsOptions{UseCaseSensitiveFileNames: true, CurrentDirectory: currentDirectory}) +} + +func ComparePathsCaseInsensitive(a string, b string, currentDirectory string) int { + return ComparePaths(a, b, ComparePathsOptions{UseCaseSensitiveFileNames: false, CurrentDirectory: currentDirectory}) +} + +func ContainsPath(parent string, child string, options ComparePathsOptions) bool { + parent = CombinePaths(options.CurrentDirectory, parent) + child = CombinePaths(options.CurrentDirectory, child) + if parent == "" || child == "" { + return false + } + if parent == child { + return true + } + parentComponents := reducePathComponents(GetPathComponents(parent, "")) + childComponents := reducePathComponents(GetPathComponents(child, "")) + if len(childComponents) < len(parentComponents) { + return false + } + + componentComparer := options.getEqualityComparer() + for i, parentComponent := range parentComponents { + var comparer func(a, b string) bool + if i == 0 { + comparer = stringutil.EquateStringCaseInsensitive + } else { + comparer = componentComparer + } + if !comparer(parentComponent, childComponents[i]) { + return false + } + } + + return true +} + +func (p Path) ContainsPath(child Path) bool { + return ContainsPath(string(p), string(child), ComparePathsOptions{UseCaseSensitiveFileNames: true}) +} + +func FileExtensionIs(path string, extension string) bool { + return len(path) > len(extension) && strings.HasSuffix(path, extension) +} + +// Calls `callback` on `directory` and every ancestor directory it has, returning the first defined result. +// Stops at global cache location +func ForEachAncestorDirectoryStoppingAtGlobalCache[T any]( + globalCacheLocation string, + directory string, + callback func(directory string) (result T, stop bool), +) T { + result, _ := ForEachAncestorDirectory(directory, func(ancestorDirectory string) (T, bool) { + result, stop := callback(ancestorDirectory) + if stop || ancestorDirectory == globalCacheLocation { + return result, true + } + return result, false + }) + return result +} + +func ForEachAncestorDirectory[T any](directory string, callback func(directory string) (result T, stop bool)) (result T, ok bool) { + for { + result, stop := callback(directory) + if stop { + return result, true + } + + parentPath := GetDirectoryPath(directory) + if parentPath == directory { + var zero T + return zero, false + } + + directory = parentPath + } +} + +func ForEachAncestorDirectoryPath[T any](directory Path, callback func(directory Path) (result T, stop bool)) (result T, ok bool) { + return ForEachAncestorDirectory(string(directory), func(directory string) (T, bool) { + return callback(Path(directory)) + }) +} + +func HasExtension(fileName string) bool { + return strings.Contains(GetBaseFileName(fileName), ".") +} + +func SplitVolumePath(path string) (volume string, rest string, ok bool) { + if len(path) >= 2 && IsVolumeCharacter(path[0]) && path[1] == ':' { + return strings.ToLower(path[0:2]), path[2:], true + } + return "", path, false +} + +// GetCommonParents returns the smallest set of directories that are parents of all paths with +// at least `minComponents` directory components. Any path that has fewer than `minComponents` directory components +// will be returned in the second return value. Examples: +// +// /a/b/c/d, /a/b/c/e, /a/b/f/g => /a/b +// /a/b/c/d, /a/b/c/e, /a/b/f/g, /x/y => / +// /a/b/c/d, /a/b/c/e, /a/b/f/g, /x/y (minComponents: 2) => /a/b, /x/y +// c:/a/b/c/d, d:/a/b/c/d => c:/a/b/c/d, d:/a/b/c/d +func GetCommonParents( + paths []string, + minComponents int, + getPathComponents func(path string, currentDirectory string) []string, + options ComparePathsOptions, +) (parents []string, ignored map[string]struct{}) { + if minComponents < 1 { + panic("minComponents must be at least 1") + } + if len(paths) == 0 { + return nil, nil + } + if len(paths) == 1 { + if len(reducePathComponents(getPathComponents(paths[0], options.CurrentDirectory))) < minComponents { + return nil, map[string]struct{}{paths[0]: {}} + } + return paths, nil + } + + ignored = make(map[string]struct{}) + pathComponents := make([][]string, 0, len(paths)) + for _, path := range paths { + components := reducePathComponents(getPathComponents(path, options.CurrentDirectory)) + if len(components) < minComponents { + ignored[path] = struct{}{} + } else { + pathComponents = append(pathComponents, components) + } + } + + results := getCommonParentsWorker(pathComponents, minComponents, options) + resultPaths := make([]string, len(results)) + for i, comps := range results { + resultPaths[i] = GetPathFromPathComponents(comps) + } + + return resultPaths, ignored +} + +func getCommonParentsWorker(componentGroups [][]string, minComponents int, options ComparePathsOptions) [][]string { + if len(componentGroups) == 0 { + return nil + } + // Determine the maximum depth we can consider + maxDepth := len(componentGroups[0]) + for _, comps := range componentGroups[1:] { + if l := len(comps); l < maxDepth { + maxDepth = l + } + } + + equality := options.getEqualityComparer() + for lastCommonIndex := range maxDepth { + candidate := componentGroups[0][lastCommonIndex] + for j, comps := range componentGroups[1:] { + if !equality(candidate, comps[lastCommonIndex]) { // divergence + if lastCommonIndex < minComponents { + // Not enough components, we need to fan out + orderedGroups := make([]Path, 0, len(componentGroups)-j) + newGroups := make(map[Path]struct { + head []string + tails [][]string + }) + for _, g := range componentGroups { + key := ToPath(g[lastCommonIndex], options.CurrentDirectory, options.UseCaseSensitiveFileNames) + if _, ok := newGroups[key]; !ok { + orderedGroups = append(orderedGroups, key) + } + newGroups[key] = struct { + head []string + tails [][]string + }{ + head: g[:lastCommonIndex+1], + tails: append(newGroups[key].tails, g[lastCommonIndex+1:]), + } + } + slices.Sort(orderedGroups) + result := make([][]string, 0, len(newGroups)) + for _, key := range orderedGroups { + group := newGroups[key] + subResults := getCommonParentsWorker(group.tails, minComponents-(lastCommonIndex+1), options) + for _, sr := range subResults { + result = append(result, append(group.head, sr...)) + } + } + return result + } + return [][]string{componentGroups[0][:lastCommonIndex]} + } + } + } + + return [][]string{componentGroups[0][:maxDepth]} +} diff --git a/kitcom/main.go b/kitcom/main.go new file mode 100644 index 0000000..1bc1cb8 --- /dev/null +++ b/kitcom/main.go @@ -0,0 +1,151 @@ +package main + +import ( + "flag" + "fmt" + "go/token" + "io/fs" + "log" + "os" + "path" + "path/filepath" + + "efprojects.com/kitten-ipc/kitcom/api" + "efprojects.com/kitten-ipc/kitcom/golang" + "efprojects.com/kitten-ipc/kitcom/ts" +) + +type ApiParser interface { + AddFile(path string) + Parse() (*api.Api, error) +} + +type ApiGenerator interface { + Generate(api *api.Api, destFile string) error +} + +func main() { + src := flag.String("src", "", "Source file/dir") + dest := flag.String("dest", "", "Dest file") + pkgName := flag.String("pkg", "", "Package name (for go)") + flag.Parse() + + if *src == "" || *dest == "" { + log.Panic("source and destination must be set") + } + + srcAbs, err := filepath.Abs(*src) + if err != nil { + log.Panic(err) + } + + destAbs, err := filepath.Abs(*dest) + if err != nil { + log.Panic(err) + } + + apiParser, err := apiParserByPath(srcAbs) + if err != nil { + log.Panic(err) + } + + apis, err := apiParser.Parse() + if err != nil { + log.Panic(err) + } + + apiGenerator, err := apiGeneratorByPath(destAbs, *pkgName) + if err != nil { + log.Panic(err) + } + + if err := apiGenerator.Generate(apis, destAbs); err != nil { + log.Panic(err) + } +} + +func apiParserByPath(src string) (ApiParser, error) { + + s, err := os.Stat(src) + if err != nil { + return nil, fmt.Errorf("stat src: %w", err) + } + + var parser ApiParser + var ext string + + if s.IsDir() { + if err := filepath.Walk(src, func(curPath string, i fs.FileInfo, err error) error { + if err != nil { + return err + } + if i.IsDir() { + return nil + } + + p, err := apiParserByFilePath(i.Name()) + if err == nil { + if parser == nil { + parser = p + ext = path.Ext(i.Name()) + } else if path.Ext(i.Name()) != ext { + return fmt.Errorf("path contain multiple supported filetypes") + } + parser.AddFile(curPath) + } + + return nil + }); err != nil { + return nil, fmt.Errorf("walk dir: %w", err) + } + } else { + parser, err = apiParserByFilePath(src) + if err != nil { + return nil, err + } + parser.AddFile(src) + } + + if parser == nil { + return nil, fmt.Errorf("could not find supported files in %s", src) + } + return parser, nil +} + +func apiParserByFilePath(src string) (ApiParser, error) { + switch path.Ext(src) { + case ".go": + return &golang.GoApiParser{}, nil + case ".ts": + return &ts.TypescriptApiParser{}, nil + case ".js": + return nil, fmt.Errorf("vanilla javascript is not supported and never will be") + case "": + return nil, fmt.Errorf("could not find file extension for %s", src) + default: + return nil, fmt.Errorf("unsupported file extension: %s", path.Ext(src)) + } +} + +func apiGeneratorByPath(dest string, pkgName string) (ApiGenerator, error) { + switch path.Ext(dest) { + case ".go": + if pkgName == "" { + return nil, fmt.Errorf("package name must be set for Go generation") + } + if !token.IsIdentifier(pkgName) { + return nil, fmt.Errorf("invalid package name: %s", pkgName) + } + return &golang.GoApiGenerator{ + PkgName: pkgName, + }, nil + case ".ts": + return &ts.TypescriptApiGenerator{}, nil + case ".js": + return nil, fmt.Errorf("vanilla javascript is not supported and never will be") + case "": + return nil, fmt.Errorf("could not find file extension for %s", dest) + default: + return nil, fmt.Errorf("unsupported file extension: %s", path.Ext(dest)) + } +} diff --git a/kitcom/ts/ts_gen.tmpl b/kitcom/ts/ts_gen.tmpl new file mode 100644 index 0000000..5432731 --- /dev/null +++ b/kitcom/ts/ts_gen.tmpl @@ -0,0 +1,25 @@ +// Code generated by kitcom. DO NOT EDIT. + +import {ParentIPC, ChildIPC} from 'kitten-ipc'; + +{{- /*gotype: efprojects.com/kitten-ipc/kitcom/ts.tsGenData*/ -}} +{{range $e := .Api.Endpoints}} +export default class {{$e.Name}} { + protected ipc: ParentIPC | ChildIPC; + + constructor(ipc: ParentIPC | ChildIPC) { + this.ipc = ipc; + } + +{{range $mtd := $e.Methods}} + async {{ $mtd.Name }}( + {{ range $par := $mtd.Params }}{{$par.Name}}: {{$par.Type | typedef }}, {{end}} + ): Promise<{{if len $mtd.Ret}}{{(index $mtd.Ret 0).Type | typedef }}{{else}}void{{end}}> { + const results = await this.ipc.call('{{$e.Name}}.{{$mtd.Name}}', + {{range $par := $mtd.Params}}{{$par.Name}}, {{end}} + ); + return {{range $i, $ret := $mtd.Ret}}{{if $i}}, {{end}}results[{{$i}}] as {{$ret.Type | typedef}}{{end}} + } +{{end}} +} +{{end}} diff --git a/kitcom/ts/tsgen.go b/kitcom/ts/tsgen.go new file mode 100644 index 0000000..c154dae --- /dev/null +++ b/kitcom/ts/tsgen.go @@ -0,0 +1,77 @@ +package ts + +import ( + "bytes" + "fmt" + "log" + "os" + "os/exec" + "text/template" + + "efprojects.com/kitten-ipc/kitcom/api" + _ "embed" +) + +//go:embed ts_gen.tmpl +var templateString string + +type tsGenData struct { + Api *api.Api +} + +type TypescriptApiGenerator struct { +} + +func (g *TypescriptApiGenerator) Generate(apis *api.Api, destFile string) error { + tplCtx := tsGenData{ + Api: apis, + } + + tpl := template.New("tsgen") + tpl = tpl.Funcs(map[string]any{ + "typedef": func(t api.ValType) (string, error) { + td, ok := map[api.ValType]string{ + api.TInt: "number", + api.TString: "string", + api.TBool: "boolean", + }[t] + if !ok { + return "", fmt.Errorf("cannot generate type %v", t) + } + return td, nil + }, + }) + tpl = template.Must(tpl.Parse(templateString)) + + var buf bytes.Buffer + + if err := tpl.ExecuteTemplate(&buf, "tsgen", tplCtx); err != nil { + return fmt.Errorf("execute template: %w", err) + } + + if err := g.writeDest(destFile, buf.Bytes()); err != nil { + return fmt.Errorf("write file: %w", err) + } + + return nil +} + +func (g *TypescriptApiGenerator) writeDest(destFile string, bytes []byte) error { + f, err := os.OpenFile(destFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) + if err != nil { + return fmt.Errorf("open destination file: %w", err) + } + defer f.Close() + + if _, err := f.Write(bytes); err != nil { + return fmt.Errorf("write formatted source: %w", err) + } + + prettierCmd := exec.Command("npx", "prettier", destFile, "--write") + if out, err := prettierCmd.CombinedOutput(); err != nil { + log.Printf("Prettier returned error: %v", err) + log.Printf("Output: \n%s", string(out)) + } + + return nil +} diff --git a/kitcom/ts/tsparser.go b/kitcom/ts/tsparser.go new file mode 100644 index 0000000..a8b7f58 --- /dev/null +++ b/kitcom/ts/tsparser.go @@ -0,0 +1,165 @@ +package ts + +import ( + "fmt" + "io" + "os" + "strings" + + "efprojects.com/kitten-ipc/kitcom/api" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/ast" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/core" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/parser" + "efprojects.com/kitten-ipc/kitcom/internal/tsgo/tspath" +) + +const TagName = "kittenipc" +const TagComment = "api" + +type TypescriptApiParser struct { + files []string +} + +func (t *TypescriptApiParser) AddFile(path string) { + t.files = append(t.files, path) +} + +func (t *TypescriptApiParser) Parse() (*api.Api, error) { + + var apis api.Api + + for _, f := range t.files { + endpoints, err := t.parseFile(f) + if err != nil { + return nil, fmt.Errorf("parse file: %w", err) + } + apis.Endpoints = append(apis.Endpoints, endpoints...) + } + + if len(apis.Endpoints) == 0 { + return nil, fmt.Errorf("no endpoints found") + } + + return &apis, nil +} + +func (t *TypescriptApiParser) parseFile(sourceFilePath string) ([]api.Endpoint, error) { + var endpoints []api.Endpoint + + f, err := os.Open(sourceFilePath) + if err != nil { + return nil, fmt.Errorf("failed to open file: %w", err) + } + defer f.Close() + + fileContents, err := io.ReadAll(f) + if err != nil { + return nil, fmt.Errorf("failed to read file: %w", err) + } + + sourceFile := parser.ParseSourceFile(ast.SourceFileParseOptions{ + FileName: sourceFilePath, + Path: tspath.Path(sourceFilePath), + CompilerOptions: core.SourceFileAffectingCompilerOptions{}, + ExternalModuleIndicatorOptions: ast.ExternalModuleIndicatorOptions{}, + JSDocParsingMode: ast.JSDocParsingModeParseAll, + }, string(fileContents), core.ScriptKindTS) + _ = sourceFile + + sourceFile.ForEachChild(func(node *ast.Node) bool { + if node.Kind != ast.KindClassDeclaration { + return false + } + cls := node.AsClassDeclaration() + + jsDocNodes := cls.JSDoc(nil) + if len(jsDocNodes) == 0 { + return false + } + + var isApi bool + + outer: + for _, jsDocNode := range jsDocNodes { + jsDoc := jsDocNode.AsJSDoc() + if jsDoc.Tags == nil { + continue + } + for _, tag := range jsDoc.Tags.Nodes { + if tag.TagName().Text() == TagName { + for _, com := range tag.Comments() { + if strings.TrimSpace(com.Text()) == TagComment { + isApi = true + break outer + } + } + } + } + } + + if !isApi { + return false + } + + var endpoint api.Endpoint + + endpoint.Name = cls.Name().Text() + + for _, member := range cls.MemberList().Nodes { + if member.Kind != ast.KindMethodDeclaration { + continue + } + + method := member.AsMethodDeclaration() + if method.ModifierFlags()&ast.ModifierFlagsPrivate > 0 || method.ModifierFlags()&ast.ModifierFlagsProtected > 0 { + continue + } + + var apiMethod api.Method + apiMethod.Name = method.Name().Text() + for _, parNode := range method.ParameterList().Nodes { + par := parNode.AsParameterDeclaration() + var apiPar api.Val + apiPar.Name = par.Name().Text() + switch par.Type.Kind { + case ast.KindNumberKeyword: + apiPar.Type = api.TInt + case ast.KindStringKeyword: + apiPar.Type = api.TString + case ast.KindBooleanKeyword: + apiPar.Type = api.TBool + default: + err = fmt.Errorf("parameter type %s is not supported yet", par.Type.Kind) + return false + } + apiMethod.Params = append(apiMethod.Params, apiPar) + } + if method.Type != nil { + var apiRet api.Val + switch method.Type.Kind { + case ast.KindNumberKeyword: + apiRet.Type = api.TInt + case ast.KindStringKeyword: + apiRet.Type = api.TString + case ast.KindBooleanKeyword: + apiRet.Type = api.TBool + default: + err = fmt.Errorf("return type %s is not supported yet", method.Type.Kind) + return false + } + apiMethod.Ret = []api.Val{apiRet} + } + endpoint.Methods = append(endpoint.Methods, apiMethod) + } + + endpoints = append(endpoints, endpoint) + + return false + }) + + if err != nil { + return nil, err + } + + return endpoints, nil +} diff --git a/lib/golang/go.mod b/lib/golang/go.mod new file mode 100644 index 0000000..e3ee602 --- /dev/null +++ b/lib/golang/go.mod @@ -0,0 +1,5 @@ +module efprojects.com/kitten-ipc + +go 1.25.1 + +require github.com/samber/mo v1.16.0 diff --git a/lib/golang/go.sum b/lib/golang/go.sum new file mode 100644 index 0000000..e83beb0 --- /dev/null +++ b/lib/golang/go.sum @@ -0,0 +1,2 @@ +github.com/samber/mo v1.16.0 h1:qpEPCI63ou6wXlsNDMLE0IIN8A+devbGX/K1xdgr4b4= +github.com/samber/mo v1.16.0/go.mod h1:DlgzJ4SYhOh41nP1L9kh9rDNERuf8IqWSAs+gj2Vxag= diff --git a/lib/golang/lib.go b/lib/golang/lib.go new file mode 100644 index 0000000..7d1d71c --- /dev/null +++ b/lib/golang/lib.go @@ -0,0 +1,428 @@ +package golang + +import ( + "bufio" + "encoding/json" + "errors" + "flag" + "fmt" + "net" + "os" + "os/exec" + "path/filepath" + "reflect" + "slices" + "strings" + "sync" + "sync/atomic" + "syscall" + "time" + + "github.com/samber/mo" +) + +const ipcSocketArg = "--ipc-socket" +const maxMessageLength = 1 * 1024 * 1024 * 1024 // 1 gigabyte + +type StdioMode int + +type MsgType int + +type Vals []any + +const ( + MsgCall MsgType = 1 + MsgResponse MsgType = 2 +) + +type Message struct { + Type MsgType `json:"type"` + Id int64 `json:"id"` + Method string `json:"method"` + Params Vals `json:"params"` + Result Vals `json:"result"` + Error string `json:"error"` +} + +type Callable interface { + Call(method string, params ...any) (Vals, error) +} + +type ipcCommon struct { + localApis map[string]any + socketPath string + conn net.Conn + errCh chan error + nextId int64 + pendingCalls map[int64]chan mo.Result[Vals] + processingCalls atomic.Int64 + stopRequested atomic.Bool + mu sync.Mutex +} + +func (ipc *ipcCommon) readConn() { + scn := bufio.NewScanner(ipc.conn) + scn.Buffer(nil, maxMessageLength) + for scn.Scan() { + var msg Message + if err := json.Unmarshal(scn.Bytes(), &msg); err != nil { + ipc.raiseErr(fmt.Errorf("unmarshal message: %w", err)) + break + } + ipc.processMsg(msg) + } + if err := scn.Err(); err != nil { + ipc.raiseErr(err) + } +} + +func (ipc *ipcCommon) processMsg(msg Message) { + switch msg.Type { + case MsgCall: + ipc.handleCall(msg) + case MsgResponse: + ipc.handleResponse(msg) + } +} + +func (ipc *ipcCommon) sendMsg(msg Message) error { + + data, err := json.Marshal(msg) + if err != nil { + return fmt.Errorf("marshal message: %w", err) + } + + data = append(data, '\n') + + if _, err := ipc.conn.Write(data); err != nil { + return fmt.Errorf("write message: %w", err) + } + + return nil +} + +func (ipc *ipcCommon) handleCall(msg Message) { + if ipc.stopRequested.Load() { + return + } + + ipc.processingCalls.Add(1) + defer ipc.processingCalls.Add(-1) + + parts := strings.Split(msg.Method, ".") + if len(parts) != 2 { + ipc.sendResponse(msg.Id, nil, fmt.Errorf("invalid method: %s", msg.Method)) + return + } + endpointName, methodName := parts[0], parts[1] + + localApi, ok := ipc.localApis[endpointName] + if !ok { + ipc.sendResponse(msg.Id, nil, fmt.Errorf("endpoint not found: %s", endpointName)) + return + } + + method := reflect.ValueOf(localApi).MethodByName(methodName) + if !method.IsValid() { + ipc.sendResponse(msg.Id, nil, fmt.Errorf("method not found: %s", msg.Method)) + return + } + + argsCount := method.Type().NumIn() + if len(msg.Params) != argsCount { + ipc.sendResponse(msg.Id, nil, fmt.Errorf("argument count mismatch: expected %d, got %d", argsCount, len(msg.Params))) + return + } + + var args []reflect.Value + for _, param := range msg.Params { + args = append(args, reflect.ValueOf(param)) + } + + results := method.Call(args) + resVals := results[0 : len(results)-1] + resErrVal := results[len(results)-1] + + var res []any + for _, resVal := range resVals { + res = append(res, resVal.Interface()) + } + + var resErr error + if !resErrVal.IsNil() { + resErr = resErrVal.Interface().(error) + } + + ipc.sendResponse(msg.Id, res, resErr) +} + +func (ipc *ipcCommon) sendResponse(id int64, result []any, err error) { + msg := Message{ + Type: MsgResponse, + Id: id, + Result: result, + } + + if err != nil { + msg.Error = err.Error() + } + + if err := ipc.sendMsg(msg); err != nil { + ipc.raiseErr(fmt.Errorf("send response for id=%d: %w", id, err)) + } +} + +func (ipc *ipcCommon) handleResponse(msg Message) { + ipc.mu.Lock() + ch, ok := ipc.pendingCalls[msg.Id] + if ok { + delete(ipc.pendingCalls, msg.Id) + } + ipc.mu.Unlock() + + if !ok { + ipc.raiseErr(fmt.Errorf("received response for unknown call id: %d", msg.Id)) + return + } + + var res mo.Result[Vals] + if msg.Error == "" { + res = mo.Ok[Vals](msg.Result) + } else { + res = mo.Err[Vals](fmt.Errorf("remote error: %s", msg.Error)) + } + ch <- res + close(ch) +} + +func (ipc *ipcCommon) Call(method string, params ...any) (Vals, error) { + if ipc.stopRequested.Load() { + return nil, fmt.Errorf("ipc is stopping") + } + + ipc.mu.Lock() + id := ipc.nextId + ipc.nextId++ + resChan := make(chan mo.Result[Vals], 1) + ipc.pendingCalls[id] = resChan + ipc.mu.Unlock() + + msg := Message{ + Type: MsgCall, + Id: id, + Method: method, + Params: params, + } + + if err := ipc.sendMsg(msg); err != nil { + ipc.mu.Lock() + delete(ipc.pendingCalls, id) + ipc.mu.Unlock() + return nil, fmt.Errorf("send call: %w", err) + } + + result := <-resChan + return result.Get() +} + +func (ipc *ipcCommon) raiseErr(err error) { + select { + case ipc.errCh <- err: + default: + } +} + +func (ipc *ipcCommon) closeConn() { + ipc.mu.Lock() + defer ipc.mu.Unlock() + _ = ipc.conn.Close() + for _, call := range ipc.pendingCalls { + call <- mo.Err[Vals](fmt.Errorf("call cancelled due to ipc termination")) + } +} + +type ParentIPC struct { + *ipcCommon + cmd *exec.Cmd + listener net.Listener +} + +func NewParent(cmd *exec.Cmd, localApis ...any) (*ParentIPC, error) { + p := ParentIPC{ + ipcCommon: &ipcCommon{ + localApis: mapTypeNames(localApis), + pendingCalls: make(map[int64]chan mo.Result[Vals]), + errCh: make(chan error, 1), + socketPath: filepath.Join(os.TempDir(), fmt.Sprintf("kitten-ipc-%d.sock", os.Getpid())), + }, + cmd: cmd, + } + + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + if slices.Contains(cmd.Args, ipcSocketArg) { + return nil, fmt.Errorf("you should not use `%s` argument in your command", ipcSocketArg) + } + cmd.Args = append(cmd.Args, ipcSocketArg, p.socketPath) + + p.errCh = make(chan error, 1) + + return &p, nil +} + +func (p *ParentIPC) Start() error { + _ = os.Remove(p.socketPath) + listener, err := net.Listen("unix", p.socketPath) + if err != nil { + return fmt.Errorf("listen unix socket: %w", err) + } + p.listener = listener + defer p.listener.Close() + + err = p.cmd.Start() + if err != nil { + return fmt.Errorf("cmd start: %w", err) + } + + return p.acceptConn() +} + +func (p *ParentIPC) acceptConn() error { + const acceptTimeout = time.Second * 10 + + res := make(chan mo.Result[net.Conn], 1) + go func() { + conn, err := p.listener.Accept() + if err != nil { + res <- mo.Err[net.Conn](err) + } else { + res <- mo.Ok[net.Conn](conn) + } + close(res) + }() + + select { + case <-time.After(acceptTimeout): + _ = p.cmd.Process.Kill() + return fmt.Errorf("accept timeout") + case res := <-res: + if res.IsError() { + _ = p.cmd.Process.Kill() + return fmt.Errorf("accept: %w", res.Error()) + } + p.conn = res.MustGet() + go p.readConn() + } + return nil +} + +func (p *ParentIPC) Stop() error { + if len(p.pendingCalls) > 0 { + return fmt.Errorf("there are calls pending") + } + if p.processingCalls.Load() > 0 { + return fmt.Errorf("there are calls processing") + } + p.stopRequested.Store(true) + if err := p.cmd.Process.Signal(syscall.SIGINT); err != nil { + return fmt.Errorf("send SIGTERM: %w", err) + } + return p.Wait() +} + +func (p *ParentIPC) Wait() error { + waitErrCh := make(chan error, 1) + + go func() { + waitErrCh <- p.cmd.Wait() + }() + + var retErr error + select { + case err := <-p.errCh: + retErr = fmt.Errorf("ipc internal error: %w", err) + case err := <-waitErrCh: + if err != nil { + var exitErr *exec.ExitError + if ok := errors.As(err, &exitErr); ok { + if !exitErr.Success() { + ws, ok := exitErr.Sys().(syscall.WaitStatus) + if !(ok && ws.Signaled() && ws.Signal() == syscall.SIGINT && p.stopRequested.Load()) { + retErr = fmt.Errorf("cmd wait: %w", err) + } + } + } else { + retErr = fmt.Errorf("cmd wait: %w", err) + } + } + } + + p.closeConn() + + return retErr +} + +type ChildIPC struct { + *ipcCommon +} + +func NewChild(localApis ...any) (*ChildIPC, error) { + c := ChildIPC{ + ipcCommon: &ipcCommon{ + localApis: mapTypeNames(localApis), + pendingCalls: make(map[int64]chan mo.Result[Vals]), + errCh: make(chan error, 1), + }, + } + + socketPath := flag.String("ipc-socket", "", "Path to IPC socket") + flag.Parse() + + if *socketPath == "" { + return nil, fmt.Errorf("ipc socket path is missing") + } + c.socketPath = *socketPath + + return &c, nil +} + +func (c *ChildIPC) Start() error { + conn, err := net.Dial("unix", c.socketPath) + if err != nil { + return fmt.Errorf("connect to parent socket: %w", err) + } + c.conn = conn + c.readConn() + return nil +} + +func (c *ChildIPC) Wait() error { + err := <-c.errCh + if err != nil { + return fmt.Errorf("ipc error: %w", err) + } + return nil +} + +func mergeErr(errs ...error) (ret error) { + for _, err := range errs { + if err != nil { + if ret == nil { + ret = err + } else { + ret = fmt.Errorf("%w; %w", ret, err) + } + } + } + return +} + +func mapTypeNames(types []any) map[string]any { + result := make(map[string]any) + for _, t := range types { + typeName := reflect.TypeOf(t).Elem().Name() + result[typeName] = t + } + return result +} diff --git a/lib/ts/dist/index.d.ts b/lib/ts/dist/index.d.ts new file mode 100644 index 0000000..98e9335 --- /dev/null +++ b/lib/ts/dist/index.d.ts @@ -0,0 +1,2 @@ +export { ParentIPC, ChildIPC } from './lib.js'; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/lib/ts/dist/index.d.ts.map b/lib/ts/dist/index.d.ts.map new file mode 100644 index 0000000..046b407 --- /dev/null +++ b/lib/ts/dist/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAE,QAAQ,EAAC,MAAM,UAAU,CAAC"} \ No newline at end of file diff --git a/lib/ts/dist/index.js.map b/lib/ts/dist/index.js.map new file mode 100644 index 0000000..c44a621 --- /dev/null +++ b/lib/ts/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAE,QAAQ,EAAC,MAAM,UAAU,CAAC"} \ No newline at end of file diff --git a/lib/ts/dist/lib.d.ts b/lib/ts/dist/lib.d.ts new file mode 100644 index 0000000..c17f914 --- /dev/null +++ b/lib/ts/dist/lib.d.ts @@ -0,0 +1,60 @@ +import * as net from 'node:net'; +declare enum MsgType { + Call = 1, + Response = 2 +} +type Vals = any[]; +interface CallMessage { + type: MsgType.Call; + id: number; + method: string; + params: Vals; +} +interface ResponseMessage { + type: MsgType.Response; + id: number; + result?: Vals; + error?: string; +} +type Message = CallMessage | ResponseMessage; +interface CallResult { + result: Vals; + error: Error | null; +} +declare abstract class IPCCommon { + protected localApis: Record; + protected socketPath: string; + protected conn: net.Socket | null; + protected nextId: number; + protected pendingCalls: Record void>; + protected stopRequested: boolean; + protected processingCalls: number; + protected onError?: (err: Error) => void; + protected onClose?: () => void; + protected constructor(localApis: object[], socketPath: string); + protected readConn(): void; + protected processMsg(msg: Message): void; + protected sendMsg(msg: Message): void; + protected handleCall(msg: CallMessage): Promise; + protected handleResponse(msg: ResponseMessage): void; + stop(): void; + call(method: string, ...params: Vals): Promise; + protected raiseErr(err: Error): void; +} +export declare class ParentIPC extends IPCCommon { + private readonly cmdPath; + private readonly cmdArgs; + private cmd; + private readonly listener; + constructor(cmdPath: string, cmdArgs: string[], ...localApis: object[]); + start(): Promise; + private acceptConn; + wait(): Promise; +} +export declare class ChildIPC extends IPCCommon { + constructor(...localApis: object[]); + start(): Promise; + wait(): Promise; +} +export {}; +//# sourceMappingURL=lib.d.ts.map \ No newline at end of file diff --git a/lib/ts/dist/lib.d.ts.map b/lib/ts/dist/lib.d.ts.map new file mode 100644 index 0000000..a8f0498 --- /dev/null +++ b/lib/ts/dist/lib.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAUhC,aAAK,OAAO;IACR,IAAI,IAAI;IACR,QAAQ,IAAI;CACf;AAED,KAAK,IAAI,GAAG,GAAG,EAAE,CAAC;AAElB,UAAU,WAAW;IACjB,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,IAAI,CAAC;CAChB;AAED,UAAU,eAAe;IACrB,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,IAAI,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,KAAK,OAAO,GAAG,WAAW,GAAG,eAAe,CAAC;AAE7C,UAAU,UAAU;IAChB,MAAM,EAAE,IAAI,CAAC;IACb,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACvB;AAED,uBAAe,SAAS;IACpB,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACzC,SAAS,CAAC,UAAU,EAAE,MAAM,CAAC;IAC7B,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,GAAG,IAAI,CAAQ;IACzC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAK;IAC7B,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC,CAAM;IAC1E,SAAS,CAAC,aAAa,EAAE,OAAO,CAAS;IACzC,SAAS,CAAC,eAAe,EAAE,MAAM,CAAK;IACtC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;IACzC,SAAS,CAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAE/B,SAAS,aAAa,SAAS,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM;IAS7D,SAAS,CAAC,QAAQ,IAAI,IAAI;IA4B1B,SAAS,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI;IAWxC,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI;cAWrB,UAAU,CAAC,GAAG,EAAE,WAAW;IA6C3C,SAAS,CAAC,cAAc,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI;IAapD,IAAI;IAWJ,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBpD,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,KAAK,GAAG,IAAI;CAGvC;AAGD,qBAAa,SAAU,SAAQ,SAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAW;IACnC,OAAO,CAAC,GAAG,CAA6B;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAa;gBAE1B,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,GAAG,SAAS,EAAE,MAAM,EAAE;IAahE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAwBd,UAAU;IAmBlB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAgB9B;AAGD,qBAAa,QAAS,SAAQ,SAAS;gBACvB,GAAG,SAAS,EAAE,MAAM,EAAE;IAI5B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAUtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAa9B"} \ No newline at end of file diff --git a/lib/ts/dist/lib.js.map b/lib/ts/dist/lib.js.map new file mode 100644 index 0000000..779c574 --- /dev/null +++ b/lib/ts/dist/lib.js.map @@ -0,0 +1 @@ +{"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAoB,KAAK,EAAC,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,MAAM,cAAc,GAAG,YAAY,CAAC;AAEpC,IAAK,OAGJ;AAHD,WAAK,OAAO;IACR,qCAAQ,CAAA;IACR,6CAAY,CAAA;AAChB,CAAC,EAHI,OAAO,KAAP,OAAO,QAGX;AAyBD,MAAe,SAAS;IACV,SAAS,CAAsB;IAC/B,UAAU,CAAS;IACnB,IAAI,GAAsB,IAAI,CAAC;IAC/B,MAAM,GAAW,CAAC,CAAC;IACnB,YAAY,GAAiD,EAAE,CAAC;IAChE,aAAa,GAAY,KAAK,CAAC;IAC/B,eAAe,GAAW,CAAC,CAAC;IAC5B,OAAO,CAAwB;IAC/B,OAAO,CAAc;IAE/B,YAAsB,SAAmB,EAAE,UAAkB;QACzD,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAE7B,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;QACpB,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YAC/B,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC;QACzD,CAAC;IACL,CAAC;IAES,QAAQ;QACd,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;QAEjD,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;YAChC,KAAK,EAAE,IAAI,CAAC,IAAI;YAChB,SAAS,EAAE,QAAQ;SACtB,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;YACxB,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QACrB,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,QAAiB,EAAE,EAAE;YACxC,IAAI,QAAQ,EAAE,CAAC;gBACX,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC,CAAC;YAC/D,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACnB,IAAI,CAAC;gBACD,MAAM,GAAG,GAAY,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACtC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;YACzB,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACT,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,GAAI,CAAE,EAAE,CAAC,CAAC,CAAC;YACvC,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAES,UAAU,CAAC,GAAY;QAC7B,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;YACf,KAAK,OAAO,CAAC,IAAI;gBACb,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;gBACrB,MAAM;YACV,KAAK,OAAO,CAAC,QAAQ;gBACjB,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;gBACzB,MAAM;QACd,CAAC;IACL,CAAC;IAES,OAAO,CAAC,GAAY;QAC1B,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;QAEjD,IAAI,CAAC;YACD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;YACxC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACT,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,qBAAsB,GAAG,CAAC,EAAG,KAAM,CAAE,EAAE,CAAC,CAAC,CAAC;QACtE,CAAC;IACL,CAAC;IAES,KAAK,CAAC,UAAU,CAAC,GAAgB;QACvC,MAAM,CAAC,YAAY,EAAE,UAAU,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACzD,IAAI,CAAC,YAAY,IAAI,CAAC,UAAU,EAAE,CAAC;YAC/B,IAAI,CAAC,OAAO,CAAC,EAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,mBAAoB,GAAG,CAAC,MAAO,EAAE,EAAC,CAAC,CAAC;YAC7F,OAAO;QACX,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QAC9C,IAAI,CAAC,QAAQ,EAAE,CAAC;YACZ,IAAI,CAAC,OAAO,CAAC,EAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,uBAAwB,YAAa,EAAE,EAAC,CAAC,CAAC;YACnG,OAAO;QACX,CAAC;QACD,MAAM,MAAM,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;QACpC,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,CAAC;YAC1C,IAAI,CAAC,OAAO,CAAC,EAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,qBAAsB,GAAG,CAAC,MAAO,EAAE,EAAC,CAAC,CAAC;YAC/F,OAAO;QACX,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC;QAChC,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAClC,IAAI,CAAC,OAAO,CAAC;gBACT,IAAI,EAAE,OAAO,CAAC,QAAQ;gBACtB,EAAE,EAAE,GAAG,CAAC,EAAE;gBACV,KAAK,EAAE,qCAAsC,SAAU,SAAU,GAAG,CAAC,MAAM,CAAC,MAAO,EAAE;aACxF,CAAC,CAAC;YACH,OAAO;QACX,CAAC;QAED,IAAI,CAAC;YACD,IAAI,CAAC,eAAe,EAAE,CAAC;YACvB,IAAI,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;YAChD,IAAI,MAAM,YAAY,OAAO,EAAE,CAAC;gBAC5B,MAAM,GAAG,MAAM,MAAM,CAAC;YAC1B,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,EAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,MAAM,CAAC,EAAC,CAAC,CAAC;QACzE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,IAAI,CAAC,OAAO,CAAC,EAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,GAAI,GAAI,EAAE,EAAC,CAAC,CAAC;QAC1E,CAAC;gBAAS,CAAC;YACP,IAAI,CAAC,eAAe,EAAE,CAAC;QAC3B,CAAC;QAED,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACrB,IAAI,IAAI,CAAC,OAAO;gBAAE,IAAI,CAAC,OAAO,EAAE,CAAC;QACrC,CAAC;IACL,CAAC;IAES,cAAc,CAAC,GAAoB;QACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC3C,IAAI,CAAC,QAAQ,EAAE,CAAC;YACZ,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,wCAAyC,GAAG,CAAC,EAAG,EAAE,CAAC,CAAC,CAAC;YAC7E,OAAO;QACX,CAAC;QAED,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEjC,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,iBAAkB,GAAG,CAAC,KAAM,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACzE,QAAQ,CAAC,EAAC,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,EAAE,EAAE,KAAK,EAAE,GAAG,EAAC,CAAC,CAAC;IACrD,CAAC;IAED,IAAI;QACA,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QAC/C,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;YAClD,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QACjD,CAAC;QACD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,IAAI,IAAI,CAAC,OAAO;YAAE,IAAI,CAAC,OAAO,EAAE,CAAC;IACrC,CAAC;IAED,IAAI,CAAC,MAAc,EAAE,GAAG,MAAY;QAChC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACnC,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YAEzB,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,MAAkB,EAAE,EAAE;gBAC3C,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;oBACf,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBACzB,CAAC;qBAAM,CAAC;oBACJ,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBAC3B,CAAC;YACL,CAAC,CAAC;YACF,IAAI,CAAC;gBACD,IAAI,CAAC,OAAO,CAAC,EAAC,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAC,CAAC,CAAC;YAC3D,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACT,OAAO,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;gBAC7B,MAAM,CAAC,IAAI,KAAK,CAAC,cAAe,CAAE,EAAE,CAAC,CAAC,CAAC;YAC3C,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAES,QAAQ,CAAC,GAAU;QACzB,IAAI,IAAI,CAAC,OAAO;YAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACxC,CAAC;CACJ;AAGD,MAAM,OAAO,SAAU,SAAQ,SAAS;IACnB,OAAO,CAAS;IAChB,OAAO,CAAW;IAC3B,GAAG,GAAwB,IAAI,CAAC;IACvB,QAAQ,CAAa;IAEtC,YAAY,OAAe,EAAE,OAAiB,EAAE,GAAG,SAAmB;QAClE,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,cAAe,OAAO,CAAC,GAAI,OAAO,CAAC,CAAC;QAC9E,KAAK,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QAE7B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAM,cAAe,EAAE,CAAC,EAAE,CAAC;YAC5C,MAAM,IAAI,KAAK,CAAC,yBAA0B,cAAe,4BAA4B,CAAC,CAAC;QAC3F,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QAEvB,IAAI,CAAC,QAAQ,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,KAAK;QACP,IAAI,CAAC;YACD,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACnC,CAAC;QAAC,MAAM,CAAC;QACT,CAAC;QAGD,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACxC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,EAAE;gBACvC,OAAO,EAAE,CAAC;YACd,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,EAAE,KAAM,cAAe,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAC5E,IAAI,CAAC,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,EAAC,KAAK,EAAE,SAAS,EAAC,CAAC,CAAC;QAE5D,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACzB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACvB,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,CAAC;IAC9B,CAAC;IAEO,KAAK,CAAC,UAAU;QACpB,MAAM,aAAa,GAAG,KAAK,CAAC;QAE5B,MAAM,aAAa,GAAG,IAAI,OAAO,CAAa,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC9D,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE;gBACtC,OAAO,CAAC,IAAI,CAAC,CAAC;YAClB,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC;YACD,IAAI,CAAC,IAAI,GAAG,MAAM,OAAO,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;YACxD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACT,IAAI,IAAI,CAAC,GAAG;gBAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;YAC9B,IAAI,CAAC,QAAQ,CAAC,CAAU,CAAC,CAAC;QAC9B,CAAC;IACL,CAAC;IAED,KAAK,CAAC,IAAI;QACN,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACnC,IAAI,CAAC,IAAI,CAAC,GAAG;gBAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;YAC7D,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;gBAC3C,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;oBACjB,IAAI,MAAM;wBAAE,MAAM,CAAC,IAAI,KAAK,CAAC,8BAA+B,MAAO,EAAE,CAAC,CAAC,CAAC;;wBACnE,MAAM,CAAC,IAAI,KAAK,CAAC,4BAA6B,IAAK,EAAE,CAAC,CAAC,CAAC;gBACjE,CAAC;qBAAM,CAAC;oBACJ,OAAO,EAAE,CAAC;gBACd,CAAC;YACL,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,OAAO,GAAG,CAAC,GAAG,EAAE,EAAE;gBACnB,MAAM,CAAC,GAAG,CAAC,CAAC;YAChB,CAAC,CAAC;QACN,CAAC,CAAC,CAAC;IACP,CAAC;CACJ;AAGD,MAAM,OAAO,QAAS,SAAQ,SAAS;IACnC,YAAY,GAAG,SAAmB;QAC9B,KAAK,CAAC,SAAS,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,KAAK;QACP,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACnC,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,gBAAgB,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,EAAE;gBACnD,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAChB,OAAO,EAAE,CAAC;YACd,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;IACP,CAAC;IAED,KAAK,CAAC,IAAI;QACN,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACnC,IAAI,CAAC,OAAO,GAAG,CAAC,GAAG,EAAE,EAAE;gBACnB,MAAM,CAAC,GAAG,CAAC,CAAC;YAChB,CAAC,CAAC;YACF,IAAI,CAAC,OAAO,GAAG,GAAG,EAAE;gBAChB,IAAI,IAAI,CAAC,eAAe,KAAK,CAAC,EAAE,CAAC;oBAC7B,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC;oBACrB,OAAO,EAAE,CAAC;gBACd,CAAC;YACL,CAAC,CAAC;QACN,CAAC,CAAC,CAAC;IACP,CAAC;CACJ;AAGD,SAAS,kBAAkB;IACvB,MAAM,EAAC,MAAM,EAAC,GAAG,IAAI,CAAC,SAAS,CAAC;QAC5B,OAAO,EAAE;YACL,CAAC,cAAc,CAAC,EAAE;gBACd,IAAI,EAAE,QAAQ;aACjB;SACJ;KACJ,CAAC,CAAC;IAEH,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAClD,CAAC;IAED,OAAO,MAAM,CAAC,cAAc,CAAC,CAAC;AAClC,CAAC;AAGD,SAAS,KAAK,CAAC,EAAU;IACrB,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC;AAGD,oBAAoB;AACpB,SAAS,OAAO,CAAI,IAAgB,EAAE,EAAU;IAC5C,OAAO,OAAO,CAAC,IAAI,CACf,CAAC,IAAI,EAAE,IAAI,OAAO,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CACjD,CAAC;AACpB,CAAC"} \ No newline at end of file diff --git a/lib/ts/package-lock.json b/lib/ts/package-lock.json new file mode 100644 index 0000000..7110d2b --- /dev/null +++ b/lib/ts/package-lock.json @@ -0,0 +1,38 @@ +{ + "name": "kitten-ipc", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "kitten-ipc", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@types/node": "^22.10.5", + "ts-events": "^3.4.1" + } + }, + "node_modules/@types/node": { + "version": "22.18.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.12.tgz", + "integrity": "sha512-BICHQ67iqxQGFSzfCFTT7MRQ5XcBjG5aeKh5Ok38UBbPe5fxTyE+aHFxwVrGyr8GNlqFMLKD1D3P2K/1ks8tog==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/ts-events": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/ts-events/-/ts-events-3.4.1.tgz", + "integrity": "sha512-px05Slmyh6Bnfi7ma0YIU6cYXnisi+iL/2lhClu+s0ZkTdfPosiGp0H8aoQW7ASSXgcXYXAqujD0CcKYr5YlAw==", + "license": "ISC" + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "license": "MIT" + } + } +} diff --git a/lib/ts/package.json b/lib/ts/package.json new file mode 100644 index 0000000..92c5ad3 --- /dev/null +++ b/lib/ts/package.json @@ -0,0 +1,27 @@ +{ + "name": "kitten-ipc", + "description": "ipc lib", + "version": "1.0.0", + "author": "Egor3f ", + "license": "Apache 2.0", + + "type": "module", + "main": "./dist/index.js", + "types": "./dist/types.d.ts", + + "exports": { + ".": { + "import": "./dist/index.js", + "types": "./dist/types.d.ts" + } + }, + + "scripts": { + "build": "tsc" + }, + + "dependencies": { + "@types/node": "^22.10.5", + "ts-events": "^3.4.1" + } +} diff --git a/lib/ts/src/index.ts b/lib/ts/src/index.ts new file mode 100644 index 0000000..35f7b93 --- /dev/null +++ b/lib/ts/src/index.ts @@ -0,0 +1 @@ +export {ParentIPC, ChildIPC} from './lib.js'; diff --git a/lib/ts/src/lib.ts b/lib/ts/src/lib.ts new file mode 100644 index 0000000..6cbb483 --- /dev/null +++ b/lib/ts/src/lib.ts @@ -0,0 +1,343 @@ +import * as net from 'node:net'; +import * as readline from 'node:readline'; +import {type ChildProcess, spawn} from 'node:child_process'; +import * as os from 'node:os'; +import * as path from 'node:path'; +import * as fs from 'node:fs'; +import * as util from 'node:util'; + +const IPC_SOCKET_ARG = 'ipc-socket'; + +enum MsgType { + Call = 1, + Response = 2, +} + +type Vals = any[]; + +interface CallMessage { + type: MsgType.Call, + id: number, + method: string; + params: Vals; +} + +interface ResponseMessage { + type: MsgType.Response, + id: number, + result?: Vals; + error?: string; +} + +type Message = CallMessage | ResponseMessage; + +interface CallResult { + result: Vals; + error: Error | null; +} + +abstract class IPCCommon { + protected localApis: Record; + protected socketPath: string; + protected conn: net.Socket | null = null; + protected nextId: number = 0; + protected pendingCalls: Record void> = {}; + protected stopRequested: boolean = false; + protected processingCalls: number = 0; + protected onError?: (err: Error) => void; + protected onClose?: () => void; + + protected constructor(localApis: object[], socketPath: string) { + this.socketPath = socketPath; + + this.localApis = {}; + for (const localApi of localApis) { + this.localApis[localApi.constructor.name] = localApi; + } + } + + protected readConn(): void { + if (!this.conn) throw new Error('no connection'); + + const rl = readline.createInterface({ + input: this.conn, + crlfDelay: Infinity, + }); + + this.conn.on('error', (e) => { + this.raiseErr(e); + }); + + this.conn.on('close', (hadError: boolean) => { + if (hadError) { + this.raiseErr(new Error('connection closed due to error')); + } + }); + + rl.on('line', (line) => { + try { + const msg: Message = JSON.parse(line); + this.processMsg(msg); + } catch (e) { + this.raiseErr(new Error(`${ e }`)); + } + }); + } + + protected processMsg(msg: Message): void { + switch (msg.type) { + case MsgType.Call: + this.handleCall(msg); + break; + case MsgType.Response: + this.handleResponse(msg); + break; + } + } + + protected sendMsg(msg: Message): void { + if (!this.conn) throw new Error('no connection'); + + try { + const data = JSON.stringify(msg) + '\n'; + this.conn.write(data); + } catch (e) { + this.raiseErr(new Error(`send response for ${ msg.id }: ${ e }`)); + } + } + + protected async handleCall(msg: CallMessage) { + const [endpointName, methodName] = msg.method.split('.'); + if (!endpointName || !methodName) { + this.sendMsg({type: MsgType.Response, id: msg.id, error: `call malformed: ${ msg.method }`}); + return; + } + const endpoint = this.localApis[endpointName]; + if (!endpoint) { + this.sendMsg({type: MsgType.Response, id: msg.id, error: `endpoint not found: ${ endpointName }`}); + return; + } + const method = endpoint[methodName]; + if (!method || typeof method !== 'function') { + this.sendMsg({type: MsgType.Response, id: msg.id, error: `method not found: ${ msg.method }`}); + return; + } + + const argsCount = method.length; + if (msg.params.length !== argsCount) { + this.sendMsg({ + type: MsgType.Response, + id: msg.id, + error: `argument count mismatch: expected ${ argsCount }, got ${ msg.params.length }` + }); + return; + } + + try { + this.processingCalls++; + let result = method.apply(endpoint, msg.params); + if (result instanceof Promise) { + result = await result; + } + this.sendMsg({type: MsgType.Response, id: msg.id, result: [result]}); + } catch (err) { + this.sendMsg({type: MsgType.Response, id: msg.id, error: `${ err }`}); + } finally { + this.processingCalls--; + } + + if (this.stopRequested) { + if (this.onClose) this.onClose(); + } + } + + protected handleResponse(msg: ResponseMessage): void { + const callback = this.pendingCalls[msg.id]; + if (!callback) { + this.raiseErr(new Error(`received response for unknown msgId: ${ msg.id }`)); + return; + } + + delete this.pendingCalls[msg.id]; + + const err = msg.error ? new Error(`remote error: ${ msg.error }`) : null; + callback({result: msg.result || [], error: err}); + } + + stop() { + if (this.stopRequested) { + throw new Error('close already requested'); + } + if (!this.conn || this.conn.readyState === 'closed') { + throw new Error('connection already closed'); + } + this.stopRequested = true; + if (this.onClose) this.onClose(); + } + + call(method: string, ...params: Vals): Promise { + return new Promise((resolve, reject) => { + const id = this.nextId++; + + this.pendingCalls[id] = (result: CallResult) => { + if (result.error) { + reject(result.error); + } else { + resolve(result.result); + } + }; + try { + this.sendMsg({type: MsgType.Call, id, method, params}); + } catch (e) { + delete this.pendingCalls[id]; + reject(new Error(`send call: ${ e }`)); + } + }); + } + + protected raiseErr(err: Error): void { + if (this.onError) this.onError(err); + } +} + + +export class ParentIPC extends IPCCommon { + private readonly cmdPath: string; + private readonly cmdArgs: string[]; + private cmd: ChildProcess | null = null; + private readonly listener: net.Server; + + constructor(cmdPath: string, cmdArgs: string[], ...localApis: object[]) { + const socketPath = path.join(os.tmpdir(), `kitten-ipc-${ process.pid }.sock`); + super(localApis, socketPath); + + this.cmdPath = cmdPath; + if (cmdArgs.includes(`--${ IPC_SOCKET_ARG }`)) { + throw new Error(`you should not use '--${ IPC_SOCKET_ARG }' argument in your command`); + } + this.cmdArgs = cmdArgs; + + this.listener = net.createServer(); + } + + async start(): Promise { + try { + fs.unlinkSync(this.socketPath); + } catch { + } + + + await new Promise((resolve, reject) => { + this.listener.listen(this.socketPath, () => { + resolve(); + }); + this.listener.on('error', reject); + }); + + const cmdArgs = [...this.cmdArgs, `--${ IPC_SOCKET_ARG }`, this.socketPath]; + this.cmd = spawn(this.cmdPath, cmdArgs, {stdio: 'inherit'}); + + this.cmd.on('error', (err) => { + this.raiseErr(err); + }); + + this.acceptConn().catch(); + } + + private async acceptConn(): Promise { + const acceptTimeout = 10000; + + const acceptPromise = new Promise((resolve, reject) => { + this.listener.once('connection', (conn) => { + resolve(conn); + }); + this.listener.once('error', reject); + }); + + try { + this.conn = await timeout(acceptPromise, acceptTimeout); + this.readConn(); + } catch (e) { + if (this.cmd) this.cmd.kill(); + this.raiseErr(e as Error); + } + } + + async wait(): Promise { + return new Promise((resolve, reject) => { + if (!this.cmd) throw new Error('Command is not started yet'); + this.cmd.addListener('close', (code, signal) => { + if (signal || code) { + if (signal) reject(new Error(`Process exited with signal ${ signal }`)); + else reject(new Error(`Process exited with code ${ code }`)); + } else { + resolve(); + } + }); + this.onError = (err) => { + reject(err); + }; + }); + } +} + + +export class ChildIPC extends IPCCommon { + constructor(...localApis: object[]) { + super(localApis, socketPathFromArgs()); + } + + async start(): Promise { + return new Promise((resolve, reject) => { + this.conn = net.createConnection(this.socketPath, () => { + this.readConn(); + resolve(); + }); + this.conn.on('error', reject); + }); + } + + async wait(): Promise { + return new Promise((resolve, reject) => { + this.onError = (err) => { + reject(err); + }; + this.onClose = () => { + if (this.processingCalls === 0) { + this.conn?.destroy(); + resolve(); + } + }; + }); + } +} + + +function socketPathFromArgs(): string { + const {values} = util.parseArgs({ + options: { + [IPC_SOCKET_ARG]: { + type: 'string', + } + } + }); + + if (!values[IPC_SOCKET_ARG]) { + throw new Error('ipc socket path is missing'); + } + + return values[IPC_SOCKET_ARG]; +} + + +function sleep(ms: number): Promise { + return new Promise(resolve => setTimeout(resolve, ms)); +} + + +// throws on timeout +function timeout(prom: Promise, ms: number): Promise { + return Promise.race( + [prom, new Promise((res, reject) => setTimeout(reject, ms))] + ) as Promise; +} diff --git a/lib/ts/tsconfig.json b/lib/ts/tsconfig.json new file mode 100644 index 0000000..bc9d683 --- /dev/null +++ b/lib/ts/tsconfig.json @@ -0,0 +1,33 @@ +{ + // Visit https://aka.ms/tsconfig to read more about this file + "compilerOptions": { + "rootDir": "./src", + "outDir": "./dist", + + "module": "Node16", + "target": "ES2022", + "lib": ["ES2022"], + + "sourceMap": true, + "declaration": true, + "declarationMap": true, + + "strict": true, + "noUncheckedIndexedAccess": true, + "exactOptionalPropertyTypes": true, + "noImplicitReturns": true, + "noImplicitOverride": true, +// "noUnusedLocals": true, +// "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noPropertyAccessFromIndexSignature": true, + "noUncheckedSideEffectImports": true, + + "verbatimModuleSyntax": true, + "moduleDetection": "force", + // "isolatedModules": true, + // "skipLibCheck": true + }, + "include": ["src"], + "exclude": ["node_modules", "dist"], +}