ttsc 0.8.0 → 0.9.0
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 +75 -66
- package/cmd/ttsc/api_compile.go +5 -1
- package/driver/program.go +23 -1
- package/driver/rewrite.go +126 -9
- package/driver/rewrite_test.go +52 -0
- package/lib/TtscCompiler.js +28 -46
- package/lib/TtscCompiler.js.map +1 -1
- package/lib/compiler/internal/buildNativeCompiler.js +8 -38
- package/lib/compiler/internal/buildNativeCompiler.js.map +1 -1
- package/lib/compiler/internal/compileProjectInMemory.js +36 -63
- package/lib/compiler/internal/compileProjectInMemory.js.map +1 -1
- package/lib/compiler/internal/project/readProjectConfig.js +108 -60
- package/lib/compiler/internal/project/readProjectConfig.js.map +1 -1
- package/lib/compiler/internal/project/resolveProjectConfig.js +15 -45
- package/lib/compiler/internal/project/resolveProjectConfig.js.map +1 -1
- package/lib/compiler/internal/resolveBinary.js +10 -40
- package/lib/compiler/internal/resolveBinary.js.map +1 -1
- package/lib/compiler/internal/resolveEmittedJavaScript.js +21 -48
- package/lib/compiler/internal/resolveEmittedJavaScript.js.map +1 -1
- package/lib/compiler/internal/resolveTsgo.js +14 -44
- package/lib/compiler/internal/resolveTsgo.js.map +1 -1
- package/lib/compiler/internal/runBuild.d.ts +7 -0
- package/lib/compiler/internal/runBuild.js +47 -66
- package/lib/compiler/internal/runBuild.js.map +1 -1
- package/lib/compiler/internal/runSingleFileEmit.js +18 -48
- package/lib/compiler/internal/runSingleFileEmit.js.map +1 -1
- package/lib/compiler/internal/transformProjectInMemory.js +41 -75
- package/lib/compiler/internal/transformProjectInMemory.js.map +1 -1
- package/lib/launcher/internal/getCompilerVersionText.js +7 -37
- package/lib/launcher/internal/getCompilerVersionText.js.map +1 -1
- package/lib/launcher/internal/prepareExecution.js +48 -69
- package/lib/launcher/internal/prepareExecution.js.map +1 -1
- package/lib/launcher/internal/runTtsc.js +53 -64
- package/lib/launcher/internal/runTtsc.js.map +1 -1
- package/lib/launcher/internal/runTtsx.js +328 -57
- package/lib/launcher/internal/runTtsx.js.map +1 -1
- package/lib/plugin/internal/buildSourcePlugin.d.ts +8 -0
- package/lib/plugin/internal/buildSourcePlugin.js +179 -125
- package/lib/plugin/internal/buildSourcePlugin.js.map +1 -1
- package/lib/plugin/internal/loadProjectPlugins.d.ts +2 -0
- package/lib/plugin/internal/loadProjectPlugins.js +197 -9
- package/lib/plugin/internal/loadProjectPlugins.js.map +1 -1
- package/lib/structures/ITtscCompilerContext.d.ts +16 -3
- package/lib/structures/ITtscCompilerResult.d.ts +4 -0
- package/lib/structures/ITtscCompilerTransformation.d.ts +2 -0
- package/lib/structures/ITtscPluginFactoryContext.d.ts +6 -3
- package/lib/structures/ITtscProjectPluginConfig.d.ts +8 -7
- package/lib/structures/internal/ITtscParsedProjectConfig.d.ts +2 -0
- package/lib/structures/internal/ITtscProjectLocatorOptions.d.ts +2 -0
- package/lib/structures/internal/TtscCommonOptions.d.ts +2 -0
- package/package.json +9 -14
- package/shim/diagnosticwriter/lint.go +8 -0
- package/src/TtscCompiler.ts +20 -5
- package/src/compiler/internal/buildNativeCompiler.ts +2 -2
- package/src/compiler/internal/compileProjectInMemory.ts +21 -16
- package/src/compiler/internal/project/readProjectConfig.ts +134 -35
- package/src/compiler/internal/project/resolveProjectConfig.ts +2 -2
- package/src/compiler/internal/resolveBinary.ts +2 -2
- package/src/compiler/internal/resolveEmittedJavaScript.ts +11 -7
- package/src/compiler/internal/resolveTsgo.ts +2 -2
- package/src/compiler/internal/runBuild.ts +34 -21
- package/src/compiler/internal/runSingleFileEmit.ts +3 -3
- package/src/compiler/internal/transformProjectInMemory.ts +37 -37
- package/src/launcher/internal/getCompilerVersionText.ts +2 -2
- package/src/launcher/internal/prepareExecution.ts +14 -4
- package/src/launcher/internal/runTtsc.ts +30 -4
- package/src/launcher/internal/runTtsx.ts +377 -26
- package/src/plugin/internal/buildSourcePlugin.ts +127 -32
- package/src/plugin/internal/loadProjectPlugins.ts +266 -10
- package/src/structures/ITtscCompilerContext.ts +17 -3
- package/src/structures/ITtscCompilerResult.ts +5 -0
- package/src/structures/ITtscCompilerTransformation.ts +3 -0
- package/src/structures/ITtscPluginFactoryContext.ts +6 -3
- package/src/structures/ITtscProjectPluginConfig.ts +8 -7
- package/src/structures/internal/ITtscParsedProjectConfig.ts +2 -0
- package/src/structures/internal/ITtscProjectLocatorOptions.ts +2 -0
- package/src/structures/internal/TtscCommonOptions.ts +2 -0
- package/utility/host.go +610 -18
- package/utility/host_test.go +162 -0
- package/test/compiler.test.ts +0 -422
- package/test/platform.test.ts +0 -12
- package/test/project.test.ts +0 -197
- package/test/source-build.test.ts +0 -45
- package/test/tsgo.test.ts +0 -69
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import fs from "node:fs";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
|
-
import
|
|
3
|
+
import path from "node:path";
|
|
4
4
|
|
|
5
5
|
import type { ITtscProjectPluginConfig } from "../../../structures/ITtscProjectPluginConfig";
|
|
6
6
|
import type { ITtscParsedProjectConfig } from "../../../structures/internal/ITtscParsedProjectConfig";
|
|
@@ -8,12 +8,25 @@ import type { ITtscProjectLocatorOptions } from "../../../structures/internal/IT
|
|
|
8
8
|
|
|
9
9
|
import { resolveProjectConfig } from "./resolveProjectConfig";
|
|
10
10
|
|
|
11
|
+
const PATH_OPTIONS = new Set(["baseUrl", "declarationDir", "rootDir"]);
|
|
12
|
+
|
|
13
|
+
type ResolvedCompilerOptions = {
|
|
14
|
+
options: Record<string, unknown>;
|
|
15
|
+
optionBaseDirs: Record<string, string>;
|
|
16
|
+
outDir?: string;
|
|
17
|
+
pluginBaseDirs: string[];
|
|
18
|
+
pluginsDeclared: boolean;
|
|
19
|
+
plugins: ITtscProjectPluginConfig[];
|
|
20
|
+
};
|
|
21
|
+
|
|
11
22
|
/** Read the resolved project config subset used by ttsc. */
|
|
12
23
|
export function readProjectConfig(
|
|
13
24
|
opts: ITtscProjectLocatorOptions = {},
|
|
14
25
|
): ITtscParsedProjectConfig {
|
|
15
26
|
const tsconfig = resolveProjectConfig(opts);
|
|
16
|
-
const root =
|
|
27
|
+
const root = opts.projectRoot
|
|
28
|
+
? path.resolve(opts.cwd ?? process.cwd(), opts.projectRoot)
|
|
29
|
+
: path.dirname(tsconfig);
|
|
17
30
|
const compilerOptions = readResolvedCompilerOptions(tsconfig);
|
|
18
31
|
return {
|
|
19
32
|
compilerOptions: {
|
|
@@ -22,6 +35,7 @@ export function readProjectConfig(
|
|
|
22
35
|
plugins: compilerOptions.plugins,
|
|
23
36
|
},
|
|
24
37
|
path: tsconfig,
|
|
38
|
+
pluginBaseDirs: compilerOptions.pluginBaseDirs,
|
|
25
39
|
root,
|
|
26
40
|
};
|
|
27
41
|
}
|
|
@@ -47,46 +61,131 @@ function resolveAbsolutePath(cwd: string, target: string): string {
|
|
|
47
61
|
function readResolvedCompilerOptions(
|
|
48
62
|
tsconfig: string,
|
|
49
63
|
seen: Set<string> = new Set(),
|
|
50
|
-
): {
|
|
51
|
-
options: Record<string, unknown>;
|
|
52
|
-
outDir?: string;
|
|
53
|
-
plugins: ITtscProjectPluginConfig[];
|
|
54
|
-
} {
|
|
64
|
+
): ResolvedCompilerOptions {
|
|
55
65
|
const canonical = resolveRealPath(tsconfig);
|
|
56
66
|
if (seen.has(canonical)) {
|
|
57
67
|
throw new Error(`ttsc: circular tsconfig extends detected: ${canonical}`);
|
|
58
68
|
}
|
|
59
69
|
seen.add(canonical);
|
|
70
|
+
try {
|
|
71
|
+
const parsed = parseJsonc(fs.readFileSync(canonical, "utf8")) as {
|
|
72
|
+
extends?: unknown;
|
|
73
|
+
compilerOptions?: Record<string, unknown> & {
|
|
74
|
+
outDir?: unknown;
|
|
75
|
+
plugins?: unknown;
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
const own = parsed.compilerOptions;
|
|
79
|
+
const base = resolveBaseCompilerOptions(canonical, parsed.extends, seen);
|
|
80
|
+
const ownBaseDir = path.dirname(canonical);
|
|
81
|
+
const ownOptionBaseDirs =
|
|
82
|
+
own === undefined
|
|
83
|
+
? {}
|
|
84
|
+
: Object.fromEntries(
|
|
85
|
+
Object.keys(own).map((key) => [key, ownBaseDir] as const),
|
|
86
|
+
);
|
|
87
|
+
const optionBaseDirs = {
|
|
88
|
+
...base.optionBaseDirs,
|
|
89
|
+
...ownOptionBaseDirs,
|
|
90
|
+
};
|
|
91
|
+
const options = resolvePathOptions(
|
|
92
|
+
{
|
|
93
|
+
...base.options,
|
|
94
|
+
...(own ?? {}),
|
|
95
|
+
},
|
|
96
|
+
optionBaseDirs,
|
|
97
|
+
);
|
|
98
|
+
const ownPlugins = own?.plugins;
|
|
99
|
+
const pluginsDeclared = Array.isArray(ownPlugins);
|
|
100
|
+
const plugins = pluginsDeclared
|
|
101
|
+
? ownPlugins.filter(isProjectPluginConfig)
|
|
102
|
+
: base.plugins;
|
|
103
|
+
return {
|
|
104
|
+
optionBaseDirs,
|
|
105
|
+
options,
|
|
106
|
+
outDir:
|
|
107
|
+
typeof own?.outDir === "string"
|
|
108
|
+
? resolveAbsolutePath(ownBaseDir, own.outDir)
|
|
109
|
+
: base.outDir,
|
|
110
|
+
pluginBaseDirs: pluginsDeclared
|
|
111
|
+
? plugins.map(() => ownBaseDir)
|
|
112
|
+
: base.pluginBaseDirs,
|
|
113
|
+
pluginsDeclared: pluginsDeclared || base.pluginsDeclared,
|
|
114
|
+
plugins,
|
|
115
|
+
};
|
|
116
|
+
} finally {
|
|
117
|
+
seen.delete(canonical);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
60
120
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
121
|
+
function resolveBaseCompilerOptions(
|
|
122
|
+
tsconfig: string,
|
|
123
|
+
extended: unknown,
|
|
124
|
+
seen: Set<string>,
|
|
125
|
+
): ResolvedCompilerOptions {
|
|
126
|
+
if (typeof extended === "string") {
|
|
127
|
+
return readResolvedCompilerOptions(
|
|
128
|
+
resolveExtendsConfig(tsconfig, extended),
|
|
129
|
+
seen,
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
if (!Array.isArray(extended)) {
|
|
133
|
+
return {
|
|
134
|
+
optionBaseDirs: {},
|
|
135
|
+
options: {},
|
|
136
|
+
pluginBaseDirs: [],
|
|
137
|
+
pluginsDeclared: false,
|
|
138
|
+
plugins: [],
|
|
66
139
|
};
|
|
140
|
+
}
|
|
141
|
+
let merged: ResolvedCompilerOptions = {
|
|
142
|
+
optionBaseDirs: {},
|
|
143
|
+
options: {},
|
|
144
|
+
pluginBaseDirs: [],
|
|
145
|
+
pluginsDeclared: false,
|
|
146
|
+
plugins: [],
|
|
67
147
|
};
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
148
|
+
for (const specifier of extended) {
|
|
149
|
+
if (typeof specifier !== "string") {
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
const current = readResolvedCompilerOptions(
|
|
153
|
+
resolveExtendsConfig(tsconfig, specifier),
|
|
154
|
+
seen,
|
|
155
|
+
);
|
|
156
|
+
merged = {
|
|
157
|
+
optionBaseDirs: {
|
|
158
|
+
...merged.optionBaseDirs,
|
|
159
|
+
...current.optionBaseDirs,
|
|
160
|
+
},
|
|
161
|
+
options: {
|
|
162
|
+
...merged.options,
|
|
163
|
+
...current.options,
|
|
164
|
+
},
|
|
165
|
+
outDir: current.outDir ?? merged.outDir,
|
|
166
|
+
pluginBaseDirs: current.pluginsDeclared
|
|
167
|
+
? current.pluginBaseDirs
|
|
168
|
+
: merged.pluginBaseDirs,
|
|
169
|
+
plugins: current.pluginsDeclared ? current.plugins : merged.plugins,
|
|
170
|
+
pluginsDeclared: merged.pluginsDeclared || current.pluginsDeclared,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
return merged;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function resolvePathOptions(
|
|
177
|
+
options: Record<string, unknown>,
|
|
178
|
+
baseDirs: Record<string, string>,
|
|
179
|
+
): Record<string, unknown> {
|
|
180
|
+
const resolved = { ...options };
|
|
181
|
+
for (const key of PATH_OPTIONS) {
|
|
182
|
+
const value = resolved[key];
|
|
183
|
+
const baseDir = baseDirs[key];
|
|
184
|
+
if (typeof value === "string" && baseDir !== undefined) {
|
|
185
|
+
resolved[key] = resolveAbsolutePath(baseDir, value);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return resolved;
|
|
90
189
|
}
|
|
91
190
|
|
|
92
191
|
function resolveExtendsConfig(tsconfig: string, specifier: string): string {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
3
|
|
|
4
4
|
/** Locate the JavaScript file emitted for a TypeScript source file. */
|
|
5
5
|
export function resolveEmittedJavaScript(options: {
|
|
@@ -37,11 +37,7 @@ function resolveExactEmittedFile(
|
|
|
37
37
|
sourceFile: string,
|
|
38
38
|
): string | null {
|
|
39
39
|
const relative = path.relative(projectRoot, sourceFile);
|
|
40
|
-
if (
|
|
41
|
-
relative === "" ||
|
|
42
|
-
relative.startsWith("..") ||
|
|
43
|
-
path.isAbsolute(relative)
|
|
44
|
-
) {
|
|
40
|
+
if (relative === "" || isOutsideRelativePath(relative)) {
|
|
45
41
|
return null;
|
|
46
42
|
}
|
|
47
43
|
return path.resolve(
|
|
@@ -87,6 +83,14 @@ function sharedSourceStemSegments(outPath: string, srcPath: string): number {
|
|
|
87
83
|
return shared;
|
|
88
84
|
}
|
|
89
85
|
|
|
86
|
+
function isOutsideRelativePath(relative: string): boolean {
|
|
87
|
+
return (
|
|
88
|
+
relative === ".." ||
|
|
89
|
+
relative.startsWith(`..${path.sep}`) ||
|
|
90
|
+
path.isAbsolute(relative)
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
90
94
|
function emittedJavaScriptExtension(filename: string): string {
|
|
91
95
|
switch (path.extname(filename).toLowerCase()) {
|
|
92
96
|
case ".mts":
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import fs from "node:fs";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
|
-
import
|
|
3
|
+
import path from "node:path";
|
|
4
4
|
|
|
5
5
|
/** Resolve the consumer project's TypeScript-Go preview binary. */
|
|
6
6
|
export function resolveTsgo(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { spawnSync } from "node:child_process";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
5
|
|
|
6
6
|
import { loadProjectPlugins } from "../../plugin/internal/loadProjectPlugins";
|
|
7
7
|
import type { ITtscCompilerDiagnostic } from "../../structures/ITtscCompilerDiagnostic";
|
|
@@ -112,10 +112,10 @@ export function runBuild(
|
|
|
112
112
|
buildWithNativeCompilerPlugins(options, execution, compilers),
|
|
113
113
|
);
|
|
114
114
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
115
|
+
return appendBuildOutput(
|
|
116
|
+
checked,
|
|
117
|
+
runTsgo(execution, ["--noEmit"], options),
|
|
118
|
+
);
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
let result: TtscBuildResult;
|
|
@@ -126,14 +126,10 @@ export function runBuild(
|
|
|
126
126
|
buildWithNativeCompilerPlugins(options, execution, compilers),
|
|
127
127
|
);
|
|
128
128
|
} else {
|
|
129
|
-
if (
|
|
130
|
-
checked.stdout === "" &&
|
|
131
|
-
checked.stderr === "" &&
|
|
132
|
-
options.skipDiagnosticsCheck !== true
|
|
133
|
-
) {
|
|
129
|
+
if (options.skipDiagnosticsCheck !== true) {
|
|
134
130
|
const tsgoChecked = runTsgo(execution, ["--noEmit"], options);
|
|
135
131
|
if (tsgoChecked.status !== 0) {
|
|
136
|
-
return tsgoChecked;
|
|
132
|
+
return appendBuildOutput(checked, tsgoChecked);
|
|
137
133
|
}
|
|
138
134
|
}
|
|
139
135
|
const args = createTsgoBuildArgs(execution, options, {
|
|
@@ -201,7 +197,7 @@ function runTsgo(
|
|
|
201
197
|
res.error.message,
|
|
202
198
|
);
|
|
203
199
|
}
|
|
204
|
-
return
|
|
200
|
+
return normalizeBuildOutput(
|
|
205
201
|
{
|
|
206
202
|
status: res.status ?? 1,
|
|
207
203
|
stdout: outputText(res.stdout),
|
|
@@ -238,7 +234,7 @@ function runTsgoBuild(
|
|
|
238
234
|
if (emittedFiles.length !== 0) {
|
|
239
235
|
result.stdout = stripEmittedFileLines(result.stdout);
|
|
240
236
|
}
|
|
241
|
-
return
|
|
237
|
+
return normalizeBuildOutput(
|
|
242
238
|
{ ...result, emittedFiles },
|
|
243
239
|
execution.projectRoot,
|
|
244
240
|
);
|
|
@@ -374,7 +370,7 @@ function runNativePluginCommand(
|
|
|
374
370
|
`${label}: failed to spawn ${plugin.binary}: ${res.error.message}`,
|
|
375
371
|
);
|
|
376
372
|
}
|
|
377
|
-
return
|
|
373
|
+
return normalizeBuildOutput(
|
|
378
374
|
{
|
|
379
375
|
status: res.status ?? 1,
|
|
380
376
|
stdout: outputText(res.stdout),
|
|
@@ -384,11 +380,11 @@ function runNativePluginCommand(
|
|
|
384
380
|
);
|
|
385
381
|
}
|
|
386
382
|
|
|
387
|
-
function appendBuildOutput(
|
|
383
|
+
export function appendBuildOutput(
|
|
388
384
|
left: TtscBuildResult,
|
|
389
385
|
right: TtscBuildResult,
|
|
390
386
|
): TtscBuildResult {
|
|
391
|
-
return
|
|
387
|
+
return normalizeBuildOutput({
|
|
392
388
|
diagnostics: [...left.diagnostics, ...right.diagnostics],
|
|
393
389
|
emittedFiles:
|
|
394
390
|
right.emittedFiles !== undefined ? right.emittedFiles : left.emittedFiles,
|
|
@@ -461,7 +457,9 @@ function resolveExecutionContext(
|
|
|
461
457
|
cwd,
|
|
462
458
|
tsconfig: options.tsconfig,
|
|
463
459
|
});
|
|
464
|
-
const projectRoot =
|
|
460
|
+
const projectRoot = options.projectRoot
|
|
461
|
+
? path.resolve(cwd, options.projectRoot)
|
|
462
|
+
: path.dirname(tsconfig);
|
|
465
463
|
const tsgo = resolveTsgo({ ...options, cwd: projectRoot });
|
|
466
464
|
const fallbackBinary = resolveBinary(options);
|
|
467
465
|
const loaded = loadProjectPlugins({
|
|
@@ -469,6 +467,7 @@ function resolveExecutionContext(
|
|
|
469
467
|
cacheDir: options.cacheDir ?? options.env?.TTSC_CACHE_DIR,
|
|
470
468
|
cwd,
|
|
471
469
|
entries: options.plugins,
|
|
470
|
+
projectRoot,
|
|
472
471
|
tsconfig,
|
|
473
472
|
});
|
|
474
473
|
return {
|
|
@@ -503,7 +502,7 @@ type PartialBuildResult = Omit<TtscBuildResult, "diagnostics"> & {
|
|
|
503
502
|
diagnostics?: ITtscCompilerDiagnostic[];
|
|
504
503
|
};
|
|
505
504
|
|
|
506
|
-
function
|
|
505
|
+
export function normalizeBuildOutput(
|
|
507
506
|
result: PartialBuildResult,
|
|
508
507
|
cwd?: string,
|
|
509
508
|
): TtscBuildResult {
|
|
@@ -557,6 +556,20 @@ function parseDiagnosticLine(
|
|
|
557
556
|
line: string,
|
|
558
557
|
cwd: string | undefined,
|
|
559
558
|
): ITtscCompilerDiagnostic | null {
|
|
559
|
+
const colonMatch = line.match(
|
|
560
|
+
/^(.+):(\d+):(\d+)\s+-\s+(error|warning|suggestion|message)\s+([A-Z]+)?(\d+|[A-Z][A-Z0-9_-]*):\s+(.+)$/i,
|
|
561
|
+
);
|
|
562
|
+
if (colonMatch) {
|
|
563
|
+
return {
|
|
564
|
+
category: normalizeDiagnosticCategory(colonMatch[4]!),
|
|
565
|
+
character: Number(colonMatch[3]),
|
|
566
|
+
code: normalizeDiagnosticCode(colonMatch[6]!),
|
|
567
|
+
file: normalizeDiagnosticFile(colonMatch[1]!, cwd),
|
|
568
|
+
line: Number(colonMatch[2]),
|
|
569
|
+
messageText: colonMatch[7]!,
|
|
570
|
+
};
|
|
571
|
+
}
|
|
572
|
+
|
|
560
573
|
const fileMatch = line.match(
|
|
561
574
|
/^(.+?)\((\d+),(\d+)\):\s+(error|warning|suggestion|message)\s+([A-Z]+)?(\d+|[A-Z][A-Z0-9_-]*):\s+(.+)$/i,
|
|
562
575
|
);
|
|
@@ -611,5 +624,5 @@ function normalizeDiagnosticCode(value: string): number | string {
|
|
|
611
624
|
}
|
|
612
625
|
|
|
613
626
|
function stripAnsi(text: string): string {
|
|
614
|
-
return text.replace(/\x1b\[[0-9
|
|
627
|
+
return text.replace(/\x1b\[[0-9;?]*[ -/]*[@-~]/g, "");
|
|
615
628
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
4
|
|
|
5
5
|
import type { TtscSingleFileEmitOptions } from "../../structures/internal/TtscSingleFileEmitOptions";
|
|
6
6
|
import { resolveProjectConfig } from "./project/resolveProjectConfig";
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { spawnSync } from "node:child_process";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
hasProjectPluginEntries,
|
|
7
|
+
loadProjectPlugins,
|
|
8
|
+
} from "../../plugin/internal/loadProjectPlugins";
|
|
6
9
|
import type { ITtscCompilerContext } from "../../structures/ITtscCompilerContext";
|
|
7
10
|
import type { ITtscCompilerDiagnostic } from "../../structures/ITtscCompilerDiagnostic";
|
|
8
|
-
import type { ITtscProjectPluginConfig } from "../../structures/ITtscProjectPluginConfig";
|
|
9
11
|
import type { ITtscLoadedNativePlugin } from "../../structures/internal/ITtscLoadedNativePlugin";
|
|
10
12
|
import type { ITtscParsedProjectConfig } from "../../structures/internal/ITtscParsedProjectConfig";
|
|
11
13
|
import type { TtscBuildResult } from "../../structures/internal/TtscBuildResult";
|
|
@@ -13,6 +15,7 @@ import { buildNativeCompiler } from "./buildNativeCompiler";
|
|
|
13
15
|
import { readProjectConfig } from "./project/readProjectConfig";
|
|
14
16
|
import { resolveBinary } from "./resolveBinary";
|
|
15
17
|
import { resolveTsgo } from "./resolveTsgo";
|
|
18
|
+
import { appendBuildOutput, normalizeBuildOutput } from "./runBuild";
|
|
16
19
|
|
|
17
20
|
/** Transform a project and capture TypeScript source output in memory. */
|
|
18
21
|
export function transformProjectInMemory(options: ITtscCompilerContext): {
|
|
@@ -22,23 +25,20 @@ export function transformProjectInMemory(options: ITtscCompilerContext): {
|
|
|
22
25
|
const cwd = path.resolve(options.cwd ?? process.cwd());
|
|
23
26
|
const project = readProjectConfig({
|
|
24
27
|
cwd,
|
|
28
|
+
projectRoot: options.projectRoot,
|
|
25
29
|
tsconfig: options.tsconfig,
|
|
26
30
|
});
|
|
27
|
-
if (
|
|
31
|
+
if (hasConfiguredPlugins(options, project)) {
|
|
28
32
|
return transformProjectWithPlugins(options, cwd, project);
|
|
29
33
|
}
|
|
30
34
|
return transformProjectWithNativeHost(options, project);
|
|
31
35
|
}
|
|
32
36
|
|
|
33
|
-
function
|
|
37
|
+
function hasConfiguredPlugins(
|
|
34
38
|
options: ITtscCompilerContext,
|
|
35
39
|
project: ITtscParsedProjectConfig,
|
|
36
|
-
):
|
|
37
|
-
|
|
38
|
-
return [];
|
|
39
|
-
}
|
|
40
|
-
const entries = options.plugins ?? project.compilerOptions.plugins;
|
|
41
|
-
return entries.filter((entry) => entry.enabled !== false);
|
|
40
|
+
): boolean {
|
|
41
|
+
return hasProjectPluginEntries(project, options.plugins);
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
function transformProjectWithNativeHost(
|
|
@@ -95,6 +95,7 @@ function transformProjectWithPlugins(
|
|
|
95
95
|
cacheDir: options.cacheDir ?? options.env?.TTSC_CACHE_DIR,
|
|
96
96
|
cwd,
|
|
97
97
|
entries: options.plugins,
|
|
98
|
+
projectRoot: options.projectRoot,
|
|
98
99
|
tsconfig: project.path,
|
|
99
100
|
});
|
|
100
101
|
const checks = loaded.nativePlugins.filter(
|
|
@@ -116,7 +117,11 @@ function transformProjectWithPlugins(
|
|
|
116
117
|
};
|
|
117
118
|
}
|
|
118
119
|
if (transformers.length === 0) {
|
|
119
|
-
|
|
120
|
+
const transformed = transformProjectWithNativeHost(options, project);
|
|
121
|
+
return {
|
|
122
|
+
result: appendBuildOutput(checked, transformed.result),
|
|
123
|
+
typescript: transformed.typescript,
|
|
124
|
+
};
|
|
120
125
|
}
|
|
121
126
|
assertTransformHostCompatibility(transformers);
|
|
122
127
|
|
|
@@ -138,13 +143,14 @@ function transformProjectWithPlugins(
|
|
|
138
143
|
outputText(res.stdout),
|
|
139
144
|
outputText(res.stderr),
|
|
140
145
|
);
|
|
146
|
+
const result = {
|
|
147
|
+
diagnostics: output.diagnostics,
|
|
148
|
+
status: res.status ?? 1,
|
|
149
|
+
stdout: "",
|
|
150
|
+
stderr: outputText(res.stderr),
|
|
151
|
+
};
|
|
141
152
|
return {
|
|
142
|
-
result:
|
|
143
|
-
diagnostics: output.diagnostics,
|
|
144
|
-
status: res.status ?? 1,
|
|
145
|
-
stdout: "",
|
|
146
|
-
stderr: outputText(res.stderr),
|
|
147
|
-
},
|
|
153
|
+
result: appendBuildOutput(checked, result),
|
|
148
154
|
typescript: output.typescript,
|
|
149
155
|
};
|
|
150
156
|
}
|
|
@@ -175,12 +181,17 @@ function runNativeChecks(
|
|
|
175
181
|
`ttsc.transform.check: failed to spawn ${plugin.binary}: ${res.error.message}`,
|
|
176
182
|
);
|
|
177
183
|
}
|
|
178
|
-
result =
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
+
result = appendBuildOutput(
|
|
185
|
+
result,
|
|
186
|
+
normalizeBuildOutput(
|
|
187
|
+
{
|
|
188
|
+
status: res.status ?? 1,
|
|
189
|
+
stdout: outputText(res.stdout),
|
|
190
|
+
stderr: outputText(res.stderr),
|
|
191
|
+
},
|
|
192
|
+
project.root,
|
|
193
|
+
),
|
|
194
|
+
);
|
|
184
195
|
if (result.status !== 0) {
|
|
185
196
|
return result;
|
|
186
197
|
}
|
|
@@ -279,18 +290,6 @@ function readNearestPackageManifest(
|
|
|
279
290
|
return undefined;
|
|
280
291
|
}
|
|
281
292
|
|
|
282
|
-
function appendBuildResult(
|
|
283
|
-
left: TtscBuildResult,
|
|
284
|
-
right: TtscBuildResult,
|
|
285
|
-
): TtscBuildResult {
|
|
286
|
-
return {
|
|
287
|
-
diagnostics: [...left.diagnostics, ...right.diagnostics],
|
|
288
|
-
status: right.status !== 0 ? right.status : left.status,
|
|
289
|
-
stdout: left.stdout + right.stdout,
|
|
290
|
-
stderr: left.stderr + right.stderr,
|
|
291
|
-
};
|
|
292
|
-
}
|
|
293
|
-
|
|
294
293
|
function nativePluginEnv(
|
|
295
294
|
options: ITtscCompilerContext,
|
|
296
295
|
projectRoot: string,
|
|
@@ -390,6 +389,7 @@ function isTextRecord(value: unknown): value is Record<string, string> {
|
|
|
390
389
|
return (
|
|
391
390
|
typeof value === "object" &&
|
|
392
391
|
value !== null &&
|
|
392
|
+
!Array.isArray(value) &&
|
|
393
393
|
Object.values(value).every((entry) => typeof entry === "string")
|
|
394
394
|
);
|
|
395
395
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { spawnSync } from "node:child_process";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
4
|
|
|
5
5
|
import { resolveTsgo } from "../../compiler/internal/resolveTsgo";
|
|
6
6
|
import type { TtscCommonOptions } from "../../structures/internal/TtscCommonOptions";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
4
|
|
|
5
5
|
import { resolveEmittedJavaScript } from "../../compiler/internal/resolveEmittedJavaScript";
|
|
6
6
|
import { runBuild } from "../../compiler/internal/runBuild";
|
|
@@ -57,8 +57,9 @@ function createProjectContext(
|
|
|
57
57
|
);
|
|
58
58
|
const tsconfig = project.path;
|
|
59
59
|
const root = project.root;
|
|
60
|
+
const explicitCacheDir = resolveCacheDir(cwd, options.cacheDir);
|
|
60
61
|
const cacheDir =
|
|
61
|
-
|
|
62
|
+
explicitCacheDir ??
|
|
62
63
|
path.join(root, "node_modules", ".cache", "ttsc", "ttsx");
|
|
63
64
|
const processDir = path.join(cacheDir, "project", PROCESS_CACHE_KEY);
|
|
64
65
|
const virtualRoot = path.join(processDir, "fs");
|
|
@@ -67,6 +68,7 @@ function createProjectContext(
|
|
|
67
68
|
root,
|
|
68
69
|
cacheDir,
|
|
69
70
|
processDir,
|
|
71
|
+
pluginCacheDir: explicitCacheDir,
|
|
70
72
|
virtualRoot,
|
|
71
73
|
emitDir: project.compilerOptions.outDir
|
|
72
74
|
? virtualPath(virtualRoot, project.compilerOptions.outDir)
|
|
@@ -104,6 +106,7 @@ function buildProject(
|
|
|
104
106
|
emit: true,
|
|
105
107
|
env: options.env,
|
|
106
108
|
forceListEmittedFiles: true,
|
|
109
|
+
cacheDir: context.pluginCacheDir,
|
|
107
110
|
outDir: context.emitDir,
|
|
108
111
|
plugins: options.plugins,
|
|
109
112
|
quiet: true,
|
|
@@ -129,6 +132,13 @@ function buildProject(
|
|
|
129
132
|
throw new Error(detail);
|
|
130
133
|
}
|
|
131
134
|
|
|
135
|
+
function resolveCacheDir(cwd: string, cacheDir?: string): string | undefined {
|
|
136
|
+
if (!cacheDir) {
|
|
137
|
+
return undefined;
|
|
138
|
+
}
|
|
139
|
+
return path.isAbsolute(cacheDir) ? cacheDir : path.resolve(cwd, cacheDir);
|
|
140
|
+
}
|
|
141
|
+
|
|
132
142
|
function linkVirtualProjectLayout(
|
|
133
143
|
context: ReturnType<typeof createProjectContext>,
|
|
134
144
|
): void {
|