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/compiler.js
CHANGED
|
@@ -19,26 +19,40 @@
|
|
|
19
19
|
|
|
20
20
|
import { readdirSync, readFileSync, statSync } from "node:fs";
|
|
21
21
|
import { basename, dirname, join, relative, resolve, sep } from "node:path";
|
|
22
|
-
import {
|
|
23
|
-
buildSourceMap,
|
|
24
|
-
buildWasmSourceMap,
|
|
25
|
-
CodeGen,
|
|
26
|
-
} from "./backend/js/index.js";
|
|
22
|
+
import { CodeGen } from "./backend/js/index.js";
|
|
27
23
|
import { compileWasmModule, optimizeWasm } from "./backend/wasm/index.js";
|
|
28
|
-
import { log } from "./colors.js";
|
|
24
|
+
import { log } from "./cli/colors.js";
|
|
29
25
|
import { parseDts } from "./dts-parser.js";
|
|
30
|
-
import { Lexer } from "./lexer.js";
|
|
26
|
+
import { Lexer } from "./lexer/lexer.js";
|
|
27
|
+
import { TemplLexer } from "./lexer/templ-lexer.js";
|
|
28
|
+
import {
|
|
29
|
+
attachSourceMap,
|
|
30
|
+
buildWasmMap,
|
|
31
|
+
mergeCompilationChunks,
|
|
32
|
+
WASM_MAP_URL,
|
|
33
|
+
} from "./link/sourcemap.js";
|
|
34
|
+
import {
|
|
35
|
+
checkJsonCodecs,
|
|
36
|
+
finishStdlibJs,
|
|
37
|
+
importStdlibPackages,
|
|
38
|
+
} from "./link/stdlib.js";
|
|
39
|
+
import {
|
|
40
|
+
linkIntoBundle,
|
|
41
|
+
registerPackageUnit,
|
|
42
|
+
registerWasmUnit,
|
|
43
|
+
wasmMarker,
|
|
44
|
+
} from "./link/wasm.js";
|
|
31
45
|
import { lower } from "./lower/index.js";
|
|
32
46
|
import { Parser } from "./parser/index.js";
|
|
47
|
+
import { TemplParser } from "./parser/templ.js";
|
|
33
48
|
import {
|
|
34
49
|
isBuiltinPackage,
|
|
35
50
|
isLocalPath,
|
|
36
51
|
resolveAll,
|
|
37
52
|
resolveGwDir,
|
|
53
|
+
resolveStdlibSource,
|
|
38
54
|
} from "./resolver.js";
|
|
39
|
-
import {
|
|
40
|
-
import { TemplParser } from "./templ-parser.js";
|
|
41
|
-
import { TypeCheckError, TypeChecker } from "./typechecker/index.js";
|
|
55
|
+
import { EXCLUDED_STDLIB_PACKAGES, TypeChecker } from "./typechecker/index.js";
|
|
42
56
|
import { WASM_SUPPORTED_STDLIB } from "./typechecker/types.js";
|
|
43
57
|
|
|
44
58
|
// ── Parse cache ──────────────────────────────────────────────
|
|
@@ -89,98 +103,6 @@ export function gwFilesIn(dir, { includeTests = false } = {}) {
|
|
|
89
103
|
.map((f) => join(dir, f));
|
|
90
104
|
}
|
|
91
105
|
|
|
92
|
-
function normalizeChunk(c) {
|
|
93
|
-
if (typeof c === "string") {
|
|
94
|
-
return { js: c, sourceFiles: [], sourcesContent: [], mappings: [] };
|
|
95
|
-
}
|
|
96
|
-
return c;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
function appendChunkMappings(dest, mappings, localToUnifiedIdx, lineOffset) {
|
|
100
|
-
if (!mappings) return;
|
|
101
|
-
for (const m of mappings) {
|
|
102
|
-
dest.push({
|
|
103
|
-
genLine: m.genLine + lineOffset,
|
|
104
|
-
srcLine: m.srcLine,
|
|
105
|
-
srcFileIdx: localToUnifiedIdx[m.srcFileIdx ?? 0] ?? 0,
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
function mergeCompilationChunks(chunks) {
|
|
111
|
-
const activeChunks = chunks
|
|
112
|
-
.filter(Boolean)
|
|
113
|
-
.map(normalizeChunk)
|
|
114
|
-
.filter((c) => c.js.length > 0);
|
|
115
|
-
|
|
116
|
-
if (activeChunks.length === 0) {
|
|
117
|
-
return { js: "", sourceFiles: [], sourcesContent: [], mappings: [] };
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
const unifiedSources = [];
|
|
121
|
-
const unifiedSourcesContent = [];
|
|
122
|
-
const fileIdxMap = new Map();
|
|
123
|
-
|
|
124
|
-
function getOrAddFile(filePath, content) {
|
|
125
|
-
const key = resolve(filePath);
|
|
126
|
-
let idx = fileIdxMap.get(key);
|
|
127
|
-
if (idx === undefined) {
|
|
128
|
-
idx = unifiedSources.length;
|
|
129
|
-
fileIdxMap.set(key, idx);
|
|
130
|
-
unifiedSources.push(key);
|
|
131
|
-
unifiedSourcesContent.push(content);
|
|
132
|
-
}
|
|
133
|
-
return idx;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
const combinedJsParts = [];
|
|
137
|
-
const mergedMappings = [];
|
|
138
|
-
let currentLineOffset = 0;
|
|
139
|
-
|
|
140
|
-
for (const chunk of activeChunks) {
|
|
141
|
-
combinedJsParts.push(chunk.js);
|
|
142
|
-
const localToUnifiedIdx = (chunk.sourceFiles ?? []).map((file, i) =>
|
|
143
|
-
getOrAddFile(file, chunk.sourcesContent?.[i] ?? ""),
|
|
144
|
-
);
|
|
145
|
-
appendChunkMappings(
|
|
146
|
-
mergedMappings,
|
|
147
|
-
chunk.mappings,
|
|
148
|
-
localToUnifiedIdx,
|
|
149
|
-
currentLineOffset,
|
|
150
|
-
);
|
|
151
|
-
currentLineOffset += chunk.js.split("\n").length;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
return {
|
|
155
|
-
js: combinedJsParts.join("\n"),
|
|
156
|
-
sourceFiles: unifiedSources,
|
|
157
|
-
sourcesContent: unifiedSourcesContent,
|
|
158
|
-
mappings: mergedMappings,
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
function attachSourceMap(merged, outputDir) {
|
|
163
|
-
const relativeSources = merged.sourceFiles.map((f) => relative(outputDir, f));
|
|
164
|
-
const mapJson = buildSourceMap(
|
|
165
|
-
relativeSources,
|
|
166
|
-
merged.mappings,
|
|
167
|
-
merged.sourcesContent,
|
|
168
|
-
);
|
|
169
|
-
const b64 = Buffer.from(mapJson).toString("base64");
|
|
170
|
-
merged.js += `\n//# sourceMappingURL=data:application/json;base64,${b64}`;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const WASM_MAP_URL = "app.wasm.map";
|
|
174
|
-
|
|
175
|
-
// Function-level `app.wasm.map` (sources relative to the output dir).
|
|
176
|
-
function buildWasmMap(info, outputDir) {
|
|
177
|
-
if (!info || info.mappings.length === 0) return null;
|
|
178
|
-
return buildWasmSourceMap(
|
|
179
|
-
info.sources.map((f) => relative(outputDir, f)),
|
|
180
|
-
info.mappings,
|
|
181
|
-
);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
106
|
// Shared tail of compileFiles / compileSingleFile: link `app.wasm`, run
|
|
185
107
|
// wasm-opt when requested and produce the wasm source map.
|
|
186
108
|
function finishWasm(options, merged, pkgTarget, outputDir) {
|
|
@@ -213,171 +135,16 @@ function finishWasm(options, merged, pkgTarget, outputDir) {
|
|
|
213
135
|
return { wasm, wat, wasmOptInfo, wasmSourceMap };
|
|
214
136
|
}
|
|
215
137
|
|
|
216
|
-
//
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
// shared `options.wasmUnits` array. The root compile links all units into a
|
|
220
|
-
// single `app.wasm` and splices the generated JS facade into the bundle where
|
|
221
|
-
// the first wasm package's JS would have been.
|
|
222
|
-
|
|
223
|
-
const WASM_MARKER_RE = /^\/\*__GOFRONT_WASM_UNIT:[^*]*\*\/$/m;
|
|
224
|
-
|
|
225
|
-
function wasmMarker(pkgName) {
|
|
226
|
-
return `/*__GOFRONT_WASM_UNIT:${pkgName}*/`;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
function registerWasmUnit(options, unit) {
|
|
230
|
-
const units = options.wasmUnits;
|
|
231
|
-
if (!units) return;
|
|
232
|
-
if (units.some((u) => u.key === unit.key)) return;
|
|
233
|
-
units.push(unit);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
// Registers a `wasm`/`both` package as a link unit and returns the target the
|
|
237
|
-
// package's own code is emitted for. `options.wasmTests` runs a `both`
|
|
238
|
-
// package's tests through the wasm backend (the package is then treated as
|
|
239
|
-
// `wasm` for linking so its test functions are exposed by the facade).
|
|
240
|
-
function registerPackageUnit(options, unit) {
|
|
241
|
-
const { pkgTarget, programs } = unit;
|
|
242
|
-
if (pkgTarget !== "wasm" && pkgTarget !== "both") return pkgTarget;
|
|
243
|
-
const emitTarget =
|
|
244
|
-
options.wasmTests && options.isTest && pkgTarget === "both"
|
|
245
|
-
? "wasm"
|
|
246
|
-
: pkgTarget;
|
|
247
|
-
registerWasmUnit(options, {
|
|
248
|
-
...unit,
|
|
249
|
-
target: emitTarget,
|
|
250
|
-
programs:
|
|
251
|
-
emitTarget === pkgTarget
|
|
252
|
-
? programs
|
|
253
|
-
: programs.map((p) => ({ ...p, target: emitTarget })),
|
|
254
|
-
});
|
|
255
|
-
return emitTarget;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
function linkWasmUnits(
|
|
259
|
-
units,
|
|
260
|
-
{ emitWat = false, rootTarget = "js", sourceMappingURL = null } = {},
|
|
261
|
-
) {
|
|
262
|
-
if (!units.some((u) => u.target === "wasm")) return null;
|
|
263
|
-
checkLinkCollisions(units);
|
|
264
|
-
|
|
265
|
-
const types = new Map();
|
|
266
|
-
const bundledPackages = new Set();
|
|
267
|
-
const programs = [];
|
|
268
|
-
for (const u of units) {
|
|
269
|
-
for (const [k, v] of u.types) types.set(k, v);
|
|
270
|
-
for (const b of u.bundledPackages) bundledPackages.add(b);
|
|
271
|
-
programs.push(...u.programs);
|
|
272
|
-
}
|
|
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
|
-
};
|
|
287
|
-
const lowerRes = lower(programs, checker);
|
|
288
|
-
return compileWasmModule(programs, checker, lowerRes, {
|
|
289
|
-
boundary: true,
|
|
290
|
-
bundledPackages,
|
|
291
|
-
emitWat,
|
|
292
|
-
callMain: rootTarget === "wasm",
|
|
293
|
-
sourceMappingURL,
|
|
294
|
-
});
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// The linked module is one flat namespace (like the JS bundle), so a top-level
|
|
298
|
-
// name declared by two different packages would silently resolve to whichever
|
|
299
|
-
// was emitted last. Reject it up front.
|
|
300
|
-
function topLevelDeclNames(decl) {
|
|
301
|
-
switch (decl.kind) {
|
|
302
|
-
case "FuncDecl":
|
|
303
|
-
return [decl.name];
|
|
304
|
-
case "MethodDecl":
|
|
305
|
-
return [`${decl.recvType?.name ?? "?"}.${decl.name}`];
|
|
306
|
-
case "TypeDecl":
|
|
307
|
-
return [decl.name];
|
|
308
|
-
case "VarDecl":
|
|
309
|
-
case "ConstDecl":
|
|
310
|
-
return (decl.decls ?? []).flatMap((spec) => spec.names ?? []);
|
|
311
|
-
default:
|
|
312
|
-
return [];
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
function checkLinkCollisions(units) {
|
|
317
|
-
const owner = new Map(); // name -> pkgName
|
|
318
|
-
const errors = [];
|
|
319
|
-
for (const u of units) {
|
|
320
|
-
for (const p of u.programs) {
|
|
321
|
-
for (const d of p.decls ?? []) {
|
|
322
|
-
for (const name of topLevelDeclNames(d)) {
|
|
323
|
-
if (name === "_") continue;
|
|
324
|
-
const prev = owner.get(name);
|
|
325
|
-
if (prev === undefined) owner.set(name, u.pkgName);
|
|
326
|
-
else if (prev !== u.pkgName)
|
|
327
|
-
errors.push(
|
|
328
|
-
`cannot link wasm packages: '${name}' is declared in both '${prev}' and '${u.pkgName}' (linked wasm packages share one namespace)`,
|
|
329
|
-
);
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
if (errors.length > 0) throw new Error([...new Set(errors)].join("\n"));
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
// Replaces the first wasm marker with the facade (dropping the others) and
|
|
338
|
-
// shifts source-map lines that follow it.
|
|
339
|
-
function spliceFacade(merged, facade) {
|
|
340
|
-
const lines = merged.js.split("\n");
|
|
341
|
-
const first = lines.findIndex((l) => WASM_MARKER_RE.test(l));
|
|
342
|
-
if (first < 0) {
|
|
343
|
-
merged.js = `${facade}\n${merged.js}`;
|
|
344
|
-
const shift = facade.split("\n").length;
|
|
345
|
-
for (const m of merged.mappings) m.genLine += shift;
|
|
346
|
-
return;
|
|
347
|
-
}
|
|
348
|
-
const facadeLines = facade.split("\n");
|
|
349
|
-
const delta = facadeLines.length - 1;
|
|
350
|
-
for (const m of merged.mappings) {
|
|
351
|
-
if (m.genLine > first) m.genLine += delta;
|
|
352
|
-
}
|
|
353
|
-
const out = [...lines.slice(0, first), ...facadeLines];
|
|
354
|
-
for (let i = first + 1; i < lines.length; i++) {
|
|
355
|
-
if (!WASM_MARKER_RE.test(lines[i])) out.push(lines[i]);
|
|
356
|
-
}
|
|
357
|
-
merged.js = out.join("\n");
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
// Root compiles only: link every registered unit into app.wasm and splice the
|
|
361
|
-
// facade into the merged bundle. Returns `{ wasm, wat, sourceMapInfo }`
|
|
362
|
-
// (nulls when there is nothing to link).
|
|
363
|
-
function linkIntoBundle(options, merged, pkgTarget, { sourceMappingURL } = {}) {
|
|
364
|
-
const none = { wasm: null, wat: null, sourceMapInfo: null };
|
|
365
|
-
if (options.isDependency) return none;
|
|
366
|
-
const linked = linkWasmUnits(options.wasmUnits, {
|
|
367
|
-
emitWat: options.emitWat,
|
|
368
|
-
rootTarget: pkgTarget,
|
|
369
|
-
sourceMappingURL,
|
|
370
|
-
});
|
|
371
|
-
if (!linked) return none;
|
|
372
|
-
spliceFacade(merged, linked.facade);
|
|
373
|
-
return {
|
|
374
|
-
wasm: linked.wasm,
|
|
375
|
-
wat: linked.wat ?? null,
|
|
376
|
-
sourceMapInfo: linked.sourceMapInfo ?? null,
|
|
377
|
-
};
|
|
138
|
+
// Prints non-fatal diagnostics (e.g. JS Number precision of a constant).
|
|
139
|
+
function logWarnings(warnings) {
|
|
140
|
+
for (const w of warnings) log.warn(w);
|
|
378
141
|
}
|
|
379
142
|
|
|
380
143
|
// ── Import resolution ─────────────────────────────────────────
|
|
144
|
+
|
|
145
|
+
// What link/stdlib.js needs from this module. Injected rather than imported
|
|
146
|
+
// so that link/stdlib.js does not depend on compiler.js.
|
|
147
|
+
const STDLIB_DEPS = { gwFilesIn, resolveImports, TypeChecker };
|
|
381
148
|
//
|
|
382
149
|
// Shared by compileFiles (multi-file) and the single-file path in index.js.
|
|
383
150
|
// Mutates checker, jsImports, bundledPackages, and preambles in place.
|
|
@@ -428,7 +195,12 @@ function resolveImports(
|
|
|
428
195
|
"'gofront/shared' requires a wasm-only package (//gofront:target wasm): a both package has no linear memory on the JS side",
|
|
429
196
|
impNode,
|
|
430
197
|
);
|
|
431
|
-
} else if (
|
|
198
|
+
} else if (
|
|
199
|
+
!isLocalPath(path) &&
|
|
200
|
+
!EXCLUDED_STDLIB_PACKAGES.has(path) &&
|
|
201
|
+
(isBuiltinPackage(path) ||
|
|
202
|
+
!resolveStdlibSource(path, options.stdlibRoot))
|
|
203
|
+
) {
|
|
432
204
|
if (!isBuiltinPackage(path)) {
|
|
433
205
|
checker.recordBlocker("js: import", path);
|
|
434
206
|
checker.err(
|
|
@@ -469,13 +241,27 @@ function resolveImports(
|
|
|
469
241
|
...imp,
|
|
470
242
|
imports: imp.imports.filter(({ alias }) => alias !== "_"),
|
|
471
243
|
}));
|
|
472
|
-
const resolved = resolveAll(
|
|
244
|
+
const resolved = resolveAll(
|
|
245
|
+
allImportsNoSideEffect,
|
|
246
|
+
fromFile,
|
|
247
|
+
parseDts,
|
|
248
|
+
options.stdlibRoot,
|
|
249
|
+
);
|
|
473
250
|
for (const [path, info] of resolved) {
|
|
474
251
|
if (!info) continue;
|
|
475
252
|
checker.addDefinitions(info.types, info.values);
|
|
476
253
|
jsImports.set(path, [...info.values.keys()]);
|
|
477
254
|
}
|
|
478
255
|
|
|
256
|
+
importStdlibPackages(
|
|
257
|
+
programs,
|
|
258
|
+
checker,
|
|
259
|
+
preambles,
|
|
260
|
+
bundledDirs,
|
|
261
|
+
options,
|
|
262
|
+
STDLIB_DEPS,
|
|
263
|
+
);
|
|
264
|
+
|
|
479
265
|
// local GoFront packages (./subdir)
|
|
480
266
|
const seenLocalPaths = new Set();
|
|
481
267
|
for (const p of programs) {
|
|
@@ -541,7 +327,10 @@ function resolveImports(
|
|
|
541
327
|
|
|
542
328
|
if (alias === "_") continue;
|
|
543
329
|
if (alias === ".") {
|
|
544
|
-
checker.addDefinitions(dep.exportedTypes, dep.exportedSymbols
|
|
330
|
+
checker.addDefinitions(dep.exportedTypes, dep.exportedSymbols, {
|
|
331
|
+
external: false,
|
|
332
|
+
consts: dep.exportedConsts,
|
|
333
|
+
});
|
|
545
334
|
continue;
|
|
546
335
|
}
|
|
547
336
|
const nameUsed = alias ?? dep.pkgName;
|
|
@@ -551,6 +340,7 @@ function resolveImports(
|
|
|
551
340
|
dep.exportedSymbols,
|
|
552
341
|
dep.exportedTypes,
|
|
553
342
|
dep.target,
|
|
343
|
+
dep.exportedConsts,
|
|
554
344
|
);
|
|
555
345
|
checker.trackImport(nameUsed, { _line }, p._filename, p._source);
|
|
556
346
|
}
|
|
@@ -590,7 +380,13 @@ export function compileSingleFile(inputPath, options = {}) {
|
|
|
590
380
|
dumpTokens = false,
|
|
591
381
|
dumpAst = false,
|
|
592
382
|
} = options;
|
|
593
|
-
options = {
|
|
383
|
+
options = {
|
|
384
|
+
...options,
|
|
385
|
+
wasmUnits: options.wasmUnits ?? [],
|
|
386
|
+
stdlibCache: options.stdlibCache ?? new Map(),
|
|
387
|
+
jsRootPrograms: options.jsRootPrograms ?? [],
|
|
388
|
+
bundledDirs: options.bundledDirs ?? new Set(),
|
|
389
|
+
};
|
|
594
390
|
|
|
595
391
|
let source;
|
|
596
392
|
try {
|
|
@@ -661,6 +457,7 @@ export function compileSingleFile(inputPath, options = {}) {
|
|
|
661
457
|
});
|
|
662
458
|
const mainJs =
|
|
663
459
|
pkgTarget === "wasm" ? wasmMarker(checker.pkgName) : cg.generate(ast);
|
|
460
|
+
logWarnings(cg.warnings);
|
|
664
461
|
|
|
665
462
|
const mainChunk = {
|
|
666
463
|
js: mainJs,
|
|
@@ -670,6 +467,7 @@ export function compileSingleFile(inputPath, options = {}) {
|
|
|
670
467
|
};
|
|
671
468
|
|
|
672
469
|
const merged = mergeCompilationChunks([...preambles, mainChunk]);
|
|
470
|
+
finishStdlibJs(merged, options, [ast], pkgTarget);
|
|
673
471
|
const { wasm, wat, wasmOptInfo, wasmSourceMap } = finishWasm(
|
|
674
472
|
{ ...options, sourceMap },
|
|
675
473
|
merged,
|
|
@@ -716,7 +514,10 @@ export function compileFiles(files, options = {}) {
|
|
|
716
514
|
options = {
|
|
717
515
|
...options,
|
|
718
516
|
wasmUnits: options.wasmUnits ?? [],
|
|
517
|
+
stdlibCache: options.stdlibCache ?? new Map(),
|
|
518
|
+
jsRootPrograms: options.jsRootPrograms ?? [],
|
|
719
519
|
rootDir: options.rootDir ?? fromDir,
|
|
520
|
+
bundledDirs: options.bundledDirs ?? new Set(),
|
|
720
521
|
};
|
|
721
522
|
const outputDir =
|
|
722
523
|
options.outputDir ??
|
|
@@ -792,6 +593,13 @@ export function compileFiles(files, options = {}) {
|
|
|
792
593
|
|
|
793
594
|
// ── 3. Type-check ─────────────────────────────────────────────
|
|
794
595
|
const errors = checker.checkAll(programs);
|
|
596
|
+
const codecs = checkJsonCodecs(
|
|
597
|
+
programs,
|
|
598
|
+
checker,
|
|
599
|
+
preambles,
|
|
600
|
+
options,
|
|
601
|
+
STDLIB_DEPS,
|
|
602
|
+
);
|
|
795
603
|
checker.reportUnusedImports();
|
|
796
604
|
if (errors.length > 0) {
|
|
797
605
|
const msgs = errors.map((e) => e.message).join("\n");
|
|
@@ -804,7 +612,7 @@ export function compileFiles(files, options = {}) {
|
|
|
804
612
|
key: resolve(fromDir),
|
|
805
613
|
pkgName,
|
|
806
614
|
pkgTarget,
|
|
807
|
-
programs,
|
|
615
|
+
programs: [...programs, ...codecs],
|
|
808
616
|
types: checker.types,
|
|
809
617
|
bundledPackages,
|
|
810
618
|
});
|
|
@@ -820,6 +628,7 @@ export function compileFiles(files, options = {}) {
|
|
|
820
628
|
: codegen.generateAll(programs, {
|
|
821
629
|
isTest: options.isTest ?? false,
|
|
822
630
|
});
|
|
631
|
+
logWarnings(codegen.warnings);
|
|
823
632
|
|
|
824
633
|
const mainChunk = {
|
|
825
634
|
js: mainJs,
|
|
@@ -829,6 +638,7 @@ export function compileFiles(files, options = {}) {
|
|
|
829
638
|
};
|
|
830
639
|
|
|
831
640
|
const merged = mergeCompilationChunks([...preambles, mainChunk]);
|
|
641
|
+
finishStdlibJs(merged, options, programs, emitTarget);
|
|
832
642
|
const { wasm, wat, wasmOptInfo, wasmSourceMap } = finishWasm(
|
|
833
643
|
options,
|
|
834
644
|
merged,
|
|
@@ -857,8 +667,36 @@ export function compileFiles(files, options = {}) {
|
|
|
857
667
|
programs,
|
|
858
668
|
exportedSymbols: checker.getExportedSymbols(),
|
|
859
669
|
exportedTypes: checker.getExportedTypes(),
|
|
670
|
+
exportedConsts: checker.getExportedConsts(),
|
|
860
671
|
sourceFiles: merged.sourceFiles,
|
|
861
672
|
sourcesContent: merged.sourcesContent,
|
|
862
673
|
mappings: merged.mappings,
|
|
863
674
|
};
|
|
864
675
|
}
|
|
676
|
+
|
|
677
|
+
export function compileWasm(source, options = {}) {
|
|
678
|
+
const filename = options.filename ?? "main.go";
|
|
679
|
+
const tokens = new Lexer(source, filename).tokenize();
|
|
680
|
+
const ast = new Parser(tokens, filename, source).parse();
|
|
681
|
+
|
|
682
|
+
const checker = new TypeChecker();
|
|
683
|
+
checker.target = "wasm";
|
|
684
|
+
checker.pkgName = ast.pkg?.name ?? "main";
|
|
685
|
+
|
|
686
|
+
const errors = checker.check(ast);
|
|
687
|
+
if (errors.length > 0) {
|
|
688
|
+
return { wasm: null, errors };
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
const lowerRes = lower([ast], checker);
|
|
692
|
+
const res = compileWasmModule([ast], checker, lowerRes, {
|
|
693
|
+
...options,
|
|
694
|
+
exportAll: options.exportAll ?? true,
|
|
695
|
+
});
|
|
696
|
+
|
|
697
|
+
if (checker.errors?.length > 0) {
|
|
698
|
+
return { wasm: null, errors: checker.errors };
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
return { ...res, errors: [] };
|
|
702
|
+
}
|