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.
- 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 +120 -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 +374 -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 +581 -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 +122 -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_attribute_function_assignments_to_members_test.go +59 -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/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/utility/host.go +8 -2
- 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":"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"}
|
package/lib/index.d.ts
CHANGED
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
|
+
"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-
|
|
36
|
-
"@ttsc/
|
|
37
|
-
"@ttsc/
|
|
38
|
-
"@ttsc/
|
|
39
|
-
"@ttsc/
|
|
40
|
-
"@ttsc/
|
|
41
|
-
"@ttsc/
|
|
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 {
|
package/shim/checker/shim.go
CHANGED
|
@@ -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
|
|
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
|
|
219
|
-
// constructor (static) type of a class symbol
|
|
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
|
-
// (`()`
|
|
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
|
|
281
|
-
// and every later parameter must be optional or rest
|
|
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
|
|
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[])
|
|
312
|
-
// seed is the ELEMENT 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
|
|
321
|
-
// from Signature_parameters(sig)[0], NOT the rest element
|
|
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
|