gofront 1.8.0 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. package/README.md +3 -3
  2. package/package.json +5 -4
  3. package/src/backend/js/expressions.js +849 -371
  4. package/src/backend/js/index.js +241 -147
  5. package/src/backend/js/natives.js +383 -0
  6. package/src/backend/js/runtime.js +512 -2547
  7. package/src/backend/js/statements.js +506 -103
  8. package/src/backend/js/stdlib/index.js +45 -93
  9. package/src/backend/js/templ.js +32 -45
  10. package/src/backend/js/type-info.js +177 -13
  11. package/src/backend/shared/fixed-float.js +20 -0
  12. package/src/backend/shared/fmt-types.js +63 -171
  13. package/src/backend/shared/host-unicode.js +36 -0
  14. package/src/backend/wasm/boundary.js +490 -965
  15. package/src/backend/wasm/emit-builtins.js +643 -256
  16. package/src/backend/wasm/emit-exprs.js +124 -57
  17. package/src/backend/wasm/emit-maps.js +17 -367
  18. package/src/backend/wasm/emit-stmts.js +325 -75
  19. package/src/backend/wasm/emit.js +104 -13
  20. package/src/backend/wasm/globals.js +47 -8
  21. package/src/backend/wasm/glue.js +2 -4
  22. package/src/backend/wasm/index.js +36 -530
  23. package/src/backend/wasm/method-expr.js +12 -1
  24. package/src/backend/wasm/module-emitter.js +92 -717
  25. package/src/backend/wasm/monomorph.js +103 -6
  26. package/src/backend/wasm/natives.js +596 -0
  27. package/src/backend/wasm/prescan.js +5 -153
  28. package/src/backend/wasm/prune-funcs.js +89 -0
  29. package/src/backend/wasm/stdlib/index.js +2 -32
  30. package/src/backend/wasm/types.js +68 -20
  31. package/src/backend/wasm/variadic.js +3 -3
  32. package/src/cli/cli-core.js +5 -1
  33. package/src/cli/test-runner.js +115 -342
  34. package/src/compiler.js +108 -130
  35. package/src/lexer/lexer.js +105 -11
  36. package/src/lexer/templ-lexer.js +61 -18
  37. package/src/lexer/tokens.js +1 -0
  38. package/src/link/stdlib.js +354 -132
  39. package/src/link/type-names.js +148 -0
  40. package/src/link/wasm.js +30 -6
  41. package/src/lower/bounds.js +153 -0
  42. package/src/lower/captures.js +92 -33
  43. package/src/lower/embedding.js +32 -3
  44. package/src/lower/errors-as.js +196 -0
  45. package/src/lower/fmt-formatters.js +905 -0
  46. package/src/lower/functions.js +2 -0
  47. package/src/lower/gen-types.js +274 -0
  48. package/src/lower/index.js +7 -1
  49. package/src/lower/json-codecs.js +228 -247
  50. package/src/lower/ownership.js +25 -7
  51. package/src/lower/reachability.js +69 -51
  52. package/src/lower/walk.js +12 -0
  53. package/src/parser/declarations.js +28 -5
  54. package/src/parser/expressions.js +86 -16
  55. package/src/parser/statements.js +1 -0
  56. package/src/parser/templ.js +44 -5
  57. package/src/parser/types.js +1 -0
  58. package/src/resolver.js +1 -2
  59. package/src/typechecker/assignability.js +124 -11
  60. package/src/typechecker/const-fold.js +70 -27
  61. package/src/typechecker/constants.js +32 -6
  62. package/src/typechecker/expressions.js +326 -98
  63. package/src/typechecker/index.js +208 -33
  64. package/src/typechecker/init-order.js +136 -40
  65. package/src/typechecker/operand-text.js +40 -0
  66. package/src/typechecker/resolve.js +192 -36
  67. package/src/typechecker/statements.js +122 -11
  68. package/src/typechecker/stdlib/excluded.js +9 -5
  69. package/src/typechecker/stdlib/index.js +25 -9
  70. package/src/typechecker/termination.js +10 -1
  71. package/src/typechecker/types.js +203 -573
  72. package/stdlib/bytes/buffer.go +479 -0
  73. package/stdlib/bytes/bytes.go +1010 -0
  74. package/stdlib/bytes/reader.go +161 -0
  75. package/stdlib/context/context.go +115 -0
  76. package/stdlib/crypto/rand/rand.go +34 -0
  77. package/stdlib/crypto/sha256/sha256.go +249 -0
  78. package/stdlib/encoding/base64/base64.go +331 -0
  79. package/stdlib/encoding/binary/binary.go +332 -0
  80. package/stdlib/encoding/hex/hex.go +140 -0
  81. package/stdlib/encoding/json/json.go +62 -0
  82. package/stdlib/errors/errors.go +174 -0
  83. package/stdlib/fmt/errors.go +110 -0
  84. package/stdlib/fmt/format.go +732 -0
  85. package/stdlib/fmt/print.go +1232 -0
  86. package/stdlib/gom/gom.go +293 -0
  87. package/stdlib/html/html.go +251 -0
  88. package/stdlib/internal/fmtrt/fmtrt.go +163 -0
  89. package/stdlib/internal/jsonrt/dec.go +171 -38
  90. package/stdlib/internal/jsonrt/enc.go +186 -36
  91. package/stdlib/internal/jsonrt/scanner.go +17 -8
  92. package/stdlib/io/io.go +157 -1
  93. package/stdlib/maps/maps.go +131 -0
  94. package/stdlib/math/bits/bits.go +507 -0
  95. package/stdlib/math/extra.go +16 -14
  96. package/stdlib/math/math.go +439 -0
  97. package/stdlib/math/rand/rand.go +297 -0
  98. package/stdlib/os/os.go +93 -0
  99. package/stdlib/path/filepath/filepath.go +47 -0
  100. package/stdlib/path/path.go +394 -0
  101. package/stdlib/regexp/regexp.go +231 -0
  102. package/stdlib/slices/slices.go +526 -0
  103. package/stdlib/slices/sort.go +209 -0
  104. package/stdlib/slices/zsort_cmp.go +480 -0
  105. package/stdlib/slices/zsort_ordered.go +482 -0
  106. package/stdlib/sort/sort.go +391 -452
  107. package/stdlib/sort/zsort_func.go +480 -0
  108. package/stdlib/sort/zsort_iface.go +480 -0
  109. package/stdlib/strconv/float.go +1699 -0
  110. package/stdlib/strconv/isprint.go +752 -0
  111. package/stdlib/strconv/quote.go +235 -50
  112. package/stdlib/strconv/strconv.go +616 -0
  113. package/stdlib/strings/builder.go +95 -0
  114. package/stdlib/strings/reader.go +163 -0
  115. package/stdlib/strings/replacer.go +102 -0
  116. package/stdlib/strings/strings.go +807 -0
  117. package/stdlib/sync/sync.go +268 -0
  118. package/stdlib/testing/async_js.go +61 -0
  119. package/stdlib/testing/benchmark.go +297 -0
  120. package/stdlib/testing/testing.go +523 -0
  121. package/stdlib/time/duration.go +233 -0
  122. package/stdlib/time/format.go +745 -0
  123. package/stdlib/time/parse.go +790 -0
  124. package/stdlib/time/sleep_js.go +63 -0
  125. package/stdlib/time/time.go +834 -0
  126. package/stdlib/unicode/unicode.go +141 -3
  127. package/stdlib/unicode/utf8/utf8.go +464 -0
  128. package/src/backend/js/fmt-runtime.js +0 -573
  129. package/src/backend/js/stdlib/base64.js +0 -12
  130. package/src/backend/js/stdlib/binary.js +0 -102
  131. package/src/backend/js/stdlib/bits.js +0 -119
  132. package/src/backend/js/stdlib/builder.js +0 -98
  133. package/src/backend/js/stdlib/bytes.js +0 -368
  134. package/src/backend/js/stdlib/errors.js +0 -45
  135. package/src/backend/js/stdlib/fmt.js +0 -517
  136. package/src/backend/js/stdlib/gom.js +0 -155
  137. package/src/backend/js/stdlib/hex.js +0 -17
  138. package/src/backend/js/stdlib/html.js +0 -20
  139. package/src/backend/js/stdlib/io.js +0 -137
  140. package/src/backend/js/stdlib/json.js +0 -1167
  141. package/src/backend/js/stdlib/maps.js +0 -37
  142. package/src/backend/js/stdlib/math.js +0 -85
  143. package/src/backend/js/stdlib/os.js +0 -13
  144. package/src/backend/js/stdlib/path.js +0 -48
  145. package/src/backend/js/stdlib/rand.js +0 -32
  146. package/src/backend/js/stdlib/regexp.js +0 -54
  147. package/src/backend/js/stdlib/sha256.js +0 -12
  148. package/src/backend/js/stdlib/shared.js +0 -17
  149. package/src/backend/js/stdlib/simd.js +0 -34
  150. package/src/backend/js/stdlib/slices.js +0 -107
  151. package/src/backend/js/stdlib/sort.js +0 -30
  152. package/src/backend/js/stdlib/strconv.js +0 -79
  153. package/src/backend/js/stdlib/strings.js +0 -301
  154. package/src/backend/js/stdlib/sync.js +0 -13
  155. package/src/backend/js/stdlib/testing.js +0 -41
  156. package/src/backend/js/stdlib/time.js +0 -152
  157. package/src/backend/js/stdlib/unicode.js +0 -25
  158. package/src/backend/js/stdlib/utf8.js +0 -26
  159. package/src/backend/wasm/stdlib/bytes.js +0 -6716
  160. package/src/backend/wasm/stdlib/core.js +0 -10278
  161. package/src/backend/wasm/stdlib/io.js +0 -3578
  162. package/src/backend/wasm/stdlib/packages.js +0 -2402
  163. package/src/backend/wasm/stdlib/pure.js +0 -720
  164. package/src/backend/wasm/stdlib/time.js +0 -2229
  165. package/src/typechecker/stdlib/core.js +0 -1079
  166. package/src/typechecker/stdlib/extended.js +0 -1210
  167. package/stdlib/bytes/iter.go +0 -192
  168. package/stdlib/bytes/search.go +0 -240
  169. package/stdlib/bytes/split.go +0 -218
  170. package/stdlib/errors/overlay.go +0 -12
  171. package/stdlib/maps/iter.go +0 -65
  172. package/stdlib/slices/extra.go +0 -73
  173. package/stdlib/slices/iter.go +0 -113
  174. package/stdlib/strings/extra.go +0 -35
  175. package/stdlib/strings/iter.go +0 -122
  176. package/stdlib/sync/extra.go +0 -105
  177. package/stdlib/unicode/utf8/bytes.go +0 -239
@@ -196,7 +196,7 @@ export class TemplLexer {
196
196
  }
197
197
 
198
198
  const chunk = this.src.slice(start, this.pos);
199
- for (const t of this._goTokens(chunk)) this.tokens.push(t);
199
+ for (const t of this._goTokens(chunk, start)) this.tokens.push(t);
200
200
  }
201
201
 
202
202
  // ── Templ / CSS declaration lexing ───────────────────────────
@@ -221,7 +221,7 @@ export class TemplLexer {
221
221
  const paramStart = this.pos;
222
222
  this._skipBalanced("(", ")");
223
223
  const paramSrc = this.src.slice(paramStart, this.pos);
224
- for (const t of this._goTokens(paramSrc)) this.tokens.push(t);
224
+ for (const t of this._goTokens(paramSrc, paramStart)) this.tokens.push(t);
225
225
 
226
226
  this.skipWhitespace();
227
227
 
@@ -492,7 +492,7 @@ export class TemplLexer {
492
492
  // ── Expression / control flow inside HTML ─────────────────────
493
493
 
494
494
  _lexBraceExprOrControl() {
495
- // { children... } → TEMPL_CHILDREN
495
+ // { name... } → TEMPL_CHILDREN
496
496
  // { goExpr } → TEMPL_EXPR
497
497
  const saveLine = this.line;
498
498
  const saveCol = this.col;
@@ -500,12 +500,12 @@ export class TemplLexer {
500
500
  this.advance(); // {
501
501
  this.skipWhitespace();
502
502
 
503
- // Check for children...
504
- if (this.src.startsWith("children...", this.pos)) {
505
- this.pos += "children...".length;
506
- this.skipWhitespace();
507
- if (this.peek() === "}") this.advance();
508
- this.tokens.push(new Token(TT.TEMPL_CHILDREN, null, saveLine, saveCol));
503
+ // `{ name... }` mounts a variadic slot; the token holds the name.
504
+ const slot = /^([A-Za-z_]\w*)\.\.\.\s*\}/.exec(this.src.slice(this.pos));
505
+ if (slot) {
506
+ const { line, col } = this;
507
+ for (let i = 0; i < slot[0].length; i++) this.advance();
508
+ this.tokens.push(new Token(TT.TEMPL_CHILDREN, slot[1], line, col));
509
509
  return;
510
510
  }
511
511
 
@@ -532,7 +532,7 @@ export class TemplLexer {
532
532
  this._skipBalanced("(", ")");
533
533
  const argsSrc = name + this.src.slice(argsStart, this.pos);
534
534
 
535
- const callTokens = this._goTokens(argsSrc);
535
+ const callTokens = this._goTokens(argsSrc, nameStart);
536
536
  this.tokens.push(new Token(TT.TEMPL_COMP, callTokens, line, col));
537
537
  }
538
538
 
@@ -604,7 +604,7 @@ export class TemplLexer {
604
604
  }
605
605
  const caseExprSrc = this.src.slice(caseExprStart, this.pos).trimEnd();
606
606
  if (this.peek() === ":") this.advance(); // :
607
- const caseTokens = this._goTokens(caseExprSrc);
607
+ const caseTokens = this._goTokens(caseExprSrc, caseExprStart);
608
608
  this.tokens.push(
609
609
  new Token(TT.TEMPL_CASE, caseTokens, caseLine, this.col),
610
610
  );
@@ -651,10 +651,20 @@ export class TemplLexer {
651
651
 
652
652
  // ── Helpers ───────────────────────────────────────────────────
653
653
 
654
- _goTokens(src) {
655
- return new Lexer(src, this.filename)
654
+ // Lexes `src`, which starts at offset `offset` of the templ source, so the
655
+ // tokens carry their position in the .templ file.
656
+ _goTokens(src, offset) {
657
+ const before = this.src.slice(0, offset);
658
+ const lineShift = before.split("\n").length - 1;
659
+ const colShift = offset - (before.lastIndexOf("\n") + 1);
660
+ const tokens = new Lexer(src, this.filename)
656
661
  .tokenize()
657
662
  .filter((t) => t.type !== T.EOF);
663
+ for (const t of tokens) {
664
+ if (t.line === 1) t.col += colShift;
665
+ t.line += lineShift;
666
+ }
667
+ return tokens;
658
668
  }
659
669
 
660
670
  // Consume text up to the opening `{`, advance past it, and return Go tokens.
@@ -663,7 +673,7 @@ export class TemplLexer {
663
673
  this._skipToOpenBrace();
664
674
  const src = this.src.slice(start, this.pos).trimEnd();
665
675
  this.advance(); // consume {
666
- return src ? this._goTokens(src) : [];
676
+ return src ? this._goTokens(src, start) : [];
667
677
  }
668
678
 
669
679
  // Read Go expression tokens until the closing }
@@ -690,10 +700,11 @@ export class TemplLexer {
690
700
  }
691
701
  this.advance();
692
702
  }
693
- const exprSrc = this.src.slice(start, this.pos).trim();
703
+ const raw = this.src.slice(start, this.pos);
704
+ const exprSrc = raw.trim();
694
705
  if (this.peek() === "}") this.advance(); // consume }
695
706
  if (!exprSrc) return [];
696
- return this._goTokens(exprSrc);
707
+ return this._goTokens(exprSrc, start + raw.length - raw.trimStart().length);
697
708
  }
698
709
 
699
710
  _readHtmlName() {
@@ -727,18 +738,50 @@ export class TemplLexer {
727
738
  return this.src.slice(start, this.pos);
728
739
  }
729
740
 
741
+ // True when the `{` at the current position opens a composite literal of a
742
+ // slice, array or map type (`[]int{1}`, `map[string]int{}`) rather than a
743
+ // body. Go allows these in a header without parentheses; a literal of a
744
+ // bare type name is not (`T{}` needs them), so it still ends the header.
745
+ _atCompositeLiteral(start) {
746
+ const before = this.src.slice(start, this.pos);
747
+ return /(?:^|[^\w\])])(?:map)?\[[^\]]*\][\w.*[\]]*$/.test(before);
748
+ }
749
+
750
+ // `{` right after the `struct` or `interface` keyword: a type literal's body.
751
+ _atTypeBrace(start) {
752
+ const before = this.src.slice(start, this.pos);
753
+ return /(?:^|[^\w])(?:struct|interface)\s*$/.test(before);
754
+ }
755
+
756
+ // `{` that opens a composite literal: after `[]T`, `map[K]V` or right after
757
+ // a `struct{...}` / `interface{...}` type ending at `typeEnd`.
758
+ _atLiteralBrace(start, typeEnd) {
759
+ if (typeEnd >= 0 && /^\s*$/.test(this.src.slice(typeEnd, this.pos)))
760
+ return true;
761
+ return this._atCompositeLiteral(start);
762
+ }
763
+
730
764
  _skipToOpenBrace() {
731
765
  // Skip text until we hit an unbalanced {, tracking parens/brackets
766
+ const start = this.pos;
732
767
  let paren = 0,
733
768
  bracket = 0;
769
+ // End of the last `struct{...}` / `interface{...}` type literal: a `{`
770
+ // right after it opens a composite literal, never the body.
771
+ let typeEnd = -1;
734
772
  while (!this.eof()) {
735
773
  const c = this.peek();
736
774
  if (c === "(") paren++;
737
775
  else if (c === ")") paren--;
738
776
  else if (c === "[") bracket++;
739
777
  else if (c === "]") bracket--;
740
- else if (c === "{" && paren === 0 && bracket === 0) return;
741
- else if (c === '"' || c === "'") {
778
+ else if (c === "{" && paren === 0 && bracket === 0) {
779
+ const isTypeBrace = this._atTypeBrace(start);
780
+ if (!isTypeBrace && !this._atLiteralBrace(start, typeEnd)) return;
781
+ this._skipBalanced("{", "}");
782
+ typeEnd = isTypeBrace ? this.pos : -1;
783
+ continue;
784
+ } else if (c === '"' || c === "'") {
742
785
  this._skipGoString(c);
743
786
  continue;
744
787
  } else if (c === "`") {
@@ -66,6 +66,7 @@ export const T = {
66
66
  PERCENT_ASSIGN: "%=",
67
67
  AMP_ASSIGN: "&=",
68
68
  PIPE_ASSIGN: "|=",
69
+ AND_NOT_ASSIGN: "&^=",
69
70
  CARET_ASSIGN: "^=",
70
71
  LSHIFT_ASSIGN: "<<=",
71
72
  RSHIFT_ASSIGN: ">>=",