ttsc 0.16.3 → 0.16.6

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 (75) 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 +120 -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 +374 -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 +581 -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 +122 -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_attribute_function_assignments_to_members_test.go +59 -0
  48. package/internal/graph/value_call_edges_cover_jsx_components_test.go +82 -0
  49. package/internal/graph/value_call_edges_cover_methods_and_constructors_test.go +70 -0
  50. package/internal/graph/value_call_edges_cover_variable_bound_callables_test.go +46 -0
  51. package/internal/graph/value_call_edges_do_not_double_record_invoked_member_access_test.go +65 -0
  52. package/internal/graph/value_call_edges_record_construct_versus_call_origin_test.go +75 -0
  53. package/internal/graph/value_call_edges_resolve_across_files_and_dedupe_test.go +55 -0
  54. package/internal/graph/value_call_edges_skip_self_and_unresolved_test.go +74 -0
  55. package/lib/TtscService.d.ts +55 -0
  56. package/lib/TtscService.js +93 -0
  57. package/lib/TtscService.js.map +1 -0
  58. package/lib/compiler/internal/residentTransformProcess.d.ts +47 -0
  59. package/lib/compiler/internal/residentTransformProcess.js +187 -0
  60. package/lib/compiler/internal/residentTransformProcess.js.map +1 -0
  61. package/lib/compiler/internal/startResidentTransform.d.ts +26 -0
  62. package/lib/compiler/internal/startResidentTransform.js +98 -0
  63. package/lib/compiler/internal/startResidentTransform.js.map +1 -0
  64. package/lib/index.d.ts +1 -0
  65. package/lib/index.js +1 -0
  66. package/lib/index.js.map +1 -1
  67. package/package.json +8 -8
  68. package/shim/ast/shim.go +6 -0
  69. package/shim/checker/shim.go +22 -12
  70. package/src/TtscService.ts +94 -0
  71. package/src/compiler/internal/residentTransformProcess.ts +216 -0
  72. package/src/compiler/internal/startResidentTransform.ts +126 -0
  73. package/src/index.ts +1 -0
  74. package/utility/host.go +8 -2
  75. package/utility/serve.go +158 -0
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.TtscService = void 0;
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const startResidentTransform_1 = require("./compiler/internal/startResidentTransform");
9
+ /**
10
+ * Resident, incremental transform service for the `ttsc` TypeScript-Go
11
+ * pipeline.
12
+ *
13
+ * Where {@link TtscCompiler.transform} spawns a fresh process and recompiles the
14
+ * whole project on every call, `TtscService` keeps one long-lived host warm: it
15
+ * compiles the project once and then answers per-file transform requests from
16
+ * that warm program. A single service instance transforms many files (a watch
17
+ * server, an editor session, a codegen tool) while paying the project compile
18
+ * once instead of once per file. Sharing one host across separate worker
19
+ * processes (a Metro worker pool) is tracked in samchon/ttsc#255.
20
+ *
21
+ * The shape mirrors a legacy TypeScript `LanguageService`: construct it against
22
+ * a project context, ask it to transform individual files, and dispose it when
23
+ * done. Construction is synchronous (it launches the host); the host compiles
24
+ * in the background, so the first {@link transformFile} resolves once that
25
+ * compile lands.
26
+ *
27
+ * Resident mode runs through the linked-plugin shared host, so the project must
28
+ * declare at least one transform-stage plugin; the constructor throws
29
+ * otherwise. It does not run check-stage plugins (unlike
30
+ * {@link TtscCompiler.transform}); only the program's own type-checking gates an
31
+ * {@link updateFile}.
32
+ */
33
+ class TtscService {
34
+ resident;
35
+ projectRoot;
36
+ /**
37
+ * Create a service bound to the given project context and launch its resident
38
+ * host. The context is the same shape {@link TtscCompiler} accepts; it is not
39
+ * replaceable per call.
40
+ */
41
+ constructor(context = {}) {
42
+ const started = (0, startResidentTransform_1.startResidentTransform)({
43
+ ...context,
44
+ env: context.env ? { ...context.env } : undefined,
45
+ plugins: Array.isArray(context.plugins)
46
+ ? [...context.plugins]
47
+ : context.plugins,
48
+ });
49
+ this.resident = started.process;
50
+ this.projectRoot = started.projectRoot;
51
+ }
52
+ /**
53
+ * Return the transformed TypeScript source for one file, or `undefined` when
54
+ * the resident program does not contain it (for example a file excluded from
55
+ * the tsconfig). A relative `fileName` is resolved against the project root.
56
+ *
57
+ * Rejects when the resident host failed to compile the project; the rejection
58
+ * carries the host's diagnostics so callers can surface a real build error.
59
+ */
60
+ async transformFile(fileName) {
61
+ const reply = await this.resident.request({
62
+ file: this.absolutePath(fileName),
63
+ });
64
+ return reply.found === true && typeof reply.typescript === "string"
65
+ ? reply.typescript
66
+ : undefined;
67
+ }
68
+ /**
69
+ * Apply new in-memory content for one file and re-transform the project, so a
70
+ * subsequent {@link transformFile} reflects the edit without restarting the
71
+ * host. Returns whether the re-transform succeeded; `false` means the edit
72
+ * did not compile and the previous transform is still in effect. A relative
73
+ * `fileName` is resolved against the project root.
74
+ */
75
+ async updateFile(fileName, content) {
76
+ const reply = await this.resident.request({
77
+ content,
78
+ update: this.absolutePath(fileName),
79
+ });
80
+ return reply.updated === true;
81
+ }
82
+ /** Terminate the resident host and reject any in-flight requests. */
83
+ dispose() {
84
+ this.resident.dispose();
85
+ }
86
+ absolutePath(fileName) {
87
+ return node_path_1.default.isAbsolute(fileName)
88
+ ? fileName
89
+ : node_path_1.default.resolve(this.projectRoot, fileName);
90
+ }
91
+ }
92
+ exports.TtscService = TtscService;
93
+ //# sourceMappingURL=TtscService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TtscService.js","sourceRoot":"","sources":["../src/TtscService.ts"],"names":[],"mappings":";;;;;;AAAA,0DAA6B;AAG7B,uFAAoF;AAGpF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH;IACmB,QAAQ,CAA2B;IACnC,WAAW,CAAS;IAErC;;;;OAIG;IACH,YAAmB,OAAO,GAAyB,EAAE;QACnD,MAAM,OAAO,GAAG,IAAA,+CAAsB,EAAC;YACrC,GAAG,OAAO;YACV,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS;YACjD,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC;gBACrC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;gBACtB,CAAC,CAAC,OAAO,CAAC,OAAO;SACpB,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;QAChC,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IACzC,CAAC;IAED;;;;;;;OAOG;IACI,KAAK,CAAC,aAAa,CAAC,QAAgB;QACzC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;YACxC,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC;SAClC,CAAC,CAAC;QACH,OAAO,KAAK,CAAC,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ;YACjE,CAAC,CAAC,KAAK,CAAC,UAAU;YAClB,CAAC,CAAC,SAAS,CAAC;IAChB,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,UAAU,CAAC,QAAgB,EAAE,OAAe;QACvD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;YACxC,OAAO;YACP,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC;SACpC,CAAC,CAAC;QACH,OAAO,KAAK,CAAC,OAAO,KAAK,IAAI,CAAC;IAChC,CAAC;IAED,qEAAqE;IAC9D,OAAO;QACZ,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;IAC1B,CAAC;IAEO,YAAY,CAAC,QAAgB;QACnC,OAAO,mBAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;YAC9B,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,mBAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAC/C,CAAC;CACF"}
@@ -0,0 +1,47 @@
1
+ /** Options for spawning the resident transform host. */
2
+ export interface ResidentTransformProcessOptions {
3
+ args: readonly string[];
4
+ binary: string;
5
+ cwd?: string;
6
+ env?: NodeJS.ProcessEnv;
7
+ }
8
+ /**
9
+ * Async client for the long-lived `utility-host serve` process.
10
+ *
11
+ * The host transforms the whole project once at startup, caches every file's
12
+ * transformed TypeScript, then answers newline-delimited requests. This class
13
+ * speaks that protocol: each {@link request} writes one JSON line and the host
14
+ * replies with one line, matched FIFO. A transform request (`{"file":...}`) is
15
+ * answered with `{"typescript":...,"found":...}`, and an update request
16
+ * (`{"update":...,"content":...}`) with `{"updated":...}`.
17
+ *
18
+ * One resident process answers every request from one service instead of
19
+ * spawning a fresh `transform` subprocess per call, so a single process pays
20
+ * the project compile once (samchon/ttsc#255).
21
+ */
22
+ export declare class ResidentTransformProcess {
23
+ private readonly child;
24
+ private readonly reader;
25
+ private readonly pending;
26
+ private stderr;
27
+ private failure;
28
+ constructor(options: ResidentTransformProcessOptions);
29
+ /**
30
+ * Send one request to the host and resolve with its parsed JSON reply. The
31
+ * host answers in FIFO order, so the caller interprets the reply shape by the
32
+ * payload it sent (a transform reply vs an update reply). Rejects when the
33
+ * host has already failed or exited, or if writing the request fails.
34
+ */
35
+ request(payload: Record<string, unknown>): Promise<Record<string, unknown>>;
36
+ /**
37
+ * Terminate the resident process and reject any in-flight requests. Safe to
38
+ * call more than once.
39
+ */
40
+ dispose(): void;
41
+ private onLine;
42
+ private onReaderClose;
43
+ private fail;
44
+ private rejectAll;
45
+ private removePending;
46
+ private exitError;
47
+ }
@@ -0,0 +1,187 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ResidentTransformProcess = void 0;
4
+ const node_child_process_1 = require("node:child_process");
5
+ const node_readline_1 = require("node:readline");
6
+ /** Cap on retained stderr so a long-lived host cannot grow it without bound. */
7
+ const STDERR_TAIL_LIMIT = 64 * 1024;
8
+ /**
9
+ * Async client for the long-lived `utility-host serve` process.
10
+ *
11
+ * The host transforms the whole project once at startup, caches every file's
12
+ * transformed TypeScript, then answers newline-delimited requests. This class
13
+ * speaks that protocol: each {@link request} writes one JSON line and the host
14
+ * replies with one line, matched FIFO. A transform request (`{"file":...}`) is
15
+ * answered with `{"typescript":...,"found":...}`, and an update request
16
+ * (`{"update":...,"content":...}`) with `{"updated":...}`.
17
+ *
18
+ * One resident process answers every request from one service instead of
19
+ * spawning a fresh `transform` subprocess per call, so a single process pays
20
+ * the project compile once (samchon/ttsc#255).
21
+ */
22
+ class ResidentTransformProcess {
23
+ child;
24
+ reader;
25
+ pending = [];
26
+ stderr = "";
27
+ failure;
28
+ constructor(options) {
29
+ // Default stdio is "pipe" for stdin/stdout/stderr, which is exactly what the
30
+ // line protocol needs; spelling it out as a string[] would not narrow to
31
+ // StdioOptions, so it is left implicit.
32
+ this.child = (0, node_child_process_1.spawn)(options.binary, [...options.args], {
33
+ cwd: options.cwd,
34
+ env: options.env,
35
+ windowsHide: true,
36
+ });
37
+ const stdout = this.child.stdout;
38
+ const stdin = this.child.stdin;
39
+ if (stdout === null || stdin === null) {
40
+ this.child.kill();
41
+ throw new Error("ttsc: resident transform host has no stdio pipes");
42
+ }
43
+ this.reader = (0, node_readline_1.createInterface)({ input: stdout });
44
+ this.reader.on("line", (line) => this.onLine(line));
45
+ // Drive completion off stdout's end, not the process "exit" event: every
46
+ // buffered "line" is delivered before "close", so a reply that arrived just
47
+ // before the host exited still resolves its request instead of racing the
48
+ // exit-time rejection.
49
+ this.reader.on("close", () => this.onReaderClose());
50
+ this.child.stderr?.on("data", (chunk) => {
51
+ const text = typeof chunk === "string" ? chunk : chunk.toString("utf8");
52
+ // Keep only the tail: stderr is consulted for the crash message, and a
53
+ // long resident session can write diagnostics on every failed update.
54
+ this.stderr = (this.stderr + text).slice(-STDERR_TAIL_LIMIT);
55
+ });
56
+ this.child.on("error", (error) => this.fail(error));
57
+ // A dead host's pipes emit "error" (EPIPE on POSIX, often ECONNRESET on
58
+ // Windows). Without these listeners Node turns a pipe error into an uncaught
59
+ // exception that crashes the whole consumer process; route them through
60
+ // fail() (stderr is non-critical) so a pipe death fails in-flight requests
61
+ // instead, and also closes the window where stdin.destroyed has not flipped.
62
+ stdin.on("error", (error) => this.fail(error));
63
+ stdout.on("error", (error) => this.fail(error));
64
+ this.child.stderr?.on("error", () => { });
65
+ }
66
+ /**
67
+ * Send one request to the host and resolve with its parsed JSON reply. The
68
+ * host answers in FIFO order, so the caller interprets the reply shape by the
69
+ * payload it sent (a transform reply vs an update reply). Rejects when the
70
+ * host has already failed or exited, or if writing the request fails.
71
+ */
72
+ request(payload) {
73
+ if (this.failure !== undefined) {
74
+ return Promise.reject(this.failure);
75
+ }
76
+ const stdin = this.child.stdin;
77
+ if (stdin === null || stdin.destroyed) {
78
+ return Promise.reject(new Error("ttsc: resident transform host stdin is closed"));
79
+ }
80
+ return new Promise((resolve, reject) => {
81
+ const pending = { reject, resolve };
82
+ this.pending.push(pending);
83
+ stdin.write(`${JSON.stringify(payload)}\n`, (error) => {
84
+ if (error) {
85
+ this.removePending(pending);
86
+ reject(error);
87
+ }
88
+ });
89
+ });
90
+ }
91
+ /**
92
+ * Terminate the resident process and reject any in-flight requests. Safe to
93
+ * call more than once.
94
+ */
95
+ dispose() {
96
+ if (this.failure === undefined) {
97
+ // If the host already died, reject with its real exit error (stderr +
98
+ // exit code) rather than a bland "disposed" message.
99
+ this.failure =
100
+ this.child.exitCode !== null || this.child.signalCode !== null
101
+ ? this.exitError()
102
+ : new Error("ttsc: resident transform host disposed");
103
+ }
104
+ const stdin = this.child.stdin;
105
+ if (stdin !== null && !stdin.destroyed) {
106
+ stdin.end();
107
+ }
108
+ this.reader.close();
109
+ this.rejectAll(this.failure);
110
+ if (this.child.exitCode === null && this.child.signalCode === null) {
111
+ this.child.kill();
112
+ }
113
+ }
114
+ onLine(line) {
115
+ const trimmed = line.trim();
116
+ if (trimmed.length === 0) {
117
+ return;
118
+ }
119
+ const request = this.pending.shift();
120
+ if (request === undefined) {
121
+ // The host must emit exactly one reply per request, so an unmatched line
122
+ // is a protocol violation that would desync every later reply into the
123
+ // wrong request. Fail fast rather than silently returning wrong output.
124
+ // A line arriving after teardown (failure already set) is benign.
125
+ if (this.failure === undefined) {
126
+ this.fail(new Error("ttsc: resident transform host sent an unsolicited reply"));
127
+ }
128
+ return;
129
+ }
130
+ request.resolve(parseReply(trimmed));
131
+ }
132
+ onReaderClose() {
133
+ if (this.pending.length === 0) {
134
+ return;
135
+ }
136
+ this.rejectAll(this.failure ?? this.exitError());
137
+ }
138
+ fail(error) {
139
+ this.failure ??= error;
140
+ this.rejectAll(this.failure);
141
+ }
142
+ rejectAll(error) {
143
+ while (this.pending.length !== 0) {
144
+ this.pending.shift().reject(error);
145
+ }
146
+ }
147
+ removePending(target) {
148
+ const index = this.pending.indexOf(target);
149
+ if (index !== -1) {
150
+ this.pending.splice(index, 1);
151
+ }
152
+ }
153
+ exitError() {
154
+ const detail = this.stderr.trim();
155
+ if (detail.length !== 0) {
156
+ return new Error(detail);
157
+ }
158
+ // Read the child's own exit fields (set synchronously by Node) so the
159
+ // message is accurate even before this instance's "exit" handler would run.
160
+ const code = this.child.exitCode;
161
+ const signalCode = this.child.signalCode;
162
+ const signal = signalCode === null ? "" : `, signal ${signalCode}`;
163
+ return new Error(`ttsc: resident transform host exited (code ${code ?? "null"}${signal})`);
164
+ }
165
+ }
166
+ exports.ResidentTransformProcess = ResidentTransformProcess;
167
+ /**
168
+ * Parse one reply line into a plain object. A malformed line degrades to an
169
+ * empty object rather than throwing, so one bad line never rejects a request
170
+ * the FIFO has already advanced past; the caller reads missing fields as
171
+ * absent.
172
+ */
173
+ function parseReply(line) {
174
+ try {
175
+ const parsed = JSON.parse(line);
176
+ if (typeof parsed === "object" &&
177
+ parsed !== null &&
178
+ !Array.isArray(parsed)) {
179
+ return parsed;
180
+ }
181
+ }
182
+ catch {
183
+ // A non-object or unparseable line is treated as an empty reply.
184
+ }
185
+ return {};
186
+ }
187
+ //# sourceMappingURL=residentTransformProcess.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"residentTransformProcess.js","sourceRoot":"","sources":["../../../src/compiler/internal/residentTransformProcess.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { ITtscCompilerContext } from "../../structures/ITtscCompilerContext";
2
+ import { ResidentTransformProcess } from "./residentTransformProcess";
3
+ /**
4
+ * A started resident transform host plus the project root its keys are relative
5
+ * to.
6
+ */
7
+ export interface StartedResidentTransform {
8
+ process: ResidentTransformProcess;
9
+ projectRoot: string;
10
+ }
11
+ /**
12
+ * Start a resident `serve` host for the configured project.
13
+ *
14
+ * Mirrors the plugin spawn of `transformProjectInMemory`, but launches the
15
+ * shared host's `serve` subcommand as one long-lived process instead of a
16
+ * per-call `transform` subprocess. The host compiles the whole project once at
17
+ * startup and then answers per-file requests, so one caller pays the project
18
+ * compile once and reuses it across its own per-file requests.
19
+ *
20
+ * Resident mode runs through the linked-plugin shared host
21
+ * (`cmd/utility-host`), which is the only binary that exposes `serve`. It
22
+ * therefore requires at least one transform-stage plugin; executable transform
23
+ * hosts that own their own process are not served and must use the per-call
24
+ * transform path. Check-stage plugins are not run by the resident host.
25
+ */
26
+ export declare function startResidentTransform(context: ITtscCompilerContext): StartedResidentTransform;
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.startResidentTransform = startResidentTransform;
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const loadProjectPlugins_1 = require("../../plugin/internal/loadProjectPlugins");
9
+ const readProjectConfig_1 = require("./project/readProjectConfig");
10
+ const residentTransformProcess_1 = require("./residentTransformProcess");
11
+ const resolveBinary_1 = require("./resolveBinary");
12
+ const resolveTsgo_1 = require("./resolveTsgo");
13
+ const sharedHostHelpers_1 = require("./sharedHostHelpers");
14
+ /**
15
+ * Start a resident `serve` host for the configured project.
16
+ *
17
+ * Mirrors the plugin spawn of `transformProjectInMemory`, but launches the
18
+ * shared host's `serve` subcommand as one long-lived process instead of a
19
+ * per-call `transform` subprocess. The host compiles the whole project once at
20
+ * startup and then answers per-file requests, so one caller pays the project
21
+ * compile once and reuses it across its own per-file requests.
22
+ *
23
+ * Resident mode runs through the linked-plugin shared host
24
+ * (`cmd/utility-host`), which is the only binary that exposes `serve`. It
25
+ * therefore requires at least one transform-stage plugin; executable transform
26
+ * hosts that own their own process are not served and must use the per-call
27
+ * transform path. Check-stage plugins are not run by the resident host.
28
+ */
29
+ function startResidentTransform(context) {
30
+ const cwd = node_path_1.default.resolve(context.cwd ?? process.cwd());
31
+ const project = (0, readProjectConfig_1.readProjectConfig)({
32
+ cwd,
33
+ projectRoot: context.projectRoot,
34
+ tsconfig: context.tsconfig,
35
+ });
36
+ const loaded = (0, loadProjectPlugins_1.loadProjectPlugins)({
37
+ binary: (0, resolveBinary_1.resolveBinary)(context) ?? "",
38
+ cacheDir: context.cacheDir ?? context.env?.TTSC_CACHE_DIR,
39
+ cwd,
40
+ entries: context.plugins,
41
+ projectRoot: context.projectRoot,
42
+ tsconfig: project.path,
43
+ });
44
+ const transformers = loaded.nativePlugins.filter((plugin) => plugin.stage === "transform");
45
+ if (transformers.length === 0) {
46
+ throw new Error("ttsc: TtscService resident mode requires at least one transform-stage plugin; " +
47
+ "use TtscCompiler.transform for projects with only check-stage plugins or none");
48
+ }
49
+ (0, sharedHostHelpers_1.assertSharedHostCompatibility)(transformers, "source-to-source");
50
+ const host = (0, sharedHostHelpers_1.selectSharedHostPlugin)(transformers);
51
+ const tsgoBinary = (0, resolveTsgo_1.resolveTsgo)({ ...context, cwd: project.root }).binary;
52
+ const resident = new residentTransformProcess_1.ResidentTransformProcess({
53
+ args: [
54
+ "serve",
55
+ `--tsconfig=${project.path}`,
56
+ `--plugins-json=${serializeNativePlugins(transformers)}`,
57
+ `--cwd=${project.root}`,
58
+ ],
59
+ binary: host.binary,
60
+ cwd: project.root,
61
+ env: residentEnv(context, tsgoBinary, loaded.nativePlugins),
62
+ });
63
+ return { process: resident, projectRoot: project.root };
64
+ }
65
+ /**
66
+ * Build the environment for the resident host spawn. Matches the per-call
67
+ * transform spawn: injects the Node, tsgo, and ttsx binaries so the host never
68
+ * searches PATH, and forwards linked transform plugins via
69
+ * `TTSC_LINKED_PLUGINS_JSON`.
70
+ */
71
+ function residentEnv(context, tsgoBinary, nativePlugins) {
72
+ const env = {
73
+ ...process.env,
74
+ TTSC_NODE_BINARY: process.env.TTSC_NODE_BINARY ?? process.execPath,
75
+ TTSC_TSGO_BINARY: process.env.TTSC_TSGO_BINARY ?? tsgoBinary,
76
+ TTSC_TTSX_BINARY: process.env.TTSC_TTSX_BINARY ??
77
+ node_path_1.default.join(__dirname, "..", "..", "launcher", "ttsx.js"),
78
+ ...context.env,
79
+ };
80
+ const linked = (0, sharedHostHelpers_1.linkedTransformPlugins)(nativePlugins);
81
+ if (linked.length !== 0) {
82
+ env.TTSC_LINKED_PLUGINS_JSON = serializeNativePlugins(linked);
83
+ }
84
+ return env;
85
+ }
86
+ /**
87
+ * Serialize the plugin list to the `--plugins-json` /
88
+ * `TTSC_LINKED_PLUGINS_JSON` shape the native host reads: only the fields it
89
+ * needs, to keep the arg short.
90
+ */
91
+ function serializeNativePlugins(plugins) {
92
+ return JSON.stringify(plugins.map((plugin) => ({
93
+ config: plugin.config,
94
+ name: plugin.name,
95
+ stage: plugin.stage,
96
+ })));
97
+ }
98
+ //# sourceMappingURL=startResidentTransform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"startResidentTransform.js","sourceRoot":"","sources":["../../../src/compiler/internal/startResidentTransform.ts"],"names":[],"mappings":";;;;;;AAAA,0DAA6B;AAE7B,iFAA8E;AAG9E,mEAAgE;AAChE,yEAAsE;AACtE,mDAAgD;AAChD,+CAA4C;AAC5C,2DAI6B;AAW7B;;;;;;;;;;;;;;GAcG;AACH,gCACE,OAA6B;IAE7B,MAAM,GAAG,GAAG,mBAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,IAAA,qCAAiB,EAAC;QAChC,GAAG;QACH,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,QAAQ,EAAE,OAAO,CAAC,QAAQ;KAC3B,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,IAAA,uCAAkB,EAAC;QAChC,MAAM,EAAE,IAAA,6BAAa,EAAC,OAAO,CAAC,IAAI,EAAE;QACpC,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,EAAE,cAAc;QACzD,GAAG;QACH,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,QAAQ,EAAE,OAAO,CAAC,IAAI;KACvB,CAAC,CAAC;IACH,MAAM,YAAY,GAAG,MAAM,CAAC,aAAa,CAAC,MAAM,CAC9C,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,KAAK,WAAW,CACzC,CAAC;IACF,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CACb,gFAAgF;YAC9E,+EAA+E,CAClF,CAAC;IACJ,CAAC;IACD,IAAA,iDAA6B,EAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC;IAEhE,MAAM,IAAI,GAAG,IAAA,0CAAsB,EAAC,YAAY,CAAC,CAAC;IAClD,MAAM,UAAU,GAAG,IAAA,yBAAW,EAAC,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;IACzE,MAAM,QAAQ,GAAG,IAAI,mDAAwB,CAAC;QAC5C,IAAI,EAAE;YACJ,OAAO;YACP,cAAc,OAAO,CAAC,IAAI,EAAE;YAC5B,kBAAkB,sBAAsB,CAAC,YAAY,CAAC,EAAE;YACxD,SAAS,OAAO,CAAC,IAAI,EAAE;SACxB;QACD,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,GAAG,EAAE,OAAO,CAAC,IAAI;QACjB,GAAG,EAAE,WAAW,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,aAAa,CAAC;KAC5D,CAAC,CAAC;IACH,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC;AAC1D,CAAC;AAED;;;;;GAKG;AACH,SAAS,WAAW,CAClB,OAA6B,EAC7B,UAAkB,EAClB,aAAiD;IAEjD,MAAM,GAAG,GAAsB;QAC7B,GAAG,OAAO,CAAC,GAAG;QACd,gBAAgB,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,OAAO,CAAC,QAAQ;QAClE,gBAAgB,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,UAAU;QAC5D,gBAAgB,EACd,OAAO,CAAC,GAAG,CAAC,gBAAgB;YAC5B,mBAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC;QACzD,GAAG,OAAO,CAAC,GAAG;KACf,CAAC;IACF,MAAM,MAAM,GAAG,IAAA,0CAAsB,EAAC,aAAa,CAAC,CAAC;IACrD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,GAAG,CAAC,wBAAwB,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,SAAS,sBAAsB,CAC7B,OAA2C;IAE3C,OAAO,IAAI,CAAC,SAAS,CACnB,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACvB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,KAAK,EAAE,MAAM,CAAC,KAAK;KACpB,CAAC,CAAC,CACJ,CAAC;AACJ,CAAC"}
package/lib/index.d.ts CHANGED
@@ -7,4 +7,5 @@
7
7
  * package surface remains small and stable.
8
8
  */
9
9
  export * from "./TtscCompiler";
10
+ export * from "./TtscService";
10
11
  export * from "./structures/index";
package/lib/index.js CHANGED
@@ -23,5 +23,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
23
23
  };
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
25
  __exportStar(require("./TtscCompiler"), exports);
26
+ __exportStar(require("./TtscService"), exports);
26
27
  __exportStar(require("./structures/index"), exports);
27
28
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;;;;;;;;;;;;;;AAEH,iDAA+B;AAC/B,qDAAmC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;;;;;;;;;;;;;;AAEH,iDAA+B;AAC/B,gDAA8B;AAC9B,qDAAmC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ttsc",
3
- "version": "0.16.3",
3
+ "version": "0.16.6",
4
4
  "description": "General-purpose TypeScript-Go compiler, runtime, plugin host, and LSP host.",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -32,13 +32,13 @@
32
32
  "typescript": "7.0.1-rc"
33
33
  },
34
34
  "optionalDependencies": {
35
- "@ttsc/linux-arm": "0.16.3",
36
- "@ttsc/darwin-arm64": "0.16.3",
37
- "@ttsc/win32-x64": "0.16.3",
38
- "@ttsc/win32-arm64": "0.16.3",
39
- "@ttsc/linux-arm64": "0.16.3",
40
- "@ttsc/linux-x64": "0.16.3",
41
- "@ttsc/darwin-x64": "0.16.3"
35
+ "@ttsc/linux-x64": "0.16.6",
36
+ "@ttsc/linux-arm": "0.16.6",
37
+ "@ttsc/linux-arm64": "0.16.6",
38
+ "@ttsc/darwin-x64": "0.16.6",
39
+ "@ttsc/win32-x64": "0.16.6",
40
+ "@ttsc/darwin-arm64": "0.16.6",
41
+ "@ttsc/win32-arm64": "0.16.6"
42
42
  },
43
43
  "sideEffects": false,
44
44
  "files": [
package/shim/ast/shim.go CHANGED
@@ -189,6 +189,12 @@ func NewNodeVisitor(visit func(node *Node) *Node, factory *NodeFactory, options
189
189
  return innerast.NewNodeVisitor(visit, factory, options)
190
190
  }
191
191
 
192
+ // GetCombinedModifierFlags returns syntactic modifiers combined across wrappers
193
+ // such as variable statements and their declaration lists.
194
+ func GetCombinedModifierFlags(node *Node) ModifierFlags {
195
+ return innerast.GetCombinedModifierFlags(node)
196
+ }
197
+
192
198
  // IsFunctionLike reports whether node is any function-like construct
193
199
  // (function declaration, arrow function, method, constructor, accessor, etc.).
194
200
  func IsFunctionLike(node *Node) bool {
@@ -81,7 +81,7 @@ func Checker_getPropertiesOfType(recv *innerchecker.Checker, t *innerchecker.Typ
81
81
  }
82
82
 
83
83
  // Checker_getApparentProperties returns the properties visible on t after
84
- // resolving primitive wrapper types (e.g. string → String).
84
+ // resolving primitive wrapper types (e.g. string to String).
85
85
  func Checker_getApparentProperties(recv *innerchecker.Checker, t *innerchecker.Type) []*innerast.Symbol {
86
86
  return recv.GetApparentProperties(t)
87
87
  }
@@ -149,6 +149,16 @@ func Checker_getAliasedSymbol(recv *innerchecker.Checker, symbol *innerast.Symbo
149
149
  return recv.GetAliasedSymbol(symbol)
150
150
  }
151
151
 
152
+ // Checker_getExportsOfModule returns the exported symbols of a source-file or
153
+ // namespace module symbol, resolving export-star aggregation the same way the
154
+ // checker does for emit and services.
155
+ func Checker_getExportsOfModule(recv *innerchecker.Checker, symbol *innerast.Symbol) []*innerast.Symbol {
156
+ if recv == nil || symbol == nil {
157
+ return nil
158
+ }
159
+ return recv.GetExportsOfModule(symbol)
160
+ }
161
+
152
162
  //go:linkname checkerResolveEntityName github.com/microsoft/typescript-go/internal/checker.(*Checker).resolveEntityName
153
163
  func checkerResolveEntityName(
154
164
  recv *innerchecker.Checker,
@@ -215,8 +225,8 @@ func Checker_getBaseTypes(recv *innerchecker.Checker, t *innerchecker.Type) []*i
215
225
  func checkerGetDeclaredTypeOfSymbol(recv *innerchecker.Checker, symbol *innerast.Symbol) *innerchecker.Type
216
226
 
217
227
  // Checker_getDeclaredTypeOfSymbol returns the declared (instance) type of a
218
- // class or interface symbol. Unlike Checker_getTypeOfSymbol — which yields the
219
- // constructor (static) type of a class symbol — the result IS a
228
+ // class or interface symbol. Unlike Checker_getTypeOfSymbol, which yields the
229
+ // constructor (static) type of a class symbol, the result IS a
220
230
  // ClassOrInterface type and is therefore safe to feed back into
221
231
  // Checker_getBaseTypes. This lets a consumer resolve a generic base's symbol to
222
232
  // its declared type and keep walking the base chain past the generic boundary
@@ -275,10 +285,10 @@ func Checker_getReturnTypeOfSignature(recv *innerchecker.Checker, signature *inn
275
285
  // parameter is excluded (it is held separately from the value parameters).
276
286
  //
277
287
  // Checker_getMinArgumentCount alone cannot tell a zero-parameter signature
278
- // (`()` — minimum 0) from a single-optional-parameter one (`(x?)` — also
288
+ // (`()` minimum 0) from a single-optional-parameter one (`(x?)` also
279
289
  // minimum 0). A type-transform plugin needs that distinction to replicate the
280
- // type-level "single meaningful argument" rule — a FIRST parameter must exist
281
- // and every later parameter must be optional or rest — as
290
+ // type-level "single meaningful argument" rule: a FIRST parameter must exist
291
+ // and every later parameter must be optional or rest, as
282
292
  // `Signature_parameterCount(sig) >= 1 && Checker_getMinArgumentCount(c, sig) <= 1`.
283
293
  // Without it the `new C(x)` / `C.from(x)` strategies silently fall back to field
284
294
  // copy for every optional-first constructor or factory. Returns 0 if signature
@@ -297,7 +307,7 @@ func Signature_parameterCount(signature *innerchecker.Signature) int {
297
307
  // yields the seed TYPE the plugin must decode before constructing the instance.
298
308
  //
299
309
  // Signature_parameterCount is len() of this slice; the slice itself is needed
300
- // because detection (count + min-args) is not enough — emission requires the
310
+ // because detection (count + min-args) is not enough; emission requires the
301
311
  // seed parameter's type. Returns nil if signature is nil.
302
312
  func Signature_parameters(signature *innerchecker.Signature) []*innerast.Symbol {
303
313
  if signature == nil {
@@ -308,8 +318,8 @@ func Signature_parameters(signature *innerchecker.Signature) []*innerast.Symbol
308
318
 
309
319
  // Signature_hasRestParameter reports whether the signature's last value
310
320
  // parameter is a rest parameter (`...xs: S[]`). It is the signal a from/new
311
- // transform needs to tell a rest-only single-seed call `(...xs: S[])` — whose
312
- // seed is the ELEMENT S — from a genuine array-typed parameter `(seed: S[])` —
321
+ // transform needs to tell a rest-only single-seed call `(...xs: S[])`, whose
322
+ // seed is the ELEMENT S, from a genuine array-typed parameter `(seed: S[])`,
313
323
  // whose seed is the array S[]: getTypeOfSymbol yields `S[]` for BOTH, so without
314
324
  // this flag they are indistinguishable and the rest case decodes the wrong
315
325
  // shape.
@@ -317,8 +327,8 @@ func Signature_parameters(signature *innerchecker.Signature) []*innerast.Symbol
317
327
  // The rest ELEMENT is the seed ONLY when the rest parameter is the sole value
318
328
  // parameter, i.e. `Signature_hasRestParameter(sig) && Signature_parameterCount(sig) == 1`.
319
329
  // A leading-required + rest-tail signature `(s: S, ...r: R[])` also has a rest
320
- // parameter (this returns true), but its seed is the FIRST parameter S — read it
321
- // from Signature_parameters(sig)[0], NOT the rest element — matching
330
+ // parameter (this returns true), but its seed is the FIRST parameter S. Read it
331
+ // from Signature_parameters(sig)[0], NOT the rest element, matching
322
332
  // ClassifiableSeed, whose `[infer P, ...Rest]` arm picks P=S there. Returns
323
333
  // false if signature is nil.
324
334
  func Signature_hasRestParameter(signature *innerchecker.Signature) bool {
@@ -330,7 +340,7 @@ func Signature_hasRestParameter(signature *innerchecker.Signature) bool {
330
340
 
331
341
  // Checker_getRestTypeOfSignature returns the ELEMENT type of the signature's
332
342
  // rest parameter (`...xs: S[]` -> S; a tuple rest unwraps to its element too),
333
- // which is the seed type for a rest-ONLY single-argument constructor/factory —
343
+ // which is the seed type for a rest-ONLY single-argument constructor/factory,
334
344
  // matching ClassifiableSeed, which unwraps the rest to its element. When the
335
345
  // signature has NO rest parameter it falls back to `any` upstream; and a
336
346
  // leading-required + rest-tail `(s: S, ...r: R[])` has a rest parameter yet its