gofront 1.5.1 → 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/README.md +174 -466
- package/package.json +16 -20
- package/src/backend/js/expressions.js +288 -128
- package/src/backend/js/index.js +138 -56
- package/src/backend/js/runtime.js +1055 -53
- package/src/backend/js/source-map.js +32 -0
- package/src/backend/js/statements.js +151 -83
- 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 +22 -3
- package/src/backend/js/stdlib/fmt.js +95 -20
- 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 +19 -0
- package/src/backend/js/stdlib/io.js +105 -3
- package/src/backend/js/stdlib/maps.js +1 -1
- package/src/backend/js/stdlib/math.js +13 -1
- package/src/backend/js/stdlib/path.js +20 -6
- package/src/backend/js/stdlib/rand.js +10 -5
- package/src/backend/js/stdlib/sha256.js +12 -0
- package/src/backend/js/stdlib/shared.js +17 -0
- package/src/backend/js/stdlib/slices.js +53 -27
- package/src/backend/js/stdlib/sort.js +1 -1
- package/src/backend/js/stdlib/strconv.js +52 -11
- package/src/backend/js/stdlib/strings.js +152 -16
- package/src/backend/js/stdlib/sync.js +13 -0
- package/src/backend/js/stdlib/testing.js +2 -2
- package/src/backend/js/stdlib/time.js +93 -22
- package/src/backend/js/stdlib/unicode.js +2 -2
- package/src/backend/js/templ.js +1 -1
- package/src/backend/wasm/boundary.js +1677 -58
- package/src/backend/wasm/const-fold.js +205 -0
- package/src/backend/wasm/emit-builtins.js +1230 -0
- package/src/backend/wasm/emit-exprs.js +2096 -0
- package/src/backend/wasm/emit-maps.js +1999 -0
- package/src/backend/wasm/emit-shared.js +519 -0
- package/src/backend/wasm/emit-stdlib.js +13 -0
- package/src/backend/wasm/emit-stmts.js +2466 -0
- package/src/backend/wasm/emit.js +656 -5031
- package/src/backend/wasm/encode.js +259 -85
- package/src/backend/wasm/glue.js +19 -5
- package/src/backend/wasm/index.js +2432 -86
- package/src/backend/wasm/monomorph.js +711 -0
- package/src/backend/wasm/optimize.js +236 -0
- 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 +312 -36
- package/src/backend/wasm/wat.js +49 -2
- package/src/cli-core.js +276 -73
- package/src/compiler.js +162 -25
- package/src/dts-parser.js +79 -126
- package/src/index.js +88 -121
- package/src/lexer.js +80 -29
- package/src/lower/boxing.js +4 -6
- package/src/lower/captures.js +12 -23
- package/src/lower/escape.js +4 -9
- package/src/lower/functions.js +277 -5
- package/src/lower/globals.js +7 -15
- package/src/lower/index.js +5 -2
- package/src/lower/ownership.js +35 -19
- package/src/lower/range.js +2 -5
- package/src/lower/walk.js +25 -0
- 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 +3 -27
- package/src/templ-lexer.js +29 -63
- package/src/templ-parser.js +22 -45
- package/src/test-runner.js +20 -0
- package/src/typechecker/assignability.js +123 -14
- package/src/typechecker/expressions.js +244 -4
- package/src/typechecker/index.js +27 -1
- package/src/typechecker/resolve.js +71 -12
- package/src/typechecker/statements.js +0 -7
- package/src/typechecker/stdlib/core.js +292 -103
- package/src/typechecker/stdlib/extended.js +471 -4
- package/src/typechecker/stdlib/shared.js +53 -0
- package/src/typechecker/stdlib.js +2 -0
- package/src/typechecker/types.js +545 -8
- package/src/vendor.js +2 -2
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import {
|
|
5
5
|
ANY,
|
|
6
6
|
BASIC_TYPES,
|
|
7
|
+
COMPARABLE,
|
|
7
8
|
defaultType,
|
|
8
9
|
isAny,
|
|
9
10
|
isTypedArraySlice,
|
|
@@ -12,6 +13,7 @@ import {
|
|
|
12
13
|
typedArrayConstructorForElem,
|
|
13
14
|
typeStr,
|
|
14
15
|
VOID,
|
|
16
|
+
WASM_STDLIB_MEMBERS,
|
|
15
17
|
} from "./types.js";
|
|
16
18
|
|
|
17
19
|
/** @typedef {import('./index.js').TypeChecker} TypeChecker */
|
|
@@ -81,8 +83,7 @@ export const resolveMethods = {
|
|
|
81
83
|
switch (node.kind) {
|
|
82
84
|
case "TypeName": {
|
|
83
85
|
if (BASIC_TYPES[node.name]) return BASIC_TYPES[node.name];
|
|
84
|
-
if (node.name === "comparable")
|
|
85
|
-
return { kind: "basic", name: "comparable" };
|
|
86
|
+
if (node.name === "comparable") return COMPARABLE;
|
|
86
87
|
if (scope) {
|
|
87
88
|
const fromScope = scope.lookup(node.name);
|
|
88
89
|
if (fromScope?.kind === "typeParam") return fromScope;
|
|
@@ -96,16 +97,29 @@ export const resolveMethods = {
|
|
|
96
97
|
}
|
|
97
98
|
return this.err(`Unknown type '${node.name}'`, node);
|
|
98
99
|
}
|
|
99
|
-
case "GenericTypeName":
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
100
|
+
case "GenericTypeName":
|
|
101
|
+
case "InstantiationExpr":
|
|
102
|
+
case "IndexExpr": {
|
|
103
|
+
const name =
|
|
104
|
+
node.name ?? (node.expr?.kind === "Ident" ? node.expr.name : null);
|
|
105
|
+
const typeArgs = node.typeArgs ?? (node.index ? [node.index] : []);
|
|
106
|
+
const base = name
|
|
107
|
+
? this.types.get(name)
|
|
108
|
+
: node.expr
|
|
109
|
+
? this.resolveTypeNode(node.expr, scope)
|
|
110
|
+
: null;
|
|
111
|
+
if (!base) return this.err(`Unknown type '${name ?? "?"}'`, node);
|
|
112
|
+
if (base.kind === "named" && base._generic) {
|
|
113
|
+
const res = this.instantiateGenericType(
|
|
104
114
|
base._generic,
|
|
105
|
-
|
|
115
|
+
typeArgs,
|
|
106
116
|
scope,
|
|
107
117
|
);
|
|
108
|
-
|
|
118
|
+
node._typeArgs = res.typeArgs;
|
|
119
|
+
node._genericType = base;
|
|
120
|
+
return res;
|
|
121
|
+
}
|
|
122
|
+
return this.err(`Type '${name ?? "?"}' is not generic`, node);
|
|
109
123
|
}
|
|
110
124
|
case "TypeParam": {
|
|
111
125
|
const constraint = node.constraint
|
|
@@ -266,12 +280,15 @@ export const resolveMethods = {
|
|
|
266
280
|
const typeArgs = typeArgNodes.map((n) => this.resolveTypeNode(n, scope));
|
|
267
281
|
for (let i = 0; i < generic.typeParams.length; i++)
|
|
268
282
|
map.set(generic.typeParams[i].name, typeArgs[i] ?? ANY);
|
|
283
|
+
// Resolve the declaration with its type params in scope (as typeParams,
|
|
284
|
+
// never as value symbols), then substitute the concrete arguments.
|
|
269
285
|
const typeScope = new Scope(this.globals);
|
|
270
|
-
for (const
|
|
286
|
+
for (const tp of generic.typeParams) typeScope.define(tp.name, tp);
|
|
271
287
|
const underlying = this.resolveTypeNode(generic.declNode.type, typeScope);
|
|
272
288
|
const instantiated = this.substituteType(underlying, map);
|
|
273
289
|
if (instantiated.kind === "struct") {
|
|
274
290
|
instantiated.name = generic.declNode.name;
|
|
291
|
+
instantiated.typeArgs = typeArgs;
|
|
275
292
|
if (!instantiated.methods) instantiated.methods = new Map();
|
|
276
293
|
if (generic.methods) {
|
|
277
294
|
for (const [mName, mType] of generic.methods)
|
|
@@ -281,7 +298,9 @@ export const resolveMethods = {
|
|
|
281
298
|
return {
|
|
282
299
|
kind: "named",
|
|
283
300
|
name: generic.declNode.name,
|
|
301
|
+
typeArgs,
|
|
284
302
|
underlying: instantiated,
|
|
303
|
+
methods: instantiated.methods,
|
|
285
304
|
};
|
|
286
305
|
},
|
|
287
306
|
|
|
@@ -372,6 +391,14 @@ export const resolveMethods = {
|
|
|
372
391
|
const found = this.types.get(t.alias);
|
|
373
392
|
if (found) return found;
|
|
374
393
|
}
|
|
394
|
+
if (
|
|
395
|
+
t.kind === "named" &&
|
|
396
|
+
(!t.typeArgs || t.typeArgs.length === 0) &&
|
|
397
|
+
(!t.underlying || !t.methods)
|
|
398
|
+
) {
|
|
399
|
+
const found = this.types.get(t.name);
|
|
400
|
+
if (found) return found;
|
|
401
|
+
}
|
|
375
402
|
return t;
|
|
376
403
|
},
|
|
377
404
|
|
|
@@ -406,6 +433,9 @@ export const resolveMethods = {
|
|
|
406
433
|
return this._fieldTypeInterface(base, baseType, field, node);
|
|
407
434
|
case "namespace":
|
|
408
435
|
return this._fieldTypeNamespace(base, field, node);
|
|
436
|
+
case "shared":
|
|
437
|
+
if (base.methods?.has(field)) return base.methods.get(field);
|
|
438
|
+
return this.err(`No method '${field}' on ${typeStr(baseType)}`, node);
|
|
409
439
|
case "slice":
|
|
410
440
|
if (isTypedArraySlice(base)) {
|
|
411
441
|
return this._fieldTypeTypedArraySlice(base, baseType, field, node);
|
|
@@ -420,7 +450,19 @@ export const resolveMethods = {
|
|
|
420
450
|
},
|
|
421
451
|
|
|
422
452
|
_fieldTypeStruct(base, baseType, field, node) {
|
|
423
|
-
if (base.fields?.has(field))
|
|
453
|
+
if (base.fields?.has(field)) {
|
|
454
|
+
if (
|
|
455
|
+
field.startsWith("_") &&
|
|
456
|
+
(baseType?.name?.startsWith("strings.") ||
|
|
457
|
+
baseType?.name?.startsWith("bytes."))
|
|
458
|
+
) {
|
|
459
|
+
return this.err(
|
|
460
|
+
`Cannot refer to unexported field '${field}' on ${typeStr(baseType)}`,
|
|
461
|
+
node,
|
|
462
|
+
);
|
|
463
|
+
}
|
|
464
|
+
return base.fields.get(field);
|
|
465
|
+
}
|
|
424
466
|
if (base.methods?.has(field)) return base.methods.get(field);
|
|
425
467
|
return this.err(`No field '${field}' on ${typeStr(baseType)}`, node);
|
|
426
468
|
},
|
|
@@ -475,7 +517,24 @@ export const resolveMethods = {
|
|
|
475
517
|
`cannot refer to unexported name ${base.name}.${field}`,
|
|
476
518
|
node,
|
|
477
519
|
);
|
|
478
|
-
if (field in base.members)
|
|
520
|
+
if (field in base.members) {
|
|
521
|
+
if (
|
|
522
|
+
(this.target === "wasm" || this.target === "both") &&
|
|
523
|
+
WASM_STDLIB_MEMBERS.has(base.name)
|
|
524
|
+
) {
|
|
525
|
+
const allowed = WASM_STDLIB_MEMBERS.get(base.name);
|
|
526
|
+
if (allowed && !allowed.has(field)) {
|
|
527
|
+
const name = `${base.name}.${field}`;
|
|
528
|
+
this.recordBlocker("unsupported stdlib member", name);
|
|
529
|
+
return this.err(
|
|
530
|
+
`'${name}' is not yet available in wasm packages`,
|
|
531
|
+
node,
|
|
532
|
+
"move this call to a JS package, or use a supported alternative",
|
|
533
|
+
);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
return base.members[field];
|
|
537
|
+
}
|
|
479
538
|
return this.err(`No member '${field}' in namespace ${base.name}`, node);
|
|
480
539
|
},
|
|
481
540
|
};
|
|
@@ -43,13 +43,6 @@ export const statementCheckMethods = {
|
|
|
43
43
|
this.checkExpr(stmt.expr, scope);
|
|
44
44
|
break;
|
|
45
45
|
case "DeferStmt":
|
|
46
|
-
if (this.target === "wasm" || this.target === "both") {
|
|
47
|
-
this.recordBlocker("defer statement");
|
|
48
|
-
this.err(
|
|
49
|
-
"'defer' is not yet supported in wasm packages (planned)",
|
|
50
|
-
stmt,
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
46
|
if (stmt.call.kind !== "CallExpr")
|
|
54
47
|
this.err("defer requires a function call", stmt.call);
|
|
55
48
|
this.checkExpr(stmt.call, scope);
|