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
|
@@ -79,6 +79,12 @@ export const statementCheckMethods = {
|
|
|
79
79
|
const name = stmt.lhs[i].name ?? stmt.lhs[i];
|
|
80
80
|
if (name === "_") continue;
|
|
81
81
|
if (scope.symbols.has(name)) stmt.lhs[i]._redecl = true;
|
|
82
|
+
if (stmt.rhs.length === stmt.lhs.length)
|
|
83
|
+
this._checkConstDefault(
|
|
84
|
+
rhsFlat[i],
|
|
85
|
+
stmt.rhs[i],
|
|
86
|
+
"variable declaration",
|
|
87
|
+
);
|
|
82
88
|
scope.defineLocal(name, defaultType(rhsFlat[i]) ?? ANY);
|
|
83
89
|
}
|
|
84
90
|
},
|
|
@@ -94,7 +100,8 @@ export const statementCheckMethods = {
|
|
|
94
100
|
const resolvedBase =
|
|
95
101
|
mapBaseType?.kind === "named" ? mapBaseType.underlying : mapBaseType;
|
|
96
102
|
if (resolvedBase?.kind !== "map") return false;
|
|
97
|
-
this.checkExpr(stmt.rhs[0].index, scope);
|
|
103
|
+
const keyType = this.checkExpr(stmt.rhs[0].index, scope);
|
|
104
|
+
this._markIfaceKey(resolvedBase, stmt.rhs[0].index, keyType);
|
|
98
105
|
stmt._commaOkMap = true;
|
|
99
106
|
stmt.rhs[0]._mapValueType = resolvedBase.value;
|
|
100
107
|
this._declareDefineVars(stmt, [resolvedBase.value, BOOL], scope);
|
|
@@ -152,7 +159,8 @@ export const statementCheckMethods = {
|
|
|
152
159
|
const resolvedBase =
|
|
153
160
|
mapBaseType?.kind === "named" ? mapBaseType.underlying : mapBaseType;
|
|
154
161
|
if (resolvedBase?.kind !== "map") return null;
|
|
155
|
-
this.checkExpr(stmt.rhs[0].index, scope);
|
|
162
|
+
const keyType = this.checkExpr(stmt.rhs[0].index, scope);
|
|
163
|
+
this._markIfaceKey(resolvedBase, stmt.rhs[0].index, keyType);
|
|
156
164
|
stmt._commaOkMap = true;
|
|
157
165
|
stmt.rhs[0]._mapValueType = resolvedBase.value;
|
|
158
166
|
return [resolvedBase.value, BOOL];
|
|
@@ -191,6 +199,16 @@ export const statementCheckMethods = {
|
|
|
191
199
|
this.resolveType(r),
|
|
192
200
|
stmt.rhs[i],
|
|
193
201
|
);
|
|
202
|
+
// A shift count is not converted to the left operand's type.
|
|
203
|
+
if (stmt.op === "<<=" || stmt.op === ">>=") {
|
|
204
|
+
if (r && !isAny(r)) this.checkShiftCount(r, stmt.rhs[i]);
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
if (
|
|
208
|
+
stmt.rhs.length === lhsTypes.length &&
|
|
209
|
+
this._checkConstOverflow(lhsTypes[i], r, stmt.rhs[i], "assignment")
|
|
210
|
+
)
|
|
211
|
+
continue;
|
|
194
212
|
if (!isAny(lhsTypes[i]) && !isAny(r)) {
|
|
195
213
|
this._skipIfaceMark = true;
|
|
196
214
|
this.assertAssignable(lhsTypes[i], r, stmt.lhs[i]);
|
|
@@ -246,9 +264,34 @@ export const statementCheckMethods = {
|
|
|
246
264
|
if (!isVoid(returnType) && types.length > 0) {
|
|
247
265
|
const expected =
|
|
248
266
|
returnType.kind === "tuple" ? returnType.types : [returnType];
|
|
267
|
+
// `return f()` forwards every result of a multi-value call.
|
|
268
|
+
if (types.length === 1 && types[0]?.kind === "tuple") {
|
|
269
|
+
const forwarded = types[0].types;
|
|
270
|
+
if (forwarded.length !== expected.length) {
|
|
271
|
+
this.err(
|
|
272
|
+
`return count mismatch: have ${forwarded.length} values, want ${expected.length}`,
|
|
273
|
+
stmt,
|
|
274
|
+
);
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
for (let i = 0; i < expected.length; i++) {
|
|
278
|
+
this.assertAssignable(
|
|
279
|
+
expected[i],
|
|
280
|
+
forwarded[i],
|
|
281
|
+
stmt.values[0],
|
|
282
|
+
"return statement",
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
249
287
|
for (let i = 0; i < expected.length; i++) {
|
|
250
288
|
if (types[i])
|
|
251
|
-
this.assertAssignable(
|
|
289
|
+
this.assertAssignable(
|
|
290
|
+
expected[i],
|
|
291
|
+
types[i],
|
|
292
|
+
stmt.values[i] ?? stmt,
|
|
293
|
+
"return statement",
|
|
294
|
+
);
|
|
252
295
|
}
|
|
253
296
|
}
|
|
254
297
|
},
|
|
@@ -288,7 +331,14 @@ export const statementCheckMethods = {
|
|
|
288
331
|
}
|
|
289
332
|
},
|
|
290
333
|
|
|
291
|
-
|
|
334
|
+
// `checkBody(bodyScope)` checks the loop body; templ `for` loops pass one
|
|
335
|
+
// that checks their HTML nodes in place of the header's empty block.
|
|
336
|
+
_checkForStmt(
|
|
337
|
+
stmt,
|
|
338
|
+
scope,
|
|
339
|
+
returnType,
|
|
340
|
+
checkBody = (s) => this.checkBlock(stmt.body, s, returnType),
|
|
341
|
+
) {
|
|
292
342
|
const inner = new Scope(scope);
|
|
293
343
|
let iterInfo = null;
|
|
294
344
|
if (stmt.init?.rhs?.[0]?.kind === "RangeExpr") {
|
|
@@ -299,7 +349,7 @@ export const statementCheckMethods = {
|
|
|
299
349
|
if (stmt.post) this.checkStmt(stmt.post, inner, returnType);
|
|
300
350
|
this._loopDepth++;
|
|
301
351
|
const bodyScope = new Scope(inner);
|
|
302
|
-
|
|
352
|
+
checkBody(bodyScope);
|
|
303
353
|
this._reportUnused(bodyScope, stmt);
|
|
304
354
|
this._loopDepth--;
|
|
305
355
|
this._reportUnused(inner, stmt);
|
|
@@ -320,6 +370,19 @@ export const statementCheckMethods = {
|
|
|
320
370
|
this._reportUnused(inner, stmt);
|
|
321
371
|
},
|
|
322
372
|
|
|
373
|
+
// A case naming an interface (literal or declared) records the resolved
|
|
374
|
+
// type so backends test its method set.
|
|
375
|
+
_markInterfaceCaseType(t, scope) {
|
|
376
|
+
if (!t || (t.kind !== "InterfaceType" && t.kind !== "TypeName")) return;
|
|
377
|
+
if (t.kind === "TypeName" && (t.name === "nil" || t.name === "error"))
|
|
378
|
+
return;
|
|
379
|
+
const resolved = this.resolveTypeNode(t, scope);
|
|
380
|
+
const u = this.resolveType(
|
|
381
|
+
resolved?.kind === "named" ? resolved.underlying : resolved,
|
|
382
|
+
);
|
|
383
|
+
if (u?.kind === "interface") t._type = resolved;
|
|
384
|
+
},
|
|
385
|
+
|
|
323
386
|
_checkTypeSwitchStmt(stmt, scope, returnType) {
|
|
324
387
|
const inner = new Scope(scope);
|
|
325
388
|
this.checkExpr(stmt.expr, inner);
|
|
@@ -327,10 +390,23 @@ export const statementCheckMethods = {
|
|
|
327
390
|
this._typeSwitchDepth++;
|
|
328
391
|
for (const c of stmt.cases) {
|
|
329
392
|
const caseScope = new Scope(inner);
|
|
393
|
+
// Resolve instantiated generic case types so backends can tell
|
|
394
|
+
// `*Stack[int]` from `*Stack[string]`.
|
|
395
|
+
for (const t of c.types ?? []) {
|
|
396
|
+
const base = t?.kind === "PointerType" ? t.base : t;
|
|
397
|
+
if (base?.kind === "GenericTypeName") this.resolveTypeNode(t, inner);
|
|
398
|
+
this._markInterfaceCaseType(t, inner);
|
|
399
|
+
}
|
|
330
400
|
if (stmt.assign) {
|
|
331
|
-
// Bind the variable to the single case type, or any for multi/default
|
|
332
|
-
|
|
333
|
-
|
|
401
|
+
// Bind the variable to the single case type, or any for multi/default.
|
|
402
|
+
// `case nil` binds the switch expression's own type, as in Go.
|
|
403
|
+
const only = c.types?.length === 1 ? c.types[0] : null;
|
|
404
|
+
const isNilCase = only?.kind === "TypeName" && only.name === "nil";
|
|
405
|
+
const bindType = isNilCase
|
|
406
|
+
? (stmt.expr._type ?? ANY)
|
|
407
|
+
: only
|
|
408
|
+
? this.resolveTypeNode(only, inner)
|
|
409
|
+
: ANY;
|
|
334
410
|
caseScope.defineLocal(stmt.assign, bindType);
|
|
335
411
|
// The capture variable is always considered used — it's the whole
|
|
336
412
|
// point of the switch-with-assign form. Each case body uses its own
|
|
@@ -346,7 +422,12 @@ export const statementCheckMethods = {
|
|
|
346
422
|
|
|
347
423
|
_checkBranchStmt(stmt) {
|
|
348
424
|
const kw = stmt.keyword;
|
|
349
|
-
if (kw === "
|
|
425
|
+
if (kw === "goto")
|
|
426
|
+
this.err(
|
|
427
|
+
"goto is not supported; restructure with labeled break/continue",
|
|
428
|
+
stmt,
|
|
429
|
+
);
|
|
430
|
+
else if (kw === "continue" && this._loopDepth === 0)
|
|
350
431
|
this.err("continue statement outside for loop", stmt);
|
|
351
432
|
else if (kw === "break" && this._loopDepth === 0 && this._switchDepth === 0)
|
|
352
433
|
this.err("break statement outside for loop or switch", stmt);
|