gofront 1.8.0 → 1.9.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 +3 -3
- package/package.json +6 -5
- package/src/backend/js/expressions.js +1157 -408
- package/src/backend/js/index.js +327 -153
- package/src/backend/js/natives.js +383 -0
- package/src/backend/js/runtime.js +559 -2552
- package/src/backend/js/statements.js +670 -158
- package/src/backend/js/stdlib/index.js +45 -93
- package/src/backend/js/templ.js +32 -45
- package/src/backend/js/type-info.js +298 -19
- package/src/backend/shared/fixed-float.js +20 -0
- package/src/backend/shared/fmt-types.js +91 -170
- package/src/backend/shared/host-unicode.js +36 -0
- package/src/backend/wasm/boundary.js +490 -965
- package/src/backend/wasm/emit-builtins.js +884 -256
- package/src/backend/wasm/emit-exprs.js +185 -77
- package/src/backend/wasm/emit-maps.js +17 -367
- package/src/backend/wasm/emit-shared.js +4 -1
- package/src/backend/wasm/emit-stmts.js +524 -240
- package/src/backend/wasm/emit.js +176 -38
- package/src/backend/wasm/globals.js +48 -8
- package/src/backend/wasm/glue.js +2 -4
- package/src/backend/wasm/index.js +44 -530
- package/src/backend/wasm/method-expr.js +12 -1
- package/src/backend/wasm/module-emitter.js +299 -770
- package/src/backend/wasm/monomorph.js +139 -8
- package/src/backend/wasm/natives.js +600 -0
- package/src/backend/wasm/prescan.js +5 -153
- package/src/backend/wasm/prune-funcs.js +89 -0
- package/src/backend/wasm/stdlib/index.js +2 -32
- package/src/backend/wasm/types.js +97 -20
- package/src/backend/wasm/variadic.js +9 -4
- package/src/cli/cli-core.js +5 -1
- package/src/cli/test-runner.js +115 -342
- package/src/compiler.js +113 -130
- package/src/lexer/lexer.js +106 -11
- package/src/lexer/templ-lexer.js +61 -18
- package/src/lexer/tokens.js +1 -0
- package/src/link/stdlib.js +355 -132
- package/src/link/type-names.js +204 -0
- package/src/link/wasm.js +30 -6
- package/src/lower/bounds.js +153 -0
- package/src/lower/captures.js +92 -33
- package/src/lower/embedding.js +62 -5
- package/src/lower/errors-as.js +196 -0
- package/src/lower/fmt-formatters.js +929 -0
- package/src/lower/functions.js +225 -7
- package/src/lower/gen-types.js +293 -0
- package/src/lower/index.js +14 -2
- package/src/lower/json-codecs.js +334 -245
- package/src/lower/ownership.js +25 -7
- package/src/lower/reachability.js +69 -51
- package/src/lower/walk.js +12 -0
- package/src/parser/declarations.js +30 -5
- package/src/parser/expressions.js +111 -57
- package/src/parser/statements.js +108 -0
- package/src/parser/templ.js +44 -5
- package/src/parser/types.js +12 -0
- package/src/resolver.js +1 -2
- package/src/typechecker/assignability.js +214 -19
- package/src/typechecker/const-fold.js +70 -27
- package/src/typechecker/constants.js +156 -8
- package/src/typechecker/expressions.js +490 -108
- package/src/typechecker/index.js +346 -42
- package/src/typechecker/init-order.js +136 -40
- package/src/typechecker/operand-text.js +41 -0
- package/src/typechecker/resolve.js +490 -65
- package/src/typechecker/statements.js +288 -27
- package/src/typechecker/stdlib/excluded.js +9 -5
- package/src/typechecker/stdlib/index.js +25 -9
- package/src/typechecker/termination.js +10 -1
- package/src/typechecker/types.js +287 -575
- package/stdlib/bytes/buffer.go +479 -0
- package/stdlib/bytes/bytes.go +1010 -0
- package/stdlib/bytes/reader.go +161 -0
- package/stdlib/context/context.go +115 -0
- package/stdlib/crypto/rand/rand.go +34 -0
- package/stdlib/crypto/sha256/sha256.go +249 -0
- package/stdlib/encoding/base64/base64.go +331 -0
- package/stdlib/encoding/binary/binary.go +332 -0
- package/stdlib/encoding/hex/hex.go +140 -0
- package/stdlib/encoding/json/json.go +62 -0
- package/stdlib/errors/errors.go +174 -0
- package/stdlib/fmt/errors.go +110 -0
- package/stdlib/fmt/format.go +732 -0
- package/stdlib/fmt/print.go +1232 -0
- package/stdlib/gom/gom.go +293 -0
- package/stdlib/html/html.go +251 -0
- package/stdlib/internal/fmtrt/fmtrt.go +163 -0
- package/stdlib/internal/jsonrt/dec.go +171 -38
- package/stdlib/internal/jsonrt/enc.go +186 -36
- package/stdlib/internal/jsonrt/scanner.go +17 -8
- package/stdlib/io/io.go +157 -1
- package/stdlib/maps/maps.go +131 -0
- package/stdlib/math/bits/bits.go +507 -0
- package/stdlib/math/extra.go +16 -14
- package/stdlib/math/math.go +439 -0
- package/stdlib/math/rand/rand.go +297 -0
- package/stdlib/os/os.go +93 -0
- package/stdlib/path/filepath/filepath.go +47 -0
- package/stdlib/path/path.go +394 -0
- package/stdlib/regexp/regexp.go +231 -0
- package/stdlib/slices/slices.go +526 -0
- package/stdlib/slices/sort.go +209 -0
- package/stdlib/slices/zsort_cmp.go +480 -0
- package/stdlib/slices/zsort_ordered.go +482 -0
- package/stdlib/sort/sort.go +391 -452
- package/stdlib/sort/zsort_func.go +480 -0
- package/stdlib/sort/zsort_iface.go +480 -0
- package/stdlib/strconv/float.go +1699 -0
- package/stdlib/strconv/isprint.go +752 -0
- package/stdlib/strconv/quote.go +235 -50
- package/stdlib/strconv/strconv.go +616 -0
- package/stdlib/strings/builder.go +95 -0
- package/stdlib/strings/reader.go +163 -0
- package/stdlib/strings/replacer.go +102 -0
- package/stdlib/strings/strings.go +807 -0
- package/stdlib/sync/sync.go +268 -0
- package/stdlib/testing/async_js.go +61 -0
- package/stdlib/testing/benchmark.go +297 -0
- package/stdlib/testing/testing.go +523 -0
- package/stdlib/time/duration.go +233 -0
- package/stdlib/time/format.go +745 -0
- package/stdlib/time/parse.go +790 -0
- package/stdlib/time/sleep_js.go +63 -0
- package/stdlib/time/time.go +834 -0
- package/stdlib/unicode/unicode.go +141 -3
- package/stdlib/unicode/utf8/utf8.go +464 -0
- package/src/backend/js/fmt-runtime.js +0 -573
- package/src/backend/js/stdlib/base64.js +0 -12
- package/src/backend/js/stdlib/binary.js +0 -102
- package/src/backend/js/stdlib/bits.js +0 -119
- package/src/backend/js/stdlib/builder.js +0 -98
- package/src/backend/js/stdlib/bytes.js +0 -368
- package/src/backend/js/stdlib/errors.js +0 -45
- package/src/backend/js/stdlib/fmt.js +0 -517
- package/src/backend/js/stdlib/gom.js +0 -155
- package/src/backend/js/stdlib/hex.js +0 -17
- package/src/backend/js/stdlib/html.js +0 -20
- package/src/backend/js/stdlib/io.js +0 -137
- package/src/backend/js/stdlib/json.js +0 -1167
- package/src/backend/js/stdlib/maps.js +0 -37
- package/src/backend/js/stdlib/math.js +0 -85
- package/src/backend/js/stdlib/os.js +0 -13
- package/src/backend/js/stdlib/path.js +0 -48
- package/src/backend/js/stdlib/rand.js +0 -32
- package/src/backend/js/stdlib/regexp.js +0 -54
- package/src/backend/js/stdlib/sha256.js +0 -12
- package/src/backend/js/stdlib/shared.js +0 -17
- package/src/backend/js/stdlib/simd.js +0 -34
- package/src/backend/js/stdlib/slices.js +0 -107
- package/src/backend/js/stdlib/sort.js +0 -30
- package/src/backend/js/stdlib/strconv.js +0 -79
- package/src/backend/js/stdlib/strings.js +0 -301
- package/src/backend/js/stdlib/sync.js +0 -13
- package/src/backend/js/stdlib/testing.js +0 -41
- package/src/backend/js/stdlib/time.js +0 -152
- package/src/backend/js/stdlib/unicode.js +0 -25
- package/src/backend/js/stdlib/utf8.js +0 -26
- package/src/backend/wasm/stdlib/bytes.js +0 -6716
- package/src/backend/wasm/stdlib/core.js +0 -10278
- package/src/backend/wasm/stdlib/io.js +0 -3578
- package/src/backend/wasm/stdlib/packages.js +0 -2402
- package/src/backend/wasm/stdlib/pure.js +0 -720
- package/src/backend/wasm/stdlib/time.js +0 -2229
- package/src/typechecker/stdlib/core.js +0 -1079
- package/src/typechecker/stdlib/extended.js +0 -1210
- package/stdlib/bytes/iter.go +0 -192
- package/stdlib/bytes/search.go +0 -240
- package/stdlib/bytes/split.go +0 -218
- package/stdlib/errors/overlay.go +0 -12
- package/stdlib/maps/iter.go +0 -65
- package/stdlib/slices/extra.go +0 -73
- package/stdlib/slices/iter.go +0 -113
- package/stdlib/strings/extra.go +0 -35
- package/stdlib/strings/iter.go +0 -122
- package/stdlib/sync/extra.go +0 -105
- package/stdlib/unicode/utf8/bytes.go +0 -239
package/src/link/stdlib.js
CHANGED
|
@@ -9,17 +9,22 @@ import { readFileSync } from "node:fs";
|
|
|
9
9
|
import { basename, dirname, join, resolve } from "node:path";
|
|
10
10
|
import { CodeGen } from "../backend/js/index.js";
|
|
11
11
|
import { Lexer } from "../lexer/lexer.js";
|
|
12
|
+
import { generateErrorsAs } from "../lower/errors-as.js";
|
|
13
|
+
import { generateFmtFormatters } from "../lower/fmt-formatters.js";
|
|
12
14
|
import { generateJsonCodecs } from "../lower/json-codecs.js";
|
|
13
|
-
import { reachableStdlibDecls } from "../lower/reachability.js";
|
|
15
|
+
import { reachableStdlibDecls, StdlibReach } from "../lower/reachability.js";
|
|
14
16
|
import { forEachChild } from "../lower/walk.js";
|
|
15
17
|
import { Parser } from "../parser/index.js";
|
|
16
|
-
import {
|
|
17
|
-
isBuiltinPackage,
|
|
18
|
-
isLocalPath,
|
|
19
|
-
resolveStdlibSource,
|
|
20
|
-
} from "../resolver.js";
|
|
18
|
+
import { isLocalPath, resolveStdlibSource } from "../resolver.js";
|
|
21
19
|
import { lowerStdlibRefs, registerWasmUnit } from "./wasm.js";
|
|
22
20
|
|
|
21
|
+
export {
|
|
22
|
+
mangleCollidingTypes,
|
|
23
|
+
registerLocalTypeOwners,
|
|
24
|
+
renameLocalTypes,
|
|
25
|
+
withOriginalTypeNames,
|
|
26
|
+
} from "./type-names.js";
|
|
27
|
+
|
|
23
28
|
// ── Go-source stdlib ──────────────────────────────────────────
|
|
24
29
|
//
|
|
25
30
|
// Packages under stdlib/<path>/ are GoFront Go. Each is type-checked
|
|
@@ -27,27 +32,56 @@ import { lowerStdlibRefs, registerWasmUnit } from "./wasm.js";
|
|
|
27
32
|
// is bundled for js/both importers and its programs are linked into app.wasm
|
|
28
33
|
// for wasm/both importers, never through the boundary facade. Top-level
|
|
29
34
|
// names are mangled to `Name$$path` so they cannot collide with user
|
|
30
|
-
// declarations in the flat JS bundle or the linked module.
|
|
31
|
-
// emitter-backed package (`errors`) is an overlay: its members join that
|
|
32
|
-
// namespace and unqualified references to emitter members become `errors.X`.
|
|
35
|
+
// declarations in the flat JS bundle or the linked module.
|
|
33
36
|
|
|
34
37
|
function stdlibSuffix(importPath) {
|
|
35
38
|
return `$$${importPath.replaceAll("/", "$")}`;
|
|
36
39
|
}
|
|
37
40
|
|
|
38
|
-
|
|
41
|
+
// Each file keeps its own `//gofront:target` (default `both`). A package
|
|
42
|
+
// with `js` files is compiled whole for `js` importers (the `js` variant) and
|
|
43
|
+
// without those files for `wasm` and `both` importers (the `shared` variant).
|
|
44
|
+
function parseStdlibFiles(dir, deps, variant = "js", target = "both") {
|
|
45
|
+
return deps
|
|
46
|
+
.gwFilesIn(dir)
|
|
47
|
+
.map((f) => {
|
|
48
|
+
const source = readFileSync(f, "utf8");
|
|
49
|
+
const filename = basename(f);
|
|
50
|
+
const tokens = new Lexer(source, filename).tokenize();
|
|
51
|
+
const ast = new Parser(tokens, filename, source).parse();
|
|
52
|
+
ast._source = source;
|
|
53
|
+
ast._path = resolve(f);
|
|
54
|
+
ast._fileTarget = tokens.target ?? "both";
|
|
55
|
+
return ast;
|
|
56
|
+
})
|
|
57
|
+
.filter((ast) => variant === "js" || ast._fileTarget !== "js")
|
|
58
|
+
.map((ast) => Object.assign(ast, { target }));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Targets of the package's files, read without parsing.
|
|
62
|
+
function stdlibFileTargets(dir, deps) {
|
|
39
63
|
return deps.gwFilesIn(dir).map((f) => {
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
const tokens = new Lexer(source, filename).tokenize();
|
|
43
|
-
const ast = new Parser(tokens, filename, source).parse();
|
|
44
|
-
ast._source = source;
|
|
45
|
-
ast._path = resolve(f);
|
|
46
|
-
ast.target = "both";
|
|
47
|
-
return ast;
|
|
64
|
+
const m = /^\/\/gofront:target\s+(\S+)/m.exec(readFileSync(f, "utf8"));
|
|
65
|
+
return m?.[1] ?? "both";
|
|
48
66
|
});
|
|
49
67
|
}
|
|
50
68
|
|
|
69
|
+
// Exported names declared by the `js` files (what a `wasm` or `both` importer
|
|
70
|
+
// cannot use).
|
|
71
|
+
function stdlibJsOnlyNames(dir, deps) {
|
|
72
|
+
const programs = parseStdlibFiles(dir, deps).filter(
|
|
73
|
+
(p) => p._fileTarget === "js",
|
|
74
|
+
);
|
|
75
|
+
const { values, types } = stdlibTopLevelNames(programs);
|
|
76
|
+
return new Set([...values, ...types].filter((n) => /^[A-Z]/.test(n)));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Whether every file of the package is `js`-only.
|
|
80
|
+
export function stdlibIsJsOnly(dir, deps) {
|
|
81
|
+
const targets = stdlibFileTargets(dir, deps);
|
|
82
|
+
return targets.length > 0 && targets.every((t) => t === "js");
|
|
83
|
+
}
|
|
84
|
+
|
|
51
85
|
// Top-level value and type names declared by the package.
|
|
52
86
|
function stdlibTopLevelNames(programs) {
|
|
53
87
|
const values = new Set();
|
|
@@ -68,13 +102,27 @@ function stdlibTopLevelNames(programs) {
|
|
|
68
102
|
// `refs` holds the `file:line:col` of identifiers the first type-check
|
|
69
103
|
// resolved to package scope; type names are resolved by name (GoFront types
|
|
70
104
|
// are package-flat) except where a type parameter shadows them.
|
|
71
|
-
|
|
105
|
+
// With `lazy`, function and method bodies are left alone: they are mangled
|
|
106
|
+
// by `mangleBody` once a lazily checked body is first reached.
|
|
107
|
+
export function mangleStdlibAst(programs, ctx, { lazy = false } = {}) {
|
|
72
108
|
for (const p of programs) {
|
|
73
109
|
for (const d of p.decls ?? []) mangleDeclNames(d, ctx);
|
|
74
|
-
|
|
110
|
+
for (const d of p.decls ?? []) {
|
|
111
|
+
const deferred =
|
|
112
|
+
lazy && (d.kind === "FuncDecl" || d.kind === "MethodDecl");
|
|
113
|
+
const body = d.body;
|
|
114
|
+
if (deferred) d.body = null;
|
|
115
|
+
mangleRefs(d, p._filename, new Set(), ctx);
|
|
116
|
+
if (deferred) d.body = body;
|
|
117
|
+
}
|
|
75
118
|
}
|
|
76
119
|
}
|
|
77
120
|
|
|
121
|
+
function mangleBody(decl, file, ctx) {
|
|
122
|
+
const tparams = new Set((decl.typeParams ?? []).map((t) => t.name));
|
|
123
|
+
mangleRefs(decl.body, file, tparams, ctx);
|
|
124
|
+
}
|
|
125
|
+
|
|
78
126
|
function mangleDeclNames(d, { suffix, values }) {
|
|
79
127
|
if (d.kind === "TypeDecl" || (d.kind === "FuncDecl" && values.has(d.name))) {
|
|
80
128
|
d.name += suffix;
|
|
@@ -123,43 +171,25 @@ function mangleRefs(node, file, tparams, ctx) {
|
|
|
123
171
|
forEachChild(node, (child) => mangleRefs(child, file, tp, ctx));
|
|
124
172
|
}
|
|
125
173
|
|
|
126
|
-
function mangleTypeRef(node, tparams, { suffix, types
|
|
174
|
+
function mangleTypeRef(node, tparams, { suffix, types }) {
|
|
127
175
|
if (types.has(node.name) && !tparams.has(node.name)) {
|
|
128
176
|
node.name += suffix;
|
|
129
|
-
} else if (overlay && node.name in overlay.members) {
|
|
130
|
-
node.name = `${overlay.name}.${node.name}`;
|
|
131
177
|
}
|
|
132
178
|
}
|
|
133
179
|
|
|
134
|
-
// A package-scope identifier: a package declaration gets the suffix
|
|
135
|
-
|
|
136
|
-
function mangleIdentRef(node, { suffix, values, types, overlay }) {
|
|
180
|
+
// A package-scope identifier: a package declaration gets the suffix.
|
|
181
|
+
function mangleIdentRef(node, { suffix, values, types }) {
|
|
137
182
|
if (values.has(node.name) || types.has(node.name)) {
|
|
138
183
|
node.name += suffix;
|
|
139
|
-
} else if (overlay && node.name in overlay.members) {
|
|
140
|
-
const field = node.name;
|
|
141
|
-
delete node.name;
|
|
142
|
-
Object.assign(node, {
|
|
143
|
-
kind: "SelectorExpr",
|
|
144
|
-
expr: { kind: "Ident", name: overlay.name, _line: node._line },
|
|
145
|
-
field,
|
|
146
|
-
});
|
|
147
184
|
}
|
|
148
185
|
}
|
|
149
186
|
|
|
150
|
-
function checkStdlibPrograms(programs, pkgName, options,
|
|
187
|
+
function checkStdlibPrograms(programs, pkgName, options, deps, target) {
|
|
151
188
|
const checker = new deps.TypeChecker();
|
|
152
|
-
checker.target =
|
|
189
|
+
checker.target = target;
|
|
153
190
|
checker.pkgName = pkgName;
|
|
154
191
|
checker.isStdlib = true;
|
|
155
|
-
|
|
156
|
-
for (const [name, t] of Object.entries(overlay.members)) {
|
|
157
|
-
checker.globals.define(name, t);
|
|
158
|
-
if (t.kind === "interface" || t.kind === "named" || t.kind === "struct") {
|
|
159
|
-
checker.types.set(name, t);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}
|
|
192
|
+
checker.lazyBodies = true;
|
|
163
193
|
deps.resolveImports(
|
|
164
194
|
programs,
|
|
165
195
|
programs[0]._path,
|
|
@@ -176,49 +206,100 @@ function checkStdlibPrograms(programs, pkgName, options, overlay, deps) {
|
|
|
176
206
|
// Errors in stdlib source are compiler bugs; the importer reports them at its
|
|
177
207
|
// import (see reportStdlibLoadError), so only the message text is kept, never
|
|
178
208
|
// a location inside stdlib/.
|
|
179
|
-
function
|
|
180
|
-
if (errors.length === 0) return;
|
|
209
|
+
function stdlibErrorText(errors) {
|
|
181
210
|
const detail = (e) =>
|
|
182
211
|
e.message
|
|
183
212
|
.split("\n")[0]
|
|
184
213
|
.replace(/^Type error(?: in \S+)?(?: at line \d+:\d+)?:\s*/, "");
|
|
185
|
-
|
|
214
|
+
return [...new Set(errors.map(detail))].join("; ");
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function throwStdlibErrors(errors) {
|
|
218
|
+
if (errors.length === 0) return;
|
|
219
|
+
throw new Error(stdlibErrorText(errors));
|
|
186
220
|
}
|
|
187
221
|
|
|
188
222
|
// Pass 1: type-check the package as written and record which identifiers
|
|
189
|
-
// refer to package scope.
|
|
190
|
-
function probeStdlibPackage(_importPath, dir, options,
|
|
191
|
-
const programs = parseStdlibFiles(dir, deps);
|
|
223
|
+
// refer to package scope.
|
|
224
|
+
function probeStdlibPackage(_importPath, dir, options, deps, v) {
|
|
225
|
+
const programs = parseStdlibFiles(dir, deps, v.variant, v.target);
|
|
192
226
|
const pkgName = programs[0].pkg.name;
|
|
193
227
|
const { values, types } = stdlibTopLevelNames(programs);
|
|
194
|
-
|
|
195
|
-
if (overlay && n in overlay.members)
|
|
196
|
-
throw new Error(`overlay redeclares ${overlay.name}.${n}`);
|
|
197
|
-
const probe = checkStdlibPrograms(programs, pkgName, options, overlay, deps);
|
|
228
|
+
const probe = checkStdlibPrograms(programs, pkgName, options, deps, v.target);
|
|
198
229
|
probe._pkgRefs = new Set();
|
|
199
230
|
throwStdlibErrors(probe.checkAll(programs));
|
|
200
|
-
return {
|
|
231
|
+
return {
|
|
232
|
+
pkgName,
|
|
233
|
+
values,
|
|
234
|
+
types,
|
|
235
|
+
refs: probe._pkgRefs,
|
|
236
|
+
probe,
|
|
237
|
+
probePrograms: programs,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Function and method bodies are checked when first reached (see
|
|
242
|
+
// `StdlibReach`), in both passes: the probe records which identifiers in the
|
|
243
|
+
// body name package scope, the body is mangled with them, and the mangled
|
|
244
|
+
// body is checked. `decl._ensure()` does all three once and returns the
|
|
245
|
+
// error text, or null.
|
|
246
|
+
function installLazyBodies(info, programs, checker) {
|
|
247
|
+
const { probe, probePrograms } = info;
|
|
248
|
+
programs.forEach((p, pi) => {
|
|
249
|
+
p.decls.forEach((decl, di) => {
|
|
250
|
+
if (decl.kind !== "FuncDecl" && decl.kind !== "MethodDecl") return;
|
|
251
|
+
const probeDecl = probePrograms[pi].decls[di];
|
|
252
|
+
let result;
|
|
253
|
+
decl._ensure = () => {
|
|
254
|
+
if (result !== undefined) return result;
|
|
255
|
+
result = null; // a body that reaches itself is in progress
|
|
256
|
+
const before = [probe.errors.length, checker.errors.length];
|
|
257
|
+
probe.checkBody(probeDecl);
|
|
258
|
+
if (probe.errors.length === before[0]) {
|
|
259
|
+
mangleBody(decl, p._filename, info);
|
|
260
|
+
checker.checkBody(decl);
|
|
261
|
+
lowerStdlibRefs(decl);
|
|
262
|
+
}
|
|
263
|
+
const errors = [
|
|
264
|
+
...probe.errors.slice(before[0]),
|
|
265
|
+
...checker.errors.slice(before[1]),
|
|
266
|
+
];
|
|
267
|
+
if (errors.length > 0) result = stdlibErrorText(errors);
|
|
268
|
+
return result;
|
|
269
|
+
};
|
|
270
|
+
});
|
|
271
|
+
});
|
|
201
272
|
}
|
|
202
273
|
|
|
203
274
|
// Exported members as seen by importers (original name -> type) and the
|
|
204
|
-
// original -> mangled name map
|
|
205
|
-
function stdlibNamespace(checker, { pkgName, values, types, suffix },
|
|
206
|
-
const members =
|
|
275
|
+
// original -> mangled name map.
|
|
276
|
+
function stdlibNamespace(checker, { pkgName, values, types, suffix }, jsOnly) {
|
|
277
|
+
const members = {};
|
|
207
278
|
const mangle = new Map();
|
|
279
|
+
const consts = new Map();
|
|
208
280
|
for (const name of [...values, ...types]) {
|
|
209
281
|
const t = checker.globals.symbols.get(name + suffix);
|
|
210
282
|
if (!/^[A-Z]/.test(name) || t === undefined) continue;
|
|
211
283
|
members[name] = t;
|
|
212
284
|
mangle.set(name, name + suffix);
|
|
285
|
+
// An exported constant's folded value, so importers fold `pkg.Name`.
|
|
286
|
+
if (checker.globals._consts.has(name + suffix)) {
|
|
287
|
+
const v = checker._constValue(
|
|
288
|
+
{ kind: "Ident", name: name + suffix },
|
|
289
|
+
checker.globals,
|
|
290
|
+
);
|
|
291
|
+
if (v) consts.set(name, v);
|
|
292
|
+
}
|
|
213
293
|
}
|
|
214
294
|
return {
|
|
215
|
-
...(overlay ?? {}),
|
|
216
295
|
kind: "namespace",
|
|
217
296
|
name: pkgName,
|
|
218
297
|
members,
|
|
219
|
-
_gofront:
|
|
298
|
+
_gofront: true,
|
|
220
299
|
_target: "both",
|
|
300
|
+
_jsOnly: jsOnly,
|
|
221
301
|
_mangle: mangle,
|
|
302
|
+
_consts: consts,
|
|
222
303
|
};
|
|
223
304
|
}
|
|
224
305
|
|
|
@@ -236,59 +317,94 @@ function stdlibExportedTypes(checker, { pkgName, suffix }) {
|
|
|
236
317
|
return out;
|
|
237
318
|
}
|
|
238
319
|
|
|
320
|
+
// The compilation a package gets for an importer: `js` importers see every
|
|
321
|
+
// file, `wasm` and `both` importers only the files for both targets (cached
|
|
322
|
+
// as `<path>#shared` when that differs). Returns { key, variant, target }.
|
|
323
|
+
function stdlibVariant(importPath, dir, importerTarget, deps) {
|
|
324
|
+
const hasJs = stdlibFileTargets(dir, deps).includes("js");
|
|
325
|
+
importerTarget ??= "js";
|
|
326
|
+
if (!hasJs) return { key: importPath, variant: "js", target: "both" };
|
|
327
|
+
if (importerTarget === "js")
|
|
328
|
+
return { key: importPath, variant: "js", target: "js" };
|
|
329
|
+
return { key: `${importPath}#shared`, variant: "shared", target: "both" };
|
|
330
|
+
}
|
|
331
|
+
|
|
239
332
|
// Loads (once per build) and compiles the Go-source package at `dir`. A
|
|
240
333
|
// failure is cached too, so every importer reports it.
|
|
241
|
-
function loadStdlibPackage(
|
|
334
|
+
function loadStdlibPackage(
|
|
335
|
+
importPath,
|
|
336
|
+
dir,
|
|
337
|
+
options,
|
|
338
|
+
deps,
|
|
339
|
+
importerTarget = "js",
|
|
340
|
+
) {
|
|
341
|
+
const v = stdlibVariant(importPath, dir, importerTarget, deps);
|
|
242
342
|
const cache = options.stdlibCache;
|
|
243
|
-
const cached = cache.get(
|
|
343
|
+
const cached = cache.get(v.key);
|
|
244
344
|
if (cached === null)
|
|
245
345
|
throw new Error(`import cycle in Go-source stdlib: ${importPath}`);
|
|
246
346
|
if (cached instanceof Error) throw cached;
|
|
247
347
|
if (cached) return cached;
|
|
248
|
-
cache.set(
|
|
348
|
+
cache.set(v.key, null);
|
|
249
349
|
try {
|
|
250
|
-
const pkg = buildStdlibPackage(importPath, dir, options, deps);
|
|
251
|
-
cache.set(
|
|
350
|
+
const pkg = buildStdlibPackage(importPath, dir, options, deps, v);
|
|
351
|
+
cache.set(v.key, pkg);
|
|
252
352
|
return pkg;
|
|
253
353
|
} catch (e) {
|
|
254
|
-
cache.set(
|
|
354
|
+
cache.set(v.key, e);
|
|
255
355
|
throw e;
|
|
256
356
|
}
|
|
257
357
|
}
|
|
258
358
|
|
|
259
|
-
function buildStdlibPackage(importPath, dir, options, deps) {
|
|
359
|
+
function buildStdlibPackage(importPath, dir, options, deps, v) {
|
|
260
360
|
const cache = options.stdlibCache;
|
|
261
|
-
const overlay = isBuiltinPackage(importPath)
|
|
262
|
-
? new deps.TypeChecker().globals.lookup(importPath.split("/").at(-1))
|
|
263
|
-
: null;
|
|
264
361
|
const info = {
|
|
265
|
-
...probeStdlibPackage(importPath, dir, options,
|
|
362
|
+
...probeStdlibPackage(importPath, dir, options, deps, v),
|
|
266
363
|
suffix: stdlibSuffix(importPath),
|
|
267
364
|
};
|
|
268
365
|
|
|
269
366
|
// Pass 2: mangle a fresh parse and check it again.
|
|
270
|
-
const programs = parseStdlibFiles(dir, deps);
|
|
271
|
-
mangleStdlibAst(programs,
|
|
367
|
+
const programs = parseStdlibFiles(dir, deps, v.variant, v.target);
|
|
368
|
+
mangleStdlibAst(programs, info, { lazy: true });
|
|
272
369
|
const checker = checkStdlibPrograms(
|
|
273
370
|
programs,
|
|
274
371
|
info.pkgName,
|
|
275
372
|
options,
|
|
276
|
-
null,
|
|
277
373
|
deps,
|
|
374
|
+
v.target,
|
|
278
375
|
);
|
|
279
376
|
throwStdlibErrors(checker.checkAll(programs));
|
|
280
377
|
lowerStdlibRefs(programs);
|
|
378
|
+
installLazyBodies(info, programs, checker);
|
|
379
|
+
|
|
380
|
+
// A user reference to a member checks the bodies it reaches, so a type
|
|
381
|
+
// error in the standard library surfaces at the call. Failures from other
|
|
382
|
+
// packages' bodies surface when the output is assembled.
|
|
383
|
+
const reach = new StdlibReach(programs);
|
|
384
|
+
const jsOnly =
|
|
385
|
+
v.variant === "shared" ? stdlibJsOnlyNames(dir, deps) : new Set();
|
|
386
|
+
const namespace = stdlibNamespace(checker, info, jsOnly);
|
|
387
|
+
namespace._path = importPath;
|
|
388
|
+
namespace._reach = (name) => {
|
|
389
|
+
const seen = reach.failures.length;
|
|
390
|
+
reach.add([{ kind: "Ident", name }]);
|
|
391
|
+
return reach.failures[seen] ?? null;
|
|
392
|
+
};
|
|
281
393
|
|
|
282
394
|
const pkg = {
|
|
283
395
|
importPath,
|
|
396
|
+
key: v.key,
|
|
284
397
|
checker,
|
|
285
398
|
pkgName: info.pkgName,
|
|
286
|
-
|
|
287
|
-
namespace: stdlibNamespace(checker, info, overlay),
|
|
399
|
+
namespace,
|
|
288
400
|
exportedTypes: stdlibExportedTypes(checker, info),
|
|
289
401
|
deps: programs
|
|
290
402
|
.flatMap((p) => p.imports.flatMap((imp) => imp.imports))
|
|
291
|
-
.map(({ path }) =>
|
|
403
|
+
.map(({ path }) =>
|
|
404
|
+
v.variant === "shared"
|
|
405
|
+
? (cache.get(`${path}#shared`) ?? cache.get(path))
|
|
406
|
+
: cache.get(path),
|
|
407
|
+
)
|
|
292
408
|
.filter(Boolean),
|
|
293
409
|
unit: {
|
|
294
410
|
key: `stdlib:${importPath}`,
|
|
@@ -307,19 +423,20 @@ function buildStdlibPackage(importPath, dir, options, deps) {
|
|
|
307
423
|
// emitted (see lower/reachability.js). Importers leave a marker line.
|
|
308
424
|
const STDLIB_MARKER_RE = /^\/\*__GOFRONT_STDLIB:([^*]*)\*\/$/;
|
|
309
425
|
|
|
310
|
-
function stdlibMarker(
|
|
311
|
-
return `/*__GOFRONT_STDLIB:${
|
|
426
|
+
function stdlibMarker(key) {
|
|
427
|
+
return `/*__GOFRONT_STDLIB:${key}*/`;
|
|
312
428
|
}
|
|
313
429
|
|
|
314
|
-
function stdlibJs(pkg, reached) {
|
|
430
|
+
function stdlibJs(pkg, reached, natives) {
|
|
315
431
|
const programs = pkg.unit.programs.map((p) => ({
|
|
316
432
|
...p,
|
|
317
433
|
decls: p.decls.filter((d) => reached.has(d)),
|
|
318
434
|
}));
|
|
319
435
|
if (programs.every((p) => p.decls.length === 0)) return "";
|
|
320
436
|
return new CodeGen(pkg.checker, new Map(), new Set(), {
|
|
321
|
-
target:
|
|
437
|
+
target: pkg.checker.target,
|
|
322
438
|
strict: true,
|
|
439
|
+
natives,
|
|
323
440
|
}).generateAll(programs, { isTest: false });
|
|
324
441
|
}
|
|
325
442
|
|
|
@@ -346,11 +463,15 @@ function spliceStdlibJs(merged, options) {
|
|
|
346
463
|
const pkgs = lines
|
|
347
464
|
.map((l) => l.match(STDLIB_MARKER_RE)?.[1])
|
|
348
465
|
.filter(Boolean)
|
|
349
|
-
.map((
|
|
466
|
+
.map((key) => options.stdlibCache.get(key));
|
|
350
467
|
if (pkgs.length === 0) return;
|
|
468
|
+
// The whole package carries everything its shared variant has.
|
|
469
|
+
const keys = new Set(pkgs.map((pkg) => pkg.key));
|
|
470
|
+
const emitted = (pkg) =>
|
|
471
|
+
pkg.key.endsWith("#shared") ? !keys.has(pkg.importPath) : true;
|
|
351
472
|
const reached = reachableStdlibDecls(
|
|
352
473
|
[options.jsRootPrograms, wasmExportedSignatures(options.wasmUnits)],
|
|
353
|
-
pkgs.flatMap((pkg) => pkg.unit.programs),
|
|
474
|
+
pkgs.filter(emitted).flatMap((pkg) => pkg.unit.programs),
|
|
354
475
|
);
|
|
355
476
|
const out = [];
|
|
356
477
|
const spliced = new Set();
|
|
@@ -362,7 +483,8 @@ function spliceStdlibJs(merged, options) {
|
|
|
362
483
|
}
|
|
363
484
|
if (spliced.has(path)) continue;
|
|
364
485
|
spliced.add(path);
|
|
365
|
-
const
|
|
486
|
+
const pkg = options.stdlibCache.get(path);
|
|
487
|
+
const js = emitted(pkg) ? stdlibJs(pkg, reached, options.natives) : "";
|
|
366
488
|
const code = js === "" ? [] : js.split("\n");
|
|
367
489
|
const delta = code.length - 1;
|
|
368
490
|
for (const m of merged.mappings)
|
|
@@ -392,10 +514,10 @@ function emitStdlibPackage(
|
|
|
392
514
|
emitStdlibPackage(dep, importerTarget, preambles, bundledDirs, options);
|
|
393
515
|
// Every importer leaves a JS marker: the facade of a wasm package may
|
|
394
516
|
// expose a stdlib type; unreachable code splices to nothing.
|
|
395
|
-
const key = `${pkg.
|
|
517
|
+
const key = `${pkg.key}:js`;
|
|
396
518
|
if (!bundledDirs.has(key)) {
|
|
397
519
|
bundledDirs.add(key);
|
|
398
|
-
preambles.push(stdlibMarker(pkg.
|
|
520
|
+
preambles.push(stdlibMarker(pkg.key));
|
|
399
521
|
}
|
|
400
522
|
if (importerTarget !== "js") registerWasmUnit(options, pkg.unit);
|
|
401
523
|
}
|
|
@@ -422,47 +544,75 @@ function bindStdlibImport(checker, p, spec, pkg) {
|
|
|
422
544
|
return;
|
|
423
545
|
}
|
|
424
546
|
const name = alias ?? pkg.pkgName;
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
if (pkg.overlay && name !== pkg.pkgName) {
|
|
428
|
-
errAtImport(
|
|
429
|
-
checker,
|
|
430
|
-
p,
|
|
431
|
-
spec,
|
|
432
|
-
`import alias for '${path}' is not supported`,
|
|
433
|
-
);
|
|
434
|
-
return;
|
|
435
|
-
}
|
|
436
|
-
checker.globals.define(name, { ...pkg.namespace, name });
|
|
547
|
+
const ns = { ...pkg.namespace, name };
|
|
548
|
+
checker.globals.define(name, ns);
|
|
437
549
|
for (const [k, t] of pkg.exportedTypes) {
|
|
438
550
|
const dot = k.indexOf(".");
|
|
439
551
|
checker.types.set(dot < 0 ? k : `${name}${k.slice(dot)}`, t);
|
|
440
552
|
}
|
|
441
|
-
if (!
|
|
553
|
+
if (!spec._implicit)
|
|
442
554
|
checker.trackImport(name, importNode(spec), p._filename, p._source);
|
|
443
555
|
}
|
|
444
556
|
|
|
445
|
-
//
|
|
446
|
-
//
|
|
447
|
-
//
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
557
|
+
// The generators behind the package's `gofront_gen.go`: each scans the
|
|
558
|
+
// checked programs for its call sites, marks them with `_genEntry` and returns
|
|
559
|
+
// null (no sites) or { body, imports, diagnostics }.
|
|
560
|
+
const GENERATORS = [
|
|
561
|
+
generateJsonCodecs,
|
|
562
|
+
generateErrorsAs,
|
|
563
|
+
generateFmtFormatters,
|
|
564
|
+
];
|
|
565
|
+
|
|
566
|
+
// Generates, imports and checks the package's generated Go (json codecs,
|
|
567
|
+
// `errors.As` functions) as one more file. Returns the generated programs:
|
|
568
|
+
// none for a package with errors or one with no generated call sites.
|
|
569
|
+
export function checkGeneratedGo(
|
|
570
|
+
programs,
|
|
571
|
+
checker,
|
|
572
|
+
preambles,
|
|
573
|
+
options,
|
|
574
|
+
deps,
|
|
575
|
+
generators = GENERATORS,
|
|
576
|
+
) {
|
|
577
|
+
if (checker.errors.length > 0) return [];
|
|
578
|
+
const parts = generators
|
|
579
|
+
.map((gen) => gen(programs, checker, checker.pkgName, options))
|
|
580
|
+
.filter(Boolean);
|
|
581
|
+
if (parts.length === 0) return [];
|
|
582
|
+
let failed = false;
|
|
583
|
+
for (const { diagnostics } of parts)
|
|
584
|
+
for (const { program, node, message, hint } of diagnostics) {
|
|
585
|
+
failed = true;
|
|
586
|
+
checker._setCurrentFile(program);
|
|
587
|
+
checker.recordBlocker("unsupported stdlib member", message);
|
|
588
|
+
checker.err(message, node, hint);
|
|
589
|
+
}
|
|
590
|
+
if (failed) return [];
|
|
591
|
+
// An import is a path or { path, alias }.
|
|
592
|
+
const specs = new Map();
|
|
593
|
+
for (const imp of parts.flatMap((p) => p.imports)) {
|
|
594
|
+
const { path, alias } = typeof imp === "string" ? { path: imp } : imp;
|
|
595
|
+
specs.set(`${alias ?? ""} ${path}`, { path, alias });
|
|
457
596
|
}
|
|
458
|
-
|
|
459
|
-
const
|
|
597
|
+
const imports = [...specs.values()];
|
|
598
|
+
const source = [
|
|
599
|
+
`package ${checker.pkgName}`,
|
|
600
|
+
...(imports.length > 0
|
|
601
|
+
? [
|
|
602
|
+
`import (\n${imports.map(({ path, alias }) => `\t${alias ? `${alias} ` : ""}${JSON.stringify(path)}`).join("\n")}\n)`,
|
|
603
|
+
]
|
|
604
|
+
: []),
|
|
605
|
+
...parts.map((p) => p.body),
|
|
606
|
+
"",
|
|
607
|
+
].join("\n\n");
|
|
608
|
+
const filename = "gofront_gen.go";
|
|
460
609
|
const ast = new Parser(
|
|
461
|
-
new Lexer(
|
|
610
|
+
new Lexer(source, filename).tokenize(),
|
|
462
611
|
filename,
|
|
463
|
-
|
|
612
|
+
source,
|
|
464
613
|
).parse();
|
|
465
|
-
ast._source =
|
|
614
|
+
ast._source = source;
|
|
615
|
+
ast._generated = true;
|
|
466
616
|
ast._path = join(dirname(programs[0]._path ?? "."), filename);
|
|
467
617
|
ast.target = checker.target;
|
|
468
618
|
importStdlibPackages(
|
|
@@ -481,12 +631,94 @@ export function checkJsonCodecs(programs, checker, preambles, options, deps) {
|
|
|
481
631
|
.map((e) => e.message)
|
|
482
632
|
.join("\n");
|
|
483
633
|
throw new Error(
|
|
484
|
-
`internal error in the generated
|
|
634
|
+
`internal error in the generated Go; please report\n${detail}`,
|
|
485
635
|
);
|
|
486
636
|
}
|
|
637
|
+
for (const { link } of parts) link?.(checker);
|
|
487
638
|
return [ast];
|
|
488
639
|
}
|
|
489
640
|
|
|
641
|
+
// Packages a `js` package may use without importing them, as the compiler
|
|
642
|
+
// has always allowed: a program that selects from the identifier (or, for
|
|
643
|
+
// `gom`, declares a templ component, typed as `gom.Node`) without declaring
|
|
644
|
+
// or importing it gets the import.
|
|
645
|
+
const IMPLICIT_PACKAGES = ["fmt", "gom", "regexp"];
|
|
646
|
+
|
|
647
|
+
function implicitImports(programs) {
|
|
648
|
+
const declared = (name) =>
|
|
649
|
+
programs.some(
|
|
650
|
+
(p) =>
|
|
651
|
+
p.imports.some((imp) =>
|
|
652
|
+
imp.imports.some((s) => s.path === name || s.alias === name),
|
|
653
|
+
) || stdlibTopLevelNames([p]).values.has(name),
|
|
654
|
+
);
|
|
655
|
+
const used = new Set();
|
|
656
|
+
const visit = (node) => {
|
|
657
|
+
if (!node || typeof node !== "object") return;
|
|
658
|
+
if (Array.isArray(node)) return node.forEach(visit);
|
|
659
|
+
if (node.kind === "TemplDecl") used.add("gom");
|
|
660
|
+
else if (
|
|
661
|
+
node.kind === "SelectorExpr" &&
|
|
662
|
+
IMPLICIT_PACKAGES.includes(node.expr?.name)
|
|
663
|
+
)
|
|
664
|
+
used.add(node.expr.name);
|
|
665
|
+
else if (typeof node.name === "string" && node.kind?.endsWith("TypeName"))
|
|
666
|
+
for (const name of IMPLICIT_PACKAGES)
|
|
667
|
+
if (node.name.startsWith(`${name}.`)) used.add(name);
|
|
668
|
+
forEachChild(node, visit);
|
|
669
|
+
};
|
|
670
|
+
for (const p of programs) visit(p.decls);
|
|
671
|
+
return [...used]
|
|
672
|
+
.filter((name) => !declared(name))
|
|
673
|
+
.map((path) => ({ path, _line: 1, _col: 1, _implicit: true }));
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
// Packages that keep their own wording for the unavailable-in-wasm error.
|
|
677
|
+
const NOT_IN_WASM = new Map([["gom", "gom usage"]]);
|
|
678
|
+
|
|
679
|
+
// Reports an import of a `js`-only package from a `wasm` or `both` package.
|
|
680
|
+
function errJsOnlyImport(checker, p, spec) {
|
|
681
|
+
// Its uses are not a second root cause.
|
|
682
|
+
checker._unavailableImports ??= new Set();
|
|
683
|
+
checker._unavailableImports.add(spec.alias ?? spec.path.split("/").at(-1));
|
|
684
|
+
const category = NOT_IN_WASM.get(spec.path);
|
|
685
|
+
if (category) {
|
|
686
|
+
checker.recordBlocker(category, spec.path);
|
|
687
|
+
const msg = `package '${spec.path}' is not available in wasm packages`;
|
|
688
|
+
return errAtImport(checker, p, spec, msg);
|
|
689
|
+
}
|
|
690
|
+
checker.recordBlocker("unsupported stdlib import", spec.path);
|
|
691
|
+
const msg = `package '${spec.path}' is only available in js packages`;
|
|
692
|
+
errAtImport(checker, p, spec, msg, "move this code to a js package");
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
// Loads and binds one import of program `p`.
|
|
696
|
+
function importStdlibSpec(
|
|
697
|
+
p,
|
|
698
|
+
spec,
|
|
699
|
+
checker,
|
|
700
|
+
preambles,
|
|
701
|
+
bundledDirs,
|
|
702
|
+
options,
|
|
703
|
+
deps,
|
|
704
|
+
) {
|
|
705
|
+
if (spec.path.startsWith("js:") || isLocalPath(spec.path)) return;
|
|
706
|
+
const dir = resolveStdlibSource(spec.path, options.stdlibRoot);
|
|
707
|
+
if (!dir) return;
|
|
708
|
+
const wasmImporter = checker.target === "wasm" || checker.target === "both";
|
|
709
|
+
if (wasmImporter && stdlibIsJsOnly(dir, deps))
|
|
710
|
+
return errJsOnlyImport(checker, p, spec);
|
|
711
|
+
let pkg;
|
|
712
|
+
try {
|
|
713
|
+
pkg = loadStdlibPackage(spec.path, dir, options, deps, checker.target);
|
|
714
|
+
} catch (e) {
|
|
715
|
+
const msg = `internal stdlib error in ${spec.path}; please report`;
|
|
716
|
+
return errAtImport(checker, p, spec, msg, e.message);
|
|
717
|
+
}
|
|
718
|
+
emitStdlibPackage(pkg, checker.target, preambles, bundledDirs, options);
|
|
719
|
+
bindStdlibImport(checker, p, spec, pkg);
|
|
720
|
+
}
|
|
721
|
+
|
|
490
722
|
export function importStdlibPackages(
|
|
491
723
|
programs,
|
|
492
724
|
checker,
|
|
@@ -495,21 +727,12 @@ export function importStdlibPackages(
|
|
|
495
727
|
options,
|
|
496
728
|
deps,
|
|
497
729
|
) {
|
|
730
|
+
const wasmImporter = checker.target === "wasm" || checker.target === "both";
|
|
731
|
+
const implicit = wasmImporter ? [] : implicitImports(programs);
|
|
498
732
|
for (const p of programs) {
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
let pkg;
|
|
504
|
-
try {
|
|
505
|
-
pkg = loadStdlibPackage(spec.path, dir, options, deps);
|
|
506
|
-
} catch (e) {
|
|
507
|
-
const msg = `internal stdlib error in ${spec.path}; please report`;
|
|
508
|
-
errAtImport(checker, p, spec, msg, e.message);
|
|
509
|
-
continue;
|
|
510
|
-
}
|
|
511
|
-
emitStdlibPackage(pkg, checker.target, preambles, bundledDirs, options);
|
|
512
|
-
bindStdlibImport(checker, p, spec, pkg);
|
|
513
|
-
}
|
|
733
|
+
const specs = p.imports.flatMap((imp) => imp.imports);
|
|
734
|
+
if (p === programs[0]) specs.push(...implicit);
|
|
735
|
+
for (const spec of specs)
|
|
736
|
+
importStdlibSpec(p, spec, checker, preambles, bundledDirs, options, deps);
|
|
514
737
|
}
|
|
515
738
|
}
|