@swiftuijs/twill 0.3.0 → 0.3.1
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 +3 -3
- package/bin/run.mjs +2 -2
- package/dist/cli.js +5 -5
- package/dist/{compiler-CbNSBUI2.js → compiler-BdkU4Ruh.js} +32 -12
- package/dist/compiler-BdkU4Ruh.js.map +1 -0
- package/dist/config-la_KkjCS.js +1 -0
- package/dist/config.js +1 -0
- package/dist/declarations-BTAS8Mb_.js +132 -0
- package/dist/declarations-BTAS8Mb_.js.map +1 -0
- package/dist/declarations.js +1 -131
- package/dist/doctor-Co_pdZtt.js +202 -0
- package/dist/doctor-Co_pdZtt.js.map +1 -0
- package/dist/doctor.js +1 -201
- package/dist/editor.js +1 -1
- package/dist/esbuild.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{loader-compiler-D1teTrXw.js → loader-compiler.js} +2 -2
- package/dist/loader-compiler.js.map +1 -0
- package/dist/loader-registration-B1ST9h1e.js +15 -0
- package/dist/loader-registration-B1ST9h1e.js.map +1 -0
- package/dist/loader-registration.d.ts +4 -0
- package/dist/loader-registration.js +2 -0
- package/dist/loader-state-DE2ArGYl.js +61 -0
- package/dist/loader-state-DE2ArGYl.js.map +1 -0
- package/dist/loader-state.d.ts +34 -0
- package/dist/loader-sync.d.ts +3 -0
- package/dist/loader-sync.js +28 -0
- package/dist/loader-sync.js.map +1 -0
- package/dist/loader.d.ts +2 -4
- package/dist/loader.js +9 -46
- package/dist/loader.js.map +1 -1
- package/dist/{plugin-BHfiQ2L-.js → plugin-DdTVagIU.js} +2 -2
- package/dist/{plugin-BHfiQ2L-.js.map → plugin-DdTVagIU.js.map} +1 -1
- package/dist/project-ZmlpFooa.js +444 -0
- package/dist/project-ZmlpFooa.js.map +1 -0
- package/dist/project.js +1 -442
- package/dist/register.js +2 -2
- package/dist/register.js.map +1 -1
- package/dist/rollup.js +1 -1
- package/dist/rspack.js +1 -1
- package/dist/syntax.js +1 -1
- package/dist/{transpile-D8P8Lsbx.js → transpile-CLNavDUr.js} +2 -2
- package/dist/{transpile-D8P8Lsbx.js.map → transpile-CLNavDUr.js.map} +1 -1
- package/dist/typescript-plugin.cjs +31 -11
- package/dist/typescript-plugin.cjs.map +1 -1
- package/dist/vite-BI-5KRgr.js +7 -0
- package/dist/vite-BI-5KRgr.js.map +1 -0
- package/dist/vite-react.js +1 -1
- package/dist/vite.js +1 -6
- package/dist/webpack.js +1 -1
- package/package.json +2 -2
- package/dist/compiler-CbNSBUI2.js.map +0 -1
- package/dist/declarations.js.map +0 -1
- package/dist/doctor.js.map +0 -1
- package/dist/loader-compiler-D1teTrXw.js.map +0 -1
- package/dist/project.js.map +0 -1
- package/dist/vite.js.map +0 -1
package/dist/project.js
CHANGED
|
@@ -1,444 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as isTwillFile, t as extensions } from "./extensions-B1xTkoYP.js";
|
|
3
|
-
import { n as loadConfig } from "./configuration-BVMf6Q_j.js";
|
|
1
|
+
import { n as sourceFilename, r as virtualFilename, t as TwillProject } from "./project-ZmlpFooa.js";
|
|
4
2
|
import { t as isDependency } from "./files-BW9geU0_.js";
|
|
5
|
-
import MagicString from "magic-string";
|
|
6
|
-
import { dirname, resolve } from "node:path";
|
|
7
|
-
import ts from "typescript";
|
|
8
|
-
import remapping from "@ampproject/remapping";
|
|
9
|
-
//#region src/recovery.ts
|
|
10
|
-
/** Editor-only recovery; build and CLI compilation always use strict parsing. */
|
|
11
|
-
function recoverTransform(source, options, onSyntaxError) {
|
|
12
|
-
const repaired = new MagicString(source);
|
|
13
|
-
let text = source;
|
|
14
|
-
for (let attempt = 0; attempt < 8; attempt++) try {
|
|
15
|
-
const result = transform(text, options);
|
|
16
|
-
if (text === source) return result;
|
|
17
|
-
const repairMap = repaired.generateMap({
|
|
18
|
-
source: options.filename,
|
|
19
|
-
includeContent: true,
|
|
20
|
-
hires: true
|
|
21
|
-
});
|
|
22
|
-
const repairedResult = {
|
|
23
|
-
...result,
|
|
24
|
-
map: repairMap
|
|
25
|
-
};
|
|
26
|
-
const starts = [0];
|
|
27
|
-
for (const match of source.matchAll(/\n/g)) starts.push(match.index + 1);
|
|
28
|
-
const sourceOffset = (offset) => {
|
|
29
|
-
const prefix = text.slice(0, offset).split("\n");
|
|
30
|
-
const point = originalPosition(repairedResult, prefix.length, prefix.at(-1).length);
|
|
31
|
-
return starts[point.line - 1] + point.column;
|
|
32
|
-
};
|
|
33
|
-
const enumPatterns = result.enumPatterns.map((pattern) => ({
|
|
34
|
-
...pattern,
|
|
35
|
-
reference: {
|
|
36
|
-
...pattern.reference,
|
|
37
|
-
property: {
|
|
38
|
-
...pattern.reference.property,
|
|
39
|
-
start: sourceOffset(pattern.reference.property.start),
|
|
40
|
-
end: sourceOffset(pattern.reference.property.end)
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}));
|
|
44
|
-
const map = remapping([JSON.parse(result.map.toString()), JSON.parse(repairMap.toString())], () => null);
|
|
45
|
-
return {
|
|
46
|
-
...result,
|
|
47
|
-
enumPatterns,
|
|
48
|
-
map
|
|
49
|
-
};
|
|
50
|
-
} catch (error) {
|
|
51
|
-
if (!(error instanceof TwillSyntaxError)) throw error;
|
|
52
|
-
if (attempt === 0) onSyntaxError?.(error);
|
|
53
|
-
const before = text.slice(0, error.offset);
|
|
54
|
-
let insertion;
|
|
55
|
-
let offset = error.offset;
|
|
56
|
-
if (/\.\s*$/.test(before)) insertion = "__twillIncomplete";
|
|
57
|
-
else if (offset >= text.length) {
|
|
58
|
-
const stack = [];
|
|
59
|
-
for (const token of text.matchAll(/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|`(?:\\.|[^`\\])*`|\/\*[\s\S]*?\*\/|\/\/[^\n]*|[()[\]{}])/g)) if ("([{".includes(token[0])) stack.push(token[0]);
|
|
60
|
-
else if (")]}".includes(token[0])) stack.pop();
|
|
61
|
-
const opening = stack.at(-1);
|
|
62
|
-
if (!opening) throw error;
|
|
63
|
-
insertion = {
|
|
64
|
-
"(": ")",
|
|
65
|
-
"[": "]",
|
|
66
|
-
"{": "}"
|
|
67
|
-
}[opening];
|
|
68
|
-
} else throw error;
|
|
69
|
-
if (offset >= text.length) offset = source.length;
|
|
70
|
-
else if (text !== source) {
|
|
71
|
-
const prefix = text.slice(0, offset).split("\n");
|
|
72
|
-
const point = originalPosition({
|
|
73
|
-
code: text,
|
|
74
|
-
map: repaired.generateMap({
|
|
75
|
-
source: options.filename,
|
|
76
|
-
hires: true
|
|
77
|
-
})
|
|
78
|
-
}, prefix.length, prefix.at(-1).length);
|
|
79
|
-
const starts = [0];
|
|
80
|
-
for (const match of source.matchAll(/\n/g)) starts.push(match.index + 1);
|
|
81
|
-
offset = point.line == null || point.column == null ? source.length : starts[point.line - 1] + point.column;
|
|
82
|
-
}
|
|
83
|
-
repaired.appendLeft(offset, insertion);
|
|
84
|
-
text = repaired.toString();
|
|
85
|
-
}
|
|
86
|
-
return transform(source, options);
|
|
87
|
-
}
|
|
88
|
-
//#endregion
|
|
89
|
-
//#region src/project.ts
|
|
90
|
-
function lineStarts(text) {
|
|
91
|
-
const starts = [0];
|
|
92
|
-
const breaks = /\n/g;
|
|
93
|
-
while (breaks.exec(text)) starts.push(breaks.lastIndex);
|
|
94
|
-
return starts;
|
|
95
|
-
}
|
|
96
|
-
function positionAt(starts, offset) {
|
|
97
|
-
let low = 0;
|
|
98
|
-
let high = starts.length;
|
|
99
|
-
while (low + 1 < high) {
|
|
100
|
-
const mid = low + high >>> 1;
|
|
101
|
-
if (starts[mid] <= offset) low = mid;
|
|
102
|
-
else high = mid;
|
|
103
|
-
}
|
|
104
|
-
return {
|
|
105
|
-
line: low + 1,
|
|
106
|
-
column: offset - starts[low]
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
var extraExtensions = extensions.map((extension) => ({
|
|
110
|
-
extension,
|
|
111
|
-
isMixedContent: false,
|
|
112
|
-
scriptKind: ts.ScriptKind.Deferred
|
|
113
|
-
}));
|
|
114
|
-
function virtualFilename(filename) {
|
|
115
|
-
filename = filename.replaceAll("\\", "/");
|
|
116
|
-
return isTwillFile(filename) ? filename + {
|
|
117
|
-
ts: ".ts",
|
|
118
|
-
tsx: ".tsx",
|
|
119
|
-
js: ".js",
|
|
120
|
-
jsx: ".jsx"
|
|
121
|
-
}[inferLanguage(filename)] : filename;
|
|
122
|
-
}
|
|
123
|
-
function sourceFilename(filename) {
|
|
124
|
-
filename = filename.replaceAll("\\", "/");
|
|
125
|
-
if (isTwillFile(filename)) return filename;
|
|
126
|
-
return filename.replace(/(\.twill)\.ts$/, "$1").replace(/(\.twillx)\.tsx$/, "$1");
|
|
127
|
-
}
|
|
128
|
-
/** A virtual-source TypeScript project shared by the CLI and VS Code extension. */
|
|
129
|
-
var TwillProject = class {
|
|
130
|
-
root;
|
|
131
|
-
service;
|
|
132
|
-
compilerOptions;
|
|
133
|
-
configFiles;
|
|
134
|
-
files;
|
|
135
|
-
overlays = /* @__PURE__ */ new Map();
|
|
136
|
-
results = /* @__PURE__ */ new Map();
|
|
137
|
-
lineMaps = /* @__PURE__ */ new WeakMap();
|
|
138
|
-
version = 0;
|
|
139
|
-
invalidation = 0;
|
|
140
|
-
fileVersions = /* @__PURE__ */ new Map();
|
|
141
|
-
configurationErrors;
|
|
142
|
-
options;
|
|
143
|
-
host;
|
|
144
|
-
recover;
|
|
145
|
-
discoverFiles;
|
|
146
|
-
constructor(tsconfig, options = {}, projectOptions = {}) {
|
|
147
|
-
const configFile = sourceFilename(resolve(tsconfig));
|
|
148
|
-
this.root = dirname(configFile);
|
|
149
|
-
this.recover = projectOptions.recover ?? false;
|
|
150
|
-
this.options = {
|
|
151
|
-
...loadConfig(this.root, configFile),
|
|
152
|
-
...options
|
|
153
|
-
};
|
|
154
|
-
const configReads = /* @__PURE__ */ new Set([configFile, sourceFilename(resolve(this.root, "twill.config.json"))]);
|
|
155
|
-
const configHost = {
|
|
156
|
-
...ts.sys,
|
|
157
|
-
readFile: (filename) => {
|
|
158
|
-
configReads.add(sourceFilename(filename));
|
|
159
|
-
return ts.sys.readFile(filename);
|
|
160
|
-
}
|
|
161
|
-
};
|
|
162
|
-
const raw = projectOptions.inferred && !ts.sys.fileExists(configFile) ? { config: { compilerOptions: {
|
|
163
|
-
strict: true,
|
|
164
|
-
target: "ES2022",
|
|
165
|
-
module: "ESNext",
|
|
166
|
-
moduleResolution: "Bundler",
|
|
167
|
-
jsx: "react-jsx"
|
|
168
|
-
} } } : ts.readConfigFile(configFile, configHost.readFile);
|
|
169
|
-
const parsed = ts.parseJsonConfigFileContent(raw.config ?? {}, configHost, this.root, {
|
|
170
|
-
allowJs: true,
|
|
171
|
-
allowImportingTsExtensions: true,
|
|
172
|
-
noEmit: true
|
|
173
|
-
}, configFile, void 0, extraExtensions);
|
|
174
|
-
this.configurationErrors = [...raw.error ? [raw.error] : [], ...parsed.errors];
|
|
175
|
-
if (parsed.projectReferences?.length && !projectOptions.declarationRedirects) this.configurationErrors = [...this.configurationErrors, {
|
|
176
|
-
category: ts.DiagnosticCategory.Error,
|
|
177
|
-
code: 90002,
|
|
178
|
-
file: void 0,
|
|
179
|
-
start: void 0,
|
|
180
|
-
length: void 0,
|
|
181
|
-
messageText: "TypeScript project references are not supported by twill check. Check each referenced project separately."
|
|
182
|
-
}];
|
|
183
|
-
this.compilerOptions = parsed.options;
|
|
184
|
-
this.configFiles = [...configReads];
|
|
185
|
-
this.options.jsxImportSource ??= parsed.options.jsxImportSource;
|
|
186
|
-
this.files = parsed.fileNames.map(virtualFilename);
|
|
187
|
-
this.discoverFiles = () => ts.parseJsonConfigFileContent(raw.config ?? {}, configHost, this.root, {
|
|
188
|
-
allowJs: true,
|
|
189
|
-
allowImportingTsExtensions: true,
|
|
190
|
-
noEmit: true
|
|
191
|
-
}, configFile, void 0, extraExtensions).fileNames.map(virtualFilename);
|
|
192
|
-
const readFile = (name) => {
|
|
193
|
-
const original = sourceFilename(name);
|
|
194
|
-
const source = this.overlays.get(original) ?? ts.sys.readFile(original);
|
|
195
|
-
if (source === void 0) return void 0;
|
|
196
|
-
if (!isTwillFile(original)) return source;
|
|
197
|
-
try {
|
|
198
|
-
return this.result(original, source).code;
|
|
199
|
-
} catch {
|
|
200
|
-
return "";
|
|
201
|
-
}
|
|
202
|
-
};
|
|
203
|
-
const fileExists = (name) => this.overlays.has(sourceFilename(name)) || ts.sys.fileExists(sourceFilename(name));
|
|
204
|
-
const resolutionHost = {
|
|
205
|
-
...ts.sys,
|
|
206
|
-
readFile,
|
|
207
|
-
fileExists
|
|
208
|
-
};
|
|
209
|
-
this.host = {
|
|
210
|
-
...ts.sys,
|
|
211
|
-
getScriptFileNames: () => this.files,
|
|
212
|
-
useCaseSensitiveFileNames: () => ts.sys.useCaseSensitiveFileNames,
|
|
213
|
-
getScriptVersion: (name) => `${this.invalidation}:${this.fileVersions.get(sourceFilename(name)) ?? 0}`,
|
|
214
|
-
getProjectVersion: () => String(this.version),
|
|
215
|
-
getScriptSnapshot: (name) => {
|
|
216
|
-
const text = readFile(name);
|
|
217
|
-
return text === void 0 ? void 0 : ts.ScriptSnapshot.fromString(text);
|
|
218
|
-
},
|
|
219
|
-
getCurrentDirectory: () => this.root,
|
|
220
|
-
getCompilationSettings: () => this.compilerOptions,
|
|
221
|
-
getDefaultLibFileName: projectOptions.defaultLibFileName ?? ((opts) => ts.getDefaultLibFilePath(opts)),
|
|
222
|
-
readFile,
|
|
223
|
-
fileExists,
|
|
224
|
-
resolveModuleNames: (names, importer) => names.map((name) => {
|
|
225
|
-
const resolved = ts.resolveModuleName(name, importer, this.compilerOptions, resolutionHost).resolvedModule;
|
|
226
|
-
if (resolved) {
|
|
227
|
-
const redirect = projectOptions.declarationRedirects?.get(sourceFilename(resolved.resolvedFileName));
|
|
228
|
-
return redirect ? {
|
|
229
|
-
...resolved,
|
|
230
|
-
resolvedFileName: redirect,
|
|
231
|
-
extension: ts.Extension.Dts
|
|
232
|
-
} : {
|
|
233
|
-
...resolved,
|
|
234
|
-
resolvedFileName: virtualFilename(resolved.resolvedFileName)
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
if (name.startsWith(".") || name.startsWith("/")) {
|
|
238
|
-
const base = resolve(dirname(sourceFilename(importer)), name);
|
|
239
|
-
const candidates = isTwillFile(base) ? [base] : extensions.flatMap((extension) => [base + extension, resolve(base, "index" + extension)]);
|
|
240
|
-
for (const candidate of candidates) if (fileExists(candidate)) {
|
|
241
|
-
const redirect = projectOptions.declarationRedirects?.get(sourceFilename(candidate));
|
|
242
|
-
if (redirect) return {
|
|
243
|
-
resolvedFileName: redirect,
|
|
244
|
-
extension: ts.Extension.Dts,
|
|
245
|
-
isExternalLibraryImport: false
|
|
246
|
-
};
|
|
247
|
-
const file = virtualFilename(candidate);
|
|
248
|
-
return {
|
|
249
|
-
resolvedFileName: file,
|
|
250
|
-
extension: file.endsWith(".tsx") ? ts.Extension.Tsx : ts.Extension.Ts,
|
|
251
|
-
isExternalLibraryImport: false
|
|
252
|
-
};
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
})
|
|
256
|
-
};
|
|
257
|
-
this.service = ts.createLanguageService(this.host);
|
|
258
|
-
}
|
|
259
|
-
/** Declaration-only native TypeScript emit from the checked virtual program. */
|
|
260
|
-
declarationOutput(outDir, declarationMap = true) {
|
|
261
|
-
const diagnostics = this.diagnostics();
|
|
262
|
-
if (diagnostics.some((item) => item.category === "error")) return {
|
|
263
|
-
diagnostics,
|
|
264
|
-
files: []
|
|
265
|
-
};
|
|
266
|
-
const previous = this.service.getProgram();
|
|
267
|
-
if (!previous) return {
|
|
268
|
-
diagnostics,
|
|
269
|
-
files: []
|
|
270
|
-
};
|
|
271
|
-
const options = {
|
|
272
|
-
...this.compilerOptions,
|
|
273
|
-
noEmit: false,
|
|
274
|
-
declaration: true,
|
|
275
|
-
emitDeclarationOnly: true,
|
|
276
|
-
declarationMap,
|
|
277
|
-
noEmitOnError: true,
|
|
278
|
-
incremental: false,
|
|
279
|
-
composite: false,
|
|
280
|
-
rootDir: this.compilerOptions.rootDir ?? this.root,
|
|
281
|
-
outDir,
|
|
282
|
-
declarationDir: outDir,
|
|
283
|
-
allowImportingTsExtensions: true
|
|
284
|
-
};
|
|
285
|
-
const host = ts.createCompilerHost(options);
|
|
286
|
-
host.readFile = this.host.readFile;
|
|
287
|
-
host.fileExists = this.host.fileExists;
|
|
288
|
-
host.getCurrentDirectory = () => this.root;
|
|
289
|
-
host.resolveModuleNames = this.host.resolveModuleNames;
|
|
290
|
-
host.getSourceFile = (filename, languageVersion) => previous.getSourceFile(filename) ?? (host.readFile(filename) === void 0 ? void 0 : ts.createSourceFile(filename, host.readFile(filename), languageVersion, true));
|
|
291
|
-
const program = ts.createProgram(previous.getRootFileNames(), options, host);
|
|
292
|
-
const errors = ts.getPreEmitDiagnostics(program).map((item) => this.diagnostic(item));
|
|
293
|
-
if (errors.some((item) => item.category === "error")) return {
|
|
294
|
-
diagnostics: errors,
|
|
295
|
-
files: []
|
|
296
|
-
};
|
|
297
|
-
const files = [];
|
|
298
|
-
const emitted = program.emit(void 0, (filename, text, _bom, _error, sources) => {
|
|
299
|
-
files.push({
|
|
300
|
-
filename: sourceFilename(filename),
|
|
301
|
-
text,
|
|
302
|
-
sources: sources?.map((source) => sourceFilename(source.fileName)) ?? []
|
|
303
|
-
});
|
|
304
|
-
}, void 0, true);
|
|
305
|
-
return {
|
|
306
|
-
diagnostics: [...diagnostics, ...emitted.diagnostics.map((item) => this.diagnostic(item))],
|
|
307
|
-
files: emitted.emitSkipped ? [] : files
|
|
308
|
-
};
|
|
309
|
-
}
|
|
310
|
-
result(filename, source) {
|
|
311
|
-
const cached = this.results.get(filename);
|
|
312
|
-
if (cached?.source === source) return cached.result;
|
|
313
|
-
const options = {
|
|
314
|
-
...this.options,
|
|
315
|
-
filename
|
|
316
|
-
};
|
|
317
|
-
let syntaxError;
|
|
318
|
-
const result = this.recover ? recoverTransform(source, options, (error) => {
|
|
319
|
-
syntaxError = error;
|
|
320
|
-
}) : transform(source, options);
|
|
321
|
-
this.results.set(filename, {
|
|
322
|
-
source,
|
|
323
|
-
result,
|
|
324
|
-
syntaxError
|
|
325
|
-
});
|
|
326
|
-
return result;
|
|
327
|
-
}
|
|
328
|
-
update(filename, text) {
|
|
329
|
-
filename = sourceFilename(resolve(filename));
|
|
330
|
-
if (text !== void 0 && text === this.overlays.get(filename) && this.files.includes(virtualFilename(filename))) return;
|
|
331
|
-
if (text === void 0) this.overlays.delete(filename);
|
|
332
|
-
else this.overlays.set(filename, text);
|
|
333
|
-
this.fileVersions.set(filename, (this.fileVersions.get(filename) ?? 0) + 1);
|
|
334
|
-
if (!this.files.includes(virtualFilename(filename))) this.files.push(virtualFilename(filename));
|
|
335
|
-
this.results.delete(filename);
|
|
336
|
-
this.version++;
|
|
337
|
-
}
|
|
338
|
-
invalidate() {
|
|
339
|
-
this.invalidation++;
|
|
340
|
-
this.version++;
|
|
341
|
-
this.results.clear();
|
|
342
|
-
}
|
|
343
|
-
/** Refresh a disk version without discarding unsaved overlays or other transforms. */
|
|
344
|
-
refresh(filename, discover = false) {
|
|
345
|
-
filename = sourceFilename(resolve(filename));
|
|
346
|
-
if (discover) this.files = [.../* @__PURE__ */ new Set([...this.discoverFiles(), ...[...this.overlays.keys()].map(virtualFilename)])];
|
|
347
|
-
if (!this.overlays.has(filename)) {
|
|
348
|
-
this.results.delete(filename);
|
|
349
|
-
this.fileVersions.set(filename, (this.fileVersions.get(filename) ?? 0) + 1);
|
|
350
|
-
}
|
|
351
|
-
this.version++;
|
|
352
|
-
}
|
|
353
|
-
text(filename) {
|
|
354
|
-
filename = sourceFilename(resolve(filename));
|
|
355
|
-
return this.overlays.get(filename) ?? ts.sys.readFile(filename);
|
|
356
|
-
}
|
|
357
|
-
transformed(filename) {
|
|
358
|
-
filename = sourceFilename(resolve(filename));
|
|
359
|
-
const source = this.text(filename);
|
|
360
|
-
return source !== void 0 && isTwillFile(filename) ? this.result(filename, source) : void 0;
|
|
361
|
-
}
|
|
362
|
-
sourceFiles() {
|
|
363
|
-
const dependencies = this.service.getProgram()?.getSourceFiles().filter((file) => !file.isDeclarationFile && !isDependency(file.fileName)).map((file) => file.fileName) ?? [];
|
|
364
|
-
return [...new Set([...this.files, ...dependencies].map(sourceFilename))];
|
|
365
|
-
}
|
|
366
|
-
lines(filename, result) {
|
|
367
|
-
let lines = this.lineMaps.get(result);
|
|
368
|
-
if (!lines) {
|
|
369
|
-
lines = {
|
|
370
|
-
original: lineStarts(this.text(filename)),
|
|
371
|
-
generated: lineStarts(result.code)
|
|
372
|
-
};
|
|
373
|
-
this.lineMaps.set(result, lines);
|
|
374
|
-
}
|
|
375
|
-
return lines;
|
|
376
|
-
}
|
|
377
|
-
toGeneratedOffset(filename, offset) {
|
|
378
|
-
const result = this.transformed(filename);
|
|
379
|
-
if (!result) return offset;
|
|
380
|
-
const lines = this.lines(filename, result);
|
|
381
|
-
const sourcePosition = positionAt(lines.original, offset);
|
|
382
|
-
const position = generatedPosition(result, sourcePosition.line, sourcePosition.column);
|
|
383
|
-
if (position.line === null || position.column === null) return offset;
|
|
384
|
-
return (lines.generated[position.line - 1] ?? 0) + position.column;
|
|
385
|
-
}
|
|
386
|
-
toOriginalOffset(filename, offset) {
|
|
387
|
-
const result = this.transformed(filename);
|
|
388
|
-
if (!result) return offset;
|
|
389
|
-
const lines = this.lines(filename, result);
|
|
390
|
-
const sourcePosition = positionAt(lines.generated, offset);
|
|
391
|
-
const position = originalPosition(result, sourcePosition.line, sourcePosition.column);
|
|
392
|
-
if (position.line === null || position.column === null) return 0;
|
|
393
|
-
return (lines.original[position.line - 1] ?? 0) + position.column;
|
|
394
|
-
}
|
|
395
|
-
diagnostic(diagnostic) {
|
|
396
|
-
const filename = diagnostic.file ? sourceFilename(diagnostic.file.fileName) : void 0;
|
|
397
|
-
const source = filename ? this.text(filename) ?? "" : "";
|
|
398
|
-
const start = filename ? this.toOriginalOffset(filename, diagnostic.start ?? 0) : 0;
|
|
399
|
-
const end = filename ? this.toOriginalOffset(filename, (diagnostic.start ?? 0) + (diagnostic.length ?? 1)) : start + 1;
|
|
400
|
-
const before = source.slice(0, start).split(/\r\n|[\r\n\u2028\u2029]/);
|
|
401
|
-
return {
|
|
402
|
-
filename,
|
|
403
|
-
line: before.length,
|
|
404
|
-
column: before.at(-1).length,
|
|
405
|
-
length: Math.max(1, end - start),
|
|
406
|
-
code: diagnostic.code,
|
|
407
|
-
category: diagnostic.category === ts.DiagnosticCategory.Error ? "error" : diagnostic.category === ts.DiagnosticCategory.Warning ? "warning" : "message",
|
|
408
|
-
message: ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n")
|
|
409
|
-
};
|
|
410
|
-
}
|
|
411
|
-
diagnostics(filename) {
|
|
412
|
-
const result = this.configurationErrors.map((error) => this.diagnostic(error));
|
|
413
|
-
if (!filename) result.push(...this.service.getCompilerOptionsDiagnostics().map((error) => this.diagnostic(error)));
|
|
414
|
-
const files = filename ? [virtualFilename(resolve(filename))] : this.sourceFiles().map(virtualFilename);
|
|
415
|
-
for (const file of files) {
|
|
416
|
-
if (/\.d\.[cm]?ts$/.test(file)) continue;
|
|
417
|
-
try {
|
|
418
|
-
this.transformed(file);
|
|
419
|
-
const syntaxError = this.results.get(sourceFilename(file))?.syntaxError;
|
|
420
|
-
if (syntaxError) throw syntaxError;
|
|
421
|
-
result.push(...[...this.service.getSyntacticDiagnostics(file), ...this.service.getSemanticDiagnostics(file)].map((error) => this.diagnostic(error)));
|
|
422
|
-
} catch (error) {
|
|
423
|
-
const syntax = error;
|
|
424
|
-
result.push({
|
|
425
|
-
filename: sourceFilename(file),
|
|
426
|
-
line: syntax.line ?? 1,
|
|
427
|
-
column: syntax.column ?? 0,
|
|
428
|
-
length: 1,
|
|
429
|
-
code: 90001,
|
|
430
|
-
category: "error",
|
|
431
|
-
message: syntax.message
|
|
432
|
-
});
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
return result;
|
|
436
|
-
}
|
|
437
|
-
dispose() {
|
|
438
|
-
this.service.dispose();
|
|
439
|
-
}
|
|
440
|
-
};
|
|
441
|
-
//#endregion
|
|
442
3
|
export { TwillProject, isDependency, sourceFilename, virtualFilename };
|
|
443
|
-
|
|
444
|
-
//# sourceMappingURL=project.js.map
|
package/dist/register.js
CHANGED
package/dist/register.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.js","names":[],"sources":["../src/register.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"register.js","names":[],"sources":["../src/register.ts"],"sourcesContent":["import { registerLoader } from './loader-registration.js';\nawait registerLoader();\n"],"mappings":";;AACA,MAAM,eAAe"}
|
package/dist/rollup.js
CHANGED
package/dist/rspack.js
CHANGED
package/dist/syntax.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { o as parse, r as inferLanguage } from "./compiler-
|
|
1
|
+
import { o as parse, r as inferLanguage } from "./compiler-BdkU4Ruh.js";
|
|
2
2
|
//#region src/syntax.ts
|
|
3
3
|
/** Original ESTree and dialect metadata for source-aware tooling. */
|
|
4
4
|
function parseSyntax(source, options = {}) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as transform, r as inferLanguage } from "./compiler-
|
|
1
|
+
import { a as transform, r as inferLanguage } from "./compiler-BdkU4Ruh.js";
|
|
2
2
|
import MagicString from "magic-string";
|
|
3
3
|
import ts from "typescript";
|
|
4
4
|
import remapping from "@ampproject/remapping";
|
|
@@ -48,4 +48,4 @@ function transpileNative(source, filename, language = inferLanguage(filename), s
|
|
|
48
48
|
//#endregion
|
|
49
49
|
export { transpileNative as n, transpile as t };
|
|
50
50
|
|
|
51
|
-
//# sourceMappingURL=transpile-
|
|
51
|
+
//# sourceMappingURL=transpile-CLNavDUr.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transpile-
|
|
1
|
+
{"version":3,"file":"transpile-CLNavDUr.js","names":[],"sources":["../src/transpile.ts"],"sourcesContent":["import ts from 'typescript';\nimport remapping from '@ampproject/remapping';\nimport MagicString from 'magic-string';\nimport { transform, inferLanguage, type TransformOptions } from './compiler.js';\n\nexport function transpile(\n source: string,\n options: TransformOptions = {},\n target = ts.ScriptTarget.ESNext,\n) {\n const filename = options.filename ?? 'input.twill';\n const result = transform(source, options);\n const language = options.language ?? inferLanguage(filename);\n return transpileNative(\n result.code,\n filename,\n language,\n result.map.toString(),\n options.jsxImportSource,\n target,\n );\n}\n\n/** Native source never goes through Twill's parser or implicit-return rules. */\nexport function transpileNative(\n source: string,\n filename: string,\n language = inferLanguage(filename),\n syntaxMap?: string,\n jsxImportSource?: string,\n target = ts.ScriptTarget.ESNext,\n) {\n // Plain JavaScript needs no type erasure or JSX transform. Leave modern JS\n // (including comments and import attributes) to the host's target pipeline.\n if (language === 'js')\n return {\n code: source,\n map:\n syntaxMap ??\n new MagicString(source)\n .generateMap({ source: filename, includeContent: true, hires: true })\n .toString(),\n };\n const output = ts.transpileModule(source, {\n fileName: syntaxMap ? filename + (language.endsWith('x') ? '.tsx' : '.ts') : filename,\n compilerOptions: {\n target,\n module: ts.ModuleKind.ESNext,\n jsx: ts.JsxEmit.ReactJSX,\n jsxImportSource,\n sourceMap: true,\n inlineSources: true,\n isolatedModules: true,\n verbatimModuleSyntax: true,\n },\n reportDiagnostics: true,\n });\n const errors = output.diagnostics?.filter(\n (diagnostic) => diagnostic.category === ts.DiagnosticCategory.Error,\n );\n if (errors?.length)\n throw new Error(\n ts.formatDiagnostics(errors, {\n getCanonicalFileName: (name) => name,\n getCurrentDirectory: () => '',\n getNewLine: () => '\\n',\n }),\n );\n const map = syntaxMap\n ? remapping([JSON.parse(output.sourceMapText!), JSON.parse(syntaxMap)], () => null).toString()\n : output.sourceMapText!;\n return {\n code: output.outputText.replace(/^\\/\\/# sourceMappingURL=.*$/m, ''),\n map,\n };\n}\n"],"mappings":";;;;;AAKA,SAAgB,UACd,QACA,UAA4B,CAAC,GAC7B,SAAS,GAAG,aAAa,QACzB;CACA,MAAM,WAAW,QAAQ,YAAY;CACrC,MAAM,SAAS,UAAU,QAAQ,OAAO;CACxC,MAAM,WAAW,QAAQ,YAAY,cAAc,QAAQ;CAC3D,OAAO,gBACL,OAAO,MACP,UACA,UACA,OAAO,IAAI,SAAS,GACpB,QAAQ,iBACR,MACF;AACF;;AAGA,SAAgB,gBACd,QACA,UACA,WAAW,cAAc,QAAQ,GACjC,WACA,iBACA,SAAS,GAAG,aAAa,QACzB;CAGA,IAAI,aAAa,MACf,OAAO;EACL,MAAM;EACN,KACE,aACA,IAAI,YAAY,MAAM,CAAC,CACpB,YAAY;GAAE,QAAQ;GAAU,gBAAgB;GAAM,OAAO;EAAK,CAAC,CAAC,CACpE,SAAS;CAChB;CACF,MAAM,SAAS,GAAG,gBAAgB,QAAQ;EACxC,UAAU,YAAY,YAAY,SAAS,SAAS,GAAG,IAAI,SAAS,SAAS;EAC7E,iBAAiB;GACf;GACA,QAAQ,GAAG,WAAW;GACtB,KAAK,GAAG,QAAQ;GAChB;GACA,WAAW;GACX,eAAe;GACf,iBAAiB;GACjB,sBAAsB;EACxB;EACA,mBAAmB;CACrB,CAAC;CACD,MAAM,SAAS,OAAO,aAAa,QAChC,eAAe,WAAW,aAAa,GAAG,mBAAmB,KAChE;CACA,IAAI,QAAQ,QACV,MAAM,IAAI,MACR,GAAG,kBAAkB,QAAQ;EAC3B,uBAAuB,SAAS;EAChC,2BAA2B;EAC3B,kBAAkB;CACpB,CAAC,CACH;CACF,MAAM,MAAM,YACR,UAAU,CAAC,KAAK,MAAM,OAAO,aAAc,GAAG,KAAK,MAAM,SAAS,CAAC,SAAS,IAAI,CAAC,CAAC,SAAS,IAC3F,OAAO;CACX,OAAO;EACL,MAAM,OAAO,WAAW,QAAQ,gCAAgC,EAAE;EAClE;CACF;AACF"}
|
|
@@ -14989,9 +14989,12 @@ function guardAt(input, offset, implicitMember = false) {
|
|
|
14989
14989
|
const lexer = Parser.tokenizer(input.slice(offset), { ecmaVersion: "latest" });
|
|
14990
14990
|
const stack = [];
|
|
14991
14991
|
let first = true;
|
|
14992
|
+
let missingElse = false;
|
|
14993
|
+
let afterNonNull = false;
|
|
14992
14994
|
try {
|
|
14993
14995
|
for (;;) {
|
|
14994
|
-
const
|
|
14996
|
+
const token = lexer.getToken();
|
|
14997
|
+
const label = token.type.label;
|
|
14995
14998
|
if (first && [
|
|
14996
14999
|
"=",
|
|
14997
15000
|
".",
|
|
@@ -15005,6 +15008,22 @@ function guardAt(input, offset, implicitMember = false) {
|
|
|
15005
15008
|
"in",
|
|
15006
15009
|
"instanceof"
|
|
15007
15010
|
].includes(label) && !(implicitMember && label === ".")) return false;
|
|
15011
|
+
if (first || afterNonNull) {
|
|
15012
|
+
missingElse = !/[\r\n\u2028\u2029]/.test(input.slice(offset, offset + token.start)) && (token.type === types$1.name && !["as", "satisfies"].includes(token.value) || [
|
|
15013
|
+
"const",
|
|
15014
|
+
"num",
|
|
15015
|
+
"string",
|
|
15016
|
+
"true",
|
|
15017
|
+
"false",
|
|
15018
|
+
"null",
|
|
15019
|
+
"this",
|
|
15020
|
+
"new",
|
|
15021
|
+
"typeof",
|
|
15022
|
+
"void",
|
|
15023
|
+
"delete"
|
|
15024
|
+
].includes(label) || token.type === types$1.prefix && token.value === "~" || implicitMember && first && label === ".");
|
|
15025
|
+
afterNonNull = token.type === types$1.prefix && token.value === "!";
|
|
15026
|
+
}
|
|
15008
15027
|
if (!stack.length && [
|
|
15009
15028
|
"if",
|
|
15010
15029
|
"for",
|
|
@@ -15015,15 +15034,12 @@ function guardAt(input, offset, implicitMember = false) {
|
|
|
15015
15034
|
"throw",
|
|
15016
15035
|
"var",
|
|
15017
15036
|
"export"
|
|
15018
|
-
].includes(label)) return false;
|
|
15019
|
-
if (!first && !stack.length && label === "const") return false;
|
|
15037
|
+
].includes(label)) return missingElse ? "missingElse" : false;
|
|
15038
|
+
if (!first && !stack.length && label === "const") return missingElse ? "missingElse" : false;
|
|
15020
15039
|
first = false;
|
|
15021
15040
|
if (!stack.length && label === "else") return true;
|
|
15022
|
-
if (!stack.length &&
|
|
15023
|
-
|
|
15024
|
-
";",
|
|
15025
|
-
"}"
|
|
15026
|
-
].includes(label)) return false;
|
|
15041
|
+
if (label === "eof") return !stack.length && missingElse ? "missingElse" : false;
|
|
15042
|
+
if (!stack.length && [";", "}"].includes(label)) return missingElse ? "missingElse" : false;
|
|
15027
15043
|
if ([
|
|
15028
15044
|
"(",
|
|
15029
15045
|
"[",
|
|
@@ -15260,7 +15276,9 @@ function parserFor(language) {
|
|
|
15260
15276
|
node.cleanup = cleanup;
|
|
15261
15277
|
return this.finishNode(node, "DeferStatement");
|
|
15262
15278
|
}
|
|
15263
|
-
|
|
15279
|
+
const guard = this.isContextual("guard") && guardAt(this.input, this.end, !!this.implicitClosure);
|
|
15280
|
+
if (guard === "missingElse") this.raise(this.start, "Missing 'else' in guard statement. Put 'else' before the failure block: 'guard condition else { return ...; }'.");
|
|
15281
|
+
if (!guard) {
|
|
15264
15282
|
const statement = super.parseStatement(context, ...args);
|
|
15265
15283
|
if (context && statement.type === "TwillEnumDeclaration") this.raise(statement.start, "An associated-value enum requires a block; add braces around this body.");
|
|
15266
15284
|
return statement;
|
|
@@ -15269,6 +15287,7 @@ function parserFor(language) {
|
|
|
15269
15287
|
node.singleStatement = !!context;
|
|
15270
15288
|
this.next();
|
|
15271
15289
|
node.binding = null;
|
|
15290
|
+
if (this.type === types$1._else) this.raise(this.start, "Guard needs a condition or 'const' binding before 'else'.");
|
|
15272
15291
|
if (this.type === types$1._const) {
|
|
15273
15292
|
if (context) this.raise(node.start, "A guard binding requires a block; add braces around this body.");
|
|
15274
15293
|
const declaration = this.startNode();
|
|
@@ -15278,8 +15297,9 @@ function parserFor(language) {
|
|
|
15278
15297
|
if (node.binding.declarations.length !== 1) this.raise(node.start, "guard const requires one binding declaration.");
|
|
15279
15298
|
} else node.test = this.parseExpression();
|
|
15280
15299
|
node.elseStart = this.start;
|
|
15281
|
-
this.
|
|
15282
|
-
|
|
15300
|
+
if (this.type !== types$1._else) this.raise(this.start, "Expected 'else' after the guard condition or binding.");
|
|
15301
|
+
this.next();
|
|
15302
|
+
if (this.type !== types$1.braceL) this.raise(this.start, "Guard 'else' must be followed by a block, for example 'else { return ...; }'.");
|
|
15283
15303
|
node.failure = this.parseBlock();
|
|
15284
15304
|
if (!exits(node.failure)) this.raise(node.failure.start, "Every guard else path must exit with return, throw, break or continue.");
|
|
15285
15305
|
return this.finishNode(node, "GuardStatement");
|