ttsc 0.12.3 → 0.12.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cmd/platform/main.go +9 -0
- package/cmd/ttsc/api_compile.go +109 -101
- package/cmd/ttsc/api_compile_branches_test.go +55 -57
- package/cmd/ttsc/api_transform.go +54 -49
- package/cmd/ttsc/api_transform_branches_test.go +30 -32
- package/cmd/ttsc/build.go +111 -108
- package/cmd/ttsc/build_branches_test.go +95 -97
- package/cmd/ttsc/helpers_test.go +39 -28
- package/cmd/ttsc/main.go +111 -104
- package/cmd/ttsc/main_alias_branches_test.go +21 -23
- package/cmd/ttscserver/main.go +96 -90
- package/cmd/ttscserver/run_lsp_prefers_tsgo_flag_test.go +22 -22
- package/cmd/ttscserver/run_lsp_reports_server_error_test.go +22 -22
- package/cmd/ttscserver/run_lsp_uses_tsgo_environment_test.go +23 -23
- package/cmd/utility-host/main.go +30 -23
- package/driver/lsp.go +53 -7
- package/driver/plugins.go +88 -72
- package/driver/program.go +362 -339
- package/driver/rewrite.go +442 -380
- package/internal/lspserver/lsp_envelope.go +64 -64
- package/internal/lspserver/lsp_frame.go +60 -60
- package/internal/lspserver/lsp_plugin.go +57 -57
- package/internal/lspserver/lsp_proxy.go +265 -251
- package/internal/lspserver/lsp_server.go +155 -144
- package/lib/TtscCompiler.d.ts +7 -0
- package/lib/TtscCompiler.js +7 -0
- package/lib/TtscCompiler.js.map +1 -1
- package/lib/compiler/internal/buildNativeCompiler.d.ts +11 -1
- package/lib/compiler/internal/buildNativeCompiler.js +23 -3
- package/lib/compiler/internal/buildNativeCompiler.js.map +1 -1
- package/lib/compiler/internal/compileProjectInMemory.d.ts +9 -0
- package/lib/compiler/internal/compileProjectInMemory.js +36 -21
- package/lib/compiler/internal/compileProjectInMemory.js.map +1 -1
- package/lib/compiler/internal/paths.d.ts +27 -0
- package/lib/compiler/internal/paths.js +70 -0
- package/lib/compiler/internal/paths.js.map +1 -0
- package/lib/compiler/internal/project/readProjectConfig.d.ts +9 -1
- package/lib/compiler/internal/project/readProjectConfig.js +80 -1
- package/lib/compiler/internal/project/readProjectConfig.js.map +1 -1
- package/lib/compiler/internal/project/resolveProjectConfig.d.ts +13 -1
- package/lib/compiler/internal/project/resolveProjectConfig.js +24 -1
- package/lib/compiler/internal/project/resolveProjectConfig.js.map +1 -1
- package/lib/compiler/internal/resolveBinary.d.ts +9 -1
- package/lib/compiler/internal/resolveBinary.js +17 -1
- package/lib/compiler/internal/resolveBinary.js.map +1 -1
- package/lib/compiler/internal/resolveEmittedJavaScript.d.ts +16 -1
- package/lib/compiler/internal/resolveEmittedJavaScript.js +42 -10
- package/lib/compiler/internal/resolveEmittedJavaScript.js.map +1 -1
- package/lib/compiler/internal/resolveTsgo.d.ts +21 -1
- package/lib/compiler/internal/resolveTsgo.js +23 -1
- package/lib/compiler/internal/resolveTsgo.js.map +1 -1
- package/lib/compiler/internal/runBuild.d.ts +19 -0
- package/lib/compiler/internal/runBuild.js +112 -46
- package/lib/compiler/internal/runBuild.js.map +1 -1
- package/lib/compiler/internal/runSingleFileEmit.d.ts +10 -1
- package/lib/compiler/internal/runSingleFileEmit.js +14 -1
- package/lib/compiler/internal/runSingleFileEmit.js.map +1 -1
- package/lib/compiler/internal/sharedHostHelpers.d.ts +5 -0
- package/lib/compiler/internal/sharedHostHelpers.js +6 -2
- package/lib/compiler/internal/sharedHostHelpers.js.map +1 -1
- package/lib/compiler/internal/spawnNative.d.ts +21 -0
- package/lib/compiler/internal/spawnNative.js +59 -0
- package/lib/compiler/internal/spawnNative.js.map +1 -0
- package/lib/compiler/internal/transformProjectInMemory.d.ts +15 -1
- package/lib/compiler/internal/transformProjectInMemory.js +57 -61
- package/lib/compiler/internal/transformProjectInMemory.js.map +1 -1
- package/lib/launcher/internal/getCompilerVersionText.js +7 -0
- package/lib/launcher/internal/getCompilerVersionText.js.map +1 -1
- package/lib/launcher/internal/prepareExecution.js +32 -0
- package/lib/launcher/internal/prepareExecution.js.map +1 -1
- package/lib/launcher/internal/resolveCacheDir.d.ts +9 -0
- package/lib/launcher/internal/resolveCacheDir.js +22 -0
- package/lib/launcher/internal/resolveCacheDir.js.map +1 -0
- package/lib/launcher/internal/resolveTtscserverBinary.js +2 -0
- package/lib/launcher/internal/resolveTtscserverBinary.js.map +1 -1
- package/lib/launcher/internal/runTtsc.d.ts +10 -0
- package/lib/launcher/internal/runTtsc.js +22 -9
- package/lib/launcher/internal/runTtsc.js.map +1 -1
- package/lib/launcher/internal/runTtscserver.js +10 -35
- package/lib/launcher/internal/runTtscserver.js.map +1 -1
- package/lib/launcher/internal/runTtsx.d.ts +8 -0
- package/lib/launcher/internal/runTtsx.js +33 -7
- package/lib/launcher/internal/runTtsx.js.map +1 -1
- package/lib/plugin/internal/buildSourcePlugin.d.ts +38 -0
- package/lib/plugin/internal/buildSourcePlugin.js +40 -17
- package/lib/plugin/internal/buildSourcePlugin.js.map +1 -1
- package/lib/plugin/internal/loadProjectPlugins.d.ts +26 -0
- package/lib/plugin/internal/loadProjectPlugins.js +32 -18
- package/lib/plugin/internal/loadProjectPlugins.js.map +1 -1
- package/lib/structures/ITtscCompilerTransformation.d.ts +15 -2
- package/lib/structures/internal/TtscSingleFileEmitOptions.d.ts +0 -2
- package/package.json +9 -9
- package/shim/ast/shim.go +24 -0
- package/shim/checker/shim.go +35 -0
- package/shim/core/shim.go +17 -0
- package/shim/diagnosticwriter/shim.go +4 -0
- package/shim/lsp/shim.go +3 -3
- package/shim/printer/shim.go +20 -0
- package/src/TtscCompiler.ts +7 -0
- package/src/compiler/internal/buildNativeCompiler.ts +23 -3
- package/src/compiler/internal/compileProjectInMemory.ts +34 -25
- package/src/compiler/internal/paths.ts +68 -0
- package/src/compiler/internal/project/readProjectConfig.ts +86 -1
- package/src/compiler/internal/project/resolveProjectConfig.ts +24 -1
- package/src/compiler/internal/resolveBinary.ts +17 -1
- package/src/compiler/internal/resolveEmittedJavaScript.ts +43 -12
- package/src/compiler/internal/resolveTsgo.ts +29 -1
- package/src/compiler/internal/runBuild.ts +110 -55
- package/src/compiler/internal/runSingleFileEmit.ts +14 -1
- package/src/compiler/internal/sharedHostHelpers.ts +7 -7
- package/src/compiler/internal/spawnNative.ts +64 -0
- package/src/compiler/internal/transformProjectInMemory.ts +47 -67
- package/src/launcher/internal/getCompilerVersionText.ts +7 -0
- package/src/launcher/internal/prepareExecution.ts +32 -0
- package/src/launcher/internal/resolveCacheDir.ts +19 -0
- package/src/launcher/internal/resolveTtscserverBinary.ts +2 -0
- package/src/launcher/internal/runTtsc.ts +22 -10
- package/src/launcher/internal/runTtscserver.ts +9 -1
- package/src/launcher/internal/runTtsx.ts +33 -8
- package/src/plugin/internal/buildSourcePlugin.ts +40 -14
- package/src/plugin/internal/loadProjectPlugins.ts +42 -18
- package/src/structures/ITtscCompilerTransformation.ts +15 -2
- package/src/structures/ITtscPlugin.ts +0 -1
- package/src/structures/internal/TtscSingleFileEmitOptions.ts +0 -2
- package/tools/gen_shims/main.go +43 -8
- package/utility/host.go +294 -245
package/cmd/platform/main.go
CHANGED
|
@@ -34,6 +34,9 @@ func main() {
|
|
|
34
34
|
os.Exit(run(os.Args[1:]))
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
// run dispatches CLI arguments for the platform helper binary. With no
|
|
38
|
+
// arguments it prints the help text. build/check print an explanatory error
|
|
39
|
+
// directing users to the JavaScript launcher instead of failing silently.
|
|
37
40
|
func run(args []string) int {
|
|
38
41
|
if len(args) == 0 {
|
|
39
42
|
printHelp(stdout)
|
|
@@ -91,6 +94,9 @@ Usage:
|
|
|
91
94
|
`))
|
|
92
95
|
}
|
|
93
96
|
|
|
97
|
+
// runDemo implements the demo sub-command, printing a synthetic JavaScript
|
|
98
|
+
// arrow function for the requested atomic type. Smoke tests in CI invoke this
|
|
99
|
+
// to verify the binary executes correctly.
|
|
94
100
|
func runDemo(args []string) int {
|
|
95
101
|
fs := flag.NewFlagSet("demo", flag.ContinueOnError)
|
|
96
102
|
fs.SetOutput(stderr)
|
|
@@ -110,6 +116,9 @@ func runDemo(args []string) int {
|
|
|
110
116
|
return 0
|
|
111
117
|
}
|
|
112
118
|
|
|
119
|
+
// demoArrow returns a JavaScript arrow-function expression for the named
|
|
120
|
+
// atomic TypeScript type. It is the platform-helper counterpart of the same
|
|
121
|
+
// function in cmd/ttsc, kept separate to avoid a shared-binary dependency.
|
|
113
122
|
func demoArrow(name string) (string, error) {
|
|
114
123
|
switch strings.ToLower(name) {
|
|
115
124
|
case "any":
|
package/cmd/ttsc/api_compile.go
CHANGED
|
@@ -7,24 +7,24 @@
|
|
|
7
7
|
package main
|
|
8
8
|
|
|
9
9
|
import (
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
"encoding/json"
|
|
11
|
+
"flag"
|
|
12
|
+
"fmt"
|
|
13
|
+
"path/filepath"
|
|
14
|
+
"strings"
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
shimcompiler "github.com/microsoft/typescript-go/shim/compiler"
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
"github.com/samchon/ttsc/packages/ttsc/driver"
|
|
19
|
+
cwdutil "github.com/samchon/ttsc/packages/ttsc/internal/cwd"
|
|
20
20
|
)
|
|
21
21
|
|
|
22
22
|
type apiCompileResult struct {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
// Diagnostics is omitted only when the compiler produced no diagnostics.
|
|
24
|
+
// Output is still returned in diagnostic cases because TypeScript-Go may
|
|
25
|
+
// produce partial emit text before a build-failing error is reported.
|
|
26
|
+
Diagnostics []apiCompileDiagnostic `json:"diagnostics,omitempty"`
|
|
27
|
+
Output map[string]string `json:"output"`
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
// apiCompileDiagnostic mirrors the public TypeScript-side diagnostic DTO.
|
|
@@ -32,109 +32,117 @@ type apiCompileResult struct {
|
|
|
32
32
|
// `character`) instead of Go naming so callers can pass the data through
|
|
33
33
|
// without remapping.
|
|
34
34
|
type apiCompileDiagnostic struct {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
35
|
+
File *string `json:"file"`
|
|
36
|
+
Category string `json:"category"`
|
|
37
|
+
Code int32 `json:"code"`
|
|
38
|
+
Start *int `json:"start,omitempty"`
|
|
39
|
+
Length *int `json:"length,omitempty"`
|
|
40
|
+
Line int `json:"line,omitempty"`
|
|
41
|
+
Character int `json:"character,omitempty"`
|
|
42
|
+
MessageText string `json:"messageText"`
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
func runAPICompile(args []string) int {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
46
|
+
fs := flag.NewFlagSet("api-compile", flag.ContinueOnError)
|
|
47
|
+
fs.SetOutput(stderr)
|
|
48
|
+
tsconfigPath := fs.String("tsconfig", "tsconfig.json", "path to tsconfig.json")
|
|
49
|
+
cwdOverride := fs.String("cwd", "", "override the working directory")
|
|
50
|
+
if err := fs.Parse(args); err != nil {
|
|
51
|
+
return 2
|
|
52
|
+
}
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
cwd, err := cwdutil.Resolve(*cwdOverride, getwd)
|
|
55
|
+
if err != nil {
|
|
56
|
+
fmt.Fprintf(stderr, "ttsc: %v\n", err)
|
|
57
|
+
return 2
|
|
58
|
+
}
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
60
|
+
prog, diags, err := driver.LoadProgram(cwd, *tsconfigPath, driver.LoadProgramOptions{
|
|
61
|
+
ForceEmit: true,
|
|
62
|
+
})
|
|
63
|
+
if err != nil {
|
|
64
|
+
fmt.Fprintf(stderr, "ttsc api-compile: %v\n", err)
|
|
65
|
+
return 2
|
|
66
|
+
}
|
|
67
|
+
if prog != nil {
|
|
68
|
+
defer prog.Close()
|
|
69
|
+
diags = append(diags, prog.Diagnostics()...)
|
|
70
|
+
}
|
|
71
71
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
72
|
+
output := map[string]string{}
|
|
73
|
+
if prog != nil {
|
|
74
|
+
rewrites := driver.NewRewriteSet()
|
|
75
|
+
// Capture WriteFile output in a map keyed by project-relative paths. This
|
|
76
|
+
// gives the JS API a deterministic object and avoids touching outDir.
|
|
77
|
+
writeFile := shimcompiler.WriteFile(
|
|
78
|
+
func(fileName, text string, _ *shimcompiler.WriteFileData) error {
|
|
79
|
+
output[apiOutputKey(cwd, fileName)] = text
|
|
80
|
+
return nil
|
|
81
|
+
},
|
|
82
|
+
)
|
|
83
|
+
_, emitDiags, err := prog.EmitAll(rewrites, writeFile)
|
|
84
|
+
if err != nil {
|
|
85
|
+
fmt.Fprintf(stderr, "ttsc api-compile: emit failed: %v\n", err)
|
|
86
|
+
return 3
|
|
87
|
+
}
|
|
88
|
+
diags = append(diags, emitDiags...)
|
|
89
|
+
}
|
|
90
90
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
91
|
+
result := apiCompileResult{
|
|
92
|
+
Diagnostics: make([]apiCompileDiagnostic, 0, len(diags)),
|
|
93
|
+
Output: output,
|
|
94
|
+
}
|
|
95
|
+
for _, diag := range diags {
|
|
96
|
+
result.Diagnostics = append(result.Diagnostics, toAPICompileDiagnostic(diag))
|
|
97
|
+
}
|
|
98
98
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
99
|
+
data, _ := json.Marshal(result)
|
|
100
|
+
fmt.Fprintln(stdout, string(data))
|
|
101
|
+
if driver.CountErrors(diags) > 0 {
|
|
102
|
+
return 2
|
|
103
|
+
}
|
|
104
|
+
return 0
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
+
// toAPICompileDiagnostic converts an internal driver.Diagnostic into the
|
|
108
|
+
// JSON-serialisable form returned by the api-compile command. Category is
|
|
109
|
+
// lowercased to match the TypeScript Language Service convention.
|
|
107
110
|
func toAPICompileDiagnostic(diag driver.Diagnostic) apiCompileDiagnostic {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
111
|
+
var file *string
|
|
112
|
+
if diag.File != "" {
|
|
113
|
+
value := diag.File
|
|
114
|
+
file = &value
|
|
115
|
+
}
|
|
116
|
+
category := "error"
|
|
117
|
+
if diag.Severity == driver.SeverityWarning {
|
|
118
|
+
category = "warning"
|
|
119
|
+
}
|
|
120
|
+
return apiCompileDiagnostic{
|
|
121
|
+
File: file,
|
|
122
|
+
Category: category,
|
|
123
|
+
Code: diag.Code,
|
|
124
|
+
Start: diag.Start,
|
|
125
|
+
Length: diag.Length,
|
|
126
|
+
Line: diag.Line,
|
|
127
|
+
Character: diag.Column,
|
|
128
|
+
MessageText: diag.Message,
|
|
129
|
+
}
|
|
127
130
|
}
|
|
128
131
|
|
|
132
|
+
// apiOutputKey returns the map key used in the api-compile result for a
|
|
133
|
+
// generated file. Files inside cwd use a slash-separated relative path (the
|
|
134
|
+
// API contract). Files outside cwd — rare, e.g. a monorepo output rooted
|
|
135
|
+
// above the project — are returned as an absolute slash path instead.
|
|
129
136
|
func apiOutputKey(cwd, fileName string) string {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
return filepath.ToSlash(fileName)
|
|
137
|
+
if rel, err := filepath.Rel(cwd, fileName); err == nil && !isOutsideRelativePath(rel) {
|
|
138
|
+
return filepath.ToSlash(rel)
|
|
139
|
+
}
|
|
140
|
+
return filepath.ToSlash(fileName)
|
|
136
141
|
}
|
|
137
142
|
|
|
143
|
+
// isOutsideRelativePath reports whether the result of filepath.Rel points
|
|
144
|
+
// above the base directory (starts with ".."), meaning the file lives outside
|
|
145
|
+
// the project root and cannot safely be expressed as a project-relative path.
|
|
138
146
|
func isOutsideRelativePath(rel string) bool {
|
|
139
|
-
|
|
147
|
+
return rel == ".." || strings.HasPrefix(rel, ".."+string(filepath.Separator))
|
|
140
148
|
}
|
|
@@ -1,81 +1,79 @@
|
|
|
1
1
|
package main
|
|
2
2
|
|
|
3
3
|
import (
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
"errors"
|
|
5
|
+
"strings"
|
|
6
|
+
"testing"
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
"github.com/samchon/ttsc/packages/ttsc/driver"
|
|
9
9
|
)
|
|
10
10
|
|
|
11
11
|
type apiCompileApplyErrorPlugin struct{}
|
|
12
12
|
|
|
13
13
|
func (apiCompileApplyErrorPlugin) ApplyProgram(*driver.Program, driver.PluginContext) error {
|
|
14
|
-
|
|
14
|
+
return errors.New("api compile apply boom")
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
* 3. Assert linked ApplyProgram errors surface through the emit branch.
|
|
27
|
-
*/
|
|
17
|
+
// TestAPICompileBranches verifies api-compile handles parse, cwd, diagnostic, and emit failures.
|
|
18
|
+
//
|
|
19
|
+
// The JSON API path is used by the JS wrapper, so its command entrypoint must
|
|
20
|
+
// return stable status codes for wrapper misuse, project diagnostics, and
|
|
21
|
+
// linked transform failures.
|
|
22
|
+
//
|
|
23
|
+
// 1. Exercise bad flags and a failing cwd resolver.
|
|
24
|
+
// 2. Compile missing and type-invalid projects.
|
|
25
|
+
// 3. Assert linked ApplyProgram errors surface through the emit branch.
|
|
28
26
|
func TestAPICompileBranches(t *testing.T) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
27
|
+
code, _, _ := captureCommand(t, func() int {
|
|
28
|
+
return runAPICompile([]string{"--cwd"})
|
|
29
|
+
})
|
|
30
|
+
if code != 2 {
|
|
31
|
+
t.Fatalf("bad flag status mismatch: %d", code)
|
|
32
|
+
}
|
|
35
33
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
34
|
+
code, _, errText := captureCommand(t, func() int {
|
|
35
|
+
getwd = failGetwd
|
|
36
|
+
return runAPICompile(nil)
|
|
37
|
+
})
|
|
38
|
+
if code != 2 || !strings.Contains(errText, "cwd boom") {
|
|
39
|
+
t.Fatalf("cwd error mismatch: code=%d stderr=%q", code, errText)
|
|
40
|
+
}
|
|
43
41
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
42
|
+
root := t.TempDir()
|
|
43
|
+
code, _, errText = captureCommand(t, func() int {
|
|
44
|
+
return runAPICompile([]string{"--cwd", root, "--tsconfig", "missing.json"})
|
|
45
|
+
})
|
|
46
|
+
if code != 2 || !strings.Contains(errText, "tsconfig not found") {
|
|
47
|
+
t.Fatalf("missing config mismatch: code=%d stderr=%q", code, errText)
|
|
48
|
+
}
|
|
51
49
|
|
|
52
|
-
|
|
50
|
+
writeCommandProjectFile(t, root, "tsconfig.json", `{
|
|
53
51
|
"compilerOptions": { "module": "commonjs", "target": "es2020", "strict": true },
|
|
54
52
|
"files": ["index.ts"]
|
|
55
53
|
}
|
|
56
54
|
`)
|
|
57
|
-
|
|
55
|
+
writeCommandProjectFile(t, root, "index.ts", `const value: number = "text";
|
|
58
56
|
export { value };
|
|
59
57
|
`)
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
58
|
+
code, out, _ := captureCommand(t, func() int {
|
|
59
|
+
return runAPICompile([]string{"--cwd", root, "--tsconfig", "tsconfig.json"})
|
|
60
|
+
})
|
|
61
|
+
if code != 2 || !strings.Contains(out, `"diagnostics"`) {
|
|
62
|
+
t.Fatalf("diagnostic compile mismatch: code=%d stdout=%q", code, out)
|
|
63
|
+
}
|
|
64
|
+
if got := toAPICompileDiagnostic(driver.Diagnostic{Severity: driver.SeverityWarning}).Category; got != "warning" {
|
|
65
|
+
t.Fatalf("warning category mismatch: %q", got)
|
|
66
|
+
}
|
|
69
67
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
68
|
+
resetCommandLinkedPluginRegistry()
|
|
69
|
+
driver.RegisterPlugin(apiCompileApplyErrorPlugin{})
|
|
70
|
+
t.Setenv(driver.LinkedPluginsEnv, `[{"name":"error","stage":"transform","config":{}}]`)
|
|
71
|
+
writeCommandProjectFile(t, root, "index.ts", `export const value = 1;
|
|
74
72
|
`)
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
73
|
+
code, _, errText = captureCommand(t, func() int {
|
|
74
|
+
return runAPICompile([]string{"--cwd", root, "--tsconfig", "tsconfig.json"})
|
|
75
|
+
})
|
|
76
|
+
if code != 3 || !strings.Contains(errText, "api compile apply boom") {
|
|
77
|
+
t.Fatalf("emit error mismatch: code=%d stderr=%q", code, errText)
|
|
78
|
+
}
|
|
81
79
|
}
|
|
@@ -7,64 +7,69 @@
|
|
|
7
7
|
package main
|
|
8
8
|
|
|
9
9
|
import (
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
"encoding/json"
|
|
11
|
+
"flag"
|
|
12
|
+
"fmt"
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
"github.com/samchon/ttsc/packages/ttsc/driver"
|
|
15
|
+
cwdutil "github.com/samchon/ttsc/packages/ttsc/internal/cwd"
|
|
16
16
|
)
|
|
17
17
|
|
|
18
18
|
type apiTransformResult struct {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
// TypeScript contains every non-library source file visible through the
|
|
20
|
+
// Program facade, keyed the same way api-compile keys emitted files.
|
|
21
|
+
Diagnostics []apiCompileDiagnostic `json:"diagnostics,omitempty"`
|
|
22
|
+
TypeScript map[string]string `json:"typescript"`
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
// runAPITransform implements the `api-transform` sub-command. It loads the
|
|
26
|
+
// TypeScript program in no-emit mode and returns the source text of every
|
|
27
|
+
// non-library file as a JSON object, keyed by the same relative-path
|
|
28
|
+
// convention as api-compile. Diagnostics are included; partial results are
|
|
29
|
+
// returned even when diagnostics are present.
|
|
25
30
|
func runAPITransform(args []string) int {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
fs := flag.NewFlagSet("api-transform", flag.ContinueOnError)
|
|
32
|
+
fs.SetOutput(stderr)
|
|
33
|
+
tsconfigPath := fs.String("tsconfig", "tsconfig.json", "path to tsconfig.json")
|
|
34
|
+
cwdOverride := fs.String("cwd", "", "override the working directory")
|
|
35
|
+
if err := fs.Parse(args); err != nil {
|
|
36
|
+
return 2
|
|
37
|
+
}
|
|
33
38
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
cwd, err := cwdutil.Resolve(*cwdOverride, getwd)
|
|
40
|
+
if err != nil {
|
|
41
|
+
fmt.Fprintf(stderr, "ttsc: %v\n", err)
|
|
42
|
+
return 2
|
|
43
|
+
}
|
|
39
44
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
45
|
+
prog, diags, err := driver.LoadProgram(cwd, *tsconfigPath, driver.LoadProgramOptions{
|
|
46
|
+
ForceNoEmit: true,
|
|
47
|
+
})
|
|
48
|
+
if err != nil {
|
|
49
|
+
fmt.Fprintf(stderr, "ttsc api-transform: %v\n", err)
|
|
50
|
+
return 2
|
|
51
|
+
}
|
|
52
|
+
typescript := map[string]string{}
|
|
53
|
+
if prog != nil {
|
|
54
|
+
defer prog.Close()
|
|
55
|
+
for _, file := range prog.SourceFiles() {
|
|
56
|
+
typescript[apiOutputKey(cwd, file.FileName())] = file.Text()
|
|
57
|
+
}
|
|
58
|
+
diags = append(diags, prog.Diagnostics()...)
|
|
59
|
+
}
|
|
55
60
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
result := apiTransformResult{
|
|
62
|
+
Diagnostics: make([]apiCompileDiagnostic, 0, len(diags)),
|
|
63
|
+
TypeScript: typescript,
|
|
64
|
+
}
|
|
65
|
+
for _, diag := range diags {
|
|
66
|
+
result.Diagnostics = append(result.Diagnostics, toAPICompileDiagnostic(diag))
|
|
67
|
+
}
|
|
63
68
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
69
|
+
data, _ := json.Marshal(result)
|
|
70
|
+
fmt.Fprintln(stdout, string(data))
|
|
71
|
+
if driver.CountErrors(diags) > 0 {
|
|
72
|
+
return 2
|
|
73
|
+
}
|
|
74
|
+
return 0
|
|
70
75
|
}
|
|
@@ -1,41 +1,39 @@
|
|
|
1
1
|
package main
|
|
2
2
|
|
|
3
3
|
import (
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
"strings"
|
|
5
|
+
"testing"
|
|
6
6
|
)
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
* 3. Point the API at a missing tsconfig.
|
|
18
|
-
*/
|
|
8
|
+
// TestAPITransformBranches verifies api-transform rejects invalid command and project setup.
|
|
9
|
+
//
|
|
10
|
+
// Source-to-source API callers need the same stable wrapper diagnostics as the
|
|
11
|
+
// compile API, but without touching emit. These branches are command-frontdoor
|
|
12
|
+
// behavior rather than TypeScript-Go internals.
|
|
13
|
+
//
|
|
14
|
+
// 1. Pass an incomplete flag.
|
|
15
|
+
// 2. Force cwd resolution to fail.
|
|
16
|
+
// 3. Point the API at a missing tsconfig.
|
|
19
17
|
func TestAPITransformBranches(t *testing.T) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
18
|
+
code, _, _ := captureCommand(t, func() int {
|
|
19
|
+
return runAPITransform([]string{"--cwd"})
|
|
20
|
+
})
|
|
21
|
+
if code != 2 {
|
|
22
|
+
t.Fatalf("bad flag status mismatch: %d", code)
|
|
23
|
+
}
|
|
26
24
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
25
|
+
code, _, errText := captureCommand(t, func() int {
|
|
26
|
+
getwd = failGetwd
|
|
27
|
+
return runAPITransform(nil)
|
|
28
|
+
})
|
|
29
|
+
if code != 2 || !strings.Contains(errText, "cwd boom") {
|
|
30
|
+
t.Fatalf("cwd error mismatch: code=%d stderr=%q", code, errText)
|
|
31
|
+
}
|
|
34
32
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
33
|
+
code, _, errText = captureCommand(t, func() int {
|
|
34
|
+
return runAPITransform([]string{"--cwd", t.TempDir(), "--tsconfig", "missing.json"})
|
|
35
|
+
})
|
|
36
|
+
if code != 2 || !strings.Contains(errText, "tsconfig not found") {
|
|
37
|
+
t.Fatalf("missing config mismatch: code=%d stderr=%q", code, errText)
|
|
38
|
+
}
|
|
41
39
|
}
|