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/typechecker/types.js
CHANGED
|
@@ -106,593 +106,178 @@ export const BROWSER_GLOBALS = new Set([
|
|
|
106
106
|
// gains support; anything not listed is rejected at import with "not yet available in
|
|
107
107
|
// wasm packages".
|
|
108
108
|
export const WASM_SUPPORTED_STDLIB = new Set([
|
|
109
|
-
"math",
|
|
110
|
-
"math/bits",
|
|
111
|
-
"math/rand",
|
|
112
|
-
"errors",
|
|
113
|
-
"fmt",
|
|
114
|
-
"strings",
|
|
115
|
-
"bytes",
|
|
116
|
-
"strconv",
|
|
117
|
-
"unicode",
|
|
118
|
-
"unicode/utf8",
|
|
119
|
-
"slices",
|
|
120
|
-
"maps",
|
|
121
|
-
"sort",
|
|
122
|
-
"path",
|
|
123
|
-
"path/filepath",
|
|
124
|
-
"html",
|
|
125
|
-
"io",
|
|
126
|
-
"time",
|
|
127
|
-
"testing",
|
|
128
109
|
"gofront/shared",
|
|
129
110
|
"gofront/simd",
|
|
130
|
-
"sync",
|
|
131
|
-
"crypto/rand",
|
|
132
|
-
"crypto/sha256",
|
|
133
|
-
"encoding/binary",
|
|
134
|
-
"encoding/hex",
|
|
135
|
-
"encoding/base64",
|
|
136
|
-
"os",
|
|
137
|
-
"encoding/json",
|
|
138
111
|
]);
|
|
139
112
|
|
|
140
|
-
export const STDLIB_PACKAGES =
|
|
141
|
-
...WASM_SUPPORTED_STDLIB,
|
|
142
|
-
"gom",
|
|
143
|
-
"regexp",
|
|
144
|
-
]);
|
|
113
|
+
export const STDLIB_PACKAGES = WASM_SUPPORTED_STDLIB;
|
|
145
114
|
|
|
146
115
|
// Per-namespace member subset the WASM backend implements. `null` means every
|
|
147
116
|
// member the checker knows about. Members outside the set are rejected in
|
|
148
117
|
// wasm/both packages with "'strings.Split' is not yet available in wasm packages".
|
|
149
|
-
export const WASM_STDLIB_MEMBERS = new Map(
|
|
150
|
-
["os", new Set(["Stdout", "Stderr", "Stdin", "File"])],
|
|
151
|
-
[
|
|
152
|
-
"math",
|
|
153
|
-
new Set([
|
|
154
|
-
"Sqrt",
|
|
155
|
-
"Floor",
|
|
156
|
-
"Ceil",
|
|
157
|
-
"Trunc",
|
|
158
|
-
"Abs",
|
|
159
|
-
"Min",
|
|
160
|
-
"Max",
|
|
161
|
-
"Copysign",
|
|
162
|
-
"Dim",
|
|
163
|
-
"Inf",
|
|
164
|
-
"NaN",
|
|
165
|
-
"IsNaN",
|
|
166
|
-
"IsInf",
|
|
167
|
-
"Signbit",
|
|
168
|
-
"Sin",
|
|
169
|
-
"Cos",
|
|
170
|
-
"Tan",
|
|
171
|
-
"Asin",
|
|
172
|
-
"Acos",
|
|
173
|
-
"Atan",
|
|
174
|
-
"Atan2",
|
|
175
|
-
"Pow",
|
|
176
|
-
"Mod",
|
|
177
|
-
"Hypot",
|
|
178
|
-
"Cbrt",
|
|
179
|
-
"Exp",
|
|
180
|
-
"Exp2",
|
|
181
|
-
"Log",
|
|
182
|
-
"Log1p",
|
|
183
|
-
"Log2",
|
|
184
|
-
"Log10",
|
|
185
|
-
"Expm1",
|
|
186
|
-
"Round",
|
|
187
|
-
"Remainder",
|
|
188
|
-
"Float64bits",
|
|
189
|
-
"Float64frombits",
|
|
190
|
-
"Float32bits",
|
|
191
|
-
"Float32frombits",
|
|
192
|
-
"Sinh",
|
|
193
|
-
"Cosh",
|
|
194
|
-
"Tanh",
|
|
195
|
-
// constants
|
|
196
|
-
"E",
|
|
197
|
-
"Pi",
|
|
198
|
-
"Phi",
|
|
199
|
-
"Sqrt2",
|
|
200
|
-
"SqrtE",
|
|
201
|
-
"SqrtPi",
|
|
202
|
-
"SqrtPhi",
|
|
203
|
-
"Ln2",
|
|
204
|
-
"Log2E",
|
|
205
|
-
"Ln10",
|
|
206
|
-
"Log10E",
|
|
207
|
-
"MaxFloat32",
|
|
208
|
-
"SmallestNonzeroFloat32",
|
|
209
|
-
"MaxFloat64",
|
|
210
|
-
"SmallestNonzeroFloat64",
|
|
211
|
-
"MaxInt",
|
|
212
|
-
"MinInt",
|
|
213
|
-
"MaxInt8",
|
|
214
|
-
"MinInt8",
|
|
215
|
-
"MaxInt16",
|
|
216
|
-
"MinInt16",
|
|
217
|
-
"MaxInt32",
|
|
218
|
-
"MinInt32",
|
|
219
|
-
"MaxInt64",
|
|
220
|
-
"MinInt64",
|
|
221
|
-
"MaxUint8",
|
|
222
|
-
"MaxUint16",
|
|
223
|
-
"MaxUint32",
|
|
224
|
-
"MaxUint",
|
|
225
|
-
"MaxUint64",
|
|
226
|
-
]),
|
|
227
|
-
],
|
|
228
|
-
[
|
|
229
|
-
"bits",
|
|
230
|
-
new Set([
|
|
231
|
-
"Add",
|
|
232
|
-
"Add32",
|
|
233
|
-
"Add64",
|
|
234
|
-
"Sub",
|
|
235
|
-
"Sub32",
|
|
236
|
-
"Sub64",
|
|
237
|
-
"Mul",
|
|
238
|
-
"Mul32",
|
|
239
|
-
"Mul64",
|
|
240
|
-
"Div",
|
|
241
|
-
"Div32",
|
|
242
|
-
"Div64",
|
|
243
|
-
"Rem",
|
|
244
|
-
"Rem32",
|
|
245
|
-
"Rem64",
|
|
246
|
-
"LeadingZeros",
|
|
247
|
-
"LeadingZeros8",
|
|
248
|
-
"LeadingZeros16",
|
|
249
|
-
"LeadingZeros32",
|
|
250
|
-
"LeadingZeros64",
|
|
251
|
-
"TrailingZeros",
|
|
252
|
-
"TrailingZeros8",
|
|
253
|
-
"TrailingZeros16",
|
|
254
|
-
"TrailingZeros32",
|
|
255
|
-
"TrailingZeros64",
|
|
256
|
-
"OnesCount",
|
|
257
|
-
"OnesCount8",
|
|
258
|
-
"OnesCount16",
|
|
259
|
-
"OnesCount32",
|
|
260
|
-
"OnesCount64",
|
|
261
|
-
"RotateLeft",
|
|
262
|
-
"RotateLeft8",
|
|
263
|
-
"RotateLeft16",
|
|
264
|
-
"RotateLeft32",
|
|
265
|
-
"RotateLeft64",
|
|
266
|
-
"Reverse",
|
|
267
|
-
"Reverse8",
|
|
268
|
-
"Reverse16",
|
|
269
|
-
"Reverse32",
|
|
270
|
-
"Reverse64",
|
|
271
|
-
"ReverseBytes",
|
|
272
|
-
"ReverseBytes16",
|
|
273
|
-
"ReverseBytes32",
|
|
274
|
-
"ReverseBytes64",
|
|
275
|
-
"Len",
|
|
276
|
-
"Len8",
|
|
277
|
-
"Len16",
|
|
278
|
-
"Len32",
|
|
279
|
-
"Len64",
|
|
280
|
-
"UintSize",
|
|
281
|
-
]),
|
|
282
|
-
],
|
|
283
|
-
["errors", new Set(["New", "Is", "Unwrap", "As", "Join"])],
|
|
284
|
-
[
|
|
285
|
-
"utf8",
|
|
286
|
-
new Set([
|
|
287
|
-
"RuneCountInString",
|
|
288
|
-
"RuneLen",
|
|
289
|
-
"ValidString",
|
|
290
|
-
"ValidRune",
|
|
291
|
-
"DecodeRuneInString",
|
|
292
|
-
"DecodeLastRuneInString",
|
|
293
|
-
"FullRuneInString",
|
|
294
|
-
"RuneError",
|
|
295
|
-
"MaxRune",
|
|
296
|
-
"UTFMax",
|
|
297
|
-
"RuneSelf",
|
|
298
|
-
"EncodeRune",
|
|
299
|
-
"AppendRune",
|
|
300
|
-
"DecodeRune",
|
|
301
|
-
"DecodeLastRune",
|
|
302
|
-
"RuneCount",
|
|
303
|
-
"FullRune",
|
|
304
|
-
"Valid",
|
|
305
|
-
"RuneStart",
|
|
306
|
-
]),
|
|
307
|
-
],
|
|
308
|
-
[
|
|
309
|
-
"sort",
|
|
310
|
-
new Set([
|
|
311
|
-
"Ints",
|
|
312
|
-
"Float64s",
|
|
313
|
-
"Strings",
|
|
314
|
-
"Slice",
|
|
315
|
-
"SliceStable",
|
|
316
|
-
"SliceIsSorted",
|
|
317
|
-
"Search",
|
|
318
|
-
"IntsAreSorted",
|
|
319
|
-
"Float64sAreSorted",
|
|
320
|
-
"StringsAreSorted",
|
|
321
|
-
]),
|
|
322
|
-
],
|
|
323
|
-
[
|
|
324
|
-
"fmt",
|
|
325
|
-
new Set([
|
|
326
|
-
"Sprintf",
|
|
327
|
-
"Sprint",
|
|
328
|
-
"Sprintln",
|
|
329
|
-
"Append",
|
|
330
|
-
"Appendf",
|
|
331
|
-
"Appendln",
|
|
332
|
-
"Errorf",
|
|
333
|
-
"Printf",
|
|
334
|
-
"Println",
|
|
335
|
-
"Print",
|
|
336
|
-
"Fprintf",
|
|
337
|
-
"Fprintln",
|
|
338
|
-
"Fprint",
|
|
339
|
-
"Sscan",
|
|
340
|
-
"Sscanln",
|
|
341
|
-
"Sscanf",
|
|
342
|
-
"Stringer",
|
|
343
|
-
]),
|
|
344
|
-
],
|
|
345
|
-
[
|
|
346
|
-
"strings",
|
|
347
|
-
new Set([
|
|
348
|
-
"Contains",
|
|
349
|
-
"ContainsAny",
|
|
350
|
-
"ContainsRune",
|
|
351
|
-
"HasPrefix",
|
|
352
|
-
"HasSuffix",
|
|
353
|
-
"Index",
|
|
354
|
-
"IndexAny",
|
|
355
|
-
"IndexByte",
|
|
356
|
-
"IndexRune",
|
|
357
|
-
"LastIndex",
|
|
358
|
-
"LastIndexByte",
|
|
359
|
-
"Count",
|
|
360
|
-
"Repeat",
|
|
361
|
-
"Replace",
|
|
362
|
-
"ReplaceAll",
|
|
363
|
-
"ToUpper",
|
|
364
|
-
"ToLower",
|
|
365
|
-
"Title",
|
|
366
|
-
"ToTitle",
|
|
367
|
-
"TrimSpace",
|
|
368
|
-
"Trim",
|
|
369
|
-
"TrimLeft",
|
|
370
|
-
"TrimRight",
|
|
371
|
-
"TrimPrefix",
|
|
372
|
-
"TrimSuffix",
|
|
373
|
-
"EqualFold",
|
|
374
|
-
"Split",
|
|
375
|
-
"Fields",
|
|
376
|
-
"Join",
|
|
377
|
-
"Cut",
|
|
378
|
-
"CutPrefix",
|
|
379
|
-
"CutSuffix",
|
|
380
|
-
"SplitN",
|
|
381
|
-
"SplitAfter",
|
|
382
|
-
"SplitAfterN",
|
|
383
|
-
"LastIndexAny",
|
|
384
|
-
"Map",
|
|
385
|
-
"IndexFunc",
|
|
386
|
-
"LastIndexFunc",
|
|
387
|
-
"TrimFunc",
|
|
388
|
-
"TrimLeftFunc",
|
|
389
|
-
"TrimRightFunc",
|
|
390
|
-
"FieldsFunc",
|
|
391
|
-
"NewReplacer",
|
|
392
|
-
"Replacer",
|
|
393
|
-
"Builder",
|
|
394
|
-
"NewReader",
|
|
395
|
-
"Reader",
|
|
396
|
-
"ToValidUTF8",
|
|
397
|
-
]),
|
|
398
|
-
],
|
|
399
|
-
[
|
|
400
|
-
"strconv",
|
|
401
|
-
new Set([
|
|
402
|
-
"Itoa",
|
|
403
|
-
"Atoi",
|
|
404
|
-
"FormatInt",
|
|
405
|
-
"FormatUint",
|
|
406
|
-
"FormatFloat",
|
|
407
|
-
"FormatBool",
|
|
408
|
-
"ParseInt",
|
|
409
|
-
"ParseUint",
|
|
410
|
-
"ParseFloat",
|
|
411
|
-
"ParseBool",
|
|
412
|
-
"Quote",
|
|
413
|
-
"Unquote",
|
|
414
|
-
"AppendInt",
|
|
415
|
-
"AppendUint",
|
|
416
|
-
"AppendFloat",
|
|
417
|
-
"AppendBool",
|
|
418
|
-
"ErrSyntax",
|
|
419
|
-
"ErrRange",
|
|
420
|
-
"IntSize",
|
|
421
|
-
"NumError",
|
|
422
|
-
"QuoteRune",
|
|
423
|
-
"QuoteToASCII",
|
|
424
|
-
"QuoteRuneToASCII",
|
|
425
|
-
"AppendQuote",
|
|
426
|
-
"AppendQuoteToASCII",
|
|
427
|
-
"AppendQuoteRune",
|
|
428
|
-
"AppendQuoteRuneToASCII",
|
|
429
|
-
"CanBackquote",
|
|
430
|
-
"UnquoteChar",
|
|
431
|
-
"QuotedPrefix",
|
|
432
|
-
"IsPrint",
|
|
433
|
-
"IsGraphic",
|
|
434
|
-
]),
|
|
435
|
-
],
|
|
436
|
-
[
|
|
437
|
-
"slices",
|
|
438
|
-
new Set([
|
|
439
|
-
"Sort",
|
|
440
|
-
"Reverse",
|
|
441
|
-
"Contains",
|
|
442
|
-
"Index",
|
|
443
|
-
"IndexFunc",
|
|
444
|
-
"ContainsFunc",
|
|
445
|
-
"BinarySearch",
|
|
446
|
-
"BinarySearchFunc",
|
|
447
|
-
"Equal",
|
|
448
|
-
"Clone",
|
|
449
|
-
"Compare",
|
|
450
|
-
"SortFunc",
|
|
451
|
-
"SortStableFunc",
|
|
452
|
-
"IsSorted",
|
|
453
|
-
"IsSortedFunc",
|
|
454
|
-
"Min",
|
|
455
|
-
"Max",
|
|
456
|
-
"MinFunc",
|
|
457
|
-
"MaxFunc",
|
|
458
|
-
"Compact",
|
|
459
|
-
"CompactFunc",
|
|
460
|
-
"Concat",
|
|
461
|
-
"Delete",
|
|
462
|
-
"DeleteFunc",
|
|
463
|
-
"Insert",
|
|
464
|
-
"Replace",
|
|
465
|
-
"Grow",
|
|
466
|
-
"Clip",
|
|
467
|
-
]),
|
|
468
|
-
],
|
|
469
|
-
[
|
|
470
|
-
"maps",
|
|
471
|
-
new Set(["Clone", "Copy", "Equal", "EqualFunc", "Delete", "DeleteFunc"]),
|
|
472
|
-
],
|
|
473
|
-
[
|
|
474
|
-
"unicode",
|
|
475
|
-
new Set([
|
|
476
|
-
"IsLetter",
|
|
477
|
-
"IsDigit",
|
|
478
|
-
"IsSpace",
|
|
479
|
-
"IsUpper",
|
|
480
|
-
"IsLower",
|
|
481
|
-
"IsPunct",
|
|
482
|
-
"IsControl",
|
|
483
|
-
"IsPrint",
|
|
484
|
-
"IsGraphic",
|
|
485
|
-
"ToUpper",
|
|
486
|
-
"ToLower",
|
|
487
|
-
]),
|
|
488
|
-
],
|
|
489
|
-
[
|
|
490
|
-
"rand",
|
|
491
|
-
new Set([
|
|
492
|
-
"Intn",
|
|
493
|
-
"Float64",
|
|
494
|
-
"Float32",
|
|
495
|
-
"Int",
|
|
496
|
-
"Int63",
|
|
497
|
-
"Int63n",
|
|
498
|
-
"Int31",
|
|
499
|
-
"Int31n",
|
|
500
|
-
"Seed",
|
|
501
|
-
"Shuffle",
|
|
502
|
-
"Perm",
|
|
503
|
-
"Read",
|
|
504
|
-
"Reader",
|
|
505
|
-
]),
|
|
506
|
-
],
|
|
507
|
-
[
|
|
508
|
-
"bytes",
|
|
509
|
-
new Set([
|
|
510
|
-
"Contains",
|
|
511
|
-
"HasPrefix",
|
|
512
|
-
"HasSuffix",
|
|
513
|
-
"Index",
|
|
514
|
-
"Count",
|
|
515
|
-
"Repeat",
|
|
516
|
-
"Replace",
|
|
517
|
-
"ReplaceAll",
|
|
518
|
-
"ToUpper",
|
|
519
|
-
"ToLower",
|
|
520
|
-
"TrimSpace",
|
|
521
|
-
"Trim",
|
|
522
|
-
"Equal",
|
|
523
|
-
"Split",
|
|
524
|
-
"Join",
|
|
525
|
-
"TrimPrefix",
|
|
526
|
-
"TrimSuffix",
|
|
527
|
-
"TrimLeft",
|
|
528
|
-
"TrimRight",
|
|
529
|
-
"TrimFunc",
|
|
530
|
-
"IndexByte",
|
|
531
|
-
"LastIndex",
|
|
532
|
-
"LastIndexByte",
|
|
533
|
-
"Fields",
|
|
534
|
-
"FieldsFunc",
|
|
535
|
-
"Clone",
|
|
536
|
-
"Cut",
|
|
537
|
-
"ToTitle",
|
|
538
|
-
"ContainsAny",
|
|
539
|
-
"ContainsRune",
|
|
540
|
-
"Map",
|
|
541
|
-
"SplitN",
|
|
542
|
-
"Buffer",
|
|
543
|
-
"NewBuffer",
|
|
544
|
-
"NewBufferString",
|
|
545
|
-
"NewReader",
|
|
546
|
-
"Reader",
|
|
547
|
-
"ToValidUTF8",
|
|
548
|
-
]),
|
|
549
|
-
],
|
|
550
|
-
[
|
|
551
|
-
"path",
|
|
552
|
-
new Set([
|
|
553
|
-
"Base",
|
|
554
|
-
"Dir",
|
|
555
|
-
"Ext",
|
|
556
|
-
"Join",
|
|
557
|
-
"Clean",
|
|
558
|
-
"IsAbs",
|
|
559
|
-
"Split",
|
|
560
|
-
"Match",
|
|
561
|
-
"ErrBadPattern",
|
|
562
|
-
]),
|
|
563
|
-
],
|
|
564
|
-
[
|
|
565
|
-
"filepath",
|
|
566
|
-
new Set([
|
|
567
|
-
"Base",
|
|
568
|
-
"Dir",
|
|
569
|
-
"Ext",
|
|
570
|
-
"Join",
|
|
571
|
-
"Clean",
|
|
572
|
-
"IsAbs",
|
|
573
|
-
"Split",
|
|
574
|
-
"Match",
|
|
575
|
-
"ErrBadPattern",
|
|
576
|
-
]),
|
|
577
|
-
],
|
|
578
|
-
["html", new Set(["EscapeString", "UnescapeString"])],
|
|
579
|
-
[
|
|
580
|
-
"io",
|
|
581
|
-
new Set([
|
|
582
|
-
"Writer",
|
|
583
|
-
"Reader",
|
|
584
|
-
"ReadWriter",
|
|
585
|
-
"Closer",
|
|
586
|
-
"EOF",
|
|
587
|
-
"ReadAll",
|
|
588
|
-
"Discard",
|
|
589
|
-
"WriteString",
|
|
590
|
-
"LimitReader",
|
|
591
|
-
"Copy",
|
|
592
|
-
"CopyN",
|
|
593
|
-
]),
|
|
594
|
-
],
|
|
595
|
-
[
|
|
596
|
-
"time",
|
|
597
|
-
new Set([
|
|
598
|
-
"Now",
|
|
599
|
-
"Since",
|
|
600
|
-
"Parse",
|
|
601
|
-
"ParseDuration",
|
|
602
|
-
"Unix",
|
|
603
|
-
"UnixMicro",
|
|
604
|
-
"UnixMilli",
|
|
605
|
-
"Date",
|
|
606
|
-
"FixedZone",
|
|
607
|
-
"Duration",
|
|
608
|
-
"Nanosecond",
|
|
609
|
-
"Microsecond",
|
|
610
|
-
"Millisecond",
|
|
611
|
-
"Second",
|
|
612
|
-
"Minute",
|
|
613
|
-
"Hour",
|
|
614
|
-
"RFC3339",
|
|
615
|
-
"RFC3339Nano",
|
|
616
|
-
"DateOnly",
|
|
617
|
-
"TimeOnly",
|
|
618
|
-
"DateTime",
|
|
619
|
-
"UTC",
|
|
620
|
-
"Local",
|
|
621
|
-
"January",
|
|
622
|
-
"February",
|
|
623
|
-
"March",
|
|
624
|
-
"April",
|
|
625
|
-
"May",
|
|
626
|
-
"June",
|
|
627
|
-
"July",
|
|
628
|
-
"August",
|
|
629
|
-
"September",
|
|
630
|
-
"October",
|
|
631
|
-
"November",
|
|
632
|
-
"December",
|
|
633
|
-
"Sunday",
|
|
634
|
-
"Monday",
|
|
635
|
-
"Tuesday",
|
|
636
|
-
"Wednesday",
|
|
637
|
-
"Thursday",
|
|
638
|
-
"Friday",
|
|
639
|
-
"Saturday",
|
|
640
|
-
"Time",
|
|
641
|
-
"Month",
|
|
642
|
-
"Weekday",
|
|
643
|
-
"Location",
|
|
644
|
-
]),
|
|
645
|
-
],
|
|
646
|
-
["testing", new Set(["T", "B", "M", "TB", "BenchmarkResult"])],
|
|
647
|
-
["sync", new Set(["Mutex", "RWMutex", "Once", "WaitGroup", "Locker"])],
|
|
648
|
-
["sha256", new Set(["Sum256", "New", "Size", "BlockSize"])],
|
|
649
|
-
[
|
|
650
|
-
"binary",
|
|
651
|
-
new Set([
|
|
652
|
-
"LittleEndian",
|
|
653
|
-
"BigEndian",
|
|
654
|
-
"ByteOrder",
|
|
655
|
-
"Read",
|
|
656
|
-
"Write",
|
|
657
|
-
"Size",
|
|
658
|
-
"AppendUint16",
|
|
659
|
-
"AppendUint32",
|
|
660
|
-
"AppendUint64",
|
|
661
|
-
]),
|
|
662
|
-
],
|
|
663
|
-
[
|
|
664
|
-
"hex",
|
|
665
|
-
new Set([
|
|
666
|
-
"EncodeToString",
|
|
667
|
-
"DecodeString",
|
|
668
|
-
"Encode",
|
|
669
|
-
"Decode",
|
|
670
|
-
"EncodedLen",
|
|
671
|
-
"DecodedLen",
|
|
672
|
-
"ErrLength",
|
|
673
|
-
]),
|
|
674
|
-
],
|
|
675
|
-
[
|
|
676
|
-
"base64",
|
|
677
|
-
new Set([
|
|
678
|
-
"StdEncoding",
|
|
679
|
-
"URLEncoding",
|
|
680
|
-
"RawStdEncoding",
|
|
681
|
-
"RawURLEncoding",
|
|
682
|
-
"Encoding",
|
|
683
|
-
"NewEncoding",
|
|
684
|
-
"StdPadding",
|
|
685
|
-
"NoPadding",
|
|
686
|
-
]),
|
|
687
|
-
],
|
|
688
|
-
]);
|
|
118
|
+
export const WASM_STDLIB_MEMBERS = new Map();
|
|
689
119
|
|
|
690
120
|
export const VALID_TARGETS = new Set(["js", "wasm", "both"]);
|
|
691
121
|
|
|
692
122
|
// Backend-provided implementations for body-less Go-source stdlib functions
|
|
693
123
|
// marked `//gofront:intrinsic <name>`: name -> required signature. New
|
|
694
124
|
// intrinsics need a plan change.
|
|
695
|
-
export const INTRINSICS = new Map([
|
|
125
|
+
export const INTRINSICS = new Map([
|
|
126
|
+
// A uniformly distributed float64 in [0, 1) from the host source
|
|
127
|
+
// (`Math.random`); the only entropy math/rand draws.
|
|
128
|
+
["rand_source", "func() float64"],
|
|
129
|
+
// The host clock in nanoseconds since the Unix epoch, and the offset in
|
|
130
|
+
// seconds east of UTC of the host's time zone at a Unix time (time).
|
|
131
|
+
["time_now", "func() int64"],
|
|
132
|
+
["time_zone_offset", "func(int64) int"],
|
|
133
|
+
// time (js only): suspend for a number of nanoseconds; the declaration is
|
|
134
|
+
// `async`.
|
|
135
|
+
["time_sleep", "func(int64) void"],
|
|
136
|
+
// os: write a string to a file descriptor (0 stdin, 1 stdout, 2 stderr),
|
|
137
|
+
// exit the process, and read and set environment variables.
|
|
138
|
+
["os_write", "func(int, string) void"],
|
|
139
|
+
["os_exit", "func(int) void"],
|
|
140
|
+
["os_getenv", "func(string) string"],
|
|
141
|
+
["os_setenv", "func(string, string) void"],
|
|
142
|
+
// unicode: the host's answer for runes above ASCII, by class (the
|
|
143
|
+
// constants of stdlib/unicode), and its case mappings.
|
|
144
|
+
["unicode_is", "func(int32, int) bool"],
|
|
145
|
+
["unicode_to_upper", "func(int32) int32"],
|
|
146
|
+
["unicode_to_lower", "func(int32) int32"],
|
|
147
|
+
// crypto/rand: four random bytes from the host's secure source.
|
|
148
|
+
["crypto_rand_u32", "func() uint32"],
|
|
149
|
+
// testing: a monotonic clock in nanoseconds, and an unanchored regular
|
|
150
|
+
// expression match for -run and -bench patterns.
|
|
151
|
+
["testing_nanotime", "func() int64"],
|
|
152
|
+
["testing_match", "func(string, string) bool"],
|
|
153
|
+
// testing (js only): call a test body and return what it returned (a
|
|
154
|
+
// promise for an async body, otherwise nil).
|
|
155
|
+
["testing_call", "func(any, any) any"],
|
|
156
|
+
// fmt: a stable number for a pointer, function or other reference.
|
|
157
|
+
["fmt_ptr_id", "func(any) uint64"],
|
|
158
|
+
// math: IEEE-754 bit casts, and the host's `Math.*` (`%` for Mod).
|
|
159
|
+
["math_float64bits", "func(float64) uint64"],
|
|
160
|
+
["math_float64frombits", "func(uint64) float64"],
|
|
161
|
+
["math_float32bits", "func(float32) uint32"],
|
|
162
|
+
["math_float32frombits", "func(uint32) float32"],
|
|
163
|
+
...[
|
|
164
|
+
"sin",
|
|
165
|
+
"cos",
|
|
166
|
+
"tan",
|
|
167
|
+
"asin",
|
|
168
|
+
"acos",
|
|
169
|
+
"atan",
|
|
170
|
+
"sinh",
|
|
171
|
+
"cosh",
|
|
172
|
+
"tanh",
|
|
173
|
+
"exp",
|
|
174
|
+
"expm1",
|
|
175
|
+
"log",
|
|
176
|
+
"log1p",
|
|
177
|
+
"log2",
|
|
178
|
+
"log10",
|
|
179
|
+
"cbrt",
|
|
180
|
+
].map((f) => [`math_${f}`, "func(float64) float64"]),
|
|
181
|
+
...["atan2", "pow", "hypot", "mod"].map((f) => [
|
|
182
|
+
`math_${f}`,
|
|
183
|
+
"func(float64, float64) float64",
|
|
184
|
+
]),
|
|
185
|
+
]);
|
|
186
|
+
|
|
187
|
+
// The fmt functions whose calls the compiler wraps with a generated function
|
|
188
|
+
// (src/lower/fmt-formatters.js); a wrapped call may forward `f()`'s results.
|
|
189
|
+
export const FMT_PRINT_FUNCS = new Set([
|
|
190
|
+
"Sprint",
|
|
191
|
+
"Sprintln",
|
|
192
|
+
"Print",
|
|
193
|
+
"Println",
|
|
194
|
+
"Fprint",
|
|
195
|
+
"Fprintln",
|
|
196
|
+
"Append",
|
|
197
|
+
"Appendln",
|
|
198
|
+
"Sprintf",
|
|
199
|
+
"Printf",
|
|
200
|
+
"Errorf",
|
|
201
|
+
"Fprintf",
|
|
202
|
+
"Appendf",
|
|
203
|
+
]);
|
|
204
|
+
|
|
205
|
+
// Names a standard-library function may carry in `//gofront:native <name>`:
|
|
206
|
+
// the function keeps its Go body, and a backend registry may replace calls to
|
|
207
|
+
// it with host code (or decline). A closed set; new names need a plan change.
|
|
208
|
+
export const NATIVES = new Set([
|
|
209
|
+
"slices.Contains",
|
|
210
|
+
"slices.Index",
|
|
211
|
+
"slices.Reverse",
|
|
212
|
+
"slices.Clone",
|
|
213
|
+
"bytes.Compare",
|
|
214
|
+
"bytes.Equal",
|
|
215
|
+
"bytes.IndexByte",
|
|
216
|
+
"slices.Sort",
|
|
217
|
+
"sort.Ints",
|
|
218
|
+
"sort.Strings",
|
|
219
|
+
"utf8.RuneCountInString",
|
|
220
|
+
"strings.Index",
|
|
221
|
+
"strings.LastIndex",
|
|
222
|
+
"strings.IndexByte",
|
|
223
|
+
"strings.LastIndexByte",
|
|
224
|
+
"strings.IndexRune",
|
|
225
|
+
"strings.IndexAny",
|
|
226
|
+
"strings.LastIndexAny",
|
|
227
|
+
"strings.Contains",
|
|
228
|
+
"strings.ContainsAny",
|
|
229
|
+
"strings.ContainsRune",
|
|
230
|
+
"strings.HasPrefix",
|
|
231
|
+
"strings.HasSuffix",
|
|
232
|
+
"strings.Count",
|
|
233
|
+
"strings.Repeat",
|
|
234
|
+
"strings.Join",
|
|
235
|
+
"strings.Replace",
|
|
236
|
+
"strings.ReplaceAll",
|
|
237
|
+
"strings.Split",
|
|
238
|
+
"strings.Fields",
|
|
239
|
+
"strings.ToUpper",
|
|
240
|
+
"strings.ToLower",
|
|
241
|
+
"strings.TrimSpace",
|
|
242
|
+
"strings.Trim",
|
|
243
|
+
"strings.TrimLeft",
|
|
244
|
+
"strings.TrimRight",
|
|
245
|
+
"strings.TrimPrefix",
|
|
246
|
+
"strings.TrimSuffix",
|
|
247
|
+
"strconv.shortest",
|
|
248
|
+
"strconv.fixed",
|
|
249
|
+
"strconv.parseDecimal",
|
|
250
|
+
// internal/jsonrt: the encoder's writes into its output buffer.
|
|
251
|
+
"jsonrt.putString",
|
|
252
|
+
"jsonrt.putInt",
|
|
253
|
+
"jsonrt.putUint",
|
|
254
|
+
"jsonrt.putFloat",
|
|
255
|
+
"jsonrt.putQuoted",
|
|
256
|
+
"jsonrt.readStr",
|
|
257
|
+
"jsonrt.readNum",
|
|
258
|
+
"jsonrt.CheckValid",
|
|
259
|
+
"jsonrt.LooksFloat32",
|
|
260
|
+
// math: the functions with a single host expression or instruction.
|
|
261
|
+
"math.IsNaN",
|
|
262
|
+
"math.IsInf",
|
|
263
|
+
"math.Inf",
|
|
264
|
+
"math.NaN",
|
|
265
|
+
"math.Signbit",
|
|
266
|
+
"math.Copysign",
|
|
267
|
+
"math.Abs",
|
|
268
|
+
"math.Max",
|
|
269
|
+
"math.Min",
|
|
270
|
+
"math.Trunc",
|
|
271
|
+
"math.Floor",
|
|
272
|
+
"math.Ceil",
|
|
273
|
+
"math.Round",
|
|
274
|
+
"math.Sqrt",
|
|
275
|
+
// math/bits: one host instruction per width (`Math.clz32`, WASM `clz`,
|
|
276
|
+
// `ctz` and `popcnt`).
|
|
277
|
+
...["Len", "LeadingZeros", "TrailingZeros", "OnesCount"].flatMap((f) =>
|
|
278
|
+
["", "8", "16", "32", "64"].map((w) => `bits.${f}${w}`),
|
|
279
|
+
),
|
|
280
|
+
]);
|
|
696
281
|
|
|
697
282
|
// ── Static operator sets (module-level for reuse) ────────────
|
|
698
283
|
export const CMP_OPS = new Set(["==", "!=", "<", ">", "<=", ">="]);
|
|
@@ -718,6 +303,9 @@ export const FLOAT64 = { kind: "basic", name: "float64" };
|
|
|
718
303
|
export const STRING = { kind: "basic", name: "string" };
|
|
719
304
|
export const BOOL = { kind: "basic", name: "bool" };
|
|
720
305
|
export const ANY = { kind: "basic", name: "any" };
|
|
306
|
+
// `any` written in source. Untyped JS interop also yields plain ANY, which stays
|
|
307
|
+
// freely assignable; only a declared `any` needs a type assertion.
|
|
308
|
+
export const DECLARED_ANY = { kind: "basic", name: "any", _declared: true };
|
|
721
309
|
export const TAINTED_ANY = { kind: "basic", name: "any", _tainted: true };
|
|
722
310
|
export const VOID = { kind: "basic", name: "void" };
|
|
723
311
|
export const NIL = { kind: "basic", name: "nil" };
|
|
@@ -735,6 +323,9 @@ export const UNTYPED_INT = { kind: "untyped", base: "int" };
|
|
|
735
323
|
export const UNTYPED_FLOAT = { kind: "untyped", base: "float64" };
|
|
736
324
|
export const UNTYPED_STRING = { kind: "untyped", base: "string" };
|
|
737
325
|
export const UNTYPED_BOOL = { kind: "untyped", base: "bool" };
|
|
326
|
+
// An untyped rune constant is an untyped integer whose default type is
|
|
327
|
+
// `rune`; every `base === "int"` rule applies to it unchanged.
|
|
328
|
+
export const UNTYPED_RUNE = { kind: "untyped", base: "int", rune: true };
|
|
738
329
|
|
|
739
330
|
// ── Complex types ────────────────────────────────────────────
|
|
740
331
|
export const COMPLEX128 = { kind: "basic", name: "complex128" };
|
|
@@ -805,6 +396,33 @@ export const isFloat = makeBasicPredicate(...SIZED_FLOAT_NAMES);
|
|
|
805
396
|
export const isString = makeBasicPredicate("string");
|
|
806
397
|
export const isBool = makeBasicPredicate("bool");
|
|
807
398
|
|
|
399
|
+
// True when type t represents an int64 or uint64 (including named types like time.Duration).
|
|
400
|
+
export function is64BitInt(t) {
|
|
401
|
+
if (!t) return false;
|
|
402
|
+
if (t.kind === "untyped") return t.base === "int64" || t.base === "uint64";
|
|
403
|
+
let cur = t;
|
|
404
|
+
while (cur?.kind === "named") cur = cur.underlying;
|
|
405
|
+
return (
|
|
406
|
+
cur?.kind === "basic" && (cur.name === "int64" || cur.name === "uint64")
|
|
407
|
+
);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
export function is64BitSigned(t) {
|
|
411
|
+
if (!t) return false;
|
|
412
|
+
if (t.kind === "untyped") return t.base === "int64";
|
|
413
|
+
let cur = t;
|
|
414
|
+
while (cur?.kind === "named") cur = cur.underlying;
|
|
415
|
+
return cur?.kind === "basic" && cur.name === "int64";
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
export function is64BitUnsigned(t) {
|
|
419
|
+
if (!t) return false;
|
|
420
|
+
if (t.kind === "untyped") return t.base === "uint64";
|
|
421
|
+
let cur = t;
|
|
422
|
+
while (cur?.kind === "named") cur = cur.underlying;
|
|
423
|
+
return cur?.kind === "basic" && cur.name === "uint64";
|
|
424
|
+
}
|
|
425
|
+
|
|
808
426
|
// ── TypedArray mappings ──────────────────────────────────────
|
|
809
427
|
// []float64 deliberately stays a plain Array for JSON / JS-library interop.
|
|
810
428
|
const TYPED_ARRAY_CONSTRUCTORS = {
|
|
@@ -915,7 +533,7 @@ export function defaultType(t) {
|
|
|
915
533
|
if (t?.kind !== "untyped") return t;
|
|
916
534
|
switch (t.base) {
|
|
917
535
|
case "int":
|
|
918
|
-
return INT;
|
|
536
|
+
return t.rune ? RUNE : INT;
|
|
919
537
|
case "float64":
|
|
920
538
|
return FLOAT64;
|
|
921
539
|
case "string":
|
|
@@ -936,7 +554,7 @@ export function typeStr(t) {
|
|
|
936
554
|
case "basic":
|
|
937
555
|
return t.name;
|
|
938
556
|
case "untyped":
|
|
939
|
-
return `untyped ${t.base}`;
|
|
557
|
+
return t.rune ? "untyped rune" : `untyped ${t.base}`;
|
|
940
558
|
case "slice":
|
|
941
559
|
return `[]${typeStr(t.elem)}`;
|
|
942
560
|
case "shared":
|
|
@@ -979,9 +597,103 @@ export function typeStr(t) {
|
|
|
979
597
|
}
|
|
980
598
|
}
|
|
981
599
|
|
|
600
|
+
// The field an embedded type declares is named after the type as written, so
|
|
601
|
+
// an alias (`type A = Base; struct{ A }`) gives the field `A`.
|
|
602
|
+
// Per struct type, the methods promoted into its method set from embedded
|
|
603
|
+
// fields: name -> { depth, viaPtr, source, mType }. `depth` counts embeds
|
|
604
|
+
// from the struct, `viaPtr` is set when an embed on the path is a pointer
|
|
605
|
+
// and `source` is the method as declared. Kept outside the struct object so
|
|
606
|
+
// a copy of the struct (`type S Base`) does not share it.
|
|
607
|
+
export const promotedMethods = new WeakMap();
|
|
608
|
+
|
|
609
|
+
// Two embedded fields at the same, shallowest depth declare method `name`,
|
|
610
|
+
// so it is in neither method set of `struct` and selecting it is an error.
|
|
611
|
+
export function isAmbiguousPromotion(struct, name) {
|
|
612
|
+
return promotedMethods.get(struct)?.get(name)?.ambiguous === true;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
// The ambiguous method names of `struct` (see isAmbiguousPromotion).
|
|
616
|
+
export function ambiguousPromotions(struct) {
|
|
617
|
+
const names = [];
|
|
618
|
+
for (const [name, p] of promotedMethods.get(struct) ?? [])
|
|
619
|
+
if (p.ambiguous) names.push(name);
|
|
620
|
+
return names;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
export function embeddedFieldName(f) {
|
|
624
|
+
const ast = f.astType?.kind === "PointerType" ? f.astType.base : f.astType;
|
|
625
|
+
const t = f.type?.kind === "pointer" ? f.type.base : f.type;
|
|
626
|
+
return (ast?.name ?? t?.name ?? "")
|
|
627
|
+
.split(".")
|
|
628
|
+
.pop()
|
|
629
|
+
.replace(/\$\$.*$/, "");
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
// Whether `st` declares `name` itself: a field of that name or an embedded
|
|
633
|
+
// field named after its type.
|
|
634
|
+
function declaresField(st, name) {
|
|
635
|
+
return (st._structFields ?? []).some((f) =>
|
|
636
|
+
f.embedded ? embeddedFieldName(f) === name : f.names?.includes(name),
|
|
637
|
+
);
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
// The shallowest depth at which `struct` promotes a field `name` from its
|
|
641
|
+
// embedded types, and how many promotion paths reach it at that depth:
|
|
642
|
+
// { depth, count }, or null when no embedded type offers one.
|
|
643
|
+
function promotedFieldDepth(struct, name, path = new Set()) {
|
|
644
|
+
if (path.has(struct)) return null;
|
|
645
|
+
path.add(struct);
|
|
646
|
+
let best = null;
|
|
647
|
+
for (const e of struct._embeds ?? []) {
|
|
648
|
+
const inner = e?.kind === "pointer" ? e.base : e;
|
|
649
|
+
const st = inner?.kind === "named" ? inner.underlying : inner;
|
|
650
|
+
if (st?.kind !== "struct" || !st._structFields) continue;
|
|
651
|
+
const sub = declaresField(st, name)
|
|
652
|
+
? { depth: 0, count: 1 }
|
|
653
|
+
: promotedFieldDepth(st, name, path);
|
|
654
|
+
if (!sub) continue;
|
|
655
|
+
const depth = 1 + sub.depth;
|
|
656
|
+
if (!best || depth < best.depth) best = { depth, count: sub.count };
|
|
657
|
+
else if (depth === best.depth) best.count += sub.count;
|
|
658
|
+
}
|
|
659
|
+
path.delete(struct);
|
|
660
|
+
return best;
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
// Whether selecting `name` on `struct`, whose flattened field map has it, is
|
|
664
|
+
// ambiguous: two promotion paths reach a field of that name at the same
|
|
665
|
+
// shallowest depth, or a field and a method promoted at that depth do. A
|
|
666
|
+
// field declared on the struct itself and a method declared on it always win.
|
|
667
|
+
export function isAmbiguousFieldSelector(struct, name) {
|
|
668
|
+
if (declaresField(struct, name)) return false;
|
|
669
|
+
const promoted = promotedMethods.get(struct)?.get(name);
|
|
670
|
+
if (struct.methods?.has(name) && promoted?.mType !== struct.methods.get(name))
|
|
671
|
+
return false;
|
|
672
|
+
const field = promotedFieldDepth(struct, name);
|
|
673
|
+
if (!field) return false;
|
|
674
|
+
if (!promoted || field.depth < promoted.depth) return field.count > 1;
|
|
675
|
+
return field.depth === promoted.depth || promoted.ambiguous === true;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
// Whether selecting `name` on `struct`, whose flattened field map has it,
|
|
679
|
+
// reaches a method promoted at a shallower depth than the field (Go's depth
|
|
680
|
+
// rule): the method is selected and the deeper field is shadowed.
|
|
681
|
+
export function isMethodPromotedOverField(struct, name) {
|
|
682
|
+
if (declaresField(struct, name)) return false;
|
|
683
|
+
const promoted = promotedMethods.get(struct)?.get(name);
|
|
684
|
+
if (!promoted?.mType || promoted.ambiguous) return false;
|
|
685
|
+
if (struct.methods?.get(name) !== promoted.mType) return false;
|
|
686
|
+
const field = promotedFieldDepth(struct, name);
|
|
687
|
+
return field !== null && promoted.depth < field.depth;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
// A function-local type shadowed by another type is renamed `Name__L<n>`.
|
|
691
|
+
export const LOCAL_TYPE_SUFFIX = /__L\d+/;
|
|
692
|
+
|
|
982
693
|
// Go-source stdlib names are mangled to `Name$$path` (`List$$container$list`);
|
|
983
694
|
// diagnostics show them qualified, as Go does (`list.List`).
|
|
984
695
|
export function displayTypeName(name) {
|
|
696
|
+
if (typeof name === "string") name = name.replace(LOCAL_TYPE_SUFFIX, "");
|
|
985
697
|
const i = typeof name === "string" ? name.indexOf("$$") : -1;
|
|
986
698
|
if (i < 0) return name;
|
|
987
699
|
return `${name
|