gofront 1.6.0 → 1.6.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 (68) hide show
  1. package/package.json +1 -1
  2. package/src/backend/js/expressions.js +238 -109
  3. package/src/backend/js/index.js +38 -1
  4. package/src/backend/js/runtime.js +953 -53
  5. package/src/backend/js/statements.js +55 -67
  6. package/src/backend/js/stdlib/base64.js +12 -0
  7. package/src/backend/js/stdlib/binary.js +102 -0
  8. package/src/backend/js/stdlib/bits.js +15 -1
  9. package/src/backend/js/stdlib/builder.js +28 -9
  10. package/src/backend/js/stdlib/bytes.js +75 -18
  11. package/src/backend/js/stdlib/errors.js +20 -1
  12. package/src/backend/js/stdlib/fmt.js +70 -13
  13. package/src/backend/js/stdlib/hex.js +17 -0
  14. package/src/backend/js/stdlib/html.js +1 -1
  15. package/src/backend/js/stdlib/index.js +16 -0
  16. package/src/backend/js/stdlib/io.js +105 -3
  17. package/src/backend/js/stdlib/math.js +13 -1
  18. package/src/backend/js/stdlib/path.js +18 -4
  19. package/src/backend/js/stdlib/rand.js +10 -5
  20. package/src/backend/js/stdlib/sha256.js +12 -0
  21. package/src/backend/js/stdlib/slices.js +52 -26
  22. package/src/backend/js/stdlib/strconv.js +21 -5
  23. package/src/backend/js/stdlib/strings.js +148 -15
  24. package/src/backend/js/stdlib/sync.js +13 -0
  25. package/src/backend/js/stdlib/time.js +90 -19
  26. package/src/backend/js/stdlib/unicode.js +2 -2
  27. package/src/backend/wasm/boundary.js +1207 -41
  28. package/src/backend/wasm/const-fold.js +205 -0
  29. package/src/backend/wasm/emit-builtins.js +203 -76
  30. package/src/backend/wasm/emit-exprs.js +464 -276
  31. package/src/backend/wasm/emit-maps.js +144 -8
  32. package/src/backend/wasm/emit-stdlib.js +12 -3005
  33. package/src/backend/wasm/emit-stmts.js +264 -270
  34. package/src/backend/wasm/emit.js +115 -87
  35. package/src/backend/wasm/encode.js +55 -29
  36. package/src/backend/wasm/index.js +1001 -32
  37. package/src/backend/wasm/optimize.js +13 -4
  38. package/src/backend/wasm/stdlib/bytes.js +5039 -0
  39. package/src/backend/wasm/stdlib/core.js +8903 -0
  40. package/src/backend/wasm/stdlib/index.js +40 -0
  41. package/src/backend/wasm/stdlib/io.js +2161 -0
  42. package/src/backend/wasm/stdlib/packages.js +2400 -0
  43. package/src/backend/wasm/stdlib/pure.js +720 -0
  44. package/src/backend/wasm/stdlib/time.js +1200 -0
  45. package/src/backend/wasm/types.js +153 -1
  46. package/src/cli-core.js +1 -1
  47. package/src/compiler.js +18 -4
  48. package/src/dts-parser.js +79 -126
  49. package/src/index.js +2 -6
  50. package/src/lexer.js +80 -29
  51. package/src/lower/boxing.js +1 -2
  52. package/src/lower/captures.js +2 -6
  53. package/src/lower/ownership.js +30 -9
  54. package/src/minifier.js +20 -68
  55. package/src/parser/declarations.js +3 -6
  56. package/src/parser/expressions.js +3 -8
  57. package/src/parser/index.js +18 -3
  58. package/src/parser/statements.js +25 -38
  59. package/src/parser/types.js +1 -2
  60. package/src/resolver.js +2 -27
  61. package/src/templ-lexer.js +29 -63
  62. package/src/templ-parser.js +22 -45
  63. package/src/typechecker/assignability.js +81 -13
  64. package/src/typechecker/expressions.js +102 -2
  65. package/src/typechecker/resolve.js +36 -6
  66. package/src/typechecker/stdlib/core.js +280 -89
  67. package/src/typechecker/stdlib/extended.js +453 -1
  68. package/src/typechecker/types.js +344 -6
@@ -142,6 +142,7 @@ export function toWasmType(goType, checker = null, mod = null) {
142
142
  return "externref";
143
143
 
144
144
  case "any":
145
+ case "error":
145
146
  return "anyref";
146
147
 
147
148
  case "void":
@@ -220,7 +221,7 @@ export function toWasmType(goType, checker = null, mod = null) {
220
221
  return { kind: "ref", nullable: true, heapType: "struct" };
221
222
  }
222
223
 
223
- if (goType.kind === "struct") {
224
+ if (goType.kind === "struct" || goType.kind === "StructType") {
224
225
  if (goType.name && mod?.getStructType(goType.name)) {
225
226
  return {
226
227
  kind: "ref",
@@ -228,6 +229,23 @@ export function toWasmType(goType, checker = null, mod = null) {
228
229
  typeIndex: mod.getStructType(goType.name).typeIndex,
229
230
  };
230
231
  }
232
+ if (mod?.getAnonStructType && goType.fields) {
233
+ const rawFields = [];
234
+ if (goType.fields instanceof Map) {
235
+ for (const [k, v] of goType.fields.entries()) {
236
+ rawFields.push({ name: k, goType: v });
237
+ }
238
+ } else if (Array.isArray(goType.fields)) {
239
+ for (const f of goType.fields) {
240
+ const names = f.names ?? (f.name ? [f.name] : []);
241
+ for (const n of names) rawFields.push({ name: n, goType: f.type });
242
+ }
243
+ }
244
+ if (rawFields.length > 0) {
245
+ const info = mod.getAnonStructType(rawFields);
246
+ return { kind: "ref", nullable: true, typeIndex: info.typeIndex };
247
+ }
248
+ }
231
249
  return { kind: "ref", nullable: true, heapType: "struct" };
232
250
  }
233
251
 
@@ -250,6 +268,96 @@ export function toWasmType(goType, checker = null, mod = null) {
250
268
  return "i32";
251
269
  }
252
270
 
271
+ export function getInterfaceMethodList(iface) {
272
+ if (!iface) return [];
273
+ if (iface.methods instanceof Map) {
274
+ return Array.from(iface.methods.entries()).map(([name, sig]) => ({
275
+ name,
276
+ params: (sig.params ?? []).map((p) => p.type ?? p),
277
+ returns: (sig.returns ?? []).map((r) => r.type ?? r),
278
+ }));
279
+ }
280
+ if (Array.isArray(iface.methods)) {
281
+ return iface.methods.map((m) => ({
282
+ name: m.name?.value ?? m.name ?? m,
283
+ params: (m.params ?? []).map((p) => p.type ?? p),
284
+ returns: m.returnType
285
+ ? m.returnType.kind === "TupleType" || m.returnType.kind === "tuple"
286
+ ? m.returnType.types
287
+ : [m.returnType]
288
+ : [],
289
+ }));
290
+ }
291
+ return [];
292
+ }
293
+
294
+ export function goTypeKey(t) {
295
+ if (!t) return "any";
296
+ if (typeof t === "string") {
297
+ if (t === "byte") return "uint8";
298
+ if (t === "rune") return "int32";
299
+ return t;
300
+ }
301
+ if (t.kind === "basic" || t.kind === "TypeName" || t.kind === "Ident") {
302
+ const name = t.name ?? "any";
303
+ if (name === "byte") return "uint8";
304
+ if (name === "rune") return "int32";
305
+ return name;
306
+ }
307
+ if (t.kind === "untyped") {
308
+ return t.base ?? "int";
309
+ }
310
+ if (t.kind === "pointer" || t.kind === "PointerType") {
311
+ return `ptr_${goTypeKey(t.base)}`;
312
+ }
313
+ if (t.kind === "StarExpr") {
314
+ return `ptr_${goTypeKey(t.expr ?? t.operand)}`;
315
+ }
316
+ if (t.kind === "slice" || t.kind === "SliceType") {
317
+ return `sl_${goTypeKey(t.elem)}`;
318
+ }
319
+ if (t.kind === "array" || t.kind === "ArrayType") {
320
+ const sz =
321
+ typeof t.size === "number" ? t.size : (t.size?.value ?? t.len ?? "");
322
+ return `arr_${sz}_${goTypeKey(t.elem)}`;
323
+ }
324
+ if (t.kind === "map" || t.kind === "MapType") {
325
+ return `map_${goTypeKey(t.key ?? t.keyType)}_${goTypeKey(t.value ?? t.val ?? t.elem ?? t.valueType ?? t.valType)}`;
326
+ }
327
+ if (t.kind === "struct" || t.kind === "StructType") {
328
+ if (t.name) return t.name;
329
+ const rawFields = [];
330
+ if (t.fields instanceof Map) {
331
+ for (const [k, v] of t.fields.entries())
332
+ rawFields.push(`${k}:${goTypeKey(v)}`);
333
+ } else if (Array.isArray(t.fields)) {
334
+ for (const f of t.fields) {
335
+ const names = f.names ?? (f.name ? [f.name] : []);
336
+ for (const n of names)
337
+ rawFields.push(`${n}:${goTypeKey(f.type ?? f.goType)}`);
338
+ }
339
+ }
340
+ return `struct_${rawFields.join("_")}`;
341
+ }
342
+ if (t.kind === "named") {
343
+ return t.name ?? (t.underlying ? goTypeKey(t.underlying) : "any");
344
+ }
345
+ if (t.name) return t.name;
346
+ return t.kind ?? "any";
347
+ }
348
+
349
+ export function anonIfaceName(iface, _checker = null, _mod = null) {
350
+ const methods = getInterfaceMethodList(iface);
351
+ methods.sort((a, b) => a.name.localeCompare(b.name));
352
+ const parts = methods.map((m) => {
353
+ const ps = m.params.map((p) => goTypeKey(p)).join("_");
354
+ const rs = m.returns.map((r) => goTypeKey(r)).join("_");
355
+ return `${m.name}_${ps}_${rs}`;
356
+ });
357
+ const key = parts.join("__").replace(/[^a-zA-Z0-9_]/g, "_");
358
+ return `anon_iface_${key}`;
359
+ }
360
+
253
361
  export function isStructType(goType, checker = null, mod = null) {
254
362
  if (!goType) return false;
255
363
  if (goType.kind === "TypeName" || goType.kind === "Ident") {
@@ -378,6 +486,11 @@ export function isAnyType(goType, checker = null) {
378
486
 
379
487
  export function isInterfaceType(goType, checker = null) {
380
488
  if (!goType) return false;
489
+ if (
490
+ goType.kind === "basic" &&
491
+ (goType.name === "any" || goType.name === "interface{}")
492
+ )
493
+ return true;
381
494
  if (goType.kind === "interface" || goType.kind === "InterfaceType")
382
495
  return true;
383
496
  if (goType.kind === "TypeName" || goType.kind === "Ident") {
@@ -542,3 +655,42 @@ export function getFuncSignature(goType, checker = null) {
542
655
  }
543
656
  return { params: [], returns: [] };
544
657
  }
658
+
659
+ export function isUnhashableGoType(goType, checker = null, seen = new Set()) {
660
+ if (!goType) return false;
661
+ if (seen.has(goType)) return false;
662
+ seen.add(goType);
663
+ if (
664
+ isSliceType(goType, checker) ||
665
+ isMapType(goType, checker) ||
666
+ isFuncType(goType, checker)
667
+ ) {
668
+ return true;
669
+ }
670
+ if (isArrayType(goType, checker)) {
671
+ const elem = goType.elem ?? goType.underlying?.elem;
672
+ return isUnhashableGoType(elem, checker, seen);
673
+ }
674
+ if (goType.kind === "struct" || goType.kind === "StructType") {
675
+ if (goType.fields instanceof Map) {
676
+ for (const f of goType.fields.values()) {
677
+ if (isUnhashableGoType(f, checker, seen)) return true;
678
+ }
679
+ } else if (Array.isArray(goType.fields)) {
680
+ for (const f of goType.fields) {
681
+ const fType = f.type ?? f.goType;
682
+ if (isUnhashableGoType(fType, checker, seen)) return true;
683
+ }
684
+ }
685
+ }
686
+ if (goType.kind === "TypeName" || goType.kind === "Ident") {
687
+ const resolved = checker?.types?.get(goType.name);
688
+ if (resolved && resolved !== goType) {
689
+ return isUnhashableGoType(resolved, checker, seen);
690
+ }
691
+ }
692
+ if (goType.kind === "named" && goType.underlying) {
693
+ return isUnhashableGoType(goType.underlying, checker, seen);
694
+ }
695
+ return false;
696
+ }
package/src/cli-core.js CHANGED
@@ -33,7 +33,7 @@ import { generatePwa } from "./pwa.js";
33
33
  import { runTests } from "./test-runner.js";
34
34
  import { bundleVendor } from "./vendor.js";
35
35
 
36
- const GOFRONT_VERSION = JSON.parse(
36
+ export const GOFRONT_VERSION = JSON.parse(
37
37
  readFileSync(new URL("../package.json", import.meta.url), "utf8"),
38
38
  ).version;
39
39
 
package/src/compiler.js CHANGED
@@ -38,7 +38,7 @@ import {
38
38
  } from "./resolver.js";
39
39
  import { TemplLexer } from "./templ-lexer.js";
40
40
  import { TemplParser } from "./templ-parser.js";
41
- import { TypeChecker } from "./typechecker/index.js";
41
+ import { TypeCheckError, TypeChecker } from "./typechecker/index.js";
42
42
  import { WASM_SUPPORTED_STDLIB } from "./typechecker/types.js";
43
43
 
44
44
  // ── Parse cache ──────────────────────────────────────────────
@@ -203,6 +203,7 @@ function finishWasm(options, merged, pkgTarget, outputDir) {
203
203
  inputSourceMap: wasmSourceMap,
204
204
  sourceMapUrl: WASM_MAP_URL,
205
205
  emitWat: Boolean(options.emitWat),
206
+ converge: Boolean(options.release),
206
207
  });
207
208
  wasm = opt.wasm;
208
209
  if (opt.wat) wat = opt.wat;
@@ -269,7 +270,20 @@ function linkWasmUnits(
269
270
  for (const b of u.bundledPackages) bundledPackages.add(b);
270
271
  programs.push(...u.programs);
271
272
  }
272
- const checker = { types };
273
+ const checker = {
274
+ types,
275
+ errors: [],
276
+ err(msg, node) {
277
+ const e = new TypeCheckError(
278
+ msg,
279
+ node,
280
+ this._currentFile,
281
+ this._currentSource,
282
+ );
283
+ this.errors.push(e);
284
+ return e;
285
+ },
286
+ };
273
287
  const lowerRes = lower(programs, checker);
274
288
  return compileWasmModule(programs, checker, lowerRes, {
275
289
  boundary: true,
@@ -809,8 +823,8 @@ export function compileFiles(files, options = {}) {
809
823
 
810
824
  const mainChunk = {
811
825
  js: mainJs,
812
- sourceFiles: files.map((f) => resolve(f)),
813
- sourcesContent: files.map((f) => readFileSync(f, "utf8")),
826
+ sourceFiles: programs.map((p) => p._path),
827
+ sourcesContent: programs.map((p) => p._source),
814
828
  mappings: emitTarget === "wasm" ? [] : codegen.getMappings(),
815
829
  };
816
830
 
package/src/dts-parser.js CHANGED
@@ -109,10 +109,9 @@ export class DtsParser {
109
109
 
110
110
  readIdent() {
111
111
  this.skip();
112
- let s = "";
113
- while (!this.eof() && /[a-zA-Z0-9_$]/.test(this.ch()))
114
- s += this.src[this.pos++];
115
- return s;
112
+ const start = this.pos;
113
+ while (!this.eof() && /[a-zA-Z0-9_$]/.test(this.ch())) this.pos++;
114
+ return this.src.slice(start, this.pos);
116
115
  }
117
116
 
118
117
  consume(ch) {
@@ -171,14 +170,14 @@ export class DtsParser {
171
170
  }
172
171
 
173
172
  _trackBracketDepth(c, depths) {
174
- const open = { "<": 0, "(": 1, "[": 2, "{": 3 };
175
- const close = { ">": 0, ")": 1, "]": 2, "}": 3 };
176
- if (c in open) {
177
- depths[open[c]]++;
173
+ const oi = "<([{".indexOf(c);
174
+ if (oi >= 0) {
175
+ depths[oi]++;
178
176
  return true;
179
177
  }
180
- if (c in close && depths[close[c]] > 0) {
181
- depths[close[c]]--;
178
+ const ci = ">)]}".indexOf(c);
179
+ if (ci >= 0 && depths[ci] > 0) {
180
+ depths[ci]--;
182
181
  return true;
183
182
  }
184
183
  return false;
@@ -392,7 +391,7 @@ export class DtsParser {
392
391
  }
393
392
  }
394
393
 
395
- _parseMemberFuncDecl(out) {
394
+ _parseFuncDecl() {
396
395
  const name = this.readIdent();
397
396
  this.skipGenerics();
398
397
  const params = this.parseParams();
@@ -403,12 +402,14 @@ export class DtsParser {
403
402
  ret = this.parseType();
404
403
  }
405
404
  this.consume(";");
406
- if (name)
407
- out[name] = {
405
+ return {
406
+ name,
407
+ val: {
408
408
  kind: "func",
409
409
  params: params.map((p) => p.type),
410
410
  returns: [ret],
411
- };
411
+ },
412
+ };
412
413
  }
413
414
 
414
415
  _parseMemberNewSig() {
@@ -422,7 +423,7 @@ export class DtsParser {
422
423
  this.consume(";");
423
424
  }
424
425
 
425
- _parseMemberTypeDecl(out) {
426
+ _parseTypeDecl() {
426
427
  const name = this.readIdent();
427
428
  this.skipGenerics();
428
429
  this.skip();
@@ -432,10 +433,10 @@ export class DtsParser {
432
433
  type = this.parseType();
433
434
  }
434
435
  this.consume(";");
435
- if (name) out[name] = type;
436
+ return { name, type };
436
437
  }
437
438
 
438
- _parseMemberClassDecl(out) {
439
+ _parseClassDecl() {
439
440
  const name = this.readIdent();
440
441
  this.skipGenerics();
441
442
  while (!this.eof() && this.ch() !== "{") this.pos++;
@@ -443,10 +444,20 @@ export class DtsParser {
443
444
  const body = this.parseBody();
444
445
  this.consume("}");
445
446
  this.consume(";");
446
- if (name) out[name] = { kind: "namespace", name, members: body };
447
+ return { name, ns: { kind: "namespace", name, members: body } };
448
+ }
449
+
450
+ _parseNamespaceDecl() {
451
+ const name = this.readIdent() || this._readStringLit();
452
+ this.skip();
453
+ this.consume("{");
454
+ const body = this.parseBody();
455
+ this.consume("}");
456
+ this.consume(";");
457
+ return { name, ns: { kind: "namespace", name, members: body } };
447
458
  }
448
459
 
449
- _parseMemberVarDecl(out) {
460
+ _parseVarDecl() {
450
461
  const name = this.readIdent();
451
462
  this.skip();
452
463
  this.consume("?");
@@ -461,7 +472,7 @@ export class DtsParser {
461
472
  this.skipTypeExpr();
462
473
  }
463
474
  this.consume(";");
464
- if (name) out[name] = type;
475
+ return { name, type };
465
476
  }
466
477
 
467
478
  _parseMember(out) {
@@ -477,28 +488,29 @@ export class DtsParser {
477
488
  }
478
489
  this.skip();
479
490
  switch (kw) {
480
- case "function":
481
- this._parseMemberFuncDecl(out);
491
+ case "function": {
492
+ const { name, val } = this._parseFuncDecl();
493
+ if (name) out[name] = val;
482
494
  break;
495
+ }
483
496
  case "new":
484
497
  this._parseMemberNewSig();
485
498
  break;
486
- case "type":
487
- this._parseMemberTypeDecl(out);
499
+ case "type": {
500
+ const { name, type } = this._parseTypeDecl();
501
+ if (name) out[name] = type;
488
502
  break;
503
+ }
489
504
  case "interface":
490
- case "class":
491
- this._parseMemberClassDecl(out);
505
+ case "class": {
506
+ const { name, ns } = this._parseClassDecl();
507
+ if (name) out[name] = ns;
492
508
  break;
509
+ }
493
510
  case "namespace":
494
511
  case "module": {
495
- const name = this.readIdent() || this._readStringLit();
496
- this.skip();
497
- this.consume("{");
498
- const body = this.parseBody();
499
- this.consume("}");
500
- this.consume(";");
501
- if (name) out[name] = { kind: "namespace", name, members: body };
512
+ const { name, ns } = this._parseNamespaceDecl();
513
+ if (name) out[name] = ns;
502
514
  break;
503
515
  }
504
516
  case "enum": {
@@ -509,9 +521,11 @@ export class DtsParser {
509
521
  }
510
522
  case "const":
511
523
  case "let":
512
- case "var":
513
- this._parseMemberVarDecl(out);
524
+ case "var": {
525
+ const { name, type } = this._parseVarDecl();
526
+ if (name) out[name] = type;
514
527
  break;
528
+ }
515
529
  default:
516
530
  this._parseMemberDefault(kw, out);
517
531
  break;
@@ -550,13 +564,15 @@ export class DtsParser {
550
564
  this.consume(";");
551
565
  }
552
566
  }
567
+
553
568
  _readStringLit() {
554
569
  this.skip();
555
570
  const c = this.ch();
556
571
  if (c !== '"' && c !== "'") return null;
557
572
  this.pos++;
558
- let s = "";
559
- while (!this.eof() && this.ch() !== c) s += this.src[this.pos++];
573
+ const start = this.pos;
574
+ while (!this.eof() && this.ch() !== c) this.pos++;
575
+ const s = this.src.slice(start, this.pos);
560
576
  this.pos++;
561
577
  return s;
562
578
  }
@@ -612,85 +628,6 @@ export class DtsParser {
612
628
  return { types, values };
613
629
  }
614
630
 
615
- _parseTopLevelTypeAlias(types) {
616
- const name = this.readIdent();
617
- this.skipGenerics();
618
- this.skip();
619
- let type = ANY;
620
- if (this.ch() === "=") {
621
- this.pos++;
622
- type = this.parseType();
623
- }
624
- this.consume(";");
625
- if (name) types.set(name, type);
626
- }
627
-
628
- _parseTopLevelClassDecl(kw, types, values) {
629
- const name = this.readIdent();
630
- this.skipGenerics();
631
- while (!this.eof() && this.ch() !== "{") this.pos++;
632
- this.consume("{");
633
- const body = this.parseBody();
634
- this.consume("}");
635
- this.consume(";");
636
- if (name) {
637
- const ns = { kind: "namespace", name, members: body };
638
- types.set(name, ns);
639
- if (kw === "class") values.set(name, ns);
640
- }
641
- }
642
-
643
- _parseTopLevelNamespaceDecl(types, values) {
644
- const name = this.readIdent() || this._readStringLit();
645
- this.skip();
646
- this.consume("{");
647
- const body = this.parseBody();
648
- this.consume("}");
649
- this.consume(";");
650
- if (name) {
651
- const ns = { kind: "namespace", name, members: body };
652
- types.set(name, ns);
653
- values.set(name, ns);
654
- }
655
- }
656
-
657
- _parseTopLevelFuncDecl(values) {
658
- const name = this.readIdent();
659
- this.skipGenerics();
660
- const params = this.parseParams();
661
- this.skip();
662
- let ret = VOID;
663
- if (this.ch() === ":") {
664
- this.pos++;
665
- ret = this.parseType();
666
- }
667
- this.consume(";");
668
- if (name)
669
- values.set(name, {
670
- kind: "func",
671
- params: params.map((p) => p.type),
672
- returns: [ret],
673
- });
674
- }
675
-
676
- _parseTopLevelVarDecl(values) {
677
- const name = this.readIdent();
678
- this.skip();
679
- this.consume("?");
680
- let type = ANY;
681
- if (this.ch() === ":") {
682
- this.pos++;
683
- type = this.parseType();
684
- }
685
- this.skip();
686
- if (this.ch() === "=") {
687
- this.pos++;
688
- this.skipTypeExpr();
689
- }
690
- this.consume(";");
691
- if (name) values.set(name, type);
692
- }
693
-
694
631
  _parseTopLevelDecl(kw, types, values) {
695
632
  switch (kw) {
696
633
  case "import":
@@ -698,17 +635,29 @@ export class DtsParser {
698
635
  this.skipTypeExpr();
699
636
  this.consume(";");
700
637
  break;
701
- case "type":
702
- this._parseTopLevelTypeAlias(types);
638
+ case "type": {
639
+ const { name, type } = this._parseTypeDecl();
640
+ if (name) types.set(name, type);
703
641
  break;
642
+ }
704
643
  case "interface":
705
- case "class":
706
- this._parseTopLevelClassDecl(kw, types, values);
644
+ case "class": {
645
+ const { name, ns } = this._parseClassDecl();
646
+ if (name) {
647
+ types.set(name, ns);
648
+ if (kw === "class") values.set(name, ns);
649
+ }
707
650
  break;
651
+ }
708
652
  case "namespace":
709
- case "module":
710
- this._parseTopLevelNamespaceDecl(types, values);
653
+ case "module": {
654
+ const { name, ns } = this._parseNamespaceDecl();
655
+ if (name) {
656
+ types.set(name, ns);
657
+ values.set(name, ns);
658
+ }
711
659
  break;
660
+ }
712
661
  case "enum": {
713
662
  const name = this.readIdent();
714
663
  this.skipBlock();
@@ -719,14 +668,18 @@ export class DtsParser {
719
668
  }
720
669
  break;
721
670
  }
722
- case "function":
723
- this._parseTopLevelFuncDecl(values);
671
+ case "function": {
672
+ const { name, val } = this._parseFuncDecl();
673
+ if (name) values.set(name, val);
724
674
  break;
675
+ }
725
676
  case "const":
726
677
  case "let":
727
- case "var":
728
- this._parseTopLevelVarDecl(values);
678
+ case "var": {
679
+ const { name, type } = this._parseVarDecl();
680
+ if (name) values.set(name, type);
729
681
  break;
682
+ }
730
683
  default:
731
684
  this.skipTypeExpr();
732
685
  this.consume(";");
package/src/index.js CHANGED
@@ -13,11 +13,6 @@
13
13
  // gofront <file.go> --tokens — dump tokens of first file (debug)
14
14
  // gofront init [dir] — scaffold a new GoFront project
15
15
 
16
- import { createRequire } from "node:module";
17
-
18
- const _require = createRequire(import.meta.url);
19
- const { version } = _require("../package.json");
20
-
21
16
  import { statSync } from "node:fs";
22
17
  import { dirname, relative, resolve } from "node:path";
23
18
  import { copyAssets } from "./asset-manager.js";
@@ -25,6 +20,7 @@ import {
25
20
  formatBuildSummary,
26
21
  formatPrepSummary,
27
22
  formatWrittenDesc,
23
+ GOFRONT_VERSION,
28
24
  handleBuild,
29
25
  handleCheck,
30
26
  handleDev,
@@ -47,7 +43,7 @@ import { colors, formatDiagnostic, log, ms, stamp } from "./colors.js";
47
43
 
48
44
  const args = process.argv.slice(2);
49
45
  if (args[0] === "--version" || args[0] === "-v") {
50
- console.log(`gofront ${version}`);
46
+ console.log(`gofront ${GOFRONT_VERSION}`);
51
47
  process.exit(0);
52
48
  }
53
49