ttsc 0.16.2 → 0.16.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/README.md +96 -25
  2. package/cmd/graphbench/main.go +135 -0
  3. package/cmd/graphdump/main.go +60 -0
  4. package/cmd/ttscgraph/dump.go +69 -0
  5. package/cmd/ttscgraph/main.go +91 -0
  6. package/cmd/ttscgraph/run_dump_prints_the_graph_as_json_test.go +80 -0
  7. package/cmd/ttscgraph/run_help_version_and_bad_flags_exit_codes_test.go +75 -0
  8. package/cmd/utility-host/main.go +4 -1
  9. package/driver/overlay.go +64 -0
  10. package/driver/program.go +8 -1
  11. package/driver/session.go +85 -0
  12. package/internal/graph/build.go +330 -0
  13. package/internal/graph/build_records_a_node_per_top_level_declaration_test.go +96 -0
  14. package/internal/graph/decorators.go +122 -0
  15. package/internal/graph/decorators_capture_name_and_literal_arguments_test.go +98 -0
  16. package/internal/graph/diagnostics.go +23 -0
  17. package/internal/graph/dump.go +390 -0
  18. package/internal/graph/dump_evidence_skips_leading_trivia_test.go +92 -0
  19. package/internal/graph/dump_serializes_the_full_graph_test.go +146 -0
  20. package/internal/graph/edge_spans_point_to_resolved_usage_test.go +90 -0
  21. package/internal/graph/edges.go +538 -0
  22. package/internal/graph/edges_cover_class_level_references_test.go +93 -0
  23. package/internal/graph/enum_initializer_calls_are_edges_test.go +63 -0
  24. package/internal/graph/exports.go +60 -0
  25. package/internal/graph/file_diagnostics_match_tsgo_code_and_location_test.go +59 -0
  26. package/internal/graph/file_diagnostics_report_code_column_and_message_test.go +69 -0
  27. package/internal/graph/function_locals_do_not_collide_test.go +66 -0
  28. package/internal/graph/gitignore.go +51 -0
  29. package/internal/graph/graph.go +119 -0
  30. package/internal/graph/heritage_edges_cover_implements_and_interface_extends_test.go +76 -0
  31. package/internal/graph/heritage_edges_keep_extends_and_implements_to_same_base_test.go +61 -0
  32. package/internal/graph/heritage_edges_record_extends_versus_implements_origin_test.go +54 -0
  33. package/internal/graph/heritage_edges_traverse_barrels_and_stop_at_external_leaves_test.go +112 -0
  34. package/internal/graph/namespace_dotted_form_qualifies_deeply_test.go +60 -0
  35. package/internal/graph/namespace_members_become_qualified_nodes_and_edges_test.go +100 -0
  36. package/internal/graph/node_identity_is_position_invariant_test.go +84 -0
  37. package/internal/graph/node_modifiers_emit_union_strings_test.go +118 -0
  38. package/internal/graph/nodes_are_marked_exported_through_the_export_table_test.go +61 -0
  39. package/internal/graph/overload_implementation_replaces_signature_test.go +54 -0
  40. package/internal/graph/property_member_edges_remain_owner_visible_test.go +83 -0
  41. package/internal/graph/resolve.go +102 -0
  42. package/internal/graph/resolve_prefers_implementation_declaration_test.go +50 -0
  43. package/internal/graph/resolve_unwraps_barrel_reexport_to_real_declaration_test.go +230 -0
  44. package/internal/graph/type_ref_edges_cover_typeof_as_satisfies_test.go +79 -0
  45. package/internal/graph/type_ref_edges_resolve_named_types_across_files_test.go +52 -0
  46. package/internal/graph/value_access_edges_cover_properties_test.go +96 -0
  47. package/internal/graph/value_call_edges_cover_jsx_components_test.go +82 -0
  48. package/internal/graph/value_call_edges_cover_methods_and_constructors_test.go +70 -0
  49. package/internal/graph/value_call_edges_cover_variable_bound_callables_test.go +46 -0
  50. package/internal/graph/value_call_edges_do_not_double_record_invoked_member_access_test.go +65 -0
  51. package/internal/graph/value_call_edges_record_construct_versus_call_origin_test.go +75 -0
  52. package/internal/graph/value_call_edges_resolve_across_files_and_dedupe_test.go +55 -0
  53. package/internal/graph/value_call_edges_skip_self_and_unresolved_test.go +74 -0
  54. package/lib/TtscService.d.ts +55 -0
  55. package/lib/TtscService.js +93 -0
  56. package/lib/TtscService.js.map +1 -0
  57. package/lib/compiler/internal/residentTransformProcess.d.ts +47 -0
  58. package/lib/compiler/internal/residentTransformProcess.js +187 -0
  59. package/lib/compiler/internal/residentTransformProcess.js.map +1 -0
  60. package/lib/compiler/internal/startResidentTransform.d.ts +26 -0
  61. package/lib/compiler/internal/startResidentTransform.js +98 -0
  62. package/lib/compiler/internal/startResidentTransform.js.map +1 -0
  63. package/lib/index.d.ts +1 -0
  64. package/lib/index.js +1 -0
  65. package/lib/index.js.map +1 -1
  66. package/lib/plugin/internal/loadProjectPlugins.js +17 -3
  67. package/lib/plugin/internal/loadProjectPlugins.js.map +1 -1
  68. package/lib/structures/ITtscPlugin.d.ts +7 -5
  69. package/lib/structures/ITtscPluginFactoryContext.d.ts +24 -1
  70. package/package.json +8 -8
  71. package/shim/ast/shim.go +6 -0
  72. package/shim/checker/shim.go +22 -12
  73. package/src/TtscService.ts +94 -0
  74. package/src/compiler/internal/residentTransformProcess.ts +216 -0
  75. package/src/compiler/internal/startResidentTransform.ts +126 -0
  76. package/src/index.ts +1 -0
  77. package/src/plugin/internal/loadProjectPlugins.ts +17 -3
  78. package/src/structures/ITtscPlugin.ts +7 -5
  79. package/src/structures/ITtscPluginFactoryContext.ts +26 -1
  80. package/utility/host.go +8 -2
  81. package/utility/serve.go +158 -0
package/utility/host.go CHANGED
@@ -10,12 +10,13 @@ import (
10
10
 
11
11
  shimcompiler "github.com/microsoft/typescript-go/shim/compiler"
12
12
  shimprinter "github.com/microsoft/typescript-go/shim/printer"
13
+ "github.com/microsoft/typescript-go/shim/vfs"
13
14
 
14
15
  "github.com/samchon/ttsc/packages/ttsc/driver"
15
16
  )
16
17
 
17
- // hostOptions is the parsed form of the flags accepted by all three
18
- // subcommands (check, build, transform).
18
+ // hostOptions is the parsed form of the flags accepted by the subcommands
19
+ // (check, build, transform, serve).
19
20
  type hostOptions struct {
20
21
  cwd string
21
22
  emit bool
@@ -28,6 +29,10 @@ type hostOptions struct {
28
29
  singleThreaded bool
29
30
  checkers int
30
31
  tsgoArgs []string
32
+ // fs overrides the filesystem the program loads from. Only the resident serve
33
+ // host sets it (to an OverlayFS), so build/check/transform leave it nil and
34
+ // LoadProgram falls back to the default filesystem.
35
+ fs vfs.FS
31
36
  }
32
37
 
33
38
  // transformResult is the JSON envelope written to stdout by RunTransform.
@@ -251,6 +256,7 @@ func loadUtilityProgram(opts hostOptions) (*driver.Program, []driver.PluginEntry
251
256
  SingleThreaded: opts.singleThreaded,
252
257
  Checkers: opts.checkers,
253
258
  TsgoArgs: opts.tsgoArgs,
259
+ FS: opts.fs,
254
260
  })
255
261
  if err != nil {
256
262
  fmt.Fprintf(os.Stderr, "ttsc utility: %v\n", err)
@@ -0,0 +1,158 @@
1
+ package utility
2
+
3
+ import (
4
+ "bufio"
5
+ "encoding/json"
6
+ "fmt"
7
+ "io"
8
+ "os"
9
+ "path/filepath"
10
+ "strings"
11
+
12
+ shimprinter "github.com/microsoft/typescript-go/shim/printer"
13
+
14
+ "github.com/samchon/ttsc/packages/ttsc/driver"
15
+ )
16
+
17
+ // serveRequest is one newline-delimited request the resident host reads from its
18
+ // input stream. It is either a transform request (File set) for the transformed
19
+ // TypeScript of a file, or an update request (Update set) that applies new
20
+ // in-memory content for a file and re-transforms the project.
21
+ type serveRequest struct {
22
+ Content string `json:"content"`
23
+ File string `json:"file"`
24
+ Update string `json:"update"`
25
+ }
26
+
27
+ // serveResponse is the reply to a transform request: the transformed TypeScript
28
+ // for the requested file and whether the resident program had it.
29
+ type serveResponse struct {
30
+ TypeScript string `json:"typescript"`
31
+ Found bool `json:"found"`
32
+ }
33
+
34
+ // serveUpdateResponse is the reply to an update request: whether re-transforming
35
+ // the project with the new content succeeded. A false reply leaves the previous
36
+ // transform in place (for example the edit introduced a type error); the host's
37
+ // diagnostics are written to stderr.
38
+ type serveUpdateResponse struct {
39
+ Updated bool `json:"updated"`
40
+ }
41
+
42
+ // RunServe is the resident transform host. It transforms the whole project once
43
+ // (the expensive compile plus linked-plugin pass) over an in-memory overlay,
44
+ // caches every file's transformed text, then answers newline-delimited requests
45
+ // read from in by writing one JSON reply per line to out, until in reaches EOF:
46
+ //
47
+ // - {"file":"<path>"} returns that file's transformed TypeScript.
48
+ // - {"update":"<path>","content":"<text>"} applies new content for the file
49
+ // and re-transforms, so subsequent transform requests reflect the edit.
50
+ //
51
+ // One resident process answers a request stream without recompiling the project
52
+ // per call and reflects edits without respawning the host. Sharing one host
53
+ // across separate worker processes (a Metro worker pool) is tracked in
54
+ // samchon/ttsc#255.
55
+ //
56
+ // in and out are explicit so the request loop is testable; the utility-host
57
+ // command wires them to os.Stdin and os.Stdout.
58
+ func RunServe(in io.Reader, out io.Writer, args []string) int {
59
+ opts, ok := parseHostOptions("serve", args)
60
+ if !ok {
61
+ return 2
62
+ }
63
+ overlay := driver.NewOverlayFS(driver.DefaultFS())
64
+ opts.fs = overlay
65
+ cache, ok := buildServeCache(opts)
66
+ if !ok {
67
+ return 2
68
+ }
69
+ encoder := json.NewEncoder(out)
70
+ // ReadString imposes no line-length limit. An update request carries a whole
71
+ // file's content on one line, so the line is as large as that content; a
72
+ // bufio.Scanner cap would be an arbitrary ceiling at which the resident host
73
+ // dies, and there is no such natural ceiling on source size.
74
+ reader := bufio.NewReader(in)
75
+ for {
76
+ raw, err := reader.ReadString('\n')
77
+ if line := strings.TrimSpace(raw); line != "" {
78
+ cache = handleServeLine(line, opts, overlay, cache, encoder)
79
+ }
80
+ if err != nil {
81
+ if err != io.EOF {
82
+ fmt.Fprintf(os.Stderr, "ttsc utility serve: read error: %v\n", err)
83
+ return 2
84
+ }
85
+ return 0
86
+ }
87
+ }
88
+ }
89
+
90
+ // handleServeLine answers one request line and returns the cache to use for the
91
+ // next request: the rebuilt cache after a successful update, the unchanged cache
92
+ // otherwise.
93
+ func handleServeLine(
94
+ line string,
95
+ opts hostOptions,
96
+ overlay *driver.OverlayFS,
97
+ cache map[string]string,
98
+ encoder *json.Encoder,
99
+ ) map[string]string {
100
+ var req serveRequest
101
+ if err := json.Unmarshal([]byte(line), &req); err != nil {
102
+ _ = encoder.Encode(serveResponse{})
103
+ return cache
104
+ }
105
+ if req.Update != "" {
106
+ abs := resolveServePath(opts.cwd, req.Update)
107
+ prev, had := overlay.Get(abs)
108
+ overlay.Set(abs, req.Content)
109
+ if rebuilt, ok := buildServeCache(opts); ok {
110
+ _ = encoder.Encode(serveUpdateResponse{Updated: true})
111
+ return rebuilt
112
+ }
113
+ // Roll the failed edit back so a file that does not compile does not poison
114
+ // every later rebuild; the previous transform stays in effect.
115
+ if had {
116
+ overlay.Set(abs, prev)
117
+ } else {
118
+ overlay.Unset(abs)
119
+ }
120
+ _ = encoder.Encode(serveUpdateResponse{Updated: false})
121
+ return cache
122
+ }
123
+ key := apiOutputKey(opts.cwd, resolveServePath(opts.cwd, req.File))
124
+ text, found := cache[key]
125
+ _ = encoder.Encode(serveResponse{TypeScript: text, Found: found})
126
+ return cache
127
+ }
128
+
129
+ // buildServeCache runs the whole-project transform once over the current overlay
130
+ // state and returns the transformed text keyed exactly like the transform
131
+ // subcommand's JSON envelope.
132
+ func buildServeCache(opts hostOptions) (map[string]string, bool) {
133
+ prog, _, ok := loadUtilityProgram(opts)
134
+ if !ok {
135
+ return nil, false
136
+ }
137
+ defer prog.Close()
138
+ if err := prog.ApplyLinkedPlugins(); err != nil {
139
+ fmt.Fprintln(os.Stderr, err)
140
+ return nil, false
141
+ }
142
+ printer := shimprinter.NewPrinter(shimprinter.PrinterOptions{}, shimprinter.PrintHandlers{}, nil)
143
+ cache := map[string]string{}
144
+ for _, file := range prog.SourceFiles() {
145
+ cache[apiOutputKey(opts.cwd, file.FileName())] = shimprinter.EmitSourceFile(printer, file)
146
+ }
147
+ return cache, true
148
+ }
149
+
150
+ // resolveServePath turns a request's file into an absolute path so apiOutputKey
151
+ // computes the same key buildServeCache stored, and so overlay overrides are
152
+ // keyed the way the program asks for them.
153
+ func resolveServePath(cwd, file string) string {
154
+ if filepath.IsAbs(file) {
155
+ return file
156
+ }
157
+ return filepath.Join(cwd, file)
158
+ }