gofront 1.7.0 → 1.8.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 +13 -13
- package/package.json +8 -37
- package/src/backend/js/expressions.js +1341 -148
- package/src/backend/js/fmt-runtime.js +573 -0
- package/src/backend/js/index.js +375 -57
- package/src/backend/js/runtime.js +1460 -133
- package/src/backend/js/statements.js +900 -86
- package/src/backend/js/stdlib/bits.js +87 -14
- package/src/backend/js/stdlib/builder.js +41 -6
- package/src/backend/js/stdlib/bytes.js +253 -7
- package/src/backend/js/stdlib/errors.js +2 -1
- package/src/backend/js/stdlib/fmt.js +349 -10
- package/src/backend/js/stdlib/index.js +8 -3
- package/src/backend/js/stdlib/json.js +247 -52
- package/src/backend/js/stdlib/maps.js +0 -8
- package/src/backend/js/stdlib/math.js +17 -1
- package/src/backend/js/stdlib/simd.js +10 -0
- package/src/backend/js/stdlib/slices.js +36 -6
- package/src/backend/js/stdlib/strconv.js +10 -5
- package/src/backend/js/stdlib/strings.js +83 -4
- package/src/backend/js/stdlib/testing.js +7 -0
- package/src/backend/js/stdlib/time.js +79 -55
- package/src/backend/js/stdlib/unicode.js +1 -1
- package/src/backend/js/stdlib/utf8.js +1 -1
- package/src/backend/js/templ.js +38 -76
- package/src/backend/js/type-info.js +272 -0
- package/src/backend/shared/fmt-types.js +188 -0
- package/src/backend/wasm/boundary.js +436 -80
- package/src/backend/wasm/emit-builtins.js +303 -13
- package/src/backend/wasm/emit-exprs.js +1397 -203
- package/src/backend/wasm/emit-maps.js +61 -13
- package/src/backend/wasm/emit-stmts.js +1359 -164
- package/src/backend/wasm/emit.js +512 -77
- package/src/backend/wasm/encode.js +43 -13
- package/src/backend/wasm/globals.js +452 -0
- package/src/backend/wasm/index.js +194 -2489
- package/src/backend/wasm/method-expr.js +381 -0
- package/src/backend/wasm/module-emitter.js +2240 -0
- package/src/backend/wasm/monomorph.js +62 -4
- package/src/backend/wasm/prescan.js +397 -0
- package/src/backend/wasm/stdlib/bytes.js +1804 -127
- package/src/backend/wasm/stdlib/core.js +1574 -199
- package/src/backend/wasm/stdlib/index.js +0 -5
- package/src/backend/wasm/stdlib/io.js +1567 -150
- package/src/backend/wasm/stdlib/packages.js +2 -0
- package/src/backend/wasm/stdlib/simd.js +293 -28
- package/src/backend/wasm/stdlib/time.js +1041 -12
- package/src/backend/wasm/types.js +200 -15
- package/src/backend/wasm/variadic.js +93 -0
- package/src/backend/wasm/wat.js +47 -20
- package/src/{cli-core.js → cli/cli-core.js} +236 -10
- package/src/{test-runner.js → cli/test-runner.js} +332 -39
- package/src/{vendor.js → cli/vendor.js} +3 -4
- package/src/compiler.js +107 -269
- package/src/index.js +15 -169
- package/src/{lexer.js → lexer/lexer.js} +102 -55
- package/src/{tokens.js → lexer/tokens.js} +1 -0
- package/src/link/sourcemap.js +97 -0
- package/src/link/stdlib.js +515 -0
- package/src/link/wasm.js +294 -0
- package/src/lower/bounds.js +394 -0
- package/src/lower/boxing.js +1 -1
- package/src/lower/captures.js +176 -32
- package/src/lower/index.js +26 -18
- package/src/lower/json-codecs.js +1398 -0
- package/src/lower/ownership.js +22 -1
- package/src/lower/range.js +86 -1
- package/src/lower/reachability.js +132 -0
- package/src/parser/declarations.js +58 -13
- package/src/parser/expressions.js +29 -7
- package/src/parser/index.js +2 -1
- package/src/parser/statements.js +37 -22
- package/src/{templ-parser.js → parser/templ.js} +138 -15
- package/src/parser/types.js +69 -9
- package/src/resolver.js +22 -1
- package/src/typechecker/assignability.js +176 -17
- package/src/typechecker/const-fold.js +356 -0
- package/src/typechecker/constants.js +256 -0
- package/src/typechecker/expressions.js +931 -122
- package/src/typechecker/index.js +459 -67
- package/src/typechecker/init-order.js +330 -0
- package/src/typechecker/resolve.js +451 -56
- package/src/typechecker/statements.js +90 -9
- package/src/typechecker/stdlib/core.js +333 -55
- package/src/typechecker/stdlib/excluded.js +898 -0
- package/src/typechecker/stdlib/extended.js +322 -26
- package/src/typechecker/{stdlib.js → stdlib/index.js} +5 -5
- package/src/typechecker/stdlib/simd.js +65 -15
- package/src/typechecker/termination.js +1 -1
- package/src/typechecker/types.js +149 -25
- package/stdlib/bytes/iter.go +192 -0
- package/stdlib/bytes/search.go +240 -0
- package/stdlib/bytes/split.go +218 -0
- package/stdlib/cmp/cmp.go +65 -0
- package/stdlib/encoding/json/errors.go +31 -0
- package/stdlib/encoding/json/indent.go +71 -0
- package/stdlib/encoding/json/number.go +12 -0
- package/stdlib/encoding/json/stream.go +173 -0
- package/stdlib/errors/overlay.go +12 -0
- package/stdlib/hash/hash.go +53 -0
- package/stdlib/internal/jsonrt/dec.go +738 -0
- package/stdlib/internal/jsonrt/enc.go +366 -0
- package/stdlib/internal/jsonrt/indent.go +135 -0
- package/stdlib/internal/jsonrt/number.go +27 -0
- package/stdlib/internal/jsonrt/reader.go +73 -0
- package/stdlib/internal/jsonrt/scanner.go +649 -0
- package/stdlib/io/io.go +346 -0
- package/stdlib/iter/iter.go +18 -0
- package/stdlib/maps/iter.go +65 -0
- package/stdlib/math/extra.go +270 -0
- package/stdlib/slices/extra.go +73 -0
- package/stdlib/slices/iter.go +113 -0
- package/stdlib/sort/sort.go +561 -0
- package/stdlib/strconv/quote.go +341 -0
- package/stdlib/strings/extra.go +35 -0
- package/stdlib/strings/iter.go +122 -0
- package/stdlib/sync/extra.go +105 -0
- package/stdlib/unicode/unicode.go +112 -0
- package/stdlib/unicode/utf8/bytes.go +239 -0
- package/src/backend/wasm/const-fold.js +0 -205
- package/src/backend/wasm/emit-stdlib.js +0 -13
- /package/src/{asset-manager.js → cli/asset-manager.js} +0 -0
- /package/src/{colors.js → cli/colors.js} +0 -0
- /package/src/{dev-server.js → cli/dev-server.js} +0 -0
- /package/src/{minifier.js → cli/minifier.js} +0 -0
- /package/src/{project-config.js → cli/project-config.js} +0 -0
- /package/src/{pwa.js → cli/pwa.js} +0 -0
- /package/src/{templ-lexer.js → lexer/templ-lexer.js} +0 -0
package/src/typechecker/types.js
CHANGED
|
@@ -102,7 +102,7 @@ export const BROWSER_GLOBALS = new Set([
|
|
|
102
102
|
"TextDecoder",
|
|
103
103
|
]);
|
|
104
104
|
|
|
105
|
-
// Stdlib packages the WASM backend can emit. Extend as src/backend/wasm/
|
|
105
|
+
// Stdlib packages the WASM backend can emit. Extend as src/backend/wasm/stdlib/
|
|
106
106
|
// gains support; anything not listed is rejected at import with "not yet available in
|
|
107
107
|
// wasm packages".
|
|
108
108
|
export const WASM_SUPPORTED_STDLIB = new Set([
|
|
@@ -133,21 +133,21 @@ export const WASM_SUPPORTED_STDLIB = new Set([
|
|
|
133
133
|
"encoding/binary",
|
|
134
134
|
"encoding/hex",
|
|
135
135
|
"encoding/base64",
|
|
136
|
+
"os",
|
|
137
|
+
"encoding/json",
|
|
136
138
|
]);
|
|
137
139
|
|
|
138
140
|
export const STDLIB_PACKAGES = new Set([
|
|
139
141
|
...WASM_SUPPORTED_STDLIB,
|
|
140
|
-
"os",
|
|
141
142
|
"gom",
|
|
142
143
|
"regexp",
|
|
143
|
-
"encoding/json",
|
|
144
144
|
]);
|
|
145
145
|
|
|
146
146
|
// Per-namespace member subset the WASM backend implements. `null` means every
|
|
147
147
|
// member the checker knows about. Members outside the set are rejected in
|
|
148
148
|
// wasm/both packages with "'strings.Split' is not yet available in wasm packages".
|
|
149
149
|
export const WASM_STDLIB_MEMBERS = new Map([
|
|
150
|
-
["
|
|
150
|
+
["os", new Set(["Stdout", "Stderr", "Stdin", "File"])],
|
|
151
151
|
[
|
|
152
152
|
"math",
|
|
153
153
|
new Set([
|
|
@@ -179,8 +179,10 @@ export const WASM_STDLIB_MEMBERS = new Map([
|
|
|
179
179
|
"Exp",
|
|
180
180
|
"Exp2",
|
|
181
181
|
"Log",
|
|
182
|
+
"Log1p",
|
|
182
183
|
"Log2",
|
|
183
184
|
"Log10",
|
|
185
|
+
"Expm1",
|
|
184
186
|
"Round",
|
|
185
187
|
"Remainder",
|
|
186
188
|
"Float64bits",
|
|
@@ -226,21 +228,56 @@ export const WASM_STDLIB_MEMBERS = new Map([
|
|
|
226
228
|
[
|
|
227
229
|
"bits",
|
|
228
230
|
new Set([
|
|
231
|
+
"Add",
|
|
232
|
+
"Add32",
|
|
233
|
+
"Add64",
|
|
234
|
+
"Sub",
|
|
235
|
+
"Sub32",
|
|
236
|
+
"Sub64",
|
|
237
|
+
"Mul",
|
|
238
|
+
"Mul32",
|
|
239
|
+
"Mul64",
|
|
240
|
+
"Div",
|
|
241
|
+
"Div32",
|
|
242
|
+
"Div64",
|
|
243
|
+
"Rem",
|
|
244
|
+
"Rem32",
|
|
245
|
+
"Rem64",
|
|
246
|
+
"LeadingZeros",
|
|
247
|
+
"LeadingZeros8",
|
|
248
|
+
"LeadingZeros16",
|
|
229
249
|
"LeadingZeros32",
|
|
230
250
|
"LeadingZeros64",
|
|
251
|
+
"TrailingZeros",
|
|
252
|
+
"TrailingZeros8",
|
|
253
|
+
"TrailingZeros16",
|
|
231
254
|
"TrailingZeros32",
|
|
232
255
|
"TrailingZeros64",
|
|
256
|
+
"OnesCount",
|
|
257
|
+
"OnesCount8",
|
|
258
|
+
"OnesCount16",
|
|
233
259
|
"OnesCount32",
|
|
234
260
|
"OnesCount64",
|
|
261
|
+
"RotateLeft",
|
|
262
|
+
"RotateLeft8",
|
|
263
|
+
"RotateLeft16",
|
|
235
264
|
"RotateLeft32",
|
|
236
265
|
"RotateLeft64",
|
|
266
|
+
"Reverse",
|
|
267
|
+
"Reverse8",
|
|
268
|
+
"Reverse16",
|
|
269
|
+
"Reverse32",
|
|
270
|
+
"Reverse64",
|
|
271
|
+
"ReverseBytes",
|
|
237
272
|
"ReverseBytes16",
|
|
238
273
|
"ReverseBytes32",
|
|
239
274
|
"ReverseBytes64",
|
|
275
|
+
"Len",
|
|
276
|
+
"Len8",
|
|
277
|
+
"Len16",
|
|
240
278
|
"Len32",
|
|
241
279
|
"Len64",
|
|
242
|
-
"
|
|
243
|
-
"Reverse64",
|
|
280
|
+
"UintSize",
|
|
244
281
|
]),
|
|
245
282
|
],
|
|
246
283
|
["errors", new Set(["New", "Is", "Unwrap", "As", "Join"])],
|
|
@@ -257,6 +294,15 @@ export const WASM_STDLIB_MEMBERS = new Map([
|
|
|
257
294
|
"RuneError",
|
|
258
295
|
"MaxRune",
|
|
259
296
|
"UTFMax",
|
|
297
|
+
"RuneSelf",
|
|
298
|
+
"EncodeRune",
|
|
299
|
+
"AppendRune",
|
|
300
|
+
"DecodeRune",
|
|
301
|
+
"DecodeLastRune",
|
|
302
|
+
"RuneCount",
|
|
303
|
+
"FullRune",
|
|
304
|
+
"Valid",
|
|
305
|
+
"RuneStart",
|
|
260
306
|
]),
|
|
261
307
|
],
|
|
262
308
|
[
|
|
@@ -278,6 +324,11 @@ export const WASM_STDLIB_MEMBERS = new Map([
|
|
|
278
324
|
"fmt",
|
|
279
325
|
new Set([
|
|
280
326
|
"Sprintf",
|
|
327
|
+
"Sprint",
|
|
328
|
+
"Sprintln",
|
|
329
|
+
"Append",
|
|
330
|
+
"Appendf",
|
|
331
|
+
"Appendln",
|
|
281
332
|
"Errorf",
|
|
282
333
|
"Printf",
|
|
283
334
|
"Println",
|
|
@@ -288,6 +339,7 @@ export const WASM_STDLIB_MEMBERS = new Map([
|
|
|
288
339
|
"Sscan",
|
|
289
340
|
"Sscanln",
|
|
290
341
|
"Sscanf",
|
|
342
|
+
"Stringer",
|
|
291
343
|
]),
|
|
292
344
|
],
|
|
293
345
|
[
|
|
@@ -337,9 +389,11 @@ export const WASM_STDLIB_MEMBERS = new Map([
|
|
|
337
389
|
"TrimRightFunc",
|
|
338
390
|
"FieldsFunc",
|
|
339
391
|
"NewReplacer",
|
|
392
|
+
"Replacer",
|
|
340
393
|
"Builder",
|
|
341
394
|
"NewReader",
|
|
342
395
|
"Reader",
|
|
396
|
+
"ToValidUTF8",
|
|
343
397
|
]),
|
|
344
398
|
],
|
|
345
399
|
[
|
|
@@ -363,6 +417,20 @@ export const WASM_STDLIB_MEMBERS = new Map([
|
|
|
363
417
|
"AppendBool",
|
|
364
418
|
"ErrSyntax",
|
|
365
419
|
"ErrRange",
|
|
420
|
+
"IntSize",
|
|
421
|
+
"NumError",
|
|
422
|
+
"QuoteRune",
|
|
423
|
+
"QuoteToASCII",
|
|
424
|
+
"QuoteRuneToASCII",
|
|
425
|
+
"AppendQuote",
|
|
426
|
+
"AppendQuoteToASCII",
|
|
427
|
+
"AppendQuoteRune",
|
|
428
|
+
"AppendQuoteRuneToASCII",
|
|
429
|
+
"CanBackquote",
|
|
430
|
+
"UnquoteChar",
|
|
431
|
+
"QuotedPrefix",
|
|
432
|
+
"IsPrint",
|
|
433
|
+
"IsGraphic",
|
|
366
434
|
]),
|
|
367
435
|
],
|
|
368
436
|
[
|
|
@@ -400,16 +468,7 @@ export const WASM_STDLIB_MEMBERS = new Map([
|
|
|
400
468
|
],
|
|
401
469
|
[
|
|
402
470
|
"maps",
|
|
403
|
-
new Set([
|
|
404
|
-
"Keys",
|
|
405
|
-
"Values",
|
|
406
|
-
"Clone",
|
|
407
|
-
"Copy",
|
|
408
|
-
"Equal",
|
|
409
|
-
"EqualFunc",
|
|
410
|
-
"Delete",
|
|
411
|
-
"DeleteFunc",
|
|
412
|
-
]),
|
|
471
|
+
new Set(["Clone", "Copy", "Equal", "EqualFunc", "Delete", "DeleteFunc"]),
|
|
413
472
|
],
|
|
414
473
|
[
|
|
415
474
|
"unicode",
|
|
@@ -481,8 +540,11 @@ export const WASM_STDLIB_MEMBERS = new Map([
|
|
|
481
540
|
"Map",
|
|
482
541
|
"SplitN",
|
|
483
542
|
"Buffer",
|
|
543
|
+
"NewBuffer",
|
|
544
|
+
"NewBufferString",
|
|
484
545
|
"NewReader",
|
|
485
546
|
"Reader",
|
|
547
|
+
"ToValidUTF8",
|
|
486
548
|
]),
|
|
487
549
|
],
|
|
488
550
|
[
|
|
@@ -522,9 +584,6 @@ export const WASM_STDLIB_MEMBERS = new Map([
|
|
|
522
584
|
"ReadWriter",
|
|
523
585
|
"Closer",
|
|
524
586
|
"EOF",
|
|
525
|
-
"ErrUnexpectedEOF",
|
|
526
|
-
"ErrShortWrite",
|
|
527
|
-
"ReadFull",
|
|
528
587
|
"ReadAll",
|
|
529
588
|
"Discard",
|
|
530
589
|
"WriteString",
|
|
@@ -539,10 +598,12 @@ export const WASM_STDLIB_MEMBERS = new Map([
|
|
|
539
598
|
"Now",
|
|
540
599
|
"Since",
|
|
541
600
|
"Parse",
|
|
601
|
+
"ParseDuration",
|
|
542
602
|
"Unix",
|
|
543
603
|
"UnixMicro",
|
|
544
604
|
"UnixMilli",
|
|
545
605
|
"Date",
|
|
606
|
+
"FixedZone",
|
|
546
607
|
"Duration",
|
|
547
608
|
"Nanosecond",
|
|
548
609
|
"Microsecond",
|
|
@@ -577,9 +638,12 @@ export const WASM_STDLIB_MEMBERS = new Map([
|
|
|
577
638
|
"Friday",
|
|
578
639
|
"Saturday",
|
|
579
640
|
"Time",
|
|
641
|
+
"Month",
|
|
642
|
+
"Weekday",
|
|
643
|
+
"Location",
|
|
580
644
|
]),
|
|
581
645
|
],
|
|
582
|
-
["testing", new Set(["T"])],
|
|
646
|
+
["testing", new Set(["T", "B", "M", "TB", "BenchmarkResult"])],
|
|
583
647
|
["sync", new Set(["Mutex", "RWMutex", "Once", "WaitGroup", "Locker"])],
|
|
584
648
|
["sha256", new Set(["Sum256", "New", "Size", "BlockSize"])],
|
|
585
649
|
[
|
|
@@ -625,6 +689,11 @@ export const WASM_STDLIB_MEMBERS = new Map([
|
|
|
625
689
|
|
|
626
690
|
export const VALID_TARGETS = new Set(["js", "wasm", "both"]);
|
|
627
691
|
|
|
692
|
+
// Backend-provided implementations for body-less Go-source stdlib functions
|
|
693
|
+
// marked `//gofront:intrinsic <name>`: name -> required signature. New
|
|
694
|
+
// intrinsics need a plan change.
|
|
695
|
+
export const INTRINSICS = new Map([]);
|
|
696
|
+
|
|
628
697
|
// ── Static operator sets (module-level for reuse) ────────────
|
|
629
698
|
export const CMP_OPS = new Set(["==", "!=", "<", ">", "<=", ">="]);
|
|
630
699
|
export const LOG_OPS = new Set(["&&", "||"]);
|
|
@@ -669,7 +738,7 @@ export const UNTYPED_BOOL = { kind: "untyped", base: "bool" };
|
|
|
669
738
|
|
|
670
739
|
// ── Complex types ────────────────────────────────────────────
|
|
671
740
|
export const COMPLEX128 = { kind: "basic", name: "complex128" };
|
|
672
|
-
const COMPLEX64 = { kind: "basic", name: "complex64" };
|
|
741
|
+
export const COMPLEX64 = { kind: "basic", name: "complex64" };
|
|
673
742
|
export const UNTYPED_COMPLEX = { kind: "untyped", base: "complex128" };
|
|
674
743
|
|
|
675
744
|
export const BASIC_TYPES = {
|
|
@@ -750,6 +819,32 @@ const TYPED_ARRAY_CONSTRUCTORS = {
|
|
|
750
819
|
rune: "Int32Array",
|
|
751
820
|
};
|
|
752
821
|
|
|
822
|
+
// Element indices of an array or slice literal (Go spec): `i: v` puts v at
|
|
823
|
+
// index i, any other element goes right after the previous one, so
|
|
824
|
+
// `[5]int{1, 3: 4, 5}` fills indices 0, 3 and 4. Array literal keys are
|
|
825
|
+
// resolved by the type checker (`_index`, which handles named constants and
|
|
826
|
+
// constant expressions); otherwise only integer-literal keys are known and
|
|
827
|
+
// another key is treated as a positional element.
|
|
828
|
+
export function compositeLitIndices(elems) {
|
|
829
|
+
const out = [];
|
|
830
|
+
let next = 0;
|
|
831
|
+
for (const e of elems) {
|
|
832
|
+
if (e.kind === "KeyValueExpr" && e._index !== undefined) next = e._index;
|
|
833
|
+
else if (e.kind === "KeyValueExpr" && e.key?.value !== undefined)
|
|
834
|
+
next = Number(e.key.value);
|
|
835
|
+
out.push(next++);
|
|
836
|
+
}
|
|
837
|
+
return out;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
// Highest element index of an array or slice literal (-1 when empty). A
|
|
841
|
+
// loop, not `Math.max(...)`: spreading a huge literal overflows the stack.
|
|
842
|
+
export function compositeLitMaxIndex(elems) {
|
|
843
|
+
let max = -1;
|
|
844
|
+
for (const i of compositeLitIndices(elems)) if (i > max) max = i;
|
|
845
|
+
return max;
|
|
846
|
+
}
|
|
847
|
+
|
|
753
848
|
export function typedArrayConstructorForElem(elemType) {
|
|
754
849
|
if (!elemType) return null;
|
|
755
850
|
const name = elemType.kind === "basic" ? elemType.name : null;
|
|
@@ -765,12 +860,28 @@ export function isTypedArraySlice(type) {
|
|
|
765
860
|
|
|
766
861
|
export function isComplex(t) {
|
|
767
862
|
if (!t) return false;
|
|
768
|
-
if (
|
|
863
|
+
if (
|
|
864
|
+
(t.kind === "basic" || t.kind === "TypeName" || t.kind === "Ident") &&
|
|
865
|
+
(t.name === "complex128" || t.name === "complex64")
|
|
866
|
+
)
|
|
769
867
|
return true;
|
|
770
868
|
if (t.kind === "untyped" && t.base === "complex128") return true;
|
|
771
869
|
if (t.kind === "named") return isComplex(t.underlying);
|
|
772
870
|
return false;
|
|
773
871
|
}
|
|
872
|
+
export function isComplex64(t) {
|
|
873
|
+
if (!t) return false;
|
|
874
|
+
if (
|
|
875
|
+
(t.kind === "basic" || t.kind === "TypeName" || t.kind === "Ident") &&
|
|
876
|
+
t.name === "complex64"
|
|
877
|
+
)
|
|
878
|
+
return true;
|
|
879
|
+
if (t.kind === "untyped" && t.base === "complex64") return true;
|
|
880
|
+
if (t.kind === "named") return isComplex64(t.underlying);
|
|
881
|
+
if (t.name === "complex64") return true;
|
|
882
|
+
if (t.underlying) return isComplex64(t.underlying);
|
|
883
|
+
return false;
|
|
884
|
+
}
|
|
774
885
|
export function isComplexOrNumeric(t) {
|
|
775
886
|
return isNumeric(t) || isComplex(t);
|
|
776
887
|
}
|
|
@@ -851,10 +962,12 @@ export function typeStr(t) {
|
|
|
851
962
|
}
|
|
852
963
|
case "tuple":
|
|
853
964
|
return `(${t.types.map(typeStr).join(", ")})`;
|
|
854
|
-
case "named":
|
|
965
|
+
case "named": {
|
|
966
|
+
const name = displayTypeName(t.name);
|
|
855
967
|
return t.typeArgs && t.typeArgs.length > 0
|
|
856
|
-
? `${
|
|
857
|
-
:
|
|
968
|
+
? `${name}[${t.typeArgs.map(typeStr).join(", ")}]`
|
|
969
|
+
: name;
|
|
970
|
+
}
|
|
858
971
|
case "pointer":
|
|
859
972
|
return `*${typeStr(t.base)}`;
|
|
860
973
|
case "typeParam":
|
|
@@ -866,6 +979,17 @@ export function typeStr(t) {
|
|
|
866
979
|
}
|
|
867
980
|
}
|
|
868
981
|
|
|
982
|
+
// Go-source stdlib names are mangled to `Name$$path` (`List$$container$list`);
|
|
983
|
+
// diagnostics show them qualified, as Go does (`list.List`).
|
|
984
|
+
export function displayTypeName(name) {
|
|
985
|
+
const i = typeof name === "string" ? name.indexOf("$$") : -1;
|
|
986
|
+
if (i < 0) return name;
|
|
987
|
+
return `${name
|
|
988
|
+
.slice(i + 2)
|
|
989
|
+
.split("$")
|
|
990
|
+
.at(-1)}.${name.slice(0, i)}`;
|
|
991
|
+
}
|
|
992
|
+
|
|
869
993
|
// ── Iterator function detection (Go 1.23 range-over-func) ───
|
|
870
994
|
|
|
871
995
|
/**
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
//go:build gofront
|
|
2
|
+
|
|
3
|
+
//gofront:target both
|
|
4
|
+
|
|
5
|
+
// Overlay on the emitter-backed bytes package: the sequence members of
|
|
6
|
+
// Go 1.24 are written in Go over iter.Seq and merged into the bytes
|
|
7
|
+
// namespace. Like Go's, the slices they yield alias the input and have their
|
|
8
|
+
// capacity clipped, so appending to one does not write into the original.
|
|
9
|
+
package bytes
|
|
10
|
+
|
|
11
|
+
import (
|
|
12
|
+
"iter"
|
|
13
|
+
"unicode"
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
const (
|
|
17
|
+
runeError = 0xFFFD
|
|
18
|
+
runeSelf = 0x80
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
// decodeRune unpacks the first UTF-8 encoding in p and returns the rune and
|
|
22
|
+
// its width in bytes, as utf8.DecodeRune does: an invalid or incomplete
|
|
23
|
+
// encoding is (RuneError, 1) and p must not be empty.
|
|
24
|
+
func decodeRune(p []byte) (rune, int) {
|
|
25
|
+
b0 := int(p[0])
|
|
26
|
+
if b0 < runeSelf {
|
|
27
|
+
return rune(b0), 1
|
|
28
|
+
}
|
|
29
|
+
n, lo, mask := 0, 0, 0
|
|
30
|
+
if b0 >= 0xC2 && b0 <= 0xDF {
|
|
31
|
+
n, lo, mask = 2, 0x80, 0x1F
|
|
32
|
+
} else if b0 >= 0xE0 && b0 <= 0xEF {
|
|
33
|
+
n, lo, mask = 3, 0x800, 0x0F
|
|
34
|
+
} else if b0 >= 0xF0 && b0 <= 0xF4 {
|
|
35
|
+
n, lo, mask = 4, 0x10000, 0x07
|
|
36
|
+
} else {
|
|
37
|
+
return runeError, 1
|
|
38
|
+
}
|
|
39
|
+
if len(p) < n {
|
|
40
|
+
return runeError, 1
|
|
41
|
+
}
|
|
42
|
+
r := b0 & mask
|
|
43
|
+
for i := 1; i < n; i++ {
|
|
44
|
+
b := int(p[i])
|
|
45
|
+
if b&0xC0 != 0x80 {
|
|
46
|
+
return runeError, 1
|
|
47
|
+
}
|
|
48
|
+
r = r<<6 | b&0x3F
|
|
49
|
+
}
|
|
50
|
+
if r < lo || r > 0x10FFFF || (r >= 0xD800 && r <= 0xDFFF) {
|
|
51
|
+
return runeError, 1
|
|
52
|
+
}
|
|
53
|
+
return rune(r), n
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// index returns the byte offset of the first instance of sep in s, or -1.
|
|
57
|
+
// It compares bytes: the emitter's bytes.Index goes through a decoded JS
|
|
58
|
+
// string on the JS backend and so counts characters, not bytes, once s holds
|
|
59
|
+
// multi-byte text. sep must not be empty.
|
|
60
|
+
func index(s, sep []byte) int {
|
|
61
|
+
first := sep[0]
|
|
62
|
+
for i := 0; i+len(sep) <= len(s); i++ {
|
|
63
|
+
if s[i] != first {
|
|
64
|
+
continue
|
|
65
|
+
}
|
|
66
|
+
j := 1
|
|
67
|
+
for j < len(sep) && s[i+j] == sep[j] {
|
|
68
|
+
j++
|
|
69
|
+
}
|
|
70
|
+
if j == len(sep) {
|
|
71
|
+
return i
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return -1
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// isSpace is unicode.IsSpace as a func(rune) bool (the checker types the
|
|
78
|
+
// unicode predicates over int).
|
|
79
|
+
func isSpace(r rune) bool {
|
|
80
|
+
return unicode.IsSpace(int(r))
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Lines returns an iterator over the newline-terminated lines in the byte slice s.
|
|
84
|
+
// The lines yielded by the iterator include their terminating newlines.
|
|
85
|
+
// If s is empty, the iterator yields no lines at all.
|
|
86
|
+
// If s does not end in a newline, the final yielded line will not end in a newline.
|
|
87
|
+
// The iterator yields slices of the original slice s.
|
|
88
|
+
func Lines(s []byte) iter.Seq[[]byte] {
|
|
89
|
+
return func(yield func([]byte) bool) {
|
|
90
|
+
for len(s) > 0 {
|
|
91
|
+
var line []byte
|
|
92
|
+
if i := IndexByte(s, '\n'); i >= 0 {
|
|
93
|
+
line, s = s[:i+1:i+1], s[i+1:]
|
|
94
|
+
} else {
|
|
95
|
+
line, s = s[:len(s):len(s)], nil
|
|
96
|
+
}
|
|
97
|
+
if !yield(line) {
|
|
98
|
+
return
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// explodeSeq returns an iterator over the UTF-8 encodings of the runes in s.
|
|
105
|
+
func explodeSeq(s []byte) iter.Seq[[]byte] {
|
|
106
|
+
return func(yield func([]byte) bool) {
|
|
107
|
+
for len(s) > 0 {
|
|
108
|
+
_, size := decodeRune(s)
|
|
109
|
+
if !yield(s[:size:size]) {
|
|
110
|
+
return
|
|
111
|
+
}
|
|
112
|
+
s = s[size:]
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// splitSeq is SplitSeq or SplitAfterSeq, configured by how many
|
|
118
|
+
// bytes of sep to include in the results (none or all).
|
|
119
|
+
func splitSeq(s, sep []byte, sepSave int) iter.Seq[[]byte] {
|
|
120
|
+
if len(sep) == 0 {
|
|
121
|
+
return explodeSeq(s)
|
|
122
|
+
}
|
|
123
|
+
return func(yield func([]byte) bool) {
|
|
124
|
+
for {
|
|
125
|
+
i := index(s, sep)
|
|
126
|
+
if i < 0 {
|
|
127
|
+
break
|
|
128
|
+
}
|
|
129
|
+
frag := s[:i+sepSave]
|
|
130
|
+
if !yield(frag[:len(frag):len(frag)]) {
|
|
131
|
+
return
|
|
132
|
+
}
|
|
133
|
+
s = s[i+len(sep):]
|
|
134
|
+
}
|
|
135
|
+
yield(s[:len(s):len(s)])
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// SplitSeq returns an iterator over subslices of s split around sep.
|
|
140
|
+
// The iterator yields the same subslices that would be returned by Split(s, sep),
|
|
141
|
+
// but without constructing the slice.
|
|
142
|
+
// It returns a single-use iterator.
|
|
143
|
+
func SplitSeq(s, sep []byte) iter.Seq[[]byte] {
|
|
144
|
+
return splitSeq(s, sep, 0)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// SplitAfterSeq returns an iterator over subslices of s split after each instance of sep.
|
|
148
|
+
// The iterator yields the same subslices that would be returned by SplitAfter(s, sep),
|
|
149
|
+
// but without constructing the slice.
|
|
150
|
+
// It returns a single-use iterator.
|
|
151
|
+
func SplitAfterSeq(s, sep []byte) iter.Seq[[]byte] {
|
|
152
|
+
return splitSeq(s, sep, len(sep))
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// FieldsSeq returns an iterator over subslices of s split around runs of
|
|
156
|
+
// whitespace characters, as defined by unicode.IsSpace.
|
|
157
|
+
// The iterator yields the same subslices that would be returned by Fields(s),
|
|
158
|
+
// but without constructing the slice.
|
|
159
|
+
func FieldsSeq(s []byte) iter.Seq[[]byte] {
|
|
160
|
+
return FieldsFuncSeq(s, isSpace)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// FieldsFuncSeq returns an iterator over subslices of s split around runs of
|
|
164
|
+
// Unicode code points satisfying f(c).
|
|
165
|
+
// The iterator yields the same subslices that would be returned by FieldsFunc(s),
|
|
166
|
+
// but without constructing the slice.
|
|
167
|
+
func FieldsFuncSeq(s []byte, f func(rune) bool) iter.Seq[[]byte] {
|
|
168
|
+
return func(yield func([]byte) bool) {
|
|
169
|
+
start := -1
|
|
170
|
+
for i := 0; i < len(s); {
|
|
171
|
+
size := 1
|
|
172
|
+
r := rune(s[i])
|
|
173
|
+
if r >= runeSelf {
|
|
174
|
+
r, size = decodeRune(s[i:])
|
|
175
|
+
}
|
|
176
|
+
if f(r) {
|
|
177
|
+
if start >= 0 {
|
|
178
|
+
if !yield(s[start:i:i]) {
|
|
179
|
+
return
|
|
180
|
+
}
|
|
181
|
+
start = -1
|
|
182
|
+
}
|
|
183
|
+
} else if start < 0 {
|
|
184
|
+
start = i
|
|
185
|
+
}
|
|
186
|
+
i += size
|
|
187
|
+
}
|
|
188
|
+
if start >= 0 {
|
|
189
|
+
yield(s[start:len(s):len(s)])
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|