@swiftuijs/twill 0.1.2 → 0.2.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 +39 -11
- package/bin/run.mjs +15 -0
- package/bin/twill.mjs +34 -11
- package/dist/branches.d.ts +6 -3
- package/dist/cli.js +13 -6
- package/dist/cli.js.map +1 -1
- package/dist/compilation-cache-CuCGz02_.js +172 -0
- package/dist/compilation-cache-CuCGz02_.js.map +1 -0
- package/dist/compilation-cache.d.ts +21 -0
- package/dist/{compiler-Bi9TNOhX.js → compiler-DY1N07np.js} +530 -50
- package/dist/compiler-DY1N07np.js.map +1 -0
- package/dist/compiler.d.ts +17 -2
- package/dist/config.d.ts +1 -6
- package/dist/config.js +1 -54
- package/dist/configuration-CTJjSu_h.js +139 -0
- package/dist/configuration-CTJjSu_h.js.map +1 -0
- package/dist/configuration.d.ts +12 -0
- package/dist/defer-helper.d.ts +1 -0
- package/dist/defer.d.ts +1 -1
- package/dist/doctor.js +9 -5
- package/dist/doctor.js.map +1 -1
- package/dist/editor.d.ts +2 -0
- package/dist/editor.js +75 -4
- package/dist/editor.js.map +1 -1
- package/dist/enums.d.ts +27 -0
- package/dist/esbuild.js +1 -1
- package/dist/extensions-B1xTkoYP.js +9 -0
- package/dist/extensions-B1xTkoYP.js.map +1 -0
- package/dist/extensions.d.ts +2 -0
- package/dist/{files-D1mERoxc.js → files-BW9geU0_.js} +2 -2
- package/dist/files-BW9geU0_.js.map +1 -0
- package/dist/index.js +2 -1
- package/dist/loader-compiler-DIw9aw5n.js +19 -0
- package/dist/loader-compiler-DIw9aw5n.js.map +1 -0
- package/dist/loader-compiler.d.ts +4 -0
- package/dist/loader.d.ts +4 -0
- package/dist/loader.js +29 -22
- package/dist/loader.js.map +1 -1
- package/dist/parser.d.ts +2 -0
- package/dist/{plugin-BGabvyT6.js → plugin-Bks2hxCJ.js} +41 -12
- package/dist/plugin-Bks2hxCJ.js.map +1 -0
- package/dist/project.js +27 -3
- package/dist/project.js.map +1 -1
- package/dist/rollup.js +1 -1
- package/dist/rspack.js +1 -1
- package/dist/syntax.d.ts +2 -0
- package/dist/syntax.js +1 -1
- package/dist/{transpile-DwVekVFM.js → transpile-DG81yfVs.js} +2 -2
- package/dist/{transpile-DwVekVFM.js.map → transpile-DG81yfVs.js.map} +1 -1
- package/dist/typescript-plugin.cjs +718 -60
- package/dist/typescript-plugin.cjs.map +1 -1
- package/dist/vite.js +1 -1
- package/dist/webpack.js +1 -1
- package/package.json +8 -4
- package/schemas/twill.schema.json +6 -0
- package/dist/compiler-Bi9TNOhX.js.map +0 -1
- package/dist/config.js.map +0 -1
- package/dist/files-D1mERoxc.js.map +0 -1
- package/dist/plugin-BGabvyT6.js.map +0 -1
package/dist/defer.d.ts
CHANGED
|
@@ -13,5 +13,5 @@ type Comment = {
|
|
|
13
13
|
type: string;
|
|
14
14
|
};
|
|
15
15
|
/** Scope-local cleanup callbacks; dynamic registrations use lazy stacks. */
|
|
16
|
-
export declare function lowerDefers(source: string, ast: Node, code: MagicString, language: Language, usedNames: Set<string>, contentStarts: Map<Node, number>, comments: Comment[], fail: (node: Node, message: string) => never): void;
|
|
16
|
+
export declare function lowerDefers(source: string, ast: Node, code: MagicString, language: Language, usedNames: Set<string>, contentStarts: Map<Node, number>, comments: Comment[], runtime: 'inline' | 'external', sourceType: 'module' | 'script', fail: (node: Node, message: string) => never): void;
|
|
17
17
|
export {};
|
package/dist/doctor.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as isTwillFile } from "./extensions-B1xTkoYP.js";
|
|
2
2
|
import ts from "typescript";
|
|
3
3
|
var package_default = {
|
|
4
4
|
name: "@swiftuijs/twill",
|
|
5
|
-
version: "0.
|
|
5
|
+
version: "0.2.0",
|
|
6
6
|
description: "Twill extends TypeScript with Swift-inspired syntax: trailing closures, guards, defer and checked switch expressions. Compiles to ordinary JavaScript.",
|
|
7
7
|
main: "./dist/typescript-plugin.cjs",
|
|
8
8
|
repository: {
|
|
@@ -134,7 +134,7 @@ var package_default = {
|
|
|
134
134
|
publishConfig: { "access": "public" },
|
|
135
135
|
module: "./dist/index.js",
|
|
136
136
|
scripts: {
|
|
137
|
-
"build": "vite build && vite build --config vite.plugin.config.ts && node scripts/prepare-core.mjs",
|
|
137
|
+
"build": "node ../../scripts/generate-runtime-helper.mjs && vite build && vite build --config vite.plugin.config.ts && node scripts/prepare-core.mjs",
|
|
138
138
|
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
139
139
|
"prepack": "pnpm run build",
|
|
140
140
|
"test:unit": "vitest run",
|
|
@@ -145,7 +145,10 @@ var package_default = {
|
|
|
145
145
|
"test:browser": "playwright test",
|
|
146
146
|
"benchmark": "node benchmarks/compiler.mjs",
|
|
147
147
|
"test": "pnpm run test:unit",
|
|
148
|
-
"benchmark:branching": "node benchmarks/branching.mjs"
|
|
148
|
+
"benchmark:branching": "node benchmarks/branching.mjs",
|
|
149
|
+
"benchmark:enum-patterns": "node benchmarks/enum-patterns.mjs",
|
|
150
|
+
"benchmark:runtime": "node benchmarks/runtime-helpers.mjs",
|
|
151
|
+
"benchmark:if-bindings": "node benchmarks/if-bindings.mjs"
|
|
149
152
|
},
|
|
150
153
|
devDependencies: {
|
|
151
154
|
"vite": "catalog:",
|
|
@@ -164,7 +167,8 @@ var package_default = {
|
|
|
164
167
|
"rollup": "catalog:",
|
|
165
168
|
"vue": "catalog:",
|
|
166
169
|
"webpack": "catalog:",
|
|
167
|
-
"@playwright/test": "catalog:"
|
|
170
|
+
"@playwright/test": "catalog:",
|
|
171
|
+
"@swiftuijs/twill-runtime": "workspace:*"
|
|
168
172
|
}
|
|
169
173
|
};
|
|
170
174
|
//#endregion
|
package/dist/doctor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.js","names":["metadata"],"sources":["../package.json","../src/doctor.ts"],"sourcesContent":["{\n \"name\": \"@swiftuijs/twill\",\n \"version\": \"0.
|
|
1
|
+
{"version":3,"file":"doctor.js","names":["metadata"],"sources":["../package.json","../src/doctor.ts"],"sourcesContent":["{\n \"name\": \"@swiftuijs/twill\",\n \"version\": \"0.2.0\",\n \"description\": \"Twill extends TypeScript with Swift-inspired syntax: trailing closures, guards, defer and checked switch expressions. Compiles to ordinary JavaScript.\",\n \"main\": \"./dist/typescript-plugin.cjs\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/swiftuijs/twill.git\",\n \"directory\": \"packages/twill\"\n },\n \"keywords\": [\n \"javascript\",\n \"typescript\",\n \"trailing-closures\",\n \"swift\",\n \"vite\",\n \"unplugin\",\n \"react\",\n \"vue\",\n \"twill\",\n \"guard\",\n \"defer\"\n ],\n \"author\": {\n \"name\": \"forth.ink\",\n \"url\": \"https://forth.ink\"\n },\n \"license\": \"MIT\",\n \"type\": \"module\",\n \"bugs\": {\n \"url\": \"https://github.com/swiftuijs/twill/issues\"\n },\n \"homepage\": \"https://twill.evecalm.com/\",\n \"dependencies\": {\n \"@ampproject/remapping\": \"^2.3.0\",\n \"@jridgewell/trace-mapping\": \"^0.3.31\",\n \"acorn\": \"8.18.0\",\n \"acorn-jsx\": \"^5.3.2\",\n \"acorn-typescript\": \"1.4.13\",\n \"magic-string\": \"^1.4.2\",\n \"typescript\": \"catalog:\",\n \"unplugin\": \"^3.4.0\"\n },\n \"sideEffects\": false,\n \"engines\": {\n \"node\": \"^20.19.0 || >=22.12.0\"\n },\n \"files\": [\n \"bin\",\n \"dist/**/*.js\",\n \"dist/**/*.js.map\",\n \"dist/**/*.d.ts\",\n \"schemas\",\n \"README.md\",\n \"LICENSE\",\n \"dist/**/*.cjs\",\n \"dist/**/*.cjs.map\",\n \"dist/*.LICENSE.txt\"\n ],\n \"bin\": {\n \"twill\": \"./bin/twill.mjs\"\n },\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\"\n },\n \"./vite\": {\n \"types\": \"./dist/vite.d.ts\",\n \"import\": \"./dist/vite.js\"\n },\n \"./rollup\": {\n \"types\": \"./dist/rollup.d.ts\",\n \"import\": \"./dist/rollup.js\"\n },\n \"./esbuild\": {\n \"types\": \"./dist/esbuild.d.ts\",\n \"import\": \"./dist/esbuild.js\"\n },\n \"./webpack\": {\n \"types\": \"./dist/webpack.d.ts\",\n \"import\": \"./dist/webpack.js\"\n },\n \"./rspack\": {\n \"types\": \"./dist/rspack.d.ts\",\n \"import\": \"./dist/rspack.js\"\n },\n \"./project\": {\n \"types\": \"./dist/project.d.ts\",\n \"import\": \"./dist/project.js\"\n },\n \"./editor\": {\n \"types\": \"./dist/editor.d.ts\",\n \"import\": \"./dist/editor.js\"\n },\n \"./register\": {\n \"types\": \"./dist/register.d.ts\",\n \"import\": \"./dist/register.js\"\n },\n \"./schema\": \"./schemas/twill.schema.json\",\n \"./typescript-plugin\": {\n \"types\": \"./dist/typescript-plugin.d.ts\",\n \"require\": \"./dist/typescript-plugin.cjs\",\n \"default\": \"./dist/typescript-plugin.cjs\"\n },\n \"./doctor\": {\n \"types\": \"./dist/doctor.d.ts\",\n \"import\": \"./dist/doctor.js\"\n },\n \"./syntax\": {\n \"types\": \"./dist/syntax.d.ts\",\n \"import\": \"./dist/syntax.js\"\n },\n \"./config\": {\n \"types\": \"./dist/config.d.ts\",\n \"import\": \"./dist/config.js\"\n },\n \"./declarations\": {\n \"types\": \"./dist/declarations.d.ts\",\n \"import\": \"./dist/declarations.js\"\n },\n \"./vite-react\": {\n \"types\": \"./dist/vite-react.d.ts\",\n \"import\": \"./dist/vite-react.js\"\n }\n },\n \"peerDependencies\": {\n \"react\": \"^18.2.0 || ^19.0.0\",\n \"vue\": \"^3.3.0\",\n \"@vitejs/plugin-react\": \"^6.1.1\"\n },\n \"peerDependenciesMeta\": {\n \"react\": {\n \"optional\": true\n },\n \"vue\": {\n \"optional\": true\n },\n \"@vitejs/plugin-react\": {\n \"optional\": true\n }\n },\n \"types\": \"./dist/index.d.ts\",\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"module\": \"./dist/index.js\",\n \"scripts\": {\n \"build\": \"node ../../scripts/generate-runtime-helper.mjs && vite build && vite build --config vite.plugin.config.ts && node scripts/prepare-core.mjs\",\n \"typecheck\": \"tsc --noEmit -p tsconfig.json\",\n \"prepack\": \"pnpm run build\",\n \"test:unit\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\",\n \"test:package\": \"node tests/consumer.mjs\",\n \"test:size\": \"node tests/bundle-size.mjs\",\n \"test:browser\": \"playwright test\",\n \"benchmark\": \"node benchmarks/compiler.mjs\",\n \"test\": \"pnpm run test:unit\",\n \"benchmark:branching\": \"node benchmarks/branching.mjs\",\n \"benchmark:enum-patterns\": \"node benchmarks/enum-patterns.mjs\",\n \"benchmark:runtime\": \"node benchmarks/runtime-helpers.mjs\",\n \"benchmark:if-bindings\": \"node benchmarks/if-bindings.mjs\"\n },\n \"devDependencies\": {\n \"vite\": \"catalog:\",\n \"vite-plugin-dts\": \"^5.1.2\",\n \"@types/node\": \"catalog:\",\n \"@vitejs/plugin-react\": \"catalog:\",\n \"vitest\": \"catalog:\",\n \"@vitest/coverage-v8\": \"catalog:\",\n \"@rspack/core\": \"catalog:\",\n \"@types/react\": \"catalog:\",\n \"@types/react-dom\": \"catalog:\",\n \"@vue/server-renderer\": \"catalog:\",\n \"esbuild\": \"catalog:\",\n \"react\": \"catalog:\",\n \"react-dom\": \"catalog:\",\n \"rollup\": \"catalog:\",\n \"vue\": \"catalog:\",\n \"webpack\": \"catalog:\",\n \"@playwright/test\": \"catalog:\",\n \"@swiftuijs/twill-runtime\": \"workspace:*\"\n }\n}\n","import ts from 'typescript';\nimport metadata from '../package.json';\nimport { TwillProject } from './project.js';\nimport { isTwillFile } from './compiler.js';\n\n/** Shareable diagnostics without source contents or environment-variable values. */\nexport function inspectProject(project: TwillProject, filename?: string) {\n const started = performance.now();\n const diagnostics = project.diagnostics(filename);\n const files = project.sourceFiles();\n return {\n twillVersion: metadata.version,\n typescriptVersion: ts.version,\n nodeVersion: process.version,\n root: project.root,\n configFiles: project.configFiles,\n compilerOptions: project.compilerOptions,\n files: {\n total: files.length,\n twill: files.filter(isTwillFile).length,\n native: files.filter((file) => !isTwillFile(file)).length,\n },\n sourceFiles: files,\n diagnostics,\n diagnosticTimeMs: performance.now() - started,\n ok: !diagnostics.some((diagnostic) => diagnostic.category === 'error'),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACMA,SAAgB,eAAe,SAAuB,UAAmB;CACvE,MAAM,UAAU,YAAY,IAAI;CAChC,MAAM,cAAc,QAAQ,YAAY,QAAQ;CAChD,MAAM,QAAQ,QAAQ,YAAY;CAClC,OAAO;EACL,cAAcA,gBAAS;EACvB,mBAAmB,GAAG;EACtB,aAAa,QAAQ;EACrB,MAAM,QAAQ;EACd,aAAa,QAAQ;EACrB,iBAAiB,QAAQ;EACzB,OAAO;GACL,OAAO,MAAM;GACb,OAAO,MAAM,OAAO,WAAW,CAAC,CAAC;GACjC,QAAQ,MAAM,QAAQ,SAAS,CAAC,YAAY,IAAI,CAAC,CAAC,CAAC;EACrD;EACA,aAAa;EACb;EACA,kBAAkB,YAAY,IAAI,IAAI;EACtC,IAAI,CAAC,YAAY,MAAM,eAAe,WAAW,aAAa,OAAO;CACvE;AACF"}
|
package/dist/editor.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ export interface CompletionRequest {
|
|
|
17
17
|
export declare class TwillEditor {
|
|
18
18
|
readonly project: TwillProject;
|
|
19
19
|
private attributeCache;
|
|
20
|
+
private descriptorCache;
|
|
20
21
|
constructor(project: TwillProject);
|
|
21
22
|
private sourceFile;
|
|
22
23
|
private attributes;
|
|
@@ -43,6 +44,7 @@ export declare class TwillEditor {
|
|
|
43
44
|
/** Read-only navigation must also exclude generated helpers and duplicate JSX tags. */
|
|
44
45
|
referenceGroups(filename: string, position: number): ts.ReferencedSymbol[] | undefined;
|
|
45
46
|
references(filename: string, position: number): ts.ReferencedSymbolEntry[] | undefined;
|
|
47
|
+
private descriptorSymbols;
|
|
46
48
|
renameInfo(filename: string, position: number): ts.RenameInfo;
|
|
47
49
|
renameLocations(filename: string, position: number, preferences?: ts.UserPreferences | boolean): ts.RenameLocation[] | undefined;
|
|
48
50
|
rename(filename: string, position: number, name: string, preferences?: ts.UserPreferences | boolean): SourceEdit[] | undefined;
|
package/dist/editor.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as isTwillFile } from "./extensions-B1xTkoYP.js";
|
|
2
2
|
import { sourceFilename, virtualFilename } from "./project.js";
|
|
3
3
|
import ts from "typescript";
|
|
4
4
|
//#region src/editor.ts
|
|
@@ -6,6 +6,7 @@ import ts from "typescript";
|
|
|
6
6
|
var TwillEditor = class {
|
|
7
7
|
project;
|
|
8
8
|
attributeCache = /* @__PURE__ */ new WeakMap();
|
|
9
|
+
descriptorCache = /* @__PURE__ */ new WeakMap();
|
|
9
10
|
constructor(project) {
|
|
10
11
|
this.project = project;
|
|
11
12
|
}
|
|
@@ -74,10 +75,11 @@ var TwillEditor = class {
|
|
|
74
75
|
const source = this.project.text(filename);
|
|
75
76
|
if (source === void 0) return void 0;
|
|
76
77
|
if (!isTwillFile(filename)) return span.start >= 0 && span.start + span.length <= source.length ? span : void 0;
|
|
77
|
-
const
|
|
78
|
+
const transformed = this.project.transformed(filename);
|
|
79
|
+
const generated = transformed?.code;
|
|
78
80
|
if (generated === void 0) return void 0;
|
|
79
81
|
const start = this.project.toOriginalOffset(filename, span.start);
|
|
80
|
-
if (start < 0 || start + span.length > source.length || this.project.toGeneratedOffset(filename, start) !== span.start || source.slice(start, start + span.length) !== generated.slice(span.start, span.start + span.length)) return void 0;
|
|
82
|
+
if (start < 0 || start + span.length > source.length || this.project.toGeneratedOffset(filename, start) !== span.start && !transformed.enumCopies.some((copy) => span.start >= copy.generatedStart && span.start + span.length <= copy.generatedStart + copy.length && start === copy.sourceStart + span.start - copy.generatedStart || start >= copy.sourceStart && start + span.length <= copy.sourceStart + copy.length && this.project.toOriginalOffset(filename, span.start + span.length - 1) === start + span.length - 1) || source.slice(start, start + span.length) !== generated.slice(span.start, span.start + span.length)) return void 0;
|
|
81
83
|
return {
|
|
82
84
|
start,
|
|
83
85
|
length: span.length
|
|
@@ -165,8 +167,77 @@ var TwillEditor = class {
|
|
|
165
167
|
references(filename, position) {
|
|
166
168
|
return this.referenceGroups(filename, position)?.flatMap((group) => group.references);
|
|
167
169
|
}
|
|
170
|
+
descriptorSymbols(program) {
|
|
171
|
+
const cached = this.descriptorCache.get(program);
|
|
172
|
+
if (cached) return cached;
|
|
173
|
+
const symbols = /* @__PURE__ */ new Set();
|
|
174
|
+
const checker = program.getTypeChecker();
|
|
175
|
+
for (const file of program.getSourceFiles()) {
|
|
176
|
+
const original = sourceFilename(file.fileName);
|
|
177
|
+
if (!isTwillFile(original)) continue;
|
|
178
|
+
let patterns;
|
|
179
|
+
try {
|
|
180
|
+
patterns = this.project.transformed(original)?.enumPatterns;
|
|
181
|
+
} catch {
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
if (!patterns?.length) continue;
|
|
185
|
+
const offsets = new Set(patterns.map((pattern) => this.project.toGeneratedOffset(original, pattern.reference.property.start)));
|
|
186
|
+
const visit = (node) => {
|
|
187
|
+
if (ts.isIdentifier(node) && offsets.has(node.getStart())) {
|
|
188
|
+
const symbol = checker.getSymbolAtLocation(node);
|
|
189
|
+
if (symbol) for (const root of checker.getRootSymbols(symbol)) symbols.add(root);
|
|
190
|
+
}
|
|
191
|
+
ts.forEachChild(node, visit);
|
|
192
|
+
};
|
|
193
|
+
visit(file);
|
|
194
|
+
}
|
|
195
|
+
this.descriptorCache.set(program, symbols);
|
|
196
|
+
return symbols;
|
|
197
|
+
}
|
|
168
198
|
renameInfo(filename, position) {
|
|
169
|
-
const
|
|
199
|
+
const offset = this.project.toGeneratedOffset(filename, position);
|
|
200
|
+
const definitions = this.project.service.getDefinitionAtPosition(virtualFilename(filename), offset);
|
|
201
|
+
const program = this.project.service.getProgram();
|
|
202
|
+
const descriptors = this.descriptorSymbols(program);
|
|
203
|
+
for (const definition of definitions ?? []) {
|
|
204
|
+
const file = sourceFilename(definition.fileName);
|
|
205
|
+
const definitionFile = this.sourceFile(file);
|
|
206
|
+
let descriptor = false;
|
|
207
|
+
const visitDefinition = (node) => {
|
|
208
|
+
if (definition.textSpan.start < node.getStart() || definition.textSpan.start >= node.end) return;
|
|
209
|
+
if (ts.isIdentifier(node) || ts.isStringLiteral(node)) {
|
|
210
|
+
const symbol = program.getTypeChecker().getSymbolAtLocation(node);
|
|
211
|
+
descriptor = !!symbol && program.getTypeChecker().getRootSymbols(symbol).some((root) => descriptors.has(root));
|
|
212
|
+
} else ts.forEachChild(node, visitDefinition);
|
|
213
|
+
};
|
|
214
|
+
if (descriptors.size && definitionFile) visitDefinition(definitionFile);
|
|
215
|
+
if (descriptor) return {
|
|
216
|
+
canRename: false,
|
|
217
|
+
localizedErrorMessage: "Renaming an enum-pattern case descriptor requires linked discriminator edits and is not supported yet."
|
|
218
|
+
};
|
|
219
|
+
const declarations = this.project.transformed(file)?.associatedEnums;
|
|
220
|
+
if (!declarations?.length) continue;
|
|
221
|
+
const sourceFile = this.sourceFile(file);
|
|
222
|
+
let generatedEnum = false;
|
|
223
|
+
const visit = (node) => {
|
|
224
|
+
if (definition.textSpan.start < node.getStart() || definition.textSpan.start >= node.end) return;
|
|
225
|
+
if ((ts.isTypeAliasDeclaration(node) || ts.isVariableDeclaration(node)) && ts.isIdentifier(node.name)) {
|
|
226
|
+
const start = this.project.toOriginalOffset(file, node.name.getStart());
|
|
227
|
+
if (declarations.some((declaration) => declaration.id.start === start)) {
|
|
228
|
+
generatedEnum = true;
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
ts.forEachChild(node, visit);
|
|
233
|
+
};
|
|
234
|
+
if (sourceFile) visit(sourceFile);
|
|
235
|
+
if (generatedEnum) return {
|
|
236
|
+
canRename: false,
|
|
237
|
+
localizedErrorMessage: "Renaming associated-value enum declarations, cases, payload fields and type parameters is not supported yet."
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
const info = this.project.service.getRenameInfo(virtualFilename(filename), offset, { allowRenameOfImportPath: false });
|
|
170
241
|
if (!info.canRename) return info;
|
|
171
242
|
const span = this.mapSpan(filename, info.triggerSpan);
|
|
172
243
|
return span ? {
|
package/dist/editor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor.js","names":[],"sources":["../src/editor.ts"],"sourcesContent":["import ts from 'typescript';\nimport { TwillProject, sourceFilename, virtualFilename } from './project.js';\nimport { isTwillFile } from './compiler.js';\n\nexport interface SourceEdit {\n filename: string;\n span: ts.TextSpan;\n newText: string;\n}\n\nexport interface CompletionRequest {\n offset: number;\n info: ts.CompletionInfo | undefined;\n props?: { start: number; end: number };\n}\n\n/** Shared semantic requests and conservative source edits for both editor hosts. */\nexport class TwillEditor {\n private attributeCache = new WeakMap<ts.SourceFile, ts.JsxAttribute[]>();\n constructor(readonly project: TwillProject) {}\n\n private sourceFile(filename: string) {\n return this.project.service.getProgram()?.getSourceFile(virtualFilename(filename));\n }\n\n private attributes(filename: string) {\n const file = this.sourceFile(filename);\n if (!file) return [];\n const cached = this.attributeCache.get(file);\n if (cached) return cached;\n const result: ts.JsxAttribute[] = [];\n const visit = (node: ts.Node) => {\n if (ts.isJsxAttribute(node)) result.push(node);\n ts.forEachChild(node, visit);\n };\n visit(file);\n this.attributeCache.set(file, result);\n return result;\n }\n\n completionLocation(filename: string, position: number) {\n let offset = this.project.toGeneratedOffset(filename, position);\n // A repaired member name and generated arm punctuation can share the same\n // original boundary. Anchor requests at the source-backed dot instead.\n const prefix = this.project.text(filename)?.slice(0, position);\n const member = prefix?.match(/\\.([\\p{ID_Continue}$\\u200c\\u200d]*)$/u);\n const missingMember = prefix?.match(/\\.\\s*$/);\n if (member) offset = this.project.toGeneratedOffset(filename, member.index!) + member[0].length;\n else if (missingMember)\n offset = this.project.toGeneratedOffset(filename, missingMember.index!) + 1;\n let props: CompletionRequest['props'];\n const metadata = this.project.transformed(filename)?.componentProps;\n const property = metadata\n ?.flatMap((object) => object.properties)\n .find((item) => item.shorthand && position >= item.start && position <= item.end);\n if (property) {\n const attribute = this.attributes(filename).find(\n (item) =>\n item.name.getText() === property.name &&\n item.initializer &&\n ts.isJsxExpression(item.initializer) &&\n item.initializer.expression &&\n this.project.toOriginalOffset(filename, item.initializer.expression.getStart()) ===\n property.start,\n );\n if (attribute) {\n offset = attribute.name.getStart() + position - property.start;\n props = { start: property.start, end: property.end };\n }\n } else if (\n metadata?.some((object) => position > object.start && position < object.end) &&\n !this.attributes(filename).some(\n (attribute) => offset >= attribute.name.end && offset <= attribute.end,\n )\n ) {\n // Empty objects and gaps between properties already map to JSX attribute\n // positions. Only classify requests that TS identifies as member lists.\n props = { start: position, end: position };\n }\n return { offset, props };\n }\n\n completions(filename: string, position: number, preferences: ts.UserPreferences = {}) {\n let { offset, props } = this.completionLocation(filename, position);\n const info = this.project.service.getCompletionsAtPosition(virtualFilename(filename), offset, {\n includeCompletionsForModuleExports: true,\n includeCompletionsWithInsertText: true,\n ...preferences,\n });\n if (props && !info?.isMemberCompletion) props = undefined;\n return { offset, info, props } satisfies CompletionRequest;\n }\n\n /** Never stretch a generated edit across lowered punctuation or helper code. */\n mapSpan(filename: string, span: ts.TextSpan): ts.TextSpan | undefined {\n filename = sourceFilename(filename);\n const source = this.project.text(filename);\n if (source === undefined) return undefined;\n if (!isTwillFile(filename))\n return span.start >= 0 && span.start + span.length <= source.length ? span : undefined;\n const generated = this.project.transformed(filename)?.code;\n if (generated === undefined) return undefined;\n const start = this.project.toOriginalOffset(filename, span.start);\n if (\n start < 0 ||\n start + span.length > source.length ||\n this.project.toGeneratedOffset(filename, start) !== span.start ||\n source.slice(start, start + span.length) !==\n generated.slice(span.start, span.start + span.length)\n )\n return undefined;\n return { start, length: span.length };\n }\n\n mapChanges(changes: readonly ts.FileTextChanges[]): SourceEdit[] | undefined {\n const edits: SourceEdit[] = [];\n for (const file of changes) {\n if (file.isNewFile) return undefined;\n const filename = sourceFilename(file.fileName);\n for (const change of file.textChanges) {\n let span = this.mapSpan(filename, change.span);\n // Inferred JSX runtime pragmas can precede the first source token.\n // A fresh import can safely be inserted before the original module.\n if (!span && change.span.length === 0 && /^\\s*import\\b/.test(change.newText)) {\n const firstStatement = this.sourceFile(filename)?.statements[0];\n if (change.span.start <= (firstStatement?.getStart() ?? 0))\n span = { start: 0, length: 0 };\n }\n if (!span) return undefined;\n edits.push({ filename, span, newText: this.importText(change.newText) });\n }\n }\n return edits;\n }\n\n private importText(text: string) {\n // Edit only module literals, never user strings in an unrelated code fix.\n const file = ts.createSourceFile('edits.ts', text, ts.ScriptTarget.Latest, true);\n const replacements: { start: number; end: number; text: string }[] = [];\n for (const statement of file.statements) {\n if (\n (ts.isImportDeclaration(statement) || ts.isExportDeclaration(statement)) &&\n statement.moduleSpecifier &&\n ts.isStringLiteral(statement.moduleSpecifier)\n ) {\n const literal = statement.moduleSpecifier;\n const value = sourceFilename(literal.text);\n if (value !== literal.text)\n replacements.push({ start: literal.getStart() + 1, end: literal.end - 1, text: value });\n }\n }\n for (const replacement of replacements.reverse())\n text = text.slice(0, replacement.start) + replacement.text + text.slice(replacement.end);\n return text;\n }\n\n organizeImports(filename: string, mode = ts.OrganizeImportsMode.All) {\n return this.mapChanges(\n this.project.service.organizeImports(\n { type: 'file', fileName: virtualFilename(filename), mode },\n {},\n {},\n ),\n );\n }\n\n /** Read-only navigation must also exclude generated helpers and duplicate JSX tags. */\n referenceGroups(filename: string, position: number): ts.ReferencedSymbol[] | undefined {\n const groups = this.project.service.findReferences(\n virtualFilename(filename),\n this.project.toGeneratedOffset(filename, position),\n );\n const mapped = <T extends ts.DocumentSpan>(entry: T): T | undefined => {\n const fileName = sourceFilename(entry.fileName);\n const textSpan = this.mapSpan(fileName, entry.textSpan);\n if (!textSpan) return undefined;\n const contextSpan = entry.contextSpan && this.mapSpan(fileName, entry.contextSpan);\n return { ...entry, fileName, textSpan, contextSpan };\n };\n return groups?.flatMap((group) => {\n const definition = mapped(group.definition);\n if (!definition) return [];\n const seen = new Set<string>();\n const references = group.references.flatMap((reference) => {\n const entry = mapped(reference);\n if (!entry) return [];\n // Some TS versions omit isDefinition from findReferences results.\n // Preserve supplied flags; otherwise compare the source-backed span\n // with this symbol group's definition for includeDeclaration requests.\n entry.isDefinition ??=\n entry.fileName === definition.fileName &&\n entry.textSpan.start === definition.textSpan.start &&\n entry.textSpan.length === definition.textSpan.length;\n const key = `${entry.fileName}:${entry.textSpan.start}:${entry.textSpan.length}`;\n if (seen.has(key)) return [];\n seen.add(key);\n return [entry];\n });\n return [{ definition, references }];\n });\n }\n\n references(filename: string, position: number) {\n return this.referenceGroups(filename, position)?.flatMap((group) => group.references);\n }\n\n renameInfo(filename: string, position: number): ts.RenameInfo {\n const info = this.project.service.getRenameInfo(\n virtualFilename(filename),\n this.project.toGeneratedOffset(filename, position),\n { allowRenameOfImportPath: false },\n );\n if (!info.canRename) return info;\n const span = this.mapSpan(filename, info.triggerSpan);\n return span\n ? { ...info, triggerSpan: span }\n : {\n canRename: false,\n localizedErrorMessage: 'This generated symbol cannot be renamed in Twill source.',\n };\n }\n\n renameLocations(\n filename: string,\n position: number,\n preferences: ts.UserPreferences | boolean = true,\n ) {\n const info = this.renameInfo(filename, position);\n if (!info.canRename) return undefined;\n const locations = this.project.service.findRenameLocations(\n virtualFilename(filename),\n this.project.toGeneratedOffset(filename, position),\n false,\n false,\n typeof preferences === 'boolean'\n ? { providePrefixAndSuffixTextForRename: preferences }\n : preferences,\n );\n if (!locations) return undefined;\n const result: ts.RenameLocation[] = [];\n for (const location of locations) {\n const file = sourceFilename(location.fileName);\n let span = this.mapSpan(file, location.textSpan);\n let prefixText = location.prefixText;\n let suffixText = location.suffixText;\n if (isTwillFile(file)) {\n const attribute = this.attributes(file).find(\n (item) =>\n item.name.getStart() === location.textSpan.start &&\n item.initializer &&\n ts.isJsxExpression(item.initializer) &&\n item.initializer.expression,\n );\n if (attribute && attribute.initializer && ts.isJsxExpression(attribute.initializer)) {\n const original = this.project.toOriginalOffset(\n file,\n attribute.initializer.expression!.getStart(),\n );\n const property = this.project\n .transformed(file)\n ?.componentProps.flatMap((object) => object.properties)\n .find(\n (item) =>\n item.name === attribute.name.getText() &&\n (item.shorthand\n ? item.start === original\n : item.start === this.project.toOriginalOffset(file, attribute.name.getStart())),\n );\n if (property) {\n span = { start: property.start, length: property.end - property.start };\n if (property.shorthand) suffixText = `: ${property.name}`;\n else {\n const quote = this.project.text(file)?.[property.start];\n if (quote === '\"' || quote === \"'\") {\n prefixText = quote;\n suffixText = quote;\n }\n }\n }\n } else if (span) {\n const property = this.project\n .transformed(file)\n ?.componentProps.flatMap((object) => object.properties)\n .find((item) => item.shorthand && item.start === span!.start);\n if (property) prefixText = `${property.name}: `;\n }\n }\n if (!span) {\n const generated = this.project.transformed(file)?.code;\n const start = this.project.toOriginalOffset(file, location.textSpan.start);\n if (\n generated &&\n this.project.text(file)?.slice(start, start + location.textSpan.length) !==\n generated.slice(\n location.textSpan.start,\n location.textSpan.start + location.textSpan.length,\n )\n )\n continue; // A compiler-inserted guard/defer reference is regenerated.\n // Generated closing JSX tags duplicate a source component reference;\n // they have no independent source occurrence to edit.\n const sf = this.sourceFile(file);\n let closing = false;\n const visit = (node: ts.Node) => {\n if (\n ts.isJsxClosingElement(node) &&\n location.textSpan.start >= node.tagName.getStart() &&\n location.textSpan.start < node.tagName.end\n )\n closing = true;\n else if (\n location.textSpan.start >= node.getFullStart() &&\n location.textSpan.start < node.end\n )\n ts.forEachChild(node, visit);\n };\n if (sf) visit(sf);\n if (closing) continue;\n return undefined;\n }\n result.push({\n ...location,\n fileName: file,\n textSpan: span,\n prefixText,\n suffixText,\n contextSpan: location.contextSpan ? this.mapSpan(file, location.contextSpan) : undefined,\n });\n }\n return result.filter(\n (item, index) =>\n result.findIndex(\n (other) =>\n item.fileName === other.fileName &&\n item.textSpan.start === other.textSpan.start &&\n item.textSpan.length === other.textSpan.length,\n ) === index,\n );\n }\n\n rename(\n filename: string,\n position: number,\n name: string,\n preferences: ts.UserPreferences | boolean = true,\n ): SourceEdit[] | undefined {\n const scanner = ts.createScanner(\n ts.ScriptTarget.Latest,\n false,\n ts.LanguageVariant.Standard,\n name,\n );\n if (\n scanner.scan() !== ts.SyntaxKind.Identifier ||\n scanner.scan() !== ts.SyntaxKind.EndOfFileToken\n )\n return undefined;\n return this.renameLocations(filename, position, preferences)?.map((location) => ({\n filename: location.fileName,\n span: location.textSpan,\n newText: (location.prefixText ?? '') + name + (location.suffixText ?? ''),\n }));\n }\n\n fixes(filename: string, start: number, end: number, codes: readonly number[]) {\n return this.project.service\n .getCodeFixesAtPosition(\n virtualFilename(filename),\n this.project.toGeneratedOffset(filename, start),\n this.project.toGeneratedOffset(filename, end),\n codes,\n {},\n {},\n )\n .flatMap((fix) => {\n const edits = this.mapChanges(fix.changes);\n return edits?.length && !fix.commands?.length\n ? [{ description: fix.description, edits }]\n : [];\n });\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"editor.js","names":[],"sources":["../src/editor.ts"],"sourcesContent":["import ts from 'typescript';\nimport { TwillProject, sourceFilename, virtualFilename } from './project.js';\nimport { isTwillFile, type TransformResult } from './compiler.js';\n\nexport interface SourceEdit {\n filename: string;\n span: ts.TextSpan;\n newText: string;\n}\n\nexport interface CompletionRequest {\n offset: number;\n info: ts.CompletionInfo | undefined;\n props?: { start: number; end: number };\n}\n\n/** Shared semantic requests and conservative source edits for both editor hosts. */\nexport class TwillEditor {\n private attributeCache = new WeakMap<ts.SourceFile, ts.JsxAttribute[]>();\n private descriptorCache = new WeakMap<ts.Program, Set<ts.Symbol>>();\n constructor(readonly project: TwillProject) {}\n\n private sourceFile(filename: string) {\n return this.project.service.getProgram()?.getSourceFile(virtualFilename(filename));\n }\n\n private attributes(filename: string) {\n const file = this.sourceFile(filename);\n if (!file) return [];\n const cached = this.attributeCache.get(file);\n if (cached) return cached;\n const result: ts.JsxAttribute[] = [];\n const visit = (node: ts.Node) => {\n if (ts.isJsxAttribute(node)) result.push(node);\n ts.forEachChild(node, visit);\n };\n visit(file);\n this.attributeCache.set(file, result);\n return result;\n }\n\n completionLocation(filename: string, position: number) {\n let offset = this.project.toGeneratedOffset(filename, position);\n // A repaired member name and generated arm punctuation can share the same\n // original boundary. Anchor requests at the source-backed dot instead.\n const prefix = this.project.text(filename)?.slice(0, position);\n const member = prefix?.match(/\\.([\\p{ID_Continue}$\\u200c\\u200d]*)$/u);\n const missingMember = prefix?.match(/\\.\\s*$/);\n if (member) offset = this.project.toGeneratedOffset(filename, member.index!) + member[0].length;\n else if (missingMember)\n offset = this.project.toGeneratedOffset(filename, missingMember.index!) + 1;\n let props: CompletionRequest['props'];\n const metadata = this.project.transformed(filename)?.componentProps;\n const property = metadata\n ?.flatMap((object) => object.properties)\n .find((item) => item.shorthand && position >= item.start && position <= item.end);\n if (property) {\n const attribute = this.attributes(filename).find(\n (item) =>\n item.name.getText() === property.name &&\n item.initializer &&\n ts.isJsxExpression(item.initializer) &&\n item.initializer.expression &&\n this.project.toOriginalOffset(filename, item.initializer.expression.getStart()) ===\n property.start,\n );\n if (attribute) {\n offset = attribute.name.getStart() + position - property.start;\n props = { start: property.start, end: property.end };\n }\n } else if (\n metadata?.some((object) => position > object.start && position < object.end) &&\n !this.attributes(filename).some(\n (attribute) => offset >= attribute.name.end && offset <= attribute.end,\n )\n ) {\n // Empty objects and gaps between properties already map to JSX attribute\n // positions. Only classify requests that TS identifies as member lists.\n props = { start: position, end: position };\n }\n return { offset, props };\n }\n\n completions(filename: string, position: number, preferences: ts.UserPreferences = {}) {\n let { offset, props } = this.completionLocation(filename, position);\n const info = this.project.service.getCompletionsAtPosition(virtualFilename(filename), offset, {\n includeCompletionsForModuleExports: true,\n includeCompletionsWithInsertText: true,\n ...preferences,\n });\n if (props && !info?.isMemberCompletion) props = undefined;\n return { offset, info, props } satisfies CompletionRequest;\n }\n\n /** Never stretch a generated edit across lowered punctuation or helper code. */\n mapSpan(filename: string, span: ts.TextSpan): ts.TextSpan | undefined {\n filename = sourceFilename(filename);\n const source = this.project.text(filename);\n if (source === undefined) return undefined;\n if (!isTwillFile(filename))\n return span.start >= 0 && span.start + span.length <= source.length ? span : undefined;\n const transformed = this.project.transformed(filename);\n const generated = transformed?.code;\n if (generated === undefined) return undefined;\n const start = this.project.toOriginalOffset(filename, span.start);\n if (\n start < 0 ||\n start + span.length > source.length ||\n (this.project.toGeneratedOffset(filename, start) !== span.start &&\n !transformed!.enumCopies.some(\n (copy) =>\n (span.start >= copy.generatedStart &&\n span.start + span.length <= copy.generatedStart + copy.length &&\n start === copy.sourceStart + span.start - copy.generatedStart) ||\n (start >= copy.sourceStart &&\n start + span.length <= copy.sourceStart + copy.length &&\n this.project.toOriginalOffset(filename, span.start + span.length - 1) ===\n start + span.length - 1),\n )) ||\n source.slice(start, start + span.length) !==\n generated.slice(span.start, span.start + span.length)\n )\n return undefined;\n return { start, length: span.length };\n }\n\n mapChanges(changes: readonly ts.FileTextChanges[]): SourceEdit[] | undefined {\n const edits: SourceEdit[] = [];\n for (const file of changes) {\n if (file.isNewFile) return undefined;\n const filename = sourceFilename(file.fileName);\n for (const change of file.textChanges) {\n let span = this.mapSpan(filename, change.span);\n // Inferred JSX runtime pragmas can precede the first source token.\n // A fresh import can safely be inserted before the original module.\n if (!span && change.span.length === 0 && /^\\s*import\\b/.test(change.newText)) {\n const firstStatement = this.sourceFile(filename)?.statements[0];\n if (change.span.start <= (firstStatement?.getStart() ?? 0))\n span = { start: 0, length: 0 };\n }\n if (!span) return undefined;\n edits.push({ filename, span, newText: this.importText(change.newText) });\n }\n }\n return edits;\n }\n\n private importText(text: string) {\n // Edit only module literals, never user strings in an unrelated code fix.\n const file = ts.createSourceFile('edits.ts', text, ts.ScriptTarget.Latest, true);\n const replacements: { start: number; end: number; text: string }[] = [];\n for (const statement of file.statements) {\n if (\n (ts.isImportDeclaration(statement) || ts.isExportDeclaration(statement)) &&\n statement.moduleSpecifier &&\n ts.isStringLiteral(statement.moduleSpecifier)\n ) {\n const literal = statement.moduleSpecifier;\n const value = sourceFilename(literal.text);\n if (value !== literal.text)\n replacements.push({ start: literal.getStart() + 1, end: literal.end - 1, text: value });\n }\n }\n for (const replacement of replacements.reverse())\n text = text.slice(0, replacement.start) + replacement.text + text.slice(replacement.end);\n return text;\n }\n\n organizeImports(filename: string, mode = ts.OrganizeImportsMode.All) {\n return this.mapChanges(\n this.project.service.organizeImports(\n { type: 'file', fileName: virtualFilename(filename), mode },\n {},\n {},\n ),\n );\n }\n\n /** Read-only navigation must also exclude generated helpers and duplicate JSX tags. */\n referenceGroups(filename: string, position: number): ts.ReferencedSymbol[] | undefined {\n const groups = this.project.service.findReferences(\n virtualFilename(filename),\n this.project.toGeneratedOffset(filename, position),\n );\n const mapped = <T extends ts.DocumentSpan>(entry: T): T | undefined => {\n const fileName = sourceFilename(entry.fileName);\n const textSpan = this.mapSpan(fileName, entry.textSpan);\n if (!textSpan) return undefined;\n const contextSpan = entry.contextSpan && this.mapSpan(fileName, entry.contextSpan);\n return { ...entry, fileName, textSpan, contextSpan };\n };\n return groups?.flatMap((group) => {\n const definition = mapped(group.definition);\n if (!definition) return [];\n const seen = new Set<string>();\n const references = group.references.flatMap((reference) => {\n const entry = mapped(reference);\n if (!entry) return [];\n // Some TS versions omit isDefinition from findReferences results.\n // Preserve supplied flags; otherwise compare the source-backed span\n // with this symbol group's definition for includeDeclaration requests.\n entry.isDefinition ??=\n entry.fileName === definition.fileName &&\n entry.textSpan.start === definition.textSpan.start &&\n entry.textSpan.length === definition.textSpan.length;\n const key = `${entry.fileName}:${entry.textSpan.start}:${entry.textSpan.length}`;\n if (seen.has(key)) return [];\n seen.add(key);\n return [entry];\n });\n return [{ definition, references }];\n });\n }\n\n references(filename: string, position: number) {\n return this.referenceGroups(filename, position)?.flatMap((group) => group.references);\n }\n\n private descriptorSymbols(program: ts.Program) {\n const cached = this.descriptorCache.get(program);\n if (cached) return cached;\n const symbols = new Set<ts.Symbol>();\n const checker = program.getTypeChecker();\n for (const file of program.getSourceFiles()) {\n const original = sourceFilename(file.fileName);\n if (!isTwillFile(original)) continue;\n let patterns: TransformResult['enumPatterns'] | undefined;\n try {\n patterns = this.project.transformed(original)?.enumPatterns;\n } catch {\n // One malformed document must not disable safe edits in other files.\n // Strict diagnostics and mapChanges still reject its unmappable edits.\n continue;\n }\n if (!patterns?.length) continue;\n const offsets = new Set(\n patterns.map((pattern) =>\n this.project.toGeneratedOffset(original, pattern.reference.property.start),\n ),\n );\n // Index each source once, rather than traversing it for every arm.\n // Program identity invalidates the cached symbols on any source edit.\n const visit = (node: ts.Node) => {\n if (ts.isIdentifier(node) && offsets.has(node.getStart())) {\n const symbol = checker.getSymbolAtLocation(node);\n if (symbol) for (const root of checker.getRootSymbols(symbol)) symbols.add(root);\n }\n ts.forEachChild(node, visit);\n };\n visit(file);\n }\n this.descriptorCache.set(program, symbols);\n return symbols;\n }\n\n renameInfo(filename: string, position: number): ts.RenameInfo {\n const offset = this.project.toGeneratedOffset(filename, position);\n const definitions = this.project.service.getDefinitionAtPosition(\n virtualFilename(filename),\n offset,\n );\n const program = this.project.service.getProgram()!;\n const descriptors = this.descriptorSymbols(program);\n for (const definition of definitions ?? []) {\n const file = sourceFilename(definition.fileName);\n const definitionFile = this.sourceFile(file);\n let descriptor = false;\n const visitDefinition = (node: ts.Node) => {\n if (definition.textSpan.start < node.getStart() || definition.textSpan.start >= node.end)\n return;\n if (ts.isIdentifier(node) || ts.isStringLiteral(node)) {\n const symbol = program.getTypeChecker().getSymbolAtLocation(node);\n descriptor =\n !!symbol &&\n program\n .getTypeChecker()\n .getRootSymbols(symbol)\n .some((root) => descriptors.has(root));\n } else ts.forEachChild(node, visitDefinition);\n };\n if (descriptors.size && definitionFile) visitDefinition(definitionFile);\n if (descriptor)\n return {\n canRename: false,\n localizedErrorMessage:\n 'Renaming an enum-pattern case descriptor requires linked discriminator edits and is not supported yet.',\n };\n const declarations = this.project.transformed(file)?.associatedEnums;\n if (!declarations?.length) continue;\n const sourceFile = this.sourceFile(file);\n let generatedEnum = false;\n const visit = (node: ts.Node) => {\n if (definition.textSpan.start < node.getStart() || definition.textSpan.start >= node.end)\n return;\n if (\n (ts.isTypeAliasDeclaration(node) || ts.isVariableDeclaration(node)) &&\n ts.isIdentifier(node.name)\n ) {\n const start = this.project.toOriginalOffset(file, node.name.getStart());\n if (declarations.some((declaration) => declaration.id.start === start)) {\n generatedEnum = true;\n return;\n }\n }\n ts.forEachChild(node, visit);\n };\n if (sourceFile) visit(sourceFile);\n if (generatedEnum)\n return {\n canRename: false,\n localizedErrorMessage:\n 'Renaming associated-value enum declarations, cases, payload fields and type parameters is not supported yet.',\n };\n }\n const info = this.project.service.getRenameInfo(virtualFilename(filename), offset, {\n allowRenameOfImportPath: false,\n });\n if (!info.canRename) return info;\n const span = this.mapSpan(filename, info.triggerSpan);\n return span\n ? { ...info, triggerSpan: span }\n : {\n canRename: false,\n localizedErrorMessage: 'This generated symbol cannot be renamed in Twill source.',\n };\n }\n\n renameLocations(\n filename: string,\n position: number,\n preferences: ts.UserPreferences | boolean = true,\n ) {\n const info = this.renameInfo(filename, position);\n if (!info.canRename) return undefined;\n const locations = this.project.service.findRenameLocations(\n virtualFilename(filename),\n this.project.toGeneratedOffset(filename, position),\n false,\n false,\n typeof preferences === 'boolean'\n ? { providePrefixAndSuffixTextForRename: preferences }\n : preferences,\n );\n if (!locations) return undefined;\n const result: ts.RenameLocation[] = [];\n for (const location of locations) {\n const file = sourceFilename(location.fileName);\n let span = this.mapSpan(file, location.textSpan);\n let prefixText = location.prefixText;\n let suffixText = location.suffixText;\n if (isTwillFile(file)) {\n const attribute = this.attributes(file).find(\n (item) =>\n item.name.getStart() === location.textSpan.start &&\n item.initializer &&\n ts.isJsxExpression(item.initializer) &&\n item.initializer.expression,\n );\n if (attribute && attribute.initializer && ts.isJsxExpression(attribute.initializer)) {\n const original = this.project.toOriginalOffset(\n file,\n attribute.initializer.expression!.getStart(),\n );\n const property = this.project\n .transformed(file)\n ?.componentProps.flatMap((object) => object.properties)\n .find(\n (item) =>\n item.name === attribute.name.getText() &&\n (item.shorthand\n ? item.start === original\n : item.start === this.project.toOriginalOffset(file, attribute.name.getStart())),\n );\n if (property) {\n span = { start: property.start, length: property.end - property.start };\n if (property.shorthand) suffixText = `: ${property.name}`;\n else {\n const quote = this.project.text(file)?.[property.start];\n if (quote === '\"' || quote === \"'\") {\n prefixText = quote;\n suffixText = quote;\n }\n }\n }\n } else if (span) {\n const property = this.project\n .transformed(file)\n ?.componentProps.flatMap((object) => object.properties)\n .find((item) => item.shorthand && item.start === span!.start);\n if (property) prefixText = `${property.name}: `;\n }\n }\n if (!span) {\n const generated = this.project.transformed(file)?.code;\n const start = this.project.toOriginalOffset(file, location.textSpan.start);\n if (\n generated &&\n this.project.text(file)?.slice(start, start + location.textSpan.length) !==\n generated.slice(\n location.textSpan.start,\n location.textSpan.start + location.textSpan.length,\n )\n )\n continue; // A compiler-inserted guard/defer reference is regenerated.\n // Generated closing JSX tags duplicate a source component reference;\n // they have no independent source occurrence to edit.\n const sf = this.sourceFile(file);\n let closing = false;\n const visit = (node: ts.Node) => {\n if (\n ts.isJsxClosingElement(node) &&\n location.textSpan.start >= node.tagName.getStart() &&\n location.textSpan.start < node.tagName.end\n )\n closing = true;\n else if (\n location.textSpan.start >= node.getFullStart() &&\n location.textSpan.start < node.end\n )\n ts.forEachChild(node, visit);\n };\n if (sf) visit(sf);\n if (closing) continue;\n return undefined;\n }\n result.push({\n ...location,\n fileName: file,\n textSpan: span,\n prefixText,\n suffixText,\n contextSpan: location.contextSpan ? this.mapSpan(file, location.contextSpan) : undefined,\n });\n }\n return result.filter(\n (item, index) =>\n result.findIndex(\n (other) =>\n item.fileName === other.fileName &&\n item.textSpan.start === other.textSpan.start &&\n item.textSpan.length === other.textSpan.length,\n ) === index,\n );\n }\n\n rename(\n filename: string,\n position: number,\n name: string,\n preferences: ts.UserPreferences | boolean = true,\n ): SourceEdit[] | undefined {\n const scanner = ts.createScanner(\n ts.ScriptTarget.Latest,\n false,\n ts.LanguageVariant.Standard,\n name,\n );\n if (\n scanner.scan() !== ts.SyntaxKind.Identifier ||\n scanner.scan() !== ts.SyntaxKind.EndOfFileToken\n )\n return undefined;\n return this.renameLocations(filename, position, preferences)?.map((location) => ({\n filename: location.fileName,\n span: location.textSpan,\n newText: (location.prefixText ?? '') + name + (location.suffixText ?? ''),\n }));\n }\n\n fixes(filename: string, start: number, end: number, codes: readonly number[]) {\n return this.project.service\n .getCodeFixesAtPosition(\n virtualFilename(filename),\n this.project.toGeneratedOffset(filename, start),\n this.project.toGeneratedOffset(filename, end),\n codes,\n {},\n {},\n )\n .flatMap((fix) => {\n const edits = this.mapChanges(fix.changes);\n return edits?.length && !fix.commands?.length\n ? [{ description: fix.description, edits }]\n : [];\n });\n }\n}\n"],"mappings":"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"}
|
package/dist/enums.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { default as MagicString, SourceMap } from 'magic-string';
|
|
2
|
+
type Node = {
|
|
3
|
+
type: string;
|
|
4
|
+
start: number;
|
|
5
|
+
end: number;
|
|
6
|
+
[key: string]: any;
|
|
7
|
+
};
|
|
8
|
+
type Insertion = {
|
|
9
|
+
anchor: number;
|
|
10
|
+
before: boolean;
|
|
11
|
+
text: string;
|
|
12
|
+
copies: {
|
|
13
|
+
start: number;
|
|
14
|
+
sourceStart: number;
|
|
15
|
+
length: number;
|
|
16
|
+
}[];
|
|
17
|
+
};
|
|
18
|
+
export declare function enumTypeParameters(node: Node, branch: Node): Node[];
|
|
19
|
+
/** Tagged records and precise factories; no application runtime is introduced. */
|
|
20
|
+
export declare function lowerEnums(source: string, ast: Node, enums: Node[], code: MagicString): Insertion[];
|
|
21
|
+
/** Generated type copies map to their actual source tokens, including .d.ts maps. */
|
|
22
|
+
export declare function mapEnumCopies(source: string, generated: string, map: SourceMap, insertions: Insertion[]): {
|
|
23
|
+
generatedStart: number;
|
|
24
|
+
sourceStart: number;
|
|
25
|
+
length: number;
|
|
26
|
+
}[];
|
|
27
|
+
export {};
|
package/dist/esbuild.js
CHANGED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//#region src/extensions.ts
|
|
2
|
+
var extensions = [".twill", ".twillx"];
|
|
3
|
+
function isTwillFile(id) {
|
|
4
|
+
return extensions.some((extension) => id.split(/[?#]/, 1)[0].endsWith(extension));
|
|
5
|
+
}
|
|
6
|
+
//#endregion
|
|
7
|
+
export { isTwillFile as n, extensions as t };
|
|
8
|
+
|
|
9
|
+
//# sourceMappingURL=extensions-B1xTkoYP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extensions-B1xTkoYP.js","names":[],"sources":["../src/extensions.ts"],"sourcesContent":["export const extensions = ['.twill', '.twillx'] as const;\nexport function isTwillFile(id: string): boolean {\n return extensions.some((extension) => id.split(/[?#]/, 1)[0]!.endsWith(extension));\n}\n"],"mappings":";AAAA,IAAa,aAAa,CAAC,UAAU,SAAS;AAC9C,SAAgB,YAAY,IAAqB;CAC/C,OAAO,WAAW,MAAM,cAAc,GAAG,MAAM,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAE,SAAS,SAAS,CAAC;AACnF"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { t as extensions } from "./extensions-B1xTkoYP.js";
|
|
2
2
|
import { statSync } from "node:fs";
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
4
|
//#region src/files.ts
|
|
@@ -43,4 +43,4 @@ function resolveSourceFile(base) {
|
|
|
43
43
|
//#endregion
|
|
44
44
|
export { splitId as a, sourceExtensions as i, needsTypeEmission as n, resolveSourceFile as r, isDependency as t };
|
|
45
45
|
|
|
46
|
-
//# sourceMappingURL=files-
|
|
46
|
+
//# sourceMappingURL=files-BW9geU0_.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files-BW9geU0_.js","names":[],"sources":["../src/files.ts"],"sourcesContent":["import { statSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport { extensions } from './extensions.js';\n\nexport const sourceExtensions = [\n '.mjs',\n '.js',\n '.mts',\n '.ts',\n '.jsx',\n '.tsx',\n '.cjs',\n '.cts',\n '.json',\n ...extensions,\n];\nexport function isDependency(filename: string) {\n return /(?:^|[\\\\/])node_modules[\\\\/]/.test(filename);\n}\nexport function needsTypeEmission(filename: string) {\n return /\\.(?:tsx?|mts|jsx)$/.test(filename) && !/\\.d\\.(?:ts|mts)$/.test(filename);\n}\nexport function splitId(id: string): [string, string] {\n const index = id.search(/[?#]/);\n return index < 0 ? [id, ''] : [id.slice(0, index), id.slice(index)];\n}\nexport function resolveSourceFile(base: string): string | undefined {\n const file = (candidate: string) => {\n try {\n return statSync(candidate).isFile();\n } catch (error) {\n if (['ENOENT', 'ENOTDIR'].includes((error as NodeJS.ErrnoException).code ?? '')) return false;\n throw error;\n }\n };\n if (file(base)) return base;\n // Match the native-first order of the Vite resolver. Explicit filenames\n // remain the way to select one of several same-stem source files.\n for (const extension of sourceExtensions) if (file(base + extension)) return base + extension;\n for (const extension of sourceExtensions) {\n const candidate = resolve(base, 'index' + extension);\n if (file(candidate)) return candidate;\n }\n}\n"],"mappings":";;;;AAIA,IAAa,mBAAmB;CAC9B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA,GAAG;AACL;AACA,SAAgB,aAAa,UAAkB;CAC7C,OAAO,+BAA+B,KAAK,QAAQ;AACrD;AACA,SAAgB,kBAAkB,UAAkB;CAClD,OAAO,sBAAsB,KAAK,QAAQ,KAAK,CAAC,mBAAmB,KAAK,QAAQ;AAClF;AACA,SAAgB,QAAQ,IAA8B;CACpD,MAAM,QAAQ,GAAG,OAAO,MAAM;CAC9B,OAAO,QAAQ,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,MAAM,GAAG,KAAK,GAAG,GAAG,MAAM,KAAK,CAAC;AACpE;AACA,SAAgB,kBAAkB,MAAkC;CAClE,MAAM,QAAQ,cAAsB;EAClC,IAAI;GACF,OAAO,SAAS,SAAS,CAAC,CAAC,OAAO;EACpC,SAAS,OAAO;GACd,IAAI,CAAC,UAAU,SAAS,CAAC,CAAC,SAAU,MAAgC,QAAQ,EAAE,GAAG,OAAO;GACxF,MAAM;EACR;CACF;CACA,IAAI,KAAK,IAAI,GAAG,OAAO;CAGvB,KAAK,MAAM,aAAa,kBAAkB,IAAI,KAAK,OAAO,SAAS,GAAG,OAAO,OAAO;CACpF,KAAK,MAAM,aAAa,kBAAkB;EACxC,MAAM,YAAY,QAAQ,MAAM,UAAU,SAAS;EACnD,IAAI,KAAK,SAAS,GAAG,OAAO;CAC9B;AACF"}
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as transform, i as originalPosition, n as generatedPosition, r as inferLanguage, t as TwillSyntaxError } from "./compiler-DY1N07np.js";
|
|
2
|
+
import { n as isTwillFile, t as extensions } from "./extensions-B1xTkoYP.js";
|
|
2
3
|
export { TwillSyntaxError, extensions, generatedPosition, inferLanguage, isTwillFile, originalPosition, transform };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { r as loaderConfiguration } from "./configuration-CTJjSu_h.js";
|
|
2
|
+
import { n as transpileNative, t as transpile } from "./transpile-DG81yfVs.js";
|
|
3
|
+
import ts from "typescript";
|
|
4
|
+
//#region src/loader-compiler.ts
|
|
5
|
+
function compileModule(source, filename, dialect) {
|
|
6
|
+
const { config, observations } = loaderConfiguration(filename);
|
|
7
|
+
const result = dialect ? transpile(source, {
|
|
8
|
+
...config,
|
|
9
|
+
filename
|
|
10
|
+
}, ts.ScriptTarget.ES2022) : transpileNative(source, filename, void 0, void 0, config.jsxImportSource, ts.ScriptTarget.ES2022);
|
|
11
|
+
return {
|
|
12
|
+
source: result.code + "\n//# sourceMappingURL=data:application/json;base64," + Buffer.from(result.map).toString("base64"),
|
|
13
|
+
observations
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { compileModule };
|
|
18
|
+
|
|
19
|
+
//# sourceMappingURL=loader-compiler-DIw9aw5n.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader-compiler-DIw9aw5n.js","names":[],"sources":["../src/loader-compiler.ts"],"sourcesContent":["import ts from 'typescript';\nimport { transpile, transpileNative } from './transpile.js';\nimport { loaderConfiguration } from './configuration.js';\n\nexport function compileModule(source: string, filename: string, dialect: boolean) {\n const { config, observations } = loaderConfiguration(filename);\n const result = dialect\n ? transpile(source, { ...config, filename }, ts.ScriptTarget.ES2022)\n : transpileNative(\n source,\n filename,\n undefined,\n undefined,\n config.jsxImportSource,\n ts.ScriptTarget.ES2022,\n );\n return {\n source:\n result.code +\n '\\n//# sourceMappingURL=data:application/json;base64,' +\n Buffer.from(result.map).toString('base64'),\n observations,\n };\n}\n"],"mappings":";;;;AAIA,SAAgB,cAAc,QAAgB,UAAkB,SAAkB;CAChF,MAAM,EAAE,QAAQ,iBAAiB,oBAAoB,QAAQ;CAC7D,MAAM,SAAS,UACX,UAAU,QAAQ;EAAE,GAAG;EAAQ;CAAS,GAAG,GAAG,aAAa,MAAM,IACjE,gBACE,QACA,UACA,KAAA,GACA,KAAA,GACA,OAAO,iBACP,GAAG,aAAa,MAClB;CACJ,OAAO;EACL,QACE,OAAO,OACP,yDACA,OAAO,KAAK,OAAO,GAAG,CAAC,CAAC,SAAS,QAAQ;EAC3C;CACF;AACF"}
|
package/dist/loader.d.ts
CHANGED
package/dist/loader.js
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { n as needsTypeEmission, r as resolveSourceFile, t as isDependency } from "./files-
|
|
4
|
-
import {
|
|
5
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
6
|
-
import { dirname, resolve as resolve$1 } from "node:path";
|
|
7
|
-
import ts from "typescript";
|
|
1
|
+
import { n as isTwillFile } from "./extensions-B1xTkoYP.js";
|
|
2
|
+
import { r as openCompilationCache } from "./compilation-cache-CuCGz02_.js";
|
|
3
|
+
import { n as needsTypeEmission, r as resolveSourceFile, t as isDependency } from "./files-BW9geU0_.js";
|
|
4
|
+
import { readFileSync } from "node:fs";
|
|
8
5
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
9
6
|
//#region src/loader.ts
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
7
|
+
var entries = /* @__PURE__ */ new Set();
|
|
8
|
+
var cacheEnabled = false;
|
|
9
|
+
var cache;
|
|
10
|
+
var cacheInitialized = false;
|
|
11
|
+
function initialize(data) {
|
|
12
|
+
entries = new Set(data?.entries);
|
|
13
|
+
cacheEnabled = data?.cache === true && process.env.TWILL_CACHE !== "0";
|
|
14
|
+
cache = void 0;
|
|
15
|
+
cacheInitialized = false;
|
|
18
16
|
}
|
|
19
17
|
var resolve = async (specifier, context, nextResolve) => {
|
|
20
18
|
try {
|
|
@@ -35,20 +33,29 @@ var resolve = async (specifier, context, nextResolve) => {
|
|
|
35
33
|
var load = async (url, context, nextLoad) => {
|
|
36
34
|
if (!url.startsWith("file:")) return nextLoad(url, context);
|
|
37
35
|
const filename = fileURLToPath(url);
|
|
38
|
-
const dialect = isTwillFile(filename);
|
|
36
|
+
const dialect = isTwillFile(filename) || entries.has(url);
|
|
39
37
|
if (!dialect && (isDependency(filename) || !needsTypeEmission(filename))) return nextLoad(url, context);
|
|
40
38
|
const source = readFileSync(filename, "utf8");
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
39
|
+
if (cacheEnabled && !cacheInitialized) {
|
|
40
|
+
cache = openCompilationCache();
|
|
41
|
+
cacheInitialized = true;
|
|
42
|
+
}
|
|
43
|
+
const cached = cache?.read(url, source, dialect);
|
|
44
|
+
if (cached !== void 0) return {
|
|
45
|
+
format: "module",
|
|
46
|
+
source: cached,
|
|
47
|
+
shortCircuit: true
|
|
48
|
+
};
|
|
49
|
+
const { compileModule } = await import("./loader-compiler-DIw9aw5n.js");
|
|
50
|
+
const result = compileModule(source, filename, dialect);
|
|
51
|
+
cache?.write(url, source, dialect, result.source, result.observations);
|
|
45
52
|
return {
|
|
46
53
|
format: "module",
|
|
47
|
-
source: result.
|
|
54
|
+
source: result.source,
|
|
48
55
|
shortCircuit: true
|
|
49
56
|
};
|
|
50
57
|
};
|
|
51
58
|
//#endregion
|
|
52
|
-
export { load, resolve };
|
|
59
|
+
export { initialize, load, resolve };
|
|
53
60
|
|
|
54
61
|
//# sourceMappingURL=loader.js.map
|
package/dist/loader.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.js","names":[
|
|
1
|
+
{"version":3,"file":"loader.js","names":[],"sources":["../src/loader.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { fileURLToPath, pathToFileURL } from 'node:url';\nimport type { ResolveHook, LoadHook } from 'node:module';\nimport { isTwillFile } from './extensions.js';\nimport { isDependency, needsTypeEmission, resolveSourceFile } from './files.js';\nimport { openCompilationCache, type CompilationCache } from './compilation-cache.js';\n\nlet entries = new Set<string>();\nlet cacheEnabled = false;\nlet cache: CompilationCache | undefined;\nlet cacheInitialized = false;\nexport function initialize(data: { entries?: string[]; cache?: boolean } | undefined) {\n entries = new Set(data?.entries);\n cacheEnabled = data?.cache === true && process.env.TWILL_CACHE !== '0';\n cache = undefined;\n cacheInitialized = false;\n}\n\nexport const resolve: ResolveHook = async (specifier, context, nextResolve) => {\n try {\n return await nextResolve(specifier, context);\n } catch (error) {\n if (\n ['ERR_MODULE_NOT_FOUND', 'ERR_UNSUPPORTED_DIR_IMPORT'].includes(\n (error as NodeJS.ErrnoException).code ?? '',\n ) &&\n specifier.startsWith('.') &&\n context.parentURL?.startsWith('file:')\n ) {\n const target = new URL(specifier, context.parentURL);\n const base = fileURLToPath(target);\n const candidate = resolveSourceFile(base);\n if (candidate)\n return {\n url: pathToFileURL(candidate).href + target.search + target.hash,\n shortCircuit: true,\n };\n }\n throw error;\n }\n};\n\nexport const load: LoadHook = async (url, context, nextLoad) => {\n if (!url.startsWith('file:')) return nextLoad(url, context);\n const filename = fileURLToPath(url);\n const dialect = isTwillFile(filename) || entries.has(url);\n if (!dialect && (isDependency(filename) || !needsTypeEmission(filename)))\n return nextLoad(url, context);\n const source = readFileSync(filename, 'utf8');\n if (cacheEnabled && !cacheInitialized) {\n cache = openCompilationCache();\n cacheInitialized = true;\n }\n const cached = cache?.read(url, source, dialect);\n if (cached !== undefined) return { format: 'module', source: cached, shortCircuit: true };\n const { compileModule } = await import('./loader-compiler.js');\n const result = compileModule(source, filename, dialect);\n cache?.write(url, source, dialect, result.source, result.observations);\n return { format: 'module', source: result.source, shortCircuit: true };\n};\n"],"mappings":";;;;;;AAOA,IAAI,0BAAU,IAAI,IAAY;AAC9B,IAAI,eAAe;AACnB,IAAI;AACJ,IAAI,mBAAmB;AACvB,SAAgB,WAAW,MAA2D;CACpF,UAAU,IAAI,IAAI,MAAM,OAAO;CAC/B,eAAe,MAAM,UAAU,QAAQ,QAAQ,IAAI,gBAAgB;CACnE,QAAQ,KAAA;CACR,mBAAmB;AACrB;AAEA,IAAa,UAAuB,OAAO,WAAW,SAAS,gBAAgB;CAC7E,IAAI;EACF,OAAO,MAAM,YAAY,WAAW,OAAO;CAC7C,SAAS,OAAO;EACd,IACE,CAAC,wBAAwB,4BAA4B,CAAC,CAAC,SACpD,MAAgC,QAAQ,EAC3C,KACA,UAAU,WAAW,GAAG,KACxB,QAAQ,WAAW,WAAW,OAAO,GACrC;GACA,MAAM,SAAS,IAAI,IAAI,WAAW,QAAQ,SAAS;GACnD,MAAM,OAAO,cAAc,MAAM;GACjC,MAAM,YAAY,kBAAkB,IAAI;GACxC,IAAI,WACF,OAAO;IACL,KAAK,cAAc,SAAS,CAAC,CAAC,OAAO,OAAO,SAAS,OAAO;IAC5D,cAAc;GAChB;EACJ;EACA,MAAM;CACR;AACF;AAEA,IAAa,OAAiB,OAAO,KAAK,SAAS,aAAa;CAC9D,IAAI,CAAC,IAAI,WAAW,OAAO,GAAG,OAAO,SAAS,KAAK,OAAO;CAC1D,MAAM,WAAW,cAAc,GAAG;CAClC,MAAM,UAAU,YAAY,QAAQ,KAAK,QAAQ,IAAI,GAAG;CACxD,IAAI,CAAC,YAAY,aAAa,QAAQ,KAAK,CAAC,kBAAkB,QAAQ,IACpE,OAAO,SAAS,KAAK,OAAO;CAC9B,MAAM,SAAS,aAAa,UAAU,MAAM;CAC5C,IAAI,gBAAgB,CAAC,kBAAkB;EACrC,QAAQ,qBAAqB;EAC7B,mBAAmB;CACrB;CACA,MAAM,SAAS,OAAO,KAAK,KAAK,QAAQ,OAAO;CAC/C,IAAI,WAAW,KAAA,GAAW,OAAO;EAAE,QAAQ;EAAU,QAAQ;EAAQ,cAAc;CAAK;CACxF,MAAM,EAAE,kBAAkB,MAAM,OAAO;CACvC,MAAM,SAAS,cAAc,QAAQ,UAAU,OAAO;CACtD,OAAO,MAAM,KAAK,QAAQ,SAAS,OAAO,QAAQ,OAAO,YAAY;CACrE,OAAO;EAAE,QAAQ;EAAU,QAAQ,OAAO;EAAQ,cAAc;CAAK;AACvE"}
|
package/dist/parser.d.ts
CHANGED