@swiftuijs/twill 0.2.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.
Files changed (64) hide show
  1. package/README.md +22 -7
  2. package/bin/run.mjs +2 -2
  3. package/dist/cli.js +6 -6
  4. package/dist/{compilation-cache-CuCGz02_.js → compilation-cache-7SugqJ4n.js} +2 -2
  5. package/dist/{compilation-cache-CuCGz02_.js.map → compilation-cache-7SugqJ4n.js.map} +1 -1
  6. package/dist/{compiler-DY1N07np.js → compiler-BdkU4Ruh.js} +85 -26
  7. package/dist/compiler-BdkU4Ruh.js.map +1 -0
  8. package/dist/config-la_KkjCS.js +1 -0
  9. package/dist/config.js +2 -1
  10. package/dist/{configuration-CTJjSu_h.js → configuration-BVMf6Q_j.js} +17 -7
  11. package/dist/configuration-BVMf6Q_j.js.map +1 -0
  12. package/dist/declarations-BTAS8Mb_.js +132 -0
  13. package/dist/declarations-BTAS8Mb_.js.map +1 -0
  14. package/dist/declarations.js +1 -131
  15. package/dist/defer.d.ts +1 -1
  16. package/dist/doctor-Co_pdZtt.js +202 -0
  17. package/dist/doctor-Co_pdZtt.js.map +1 -0
  18. package/dist/doctor.js +1 -201
  19. package/dist/editor.js +1 -1
  20. package/dist/esbuild.js +1 -1
  21. package/dist/index.js +1 -1
  22. package/dist/{loader-compiler-DIw9aw5n.js → loader-compiler.js} +3 -3
  23. package/dist/loader-compiler.js.map +1 -0
  24. package/dist/loader-registration-B1ST9h1e.js +15 -0
  25. package/dist/loader-registration-B1ST9h1e.js.map +1 -0
  26. package/dist/loader-registration.d.ts +4 -0
  27. package/dist/loader-registration.js +2 -0
  28. package/dist/loader-state-DE2ArGYl.js +61 -0
  29. package/dist/loader-state-DE2ArGYl.js.map +1 -0
  30. package/dist/loader-state.d.ts +34 -0
  31. package/dist/loader-sync.d.ts +3 -0
  32. package/dist/loader-sync.js +28 -0
  33. package/dist/loader-sync.js.map +1 -0
  34. package/dist/loader.d.ts +2 -4
  35. package/dist/loader.js +9 -46
  36. package/dist/loader.js.map +1 -1
  37. package/dist/{plugin-Bks2hxCJ.js → plugin-DdTVagIU.js} +3 -3
  38. package/dist/{plugin-Bks2hxCJ.js.map → plugin-DdTVagIU.js.map} +1 -1
  39. package/dist/project-ZmlpFooa.js +444 -0
  40. package/dist/project-ZmlpFooa.js.map +1 -0
  41. package/dist/project.js +1 -438
  42. package/dist/recovery.d.ts +2 -2
  43. package/dist/register.js +2 -2
  44. package/dist/register.js.map +1 -1
  45. package/dist/rollup.js +1 -1
  46. package/dist/rspack.js +1 -1
  47. package/dist/syntax.js +1 -1
  48. package/dist/{transpile-DG81yfVs.js → transpile-CLNavDUr.js} +2 -2
  49. package/dist/{transpile-DG81yfVs.js.map → transpile-CLNavDUr.js.map} +1 -1
  50. package/dist/typescript-plugin.cjs +96 -33
  51. package/dist/typescript-plugin.cjs.map +1 -1
  52. package/dist/vite-BI-5KRgr.js +7 -0
  53. package/dist/vite-BI-5KRgr.js.map +1 -0
  54. package/dist/vite-react.js +1 -1
  55. package/dist/vite.js +1 -6
  56. package/dist/webpack.js +1 -1
  57. package/package.json +2 -2
  58. package/dist/compiler-DY1N07np.js.map +0 -1
  59. package/dist/configuration-CTJjSu_h.js.map +0 -1
  60. package/dist/declarations.js.map +0 -1
  61. package/dist/doctor.js.map +0 -1
  62. package/dist/loader-compiler-DIw9aw5n.js.map +0 -1
  63. package/dist/project.js.map +0 -1
  64. package/dist/vite.js.map +0 -1
@@ -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 label = lexer.getToken().type.label;
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
- "eof",
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
  "[",
@@ -15159,6 +15175,15 @@ function parserFor(language) {
15159
15175
  if (parsers.has(language)) return parsers.get(language);
15160
15176
  const Base = bases[language];
15161
15177
  class TwillParser extends Base {
15178
+ declareName(name, bindingType, position) {
15179
+ if (bindingType === 6 || bindingType === 7) {
15180
+ const scope = this.currentScope();
15181
+ (scope.types ??= []).push(name);
15182
+ if (this.inModule && scope.flags & 1) delete this.undefinedExports[name];
15183
+ return;
15184
+ }
15185
+ super.declareName(name, bindingType, position);
15186
+ }
15162
15187
  skipHeader = null;
15163
15188
  closures = [];
15164
15189
  lineStarts = null;
@@ -15251,7 +15276,9 @@ function parserFor(language) {
15251
15276
  node.cleanup = cleanup;
15252
15277
  return this.finishNode(node, "DeferStatement");
15253
15278
  }
15254
- if (!this.isContextual("guard") || !guardAt(this.input, this.end, !!this.implicitClosure)) {
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) {
15255
15282
  const statement = super.parseStatement(context, ...args);
15256
15283
  if (context && statement.type === "TwillEnumDeclaration") this.raise(statement.start, "An associated-value enum requires a block; add braces around this body.");
15257
15284
  return statement;
@@ -15260,6 +15287,7 @@ function parserFor(language) {
15260
15287
  node.singleStatement = !!context;
15261
15288
  this.next();
15262
15289
  node.binding = null;
15290
+ if (this.type === types$1._else) this.raise(this.start, "Guard needs a condition or 'const' binding before 'else'.");
15263
15291
  if (this.type === types$1._const) {
15264
15292
  if (context) this.raise(node.start, "A guard binding requires a block; add braces around this body.");
15265
15293
  const declaration = this.startNode();
@@ -15269,8 +15297,9 @@ function parserFor(language) {
15269
15297
  if (node.binding.declarations.length !== 1) this.raise(node.start, "guard const requires one binding declaration.");
15270
15298
  } else node.test = this.parseExpression();
15271
15299
  node.elseStart = this.start;
15272
- this.expect(types$1._else);
15273
- if (this.type !== types$1.braceL) this.unexpected();
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 ...; }'.");
15274
15303
  node.failure = this.parseBlock();
15275
15304
  if (!exits(node.failure)) this.raise(node.failure.start, "Every guard else path must exit with return, throw, break or continue.");
15276
15305
  return this.finishNode(node, "GuardStatement");
@@ -15632,9 +15661,10 @@ function parse$1(source, language = "ts", sourceType = "module") {
15632
15661
  if (node.type === "DeferStatement") defers.push(node);
15633
15662
  if (node.type === "TwillSwitchExpression") switches.push(node);
15634
15663
  if (node.type === "TwillEnumDeclaration") enums.push(node);
15635
- for (const [key, value] of Object.entries(node)) {
15664
+ for (const key of Object.keys(node)) {
15636
15665
  if (key === "trailing" || key === "loc") continue;
15637
- if (Array.isArray(value)) value.forEach(visit);
15666
+ const value = node[key];
15667
+ if (Array.isArray(value)) for (const child of value) visit(child);
15638
15668
  else if (value?.type) visit(value);
15639
15669
  }
15640
15670
  };
@@ -15667,15 +15697,15 @@ var functions = /* @__PURE__ */ new Set([
15667
15697
  "ArrowFunctionExpression"
15668
15698
  ]);
15669
15699
  function children(node, visit) {
15670
- for (const [key, value] of Object.entries(node)) {
15700
+ for (const key of Object.keys(node)) {
15671
15701
  if (key === "loc" || key === "trailing") continue;
15672
- if (Array.isArray(value)) value.forEach((child) => {
15673
- if (child?.type) visit(child);
15674
- });
15675
- else if (value?.type) visit(value);
15702
+ const value = node[key];
15703
+ if (Array.isArray(value)) {
15704
+ for (const child of value) if (child?.type) visit(child);
15705
+ } else if (value?.type) visit(value);
15676
15706
  }
15677
15707
  }
15678
- /** Scope-local cleanup callbacks; dynamic registrations use lazy stacks. */
15708
+ /** Native finally where scope permits; callbacks retain dynamic registration semantics. */
15679
15709
  function lowerDefers(source, ast, code, language, usedNames, contentStarts, comments, runtime, sourceType, fail) {
15680
15710
  const scopes = [];
15681
15711
  const visit = (node, scope, parent) => {
@@ -15730,6 +15760,35 @@ function lowerDefers(source, ast, code, language, usedNames, contentStarts, comm
15730
15760
  if (!scope.defers.length) continue;
15731
15761
  const { block } = scope;
15732
15762
  const statements = block.body;
15763
+ const first = statements.indexOf(scope.defers[0]);
15764
+ let native = first >= 0 && scope.defers.every((node) => !node.awaited && statements.includes(node));
15765
+ if (native) {
15766
+ native = !statements.some((node, index) => node.type === "FunctionDeclaration" || node.type === "TSDeclareFunction" || node.type === "VariableDeclaration" && node.kind.endsWith("using") || index > first && (node.type === "VariableDeclaration" && node.kind !== "var" || node.type.endsWith("Declaration") && node.type !== "VariableDeclaration" || node.type === "GuardStatement" && node.binding));
15767
+ const check = (node) => {
15768
+ if (node.type === "WithStatement" || node.type === "ThisExpression" || node.type === "VariableDeclarator" && !node.init || node.type === "VariableDeclaration" && node.kind === "var" && (!statements.includes(node) || node.start > scope.defers[0].start) || node.type === "CallExpression" && node.callee.type === "Identifier" && node.callee.name === "eval") native = false;
15769
+ children(node, check);
15770
+ };
15771
+ if (native) check(block);
15772
+ const cleanupScope = (node) => {
15773
+ if (node.type === "FunctionDeclaration" || node.directive || node.type === "VariableDeclaration" && node.kind === "var") native = false;
15774
+ if (!functions.has(node.type)) children(node, cleanupScope);
15775
+ };
15776
+ if (native) for (const node of scope.defers) cleanupScope(node.cleanup.body);
15777
+ }
15778
+ if (native) {
15779
+ for (const node of [...scope.defers].reverse()) {
15780
+ code.overwrite(node.start, node.cleanup.body.start, ";try {");
15781
+ if (!node.cleanup.body.body.length) {
15782
+ code.remove(node.cleanup.body.start, node.cleanup.body.end);
15783
+ code.appendLeft(block.end - 1, "\n} finally " + source.slice(node.cleanup.body.start, node.cleanup.body.end) + "\n");
15784
+ continue;
15785
+ }
15786
+ code.prependRight(node.cleanup.body.start, "\n} finally ");
15787
+ code.appendLeft(node.cleanup.body.end, "\n");
15788
+ if (node.cleanup.body.end !== block.end - 1) code.move(node.cleanup.body.start, node.cleanup.body.end, block.end - 1);
15789
+ }
15790
+ continue;
15791
+ }
15733
15792
  const single = scope.defers.length === 1 && statements.includes(scope.defers[0]);
15734
15793
  const stack = fresh(single ? "Cleanup" : "Defers");
15735
15794
  const failure = single ? "" : fresh("Failure");
@@ -16610,12 +16669,12 @@ var TwillSyntaxError = class extends SyntaxError {
16610
16669
  };
16611
16670
  function walk(node, visit) {
16612
16671
  visit(node);
16613
- for (const [key, value] of Object.entries(node)) {
16614
- if (["loc", "trailing"].includes(key)) continue;
16615
- if (Array.isArray(value)) value.forEach((child) => {
16616
- if (child?.type) walk(child, visit);
16617
- });
16618
- else if (value?.type) walk(value, visit);
16672
+ for (const key of Object.keys(node)) {
16673
+ if (key === "loc" || key === "trailing") continue;
16674
+ const value = node[key];
16675
+ if (Array.isArray(value)) {
16676
+ for (const child of value) if (child?.type) walk(child, visit);
16677
+ } else if (value?.type) walk(value, visit);
16619
16678
  }
16620
16679
  }
16621
16680
  function calleeName(node) {
@@ -17392,7 +17451,7 @@ function remapping(input, loader, options) {
17392
17451
  //#endregion
17393
17452
  //#region src/recovery.ts
17394
17453
  /** Editor-only recovery; build and CLI compilation always use strict parsing. */
17395
- function recoverTransform(source, options) {
17454
+ function recoverTransform(source, options, onSyntaxError) {
17396
17455
  const repaired = new MagicString(source);
17397
17456
  let text = source;
17398
17457
  for (let attempt = 0; attempt < 8; attempt++) try {
@@ -17433,6 +17492,7 @@ function recoverTransform(source, options) {
17433
17492
  };
17434
17493
  } catch (error) {
17435
17494
  if (!(error instanceof TwillSyntaxError)) throw error;
17495
+ if (attempt === 0) onSyntaxError?.(error);
17436
17496
  const before = text.slice(0, error.offset);
17437
17497
  let insertion;
17438
17498
  let offset = error.offset;
@@ -17697,13 +17757,18 @@ var TwillProject = class {
17697
17757
  result(filename, source) {
17698
17758
  const cached = this.results.get(filename);
17699
17759
  if (cached?.source === source) return cached.result;
17700
- const result = (this.recover ? recoverTransform : transform)(source, {
17760
+ const options = {
17701
17761
  ...this.options,
17702
17762
  filename
17703
- });
17763
+ };
17764
+ let syntaxError;
17765
+ const result = this.recover ? recoverTransform(source, options, (error) => {
17766
+ syntaxError = error;
17767
+ }) : transform(source, options);
17704
17768
  this.results.set(filename, {
17705
17769
  source,
17706
- result
17770
+ result,
17771
+ syntaxError
17707
17772
  });
17708
17773
  return result;
17709
17774
  }
@@ -17797,11 +17862,9 @@ var TwillProject = class {
17797
17862
  for (const file of files) {
17798
17863
  if (/\.d\.[cm]?ts$/.test(file)) continue;
17799
17864
  try {
17800
- if (this.recover && isTwillFile(sourceFilename(file))) transform(this.text(file) ?? "", {
17801
- ...this.options,
17802
- filename: sourceFilename(file)
17803
- });
17804
17865
  this.transformed(file);
17866
+ const syntaxError = this.results.get(sourceFilename(file))?.syntaxError;
17867
+ if (syntaxError) throw syntaxError;
17805
17868
  result.push(...[...this.service.getSyntacticDiagnostics(file), ...this.service.getSemanticDiagnostics(file)].map((error) => this.diagnostic(error)));
17806
17869
  } catch (error) {
17807
17870
  const syntax = error;