typia 13.0.0-dev.20260509 → 13.0.0-dev.20260510

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/native/adapter/adapter.go +3 -3
  2. package/native/go.mod +0 -4
  3. package/native/internal/printer/printer.go +229 -0
  4. package/package.json +6 -6
  5. package/native/go.work +0 -20
  6. package/native/go.work.sum +0 -11
  7. package/native/shim/printer/go.mod +0 -5
  8. package/native/shim/printer/shim.go +0 -249
  9. package/native/third_party/ttsc/driver/host.go +0 -31
  10. package/native/third_party/ttsc/driver/program.go +0 -466
  11. package/native/third_party/ttsc/driver/rewrite.go +0 -341
  12. package/native/third_party/ttsc/go.mod +0 -48
  13. package/native/third_party/ttsc/go.sum +0 -22
  14. package/native/third_party/ttsc/shim/ast/extra-shim.json +0 -4
  15. package/native/third_party/ttsc/shim/ast/go.mod +0 -5
  16. package/native/third_party/ttsc/shim/ast/lint.go +0 -331
  17. package/native/third_party/ttsc/shim/ast/shim.go +0 -210
  18. package/native/third_party/ttsc/shim/bundled/extra-shim.json +0 -1
  19. package/native/third_party/ttsc/shim/bundled/go.mod +0 -5
  20. package/native/third_party/ttsc/shim/bundled/shim.go +0 -23
  21. package/native/third_party/ttsc/shim/checker/extra-shim.json +0 -31
  22. package/native/third_party/ttsc/shim/checker/go.mod +0 -5
  23. package/native/third_party/ttsc/shim/checker/shim.go +0 -166
  24. package/native/third_party/ttsc/shim/compiler/extra-shim.json +0 -4
  25. package/native/third_party/ttsc/shim/compiler/go.mod +0 -5
  26. package/native/third_party/ttsc/shim/compiler/shim.go +0 -65
  27. package/native/third_party/ttsc/shim/core/extra-shim.json +0 -4
  28. package/native/third_party/ttsc/shim/core/go.mod +0 -5
  29. package/native/third_party/ttsc/shim/core/shim.go +0 -29
  30. package/native/third_party/ttsc/shim/diagnosticwriter/go.mod +0 -5
  31. package/native/third_party/ttsc/shim/diagnosticwriter/lint.go +0 -137
  32. package/native/third_party/ttsc/shim/diagnosticwriter/shim.go +0 -29
  33. package/native/third_party/ttsc/shim/parser/extra-shim.json +0 -4
  34. package/native/third_party/ttsc/shim/parser/go.mod +0 -5
  35. package/native/third_party/ttsc/shim/parser/shim.go +0 -61
  36. package/native/third_party/ttsc/shim/scanner/extra-shim.json +0 -4
  37. package/native/third_party/ttsc/shim/scanner/go.mod +0 -5
  38. package/native/third_party/ttsc/shim/scanner/shim.go +0 -134
  39. package/native/third_party/ttsc/shim/tsoptions/extra-shim.json +0 -4
  40. package/native/third_party/ttsc/shim/tsoptions/go.mod +0 -5
  41. package/native/third_party/ttsc/shim/tsoptions/shim.go +0 -173
  42. package/native/third_party/ttsc/shim/tspath/extra-shim.json +0 -4
  43. package/native/third_party/ttsc/shim/tspath/go.mod +0 -5
  44. package/native/third_party/ttsc/shim/tspath/shim.go +0 -236
  45. package/native/third_party/ttsc/shim/vfs/cachedvfs/extra-shim.json +0 -4
  46. package/native/third_party/ttsc/shim/vfs/cachedvfs/go.mod +0 -5
  47. package/native/third_party/ttsc/shim/vfs/cachedvfs/shim.go +0 -12
  48. package/native/third_party/ttsc/shim/vfs/extra-shim.json +0 -4
  49. package/native/third_party/ttsc/shim/vfs/go.mod +0 -5
  50. package/native/third_party/ttsc/shim/vfs/osvfs/extra-shim.json +0 -4
  51. package/native/third_party/ttsc/shim/vfs/osvfs/go.mod +0 -5
  52. package/native/third_party/ttsc/shim/vfs/osvfs/shim.go +0 -13
  53. package/native/third_party/ttsc/shim/vfs/shim.go +0 -22
@@ -1,466 +0,0 @@
1
- package driver
2
-
3
- import (
4
- "context"
5
- "errors"
6
- "fmt"
7
- "io"
8
- "path/filepath"
9
- "strings"
10
- "time"
11
-
12
- "github.com/microsoft/typescript-go/shim/ast"
13
- shimchecker "github.com/microsoft/typescript-go/shim/checker"
14
- shimcompiler "github.com/microsoft/typescript-go/shim/compiler"
15
- "github.com/microsoft/typescript-go/shim/core"
16
- shimdiagnosticwriter "github.com/microsoft/typescript-go/shim/diagnosticwriter"
17
- shimscanner "github.com/microsoft/typescript-go/shim/scanner"
18
- "github.com/microsoft/typescript-go/shim/tsoptions"
19
- "github.com/microsoft/typescript-go/shim/tspath"
20
- "github.com/microsoft/typescript-go/shim/vfs"
21
- )
22
-
23
- // Diagnostic is the compilation diagnostic shape ttsc passes around. Kept
24
- // dependency-free (no shim types) so callers can render or inspect freely.
25
- //
26
- // `raw` carries the original tsgo diagnostic for full color/context
27
- // rendering. `lint` carries a plugin-emitted lint diagnostic when the
28
- // diagnostic was produced outside the typecheck pipeline (e.g. by
29
- // `@ttsc/lint`). At most one of `raw` / `lint` is non-nil; both nil falls
30
- // back to the legacy single-line form.
31
- type Diagnostic struct {
32
- File string
33
- Line int
34
- Column int
35
- Code int32
36
- Start *int
37
- Length *int
38
- Message string
39
- Severity Severity
40
- raw *ast.Diagnostic
41
- lint *shimdiagnosticwriter.LintDiagnostic
42
- }
43
-
44
- // Severity classifies a diagnostic's blast radius. ttsc treats Error as a
45
- // build-failing condition; Warning prints but does not flip the exit code.
46
- type Severity int
47
-
48
- const (
49
- // SeverityError is the default for tsgo typecheck output and any
50
- // plugin-emitted finding that should fail the build.
51
- SeverityError Severity = iota
52
- // SeverityWarning prints with warning coloring but keeps the build
53
- // status at zero.
54
- SeverityWarning
55
- )
56
-
57
- // IsError reports whether the diagnostic counts toward the build's error
58
- // total. Useful when plugins want to gate emit on the lint outcome without
59
- // re-walking the diagnostic list.
60
- func (d Diagnostic) IsError() bool { return d.Severity == SeverityError }
61
-
62
- // NewLintDiagnostic shapes a plugin finding so it renders alongside tsgo
63
- // diagnostics with full color / source context. `pos` and `end` are byte
64
- // offsets into the source file; `code` is a stable rule identifier (e.g. the
65
- // rule's enum index). Severity controls both the rendered banner color and
66
- // the exit-code outcome.
67
- func NewLintDiagnostic(
68
- file *ast.SourceFile,
69
- pos, end int,
70
- code int32,
71
- severity Severity,
72
- message string,
73
- ) Diagnostic {
74
- cat := shimdiagnosticwriter.LintCategoryError
75
- if severity == SeverityWarning {
76
- cat = shimdiagnosticwriter.LintCategoryWarning
77
- }
78
- lint := shimdiagnosticwriter.NewLintDiagnostic(file, pos, end, code, cat, message)
79
- d := Diagnostic{
80
- Code: code,
81
- Message: message,
82
- Severity: severity,
83
- lint: lint,
84
- }
85
- if file != nil {
86
- d.File = file.FileName()
87
- if pos >= 0 {
88
- length := end - pos
89
- d.Start = &pos
90
- d.Length = &length
91
- line, col := shimscanner.GetECMALineAndByteOffsetOfPosition(file, pos)
92
- d.Line = line + 1
93
- d.Column = col + 1
94
- }
95
- }
96
- return d
97
- }
98
-
99
- // SourceFile returns the program source file matching filename.
100
- func (p *Program) SourceFile(filename string) *ast.SourceFile {
101
- if p == nil || p.TSProgram == nil {
102
- return nil
103
- }
104
- normalized := filepath.ToSlash(filename)
105
- for _, file := range p.TSProgram.SourceFiles() {
106
- if filepath.ToSlash(file.FileName()) == normalized {
107
- return file
108
- }
109
- }
110
- return nil
111
- }
112
-
113
- // String returns a `path:line:col: message` formatted string.
114
- func (d Diagnostic) String() string {
115
- if d.File == "" {
116
- return d.Message
117
- }
118
- if d.Line > 0 {
119
- return fmt.Sprintf("%s:%d:%d: %s", d.File, d.Line, d.Column, d.Message)
120
- }
121
- return fmt.Sprintf("%s: %s", d.File, d.Message)
122
- }
123
-
124
- // WritePrettyDiagnostics renders diagnostics with TypeScript-style colors,
125
- // source snippets and the trailing error summary when raw tsgo or lint
126
- // diagnostic objects are available. Mixed batches (e.g. typecheck + lint)
127
- // are rendered through the same color/context pipeline; entries without
128
- // either anchor fall back to the legacy `path:line:col: message` form.
129
- func WritePrettyDiagnostics(w io.Writer, diagnostics []Diagnostic, cwd string) {
130
- if len(diagnostics) == 0 {
131
- return
132
- }
133
- rich := make([]Diagnostic, 0, len(diagnostics))
134
- plain := make([]Diagnostic, 0)
135
- for _, d := range diagnostics {
136
- if d.raw != nil || d.lint != nil {
137
- rich = append(rich, d)
138
- } else {
139
- plain = append(plain, d)
140
- }
141
- }
142
- if len(rich) > 0 {
143
- astDiags := make([]*ast.Diagnostic, 0, len(rich))
144
- lintDiags := make([]*shimdiagnosticwriter.LintDiagnostic, 0, len(rich))
145
- for _, d := range rich {
146
- if d.raw != nil {
147
- astDiags = append(astDiags, d.raw)
148
- }
149
- if d.lint != nil {
150
- lintDiags = append(lintDiags, d.lint)
151
- }
152
- }
153
- shimdiagnosticwriter.FormatMixedDiagnostics(w, astDiags, lintDiags, cwd)
154
- }
155
- for _, d := range plain {
156
- fmt.Fprintln(w, " -", d.String())
157
- }
158
- }
159
-
160
- // CountErrors returns the number of diagnostics that should fail the build.
161
- // tsgo diagnostics carry their own `Error` category; lint diagnostics carry a
162
- // caller-set Severity. Anything that isn't an explicit warning counts.
163
- func CountErrors(diagnostics []Diagnostic) int {
164
- n := 0
165
- for _, d := range diagnostics {
166
- if d.lint != nil {
167
- if d.lint.IsError() {
168
- n++
169
- }
170
- continue
171
- }
172
- if d.raw != nil {
173
- // tsgo diagnostics use the diagnostics package category. The
174
- // renderer shim already mirrors the same Error/Warning split, so
175
- // re-categorize via the public IsError shortcut.
176
- if d.Severity != SeverityWarning {
177
- n++
178
- }
179
- continue
180
- }
181
- // Plain text diagnostics (manually assembled): treat as errors so
182
- // "ttsc: tsconfig not found"-style failures still flip the exit code.
183
- n++
184
- }
185
- return n
186
- }
187
-
188
- // Program is the shim-agnostic facade the rest of the engine sees.
189
- type Program struct {
190
- TSProgram *shimcompiler.Program
191
- ParsedConfig *tsoptions.ParsedCommandLine
192
- Checker *shimchecker.Checker
193
- checkerRelease func()
194
- Host shimcompiler.CompilerHost
195
- FS vfs.FS
196
- }
197
-
198
- // LoadProgramOptions controls tsconfig overrides applied before tsgo creates
199
- // the program. `ForceEmit` is used by `ttsc --emit` and runtime compilation
200
- // so execution still works when the project defaults to `noEmit`.
201
- type LoadProgramOptions struct {
202
- ForceEmit bool
203
- ForceNoEmit bool
204
- OutDir string
205
- SourcePreamble string
206
- }
207
-
208
- // Close releases the checker pool lease acquired by LoadProgram.
209
- func (p *Program) Close() error {
210
- if p.checkerRelease != nil {
211
- p.checkerRelease()
212
- p.checkerRelease = nil
213
- }
214
- return nil
215
- }
216
-
217
- // ParseTSConfig parses a tsconfig.json file via tsgo's native JSONC parser.
218
- // Comments, trailing commas, and `extends` chains are handled automatically.
219
- //
220
- // The absolute path is resolved against cwd before any VFS lookups because
221
- // tsgo's filesystem APIs require absolute paths — mirrors what tsc does when
222
- // you pass a relative `--project` flag.
223
- func ParseTSConfig(fs vfs.FS, cwd, tsconfigPath string, host shimcompiler.CompilerHost) (*tsoptions.ParsedCommandLine, []Diagnostic, error) {
224
- resolved := tspath.ResolvePath(cwd, tsconfigPath)
225
- if !fs.FileExists(resolved) {
226
- return nil, nil, fmt.Errorf("tsconfig not found: %s", resolved)
227
- }
228
- parsed, diags := tsoptions.GetParsedCommandLineOfConfigFile(resolved, &core.CompilerOptions{}, nil, host, nil)
229
- if len(diags) > 0 {
230
- return nil, convertDiagnostics(diags), nil
231
- }
232
- if parsed == nil {
233
- return nil, nil, errors.New("tsoptions: parsed command line was nil")
234
- }
235
- if len(parsed.Errors) > 0 {
236
- return nil, convertDiagnostics(parsed.Errors), nil
237
- }
238
- return parsed, nil, nil
239
- }
240
-
241
- // CreateProgramFromConfig builds a tsgo Program from the parsed config.
242
- func CreateProgramFromConfig(parsed *tsoptions.ParsedCommandLine, host shimcompiler.CompilerHost) (*shimcompiler.Program, []Diagnostic, error) {
243
- opts := shimcompiler.ProgramOptions{
244
- Config: parsed,
245
- SingleThreaded: core.TSTrue,
246
- Host: host,
247
- UseSourceOfProjectReference: true,
248
- }
249
- p := shimcompiler.NewProgram(opts)
250
- if p == nil {
251
- return nil, nil, errors.New("shimcompiler.NewProgram returned nil")
252
- }
253
- return p, nil, nil
254
- }
255
-
256
- // LoadProgram is the one-shot convenience used by `ttsc`.
257
- // It parses the tsconfig, creates a program and a type-checker, and returns
258
- // the wrapped facade.
259
- //
260
- // cwd must be absolute; tsconfigPath may be relative to cwd.
261
- func LoadProgram(cwd, tsconfigPath string, options LoadProgramOptions) (*Program, []Diagnostic, error) {
262
- if !filepath.IsAbs(cwd) {
263
- if abs, err := filepath.Abs(cwd); err == nil {
264
- cwd = abs
265
- }
266
- }
267
- cwd = tspath.ResolvePath(cwd)
268
- fs := DefaultFS()
269
- if options.SourcePreamble != "" {
270
- fs = sourcePreambleFS{
271
- FS: fs,
272
- preamble: options.SourcePreamble,
273
- }
274
- }
275
- host := DefaultHost(cwd, fs)
276
-
277
- parsed, diags, err := ParseTSConfig(fs, cwd, tsconfigPath, host)
278
- if err != nil {
279
- return nil, nil, err
280
- }
281
- if len(diags) > 0 {
282
- return nil, diags, nil
283
- }
284
- if options.ForceNoEmit {
285
- forceNoEmit(parsed)
286
- }
287
- if options.ForceEmit {
288
- forceEmit(parsed)
289
- }
290
- if options.OutDir != "" {
291
- overrideOutDir(cwd, parsed, options.OutDir)
292
- }
293
-
294
- tsProgram, progDiags, err := CreateProgramFromConfig(parsed, host)
295
- if err != nil {
296
- return nil, nil, err
297
- }
298
- if len(progDiags) > 0 {
299
- return nil, progDiags, nil
300
- }
301
-
302
- checker, done := tsProgram.GetTypeChecker(context.Background())
303
- return &Program{
304
- TSProgram: tsProgram,
305
- ParsedConfig: parsed,
306
- Checker: checker,
307
- checkerRelease: done,
308
- Host: host,
309
- FS: fs,
310
- }, nil, nil
311
- }
312
-
313
- func forceEmit(parsed *tsoptions.ParsedCommandLine) {
314
- if parsed == nil || parsed.ParsedConfig == nil || parsed.ParsedConfig.CompilerOptions == nil {
315
- return
316
- }
317
- options := parsed.ParsedConfig.CompilerOptions
318
- options.NoEmit = core.TSFalse
319
- options.EmitDeclarationOnly = core.TSFalse
320
- }
321
-
322
- func forceNoEmit(parsed *tsoptions.ParsedCommandLine) {
323
- if parsed == nil || parsed.ParsedConfig == nil || parsed.ParsedConfig.CompilerOptions == nil {
324
- return
325
- }
326
- parsed.ParsedConfig.CompilerOptions.NoEmit = core.TSTrue
327
- }
328
-
329
- func overrideOutDir(cwd string, parsed *tsoptions.ParsedCommandLine, outDir string) {
330
- if parsed == nil || parsed.ParsedConfig == nil || parsed.ParsedConfig.CompilerOptions == nil {
331
- return
332
- }
333
- parsed.ParsedConfig.CompilerOptions.OutDir = tspath.ResolvePath(cwd, outDir)
334
- }
335
-
336
- type sourcePreambleFS struct {
337
- vfs.FS
338
- preamble string
339
- }
340
-
341
- func (fs sourcePreambleFS) ReadFile(filePath string) (string, bool) {
342
- contents, ok := fs.FS.ReadFile(filePath)
343
- if !ok || !isSourcePreambleTarget(filePath) {
344
- return contents, ok
345
- }
346
- return fs.preamble + contents, true
347
- }
348
-
349
- func (fs sourcePreambleFS) WriteFile(filePath string, data string) error {
350
- return fs.FS.WriteFile(filePath, data)
351
- }
352
-
353
- func (fs sourcePreambleFS) AppendFile(filePath string, data string) error {
354
- return fs.FS.AppendFile(filePath, data)
355
- }
356
-
357
- func (fs sourcePreambleFS) Remove(filePath string) error {
358
- return fs.FS.Remove(filePath)
359
- }
360
-
361
- func (fs sourcePreambleFS) Chtimes(filePath string, aTime time.Time, mTime time.Time) error {
362
- return fs.FS.Chtimes(filePath, aTime, mTime)
363
- }
364
-
365
- func isSourcePreambleTarget(filePath string) bool {
366
- lower := strings.ToLower(filepath.ToSlash(filePath))
367
- for _, suffix := range []string{".d.ts", ".d.mts", ".d.cts"} {
368
- if strings.HasSuffix(lower, suffix) {
369
- return false
370
- }
371
- }
372
- for _, suffix := range []string{".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"} {
373
- if strings.HasSuffix(lower, suffix) {
374
- return true
375
- }
376
- }
377
- return false
378
- }
379
-
380
- // SourceFiles exposes the program's user-authored source files (declaration
381
- // files filtered out).
382
- func (p *Program) SourceFiles() []*ast.SourceFile {
383
- out := make([]*ast.SourceFile, 0)
384
- for _, f := range p.TSProgram.SourceFiles() {
385
- if f.IsDeclarationFile {
386
- continue
387
- }
388
- out = append(out, f)
389
- }
390
- return out
391
- }
392
-
393
- // Diagnostics returns project diagnostics that must block compilation or
394
- // runtime execution before any JavaScript is emitted or evaluated.
395
- func (p *Program) Diagnostics() []Diagnostic {
396
- if p == nil || p.TSProgram == nil {
397
- return []Diagnostic{{Message: "driver: nil program"}}
398
- }
399
- ctx := context.Background()
400
- raw := shimcompiler.GetDiagnosticsOfAnyProgram(
401
- ctx,
402
- p.TSProgram,
403
- nil,
404
- false,
405
- p.TSProgram.GetBindDiagnostics,
406
- p.TSProgram.GetSemanticDiagnostics,
407
- )
408
- raw = filterDiagnostics(raw)
409
- return convertDiagnostics(shimcompiler.SortAndDeduplicateDiagnostics(raw))
410
- }
411
-
412
- func filterDiagnostics(in []*ast.Diagnostic) []*ast.Diagnostic {
413
- out := in[:0]
414
- for _, d := range in {
415
- if isUnusedOverloadSignatureTypeParameterDiagnostic(d) {
416
- continue
417
- }
418
- out = append(out, d)
419
- }
420
- return out
421
- }
422
-
423
- func isUnusedOverloadSignatureTypeParameterDiagnostic(d *ast.Diagnostic) bool {
424
- if d == nil || d.File() == nil {
425
- return false
426
- }
427
- switch d.Code() {
428
- case 6196, 6205: // unused declaration / all type parameters are unused
429
- default:
430
- return false
431
- }
432
- node := ast.GetNodeAtPosition(d.File(), d.Pos(), false)
433
- for node != nil {
434
- if node.Kind == ast.KindFunctionDeclaration {
435
- return node.Body() == nil
436
- }
437
- node = node.Parent
438
- }
439
- return false
440
- }
441
-
442
- // convertDiagnostics translates shim-specific diagnostics into the plain
443
- // Diagnostic struct with line/column populated via tsgo's ECMALineMap (the
444
- // same helper tsc uses for its "file:line:col: message" banner).
445
- func convertDiagnostics(in []*ast.Diagnostic) []Diagnostic {
446
- out := make([]Diagnostic, 0, len(in))
447
- for _, d := range in {
448
- if d == nil {
449
- continue
450
- }
451
- diag := Diagnostic{Code: d.Code(), Message: d.String(), raw: d}
452
- if file := d.File(); file != nil {
453
- diag.File = file.FileName()
454
- if pos := d.Pos(); pos >= 0 {
455
- length := d.Len()
456
- diag.Start = &pos
457
- diag.Length = &length
458
- line, col := shimscanner.GetECMALineAndByteOffsetOfPosition(file, pos)
459
- diag.Line = line + 1
460
- diag.Column = col + 1
461
- }
462
- }
463
- out = append(out, diag)
464
- }
465
- return out
466
- }