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.
- package/package.json +1 -1
- package/src/backend/js/expressions.js +238 -109
- package/src/backend/js/index.js +38 -1
- package/src/backend/js/runtime.js +953 -53
- package/src/backend/js/statements.js +55 -67
- package/src/backend/js/stdlib/base64.js +12 -0
- package/src/backend/js/stdlib/binary.js +102 -0
- package/src/backend/js/stdlib/bits.js +15 -1
- package/src/backend/js/stdlib/builder.js +28 -9
- package/src/backend/js/stdlib/bytes.js +75 -18
- package/src/backend/js/stdlib/errors.js +20 -1
- package/src/backend/js/stdlib/fmt.js +70 -13
- package/src/backend/js/stdlib/hex.js +17 -0
- package/src/backend/js/stdlib/html.js +1 -1
- package/src/backend/js/stdlib/index.js +16 -0
- package/src/backend/js/stdlib/io.js +105 -3
- package/src/backend/js/stdlib/math.js +13 -1
- package/src/backend/js/stdlib/path.js +18 -4
- package/src/backend/js/stdlib/rand.js +10 -5
- package/src/backend/js/stdlib/sha256.js +12 -0
- package/src/backend/js/stdlib/slices.js +52 -26
- package/src/backend/js/stdlib/strconv.js +21 -5
- package/src/backend/js/stdlib/strings.js +148 -15
- package/src/backend/js/stdlib/sync.js +13 -0
- package/src/backend/js/stdlib/time.js +90 -19
- package/src/backend/js/stdlib/unicode.js +2 -2
- package/src/backend/wasm/boundary.js +1207 -41
- package/src/backend/wasm/const-fold.js +205 -0
- package/src/backend/wasm/emit-builtins.js +203 -76
- package/src/backend/wasm/emit-exprs.js +464 -276
- package/src/backend/wasm/emit-maps.js +144 -8
- package/src/backend/wasm/emit-stdlib.js +12 -3005
- package/src/backend/wasm/emit-stmts.js +264 -270
- package/src/backend/wasm/emit.js +115 -87
- package/src/backend/wasm/encode.js +55 -29
- package/src/backend/wasm/index.js +1001 -32
- package/src/backend/wasm/optimize.js +13 -4
- package/src/backend/wasm/stdlib/bytes.js +5039 -0
- package/src/backend/wasm/stdlib/core.js +8903 -0
- package/src/backend/wasm/stdlib/index.js +40 -0
- package/src/backend/wasm/stdlib/io.js +2161 -0
- package/src/backend/wasm/stdlib/packages.js +2400 -0
- package/src/backend/wasm/stdlib/pure.js +720 -0
- package/src/backend/wasm/stdlib/time.js +1200 -0
- package/src/backend/wasm/types.js +153 -1
- package/src/cli-core.js +1 -1
- package/src/compiler.js +18 -4
- package/src/dts-parser.js +79 -126
- package/src/index.js +2 -6
- package/src/lexer.js +80 -29
- package/src/lower/boxing.js +1 -2
- package/src/lower/captures.js +2 -6
- package/src/lower/ownership.js +30 -9
- package/src/minifier.js +20 -68
- package/src/parser/declarations.js +3 -6
- package/src/parser/expressions.js +3 -8
- package/src/parser/index.js +18 -3
- package/src/parser/statements.js +25 -38
- package/src/parser/types.js +1 -2
- package/src/resolver.js +2 -27
- package/src/templ-lexer.js +29 -63
- package/src/templ-parser.js +22 -45
- package/src/typechecker/assignability.js +81 -13
- package/src/typechecker/expressions.js +102 -2
- package/src/typechecker/resolve.js +36 -6
- package/src/typechecker/stdlib/core.js +280 -89
- package/src/typechecker/stdlib/extended.js +453 -1
- 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 = {
|
|
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:
|
|
813
|
-
sourcesContent:
|
|
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
|
-
|
|
113
|
-
while (!this.eof() && /[a-zA-Z0-9_$]/.test(this.ch()))
|
|
114
|
-
|
|
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
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
depths[open[c]]++;
|
|
173
|
+
const oi = "<([{".indexOf(c);
|
|
174
|
+
if (oi >= 0) {
|
|
175
|
+
depths[oi]++;
|
|
178
176
|
return true;
|
|
179
177
|
}
|
|
180
|
-
|
|
181
|
-
|
|
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
|
-
|
|
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
|
-
|
|
407
|
-
|
|
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
|
-
|
|
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
|
-
|
|
436
|
+
return { name, type };
|
|
436
437
|
}
|
|
437
438
|
|
|
438
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
496
|
-
|
|
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.
|
|
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
|
-
|
|
559
|
-
while (!this.eof() && this.ch() !== c)
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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 ${
|
|
46
|
+
console.log(`gofront ${GOFRONT_VERSION}`);
|
|
51
47
|
process.exit(0);
|
|
52
48
|
}
|
|
53
49
|
|