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.
- package/README.md +96 -25
- package/cmd/graphbench/main.go +135 -0
- package/cmd/graphdump/main.go +60 -0
- package/cmd/ttscgraph/dump.go +69 -0
- package/cmd/ttscgraph/main.go +91 -0
- package/cmd/ttscgraph/run_dump_prints_the_graph_as_json_test.go +80 -0
- package/cmd/ttscgraph/run_help_version_and_bad_flags_exit_codes_test.go +75 -0
- package/cmd/utility-host/main.go +4 -1
- package/driver/overlay.go +64 -0
- package/driver/program.go +8 -1
- package/driver/session.go +85 -0
- package/internal/graph/build.go +330 -0
- package/internal/graph/build_records_a_node_per_top_level_declaration_test.go +96 -0
- package/internal/graph/decorators.go +122 -0
- package/internal/graph/decorators_capture_name_and_literal_arguments_test.go +98 -0
- package/internal/graph/diagnostics.go +23 -0
- package/internal/graph/dump.go +390 -0
- package/internal/graph/dump_evidence_skips_leading_trivia_test.go +92 -0
- package/internal/graph/dump_serializes_the_full_graph_test.go +146 -0
- package/internal/graph/edge_spans_point_to_resolved_usage_test.go +90 -0
- package/internal/graph/edges.go +538 -0
- package/internal/graph/edges_cover_class_level_references_test.go +93 -0
- package/internal/graph/enum_initializer_calls_are_edges_test.go +63 -0
- package/internal/graph/exports.go +60 -0
- package/internal/graph/file_diagnostics_match_tsgo_code_and_location_test.go +59 -0
- package/internal/graph/file_diagnostics_report_code_column_and_message_test.go +69 -0
- package/internal/graph/function_locals_do_not_collide_test.go +66 -0
- package/internal/graph/gitignore.go +51 -0
- package/internal/graph/graph.go +119 -0
- package/internal/graph/heritage_edges_cover_implements_and_interface_extends_test.go +76 -0
- package/internal/graph/heritage_edges_keep_extends_and_implements_to_same_base_test.go +61 -0
- package/internal/graph/heritage_edges_record_extends_versus_implements_origin_test.go +54 -0
- package/internal/graph/heritage_edges_traverse_barrels_and_stop_at_external_leaves_test.go +112 -0
- package/internal/graph/namespace_dotted_form_qualifies_deeply_test.go +60 -0
- package/internal/graph/namespace_members_become_qualified_nodes_and_edges_test.go +100 -0
- package/internal/graph/node_identity_is_position_invariant_test.go +84 -0
- package/internal/graph/node_modifiers_emit_union_strings_test.go +118 -0
- package/internal/graph/nodes_are_marked_exported_through_the_export_table_test.go +61 -0
- package/internal/graph/overload_implementation_replaces_signature_test.go +54 -0
- package/internal/graph/property_member_edges_remain_owner_visible_test.go +83 -0
- package/internal/graph/resolve.go +102 -0
- package/internal/graph/resolve_prefers_implementation_declaration_test.go +50 -0
- package/internal/graph/resolve_unwraps_barrel_reexport_to_real_declaration_test.go +230 -0
- package/internal/graph/type_ref_edges_cover_typeof_as_satisfies_test.go +79 -0
- package/internal/graph/type_ref_edges_resolve_named_types_across_files_test.go +52 -0
- package/internal/graph/value_access_edges_cover_properties_test.go +96 -0
- package/internal/graph/value_call_edges_cover_jsx_components_test.go +82 -0
- package/internal/graph/value_call_edges_cover_methods_and_constructors_test.go +70 -0
- package/internal/graph/value_call_edges_cover_variable_bound_callables_test.go +46 -0
- package/internal/graph/value_call_edges_do_not_double_record_invoked_member_access_test.go +65 -0
- package/internal/graph/value_call_edges_record_construct_versus_call_origin_test.go +75 -0
- package/internal/graph/value_call_edges_resolve_across_files_and_dedupe_test.go +55 -0
- package/internal/graph/value_call_edges_skip_self_and_unresolved_test.go +74 -0
- package/lib/TtscService.d.ts +55 -0
- package/lib/TtscService.js +93 -0
- package/lib/TtscService.js.map +1 -0
- package/lib/compiler/internal/residentTransformProcess.d.ts +47 -0
- package/lib/compiler/internal/residentTransformProcess.js +187 -0
- package/lib/compiler/internal/residentTransformProcess.js.map +1 -0
- package/lib/compiler/internal/startResidentTransform.d.ts +26 -0
- package/lib/compiler/internal/startResidentTransform.js +98 -0
- package/lib/compiler/internal/startResidentTransform.js.map +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/plugin/internal/loadProjectPlugins.js +17 -3
- package/lib/plugin/internal/loadProjectPlugins.js.map +1 -1
- package/lib/structures/ITtscPlugin.d.ts +7 -5
- package/lib/structures/ITtscPluginFactoryContext.d.ts +24 -1
- package/package.json +8 -8
- package/shim/ast/shim.go +6 -0
- package/shim/checker/shim.go +22 -12
- package/src/TtscService.ts +94 -0
- package/src/compiler/internal/residentTransformProcess.ts +216 -0
- package/src/compiler/internal/startResidentTransform.ts +126 -0
- package/src/index.ts +1 -0
- package/src/plugin/internal/loadProjectPlugins.ts +17 -3
- package/src/structures/ITtscPlugin.ts +7 -5
- package/src/structures/ITtscPluginFactoryContext.ts +26 -1
- package/utility/host.go +8 -2
- 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
|
|
18
|
-
//
|
|
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)
|
package/utility/serve.go
ADDED
|
@@ -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
|
+
}
|