gofront 1.8.0 → 1.9.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.
Files changed (177) hide show
  1. package/README.md +3 -3
  2. package/package.json +5 -4
  3. package/src/backend/js/expressions.js +849 -371
  4. package/src/backend/js/index.js +241 -147
  5. package/src/backend/js/natives.js +383 -0
  6. package/src/backend/js/runtime.js +512 -2547
  7. package/src/backend/js/statements.js +506 -103
  8. package/src/backend/js/stdlib/index.js +45 -93
  9. package/src/backend/js/templ.js +32 -45
  10. package/src/backend/js/type-info.js +177 -13
  11. package/src/backend/shared/fixed-float.js +20 -0
  12. package/src/backend/shared/fmt-types.js +63 -171
  13. package/src/backend/shared/host-unicode.js +36 -0
  14. package/src/backend/wasm/boundary.js +490 -965
  15. package/src/backend/wasm/emit-builtins.js +643 -256
  16. package/src/backend/wasm/emit-exprs.js +124 -57
  17. package/src/backend/wasm/emit-maps.js +17 -367
  18. package/src/backend/wasm/emit-stmts.js +325 -75
  19. package/src/backend/wasm/emit.js +104 -13
  20. package/src/backend/wasm/globals.js +47 -8
  21. package/src/backend/wasm/glue.js +2 -4
  22. package/src/backend/wasm/index.js +36 -530
  23. package/src/backend/wasm/method-expr.js +12 -1
  24. package/src/backend/wasm/module-emitter.js +92 -717
  25. package/src/backend/wasm/monomorph.js +103 -6
  26. package/src/backend/wasm/natives.js +596 -0
  27. package/src/backend/wasm/prescan.js +5 -153
  28. package/src/backend/wasm/prune-funcs.js +89 -0
  29. package/src/backend/wasm/stdlib/index.js +2 -32
  30. package/src/backend/wasm/types.js +68 -20
  31. package/src/backend/wasm/variadic.js +3 -3
  32. package/src/cli/cli-core.js +5 -1
  33. package/src/cli/test-runner.js +115 -342
  34. package/src/compiler.js +108 -130
  35. package/src/lexer/lexer.js +105 -11
  36. package/src/lexer/templ-lexer.js +61 -18
  37. package/src/lexer/tokens.js +1 -0
  38. package/src/link/stdlib.js +354 -132
  39. package/src/link/type-names.js +148 -0
  40. package/src/link/wasm.js +30 -6
  41. package/src/lower/bounds.js +153 -0
  42. package/src/lower/captures.js +92 -33
  43. package/src/lower/embedding.js +32 -3
  44. package/src/lower/errors-as.js +196 -0
  45. package/src/lower/fmt-formatters.js +905 -0
  46. package/src/lower/functions.js +2 -0
  47. package/src/lower/gen-types.js +274 -0
  48. package/src/lower/index.js +7 -1
  49. package/src/lower/json-codecs.js +228 -247
  50. package/src/lower/ownership.js +25 -7
  51. package/src/lower/reachability.js +69 -51
  52. package/src/lower/walk.js +12 -0
  53. package/src/parser/declarations.js +28 -5
  54. package/src/parser/expressions.js +86 -16
  55. package/src/parser/statements.js +1 -0
  56. package/src/parser/templ.js +44 -5
  57. package/src/parser/types.js +1 -0
  58. package/src/resolver.js +1 -2
  59. package/src/typechecker/assignability.js +124 -11
  60. package/src/typechecker/const-fold.js +70 -27
  61. package/src/typechecker/constants.js +32 -6
  62. package/src/typechecker/expressions.js +326 -98
  63. package/src/typechecker/index.js +208 -33
  64. package/src/typechecker/init-order.js +136 -40
  65. package/src/typechecker/operand-text.js +40 -0
  66. package/src/typechecker/resolve.js +192 -36
  67. package/src/typechecker/statements.js +122 -11
  68. package/src/typechecker/stdlib/excluded.js +9 -5
  69. package/src/typechecker/stdlib/index.js +25 -9
  70. package/src/typechecker/termination.js +10 -1
  71. package/src/typechecker/types.js +203 -573
  72. package/stdlib/bytes/buffer.go +479 -0
  73. package/stdlib/bytes/bytes.go +1010 -0
  74. package/stdlib/bytes/reader.go +161 -0
  75. package/stdlib/context/context.go +115 -0
  76. package/stdlib/crypto/rand/rand.go +34 -0
  77. package/stdlib/crypto/sha256/sha256.go +249 -0
  78. package/stdlib/encoding/base64/base64.go +331 -0
  79. package/stdlib/encoding/binary/binary.go +332 -0
  80. package/stdlib/encoding/hex/hex.go +140 -0
  81. package/stdlib/encoding/json/json.go +62 -0
  82. package/stdlib/errors/errors.go +174 -0
  83. package/stdlib/fmt/errors.go +110 -0
  84. package/stdlib/fmt/format.go +732 -0
  85. package/stdlib/fmt/print.go +1232 -0
  86. package/stdlib/gom/gom.go +293 -0
  87. package/stdlib/html/html.go +251 -0
  88. package/stdlib/internal/fmtrt/fmtrt.go +163 -0
  89. package/stdlib/internal/jsonrt/dec.go +171 -38
  90. package/stdlib/internal/jsonrt/enc.go +186 -36
  91. package/stdlib/internal/jsonrt/scanner.go +17 -8
  92. package/stdlib/io/io.go +157 -1
  93. package/stdlib/maps/maps.go +131 -0
  94. package/stdlib/math/bits/bits.go +507 -0
  95. package/stdlib/math/extra.go +16 -14
  96. package/stdlib/math/math.go +439 -0
  97. package/stdlib/math/rand/rand.go +297 -0
  98. package/stdlib/os/os.go +93 -0
  99. package/stdlib/path/filepath/filepath.go +47 -0
  100. package/stdlib/path/path.go +394 -0
  101. package/stdlib/regexp/regexp.go +231 -0
  102. package/stdlib/slices/slices.go +526 -0
  103. package/stdlib/slices/sort.go +209 -0
  104. package/stdlib/slices/zsort_cmp.go +480 -0
  105. package/stdlib/slices/zsort_ordered.go +482 -0
  106. package/stdlib/sort/sort.go +391 -452
  107. package/stdlib/sort/zsort_func.go +480 -0
  108. package/stdlib/sort/zsort_iface.go +480 -0
  109. package/stdlib/strconv/float.go +1699 -0
  110. package/stdlib/strconv/isprint.go +752 -0
  111. package/stdlib/strconv/quote.go +235 -50
  112. package/stdlib/strconv/strconv.go +616 -0
  113. package/stdlib/strings/builder.go +95 -0
  114. package/stdlib/strings/reader.go +163 -0
  115. package/stdlib/strings/replacer.go +102 -0
  116. package/stdlib/strings/strings.go +807 -0
  117. package/stdlib/sync/sync.go +268 -0
  118. package/stdlib/testing/async_js.go +61 -0
  119. package/stdlib/testing/benchmark.go +297 -0
  120. package/stdlib/testing/testing.go +523 -0
  121. package/stdlib/time/duration.go +233 -0
  122. package/stdlib/time/format.go +745 -0
  123. package/stdlib/time/parse.go +790 -0
  124. package/stdlib/time/sleep_js.go +63 -0
  125. package/stdlib/time/time.go +834 -0
  126. package/stdlib/unicode/unicode.go +141 -3
  127. package/stdlib/unicode/utf8/utf8.go +464 -0
  128. package/src/backend/js/fmt-runtime.js +0 -573
  129. package/src/backend/js/stdlib/base64.js +0 -12
  130. package/src/backend/js/stdlib/binary.js +0 -102
  131. package/src/backend/js/stdlib/bits.js +0 -119
  132. package/src/backend/js/stdlib/builder.js +0 -98
  133. package/src/backend/js/stdlib/bytes.js +0 -368
  134. package/src/backend/js/stdlib/errors.js +0 -45
  135. package/src/backend/js/stdlib/fmt.js +0 -517
  136. package/src/backend/js/stdlib/gom.js +0 -155
  137. package/src/backend/js/stdlib/hex.js +0 -17
  138. package/src/backend/js/stdlib/html.js +0 -20
  139. package/src/backend/js/stdlib/io.js +0 -137
  140. package/src/backend/js/stdlib/json.js +0 -1167
  141. package/src/backend/js/stdlib/maps.js +0 -37
  142. package/src/backend/js/stdlib/math.js +0 -85
  143. package/src/backend/js/stdlib/os.js +0 -13
  144. package/src/backend/js/stdlib/path.js +0 -48
  145. package/src/backend/js/stdlib/rand.js +0 -32
  146. package/src/backend/js/stdlib/regexp.js +0 -54
  147. package/src/backend/js/stdlib/sha256.js +0 -12
  148. package/src/backend/js/stdlib/shared.js +0 -17
  149. package/src/backend/js/stdlib/simd.js +0 -34
  150. package/src/backend/js/stdlib/slices.js +0 -107
  151. package/src/backend/js/stdlib/sort.js +0 -30
  152. package/src/backend/js/stdlib/strconv.js +0 -79
  153. package/src/backend/js/stdlib/strings.js +0 -301
  154. package/src/backend/js/stdlib/sync.js +0 -13
  155. package/src/backend/js/stdlib/testing.js +0 -41
  156. package/src/backend/js/stdlib/time.js +0 -152
  157. package/src/backend/js/stdlib/unicode.js +0 -25
  158. package/src/backend/js/stdlib/utf8.js +0 -26
  159. package/src/backend/wasm/stdlib/bytes.js +0 -6716
  160. package/src/backend/wasm/stdlib/core.js +0 -10278
  161. package/src/backend/wasm/stdlib/io.js +0 -3578
  162. package/src/backend/wasm/stdlib/packages.js +0 -2402
  163. package/src/backend/wasm/stdlib/pure.js +0 -720
  164. package/src/backend/wasm/stdlib/time.js +0 -2229
  165. package/src/typechecker/stdlib/core.js +0 -1079
  166. package/src/typechecker/stdlib/extended.js +0 -1210
  167. package/stdlib/bytes/iter.go +0 -192
  168. package/stdlib/bytes/search.go +0 -240
  169. package/stdlib/bytes/split.go +0 -218
  170. package/stdlib/errors/overlay.go +0 -12
  171. package/stdlib/maps/iter.go +0 -65
  172. package/stdlib/slices/extra.go +0 -73
  173. package/stdlib/slices/iter.go +0 -113
  174. package/stdlib/strings/extra.go +0 -35
  175. package/stdlib/strings/iter.go +0 -122
  176. package/stdlib/sync/extra.go +0 -105
  177. package/stdlib/unicode/utf8/bytes.go +0 -239
@@ -0,0 +1,140 @@
1
+ //go:build gofront
2
+
3
+ //gofront:target both
4
+
5
+ // Copyright 2009 The Go Authors. All rights reserved.
6
+ // Use of this source code is governed by a BSD-style
7
+ // license that can be found in the LICENSE file.
8
+
9
+ // Package hex implements hexadecimal encoding and decoding.
10
+ package hex
11
+
12
+ import (
13
+ "errors"
14
+ "fmt"
15
+ )
16
+
17
+ var hextable = []byte("0123456789abcdef")
18
+
19
+ // ErrLength reports an attempt to decode an odd-length input
20
+ // using [Decode] or [DecodeString].
21
+ // The stream-based Decoder returns [io.ErrUnexpectedEOF] instead of ErrLength.
22
+ var ErrLength = errors.New("encoding/hex: odd length hex string")
23
+
24
+ // InvalidByteError values describe errors resulting from an invalid byte in a hex string.
25
+ type InvalidByteError byte
26
+
27
+ func (e InvalidByteError) Error() string {
28
+ return fmt.Sprintf("encoding/hex: invalid byte: %#U", rune(e))
29
+ }
30
+
31
+ // EncodedLen returns the length of an encoding of n source bytes.
32
+ // Specifically, it returns n * 2.
33
+ func EncodedLen(n int) int { return n * 2 }
34
+
35
+ // Encode encodes src into [EncodedLen](len(src))
36
+ // bytes of dst. As a convenience, it returns the number
37
+ // of bytes written to dst, but this value is always [EncodedLen](len(src)).
38
+ // Encode implements hexadecimal encoding.
39
+ func Encode(dst, src []byte) int {
40
+ j := 0
41
+ for _, v := range src {
42
+ dst[j] = hextable[v>>4]
43
+ dst[j+1] = hextable[v&0x0f]
44
+ j += 2
45
+ }
46
+ return len(src) * 2
47
+ }
48
+
49
+ // AppendEncode appends the hexadecimally encoded src to dst
50
+ // and returns the extended buffer.
51
+ func AppendEncode(dst, src []byte) []byte {
52
+ for _, v := range src {
53
+ dst = append(dst, hextable[v>>4], hextable[v&0x0f])
54
+ }
55
+ return dst
56
+ }
57
+
58
+ // DecodedLen returns the length of a decoding of x source bytes.
59
+ // Specifically, it returns x / 2.
60
+ func DecodedLen(x int) int { return x / 2 }
61
+
62
+ // fromHexChar converts a hex character into its value and a success flag.
63
+ func fromHexChar(c byte) (byte, bool) {
64
+ switch {
65
+ case '0' <= c && c <= '9':
66
+ return c - '0', true
67
+ case 'a' <= c && c <= 'f':
68
+ return c - 'a' + 10, true
69
+ case 'A' <= c && c <= 'F':
70
+ return c - 'A' + 10, true
71
+ }
72
+
73
+ return 0, false
74
+ }
75
+
76
+ // Decode decodes src into [DecodedLen](len(src)) bytes,
77
+ // returning the actual number of bytes written to dst.
78
+ //
79
+ // Decode expects that src contains only hexadecimal
80
+ // characters and that src has even length.
81
+ // If the input is malformed, Decode returns the number
82
+ // of bytes decoded before the error.
83
+ func Decode(dst, src []byte) (int, error) {
84
+ i, j := 0, 1
85
+ for ; j < len(src); j += 2 {
86
+ p := src[j-1]
87
+ q := src[j]
88
+
89
+ a, aok := fromHexChar(p)
90
+ if !aok {
91
+ return i, InvalidByteError(p)
92
+ }
93
+ b, bok := fromHexChar(q)
94
+ if !bok {
95
+ return i, InvalidByteError(q)
96
+ }
97
+
98
+ dst[i] = (a << 4) | b
99
+ i++
100
+ }
101
+ if len(src)%2 == 1 {
102
+ // Check for invalid char before reporting bad length,
103
+ // since the invalid char (if present) is an earlier problem.
104
+ if _, ok := fromHexChar(src[j-1]); !ok {
105
+ return i, InvalidByteError(src[j-1])
106
+ }
107
+ return i, ErrLength
108
+ }
109
+ return i, nil
110
+ }
111
+
112
+ // AppendDecode appends the hexadecimally decoded src to dst
113
+ // and returns the extended buffer.
114
+ // If the input is malformed, it returns the partially decoded src and an error.
115
+ func AppendDecode(dst, src []byte) ([]byte, error) {
116
+ buf := make([]byte, DecodedLen(len(src)))
117
+ n, err := Decode(buf, src)
118
+ return append(dst, buf[:n]...), err
119
+ }
120
+
121
+ // EncodeToString returns the hexadecimal encoding of src.
122
+ func EncodeToString(src []byte) string {
123
+ dst := make([]byte, EncodedLen(len(src)))
124
+ Encode(dst, src)
125
+ return string(dst)
126
+ }
127
+
128
+ // DecodeString returns the bytes represented by the hexadecimal string s.
129
+ //
130
+ // DecodeString expects that src contains only hexadecimal
131
+ // characters and that src has even length.
132
+ // If the input is malformed, DecodeString returns
133
+ // the bytes decoded before the error.
134
+ func DecodeString(s string) ([]byte, error) {
135
+ src := []byte(s)
136
+ // We can use the source slice itself as the destination
137
+ // because the decode loop increments by one and then the 'seen' byte is not used anymore.
138
+ n, err := Decode(src, src)
139
+ return src[:n], err
140
+ }
@@ -0,0 +1,62 @@
1
+ //go:build gofront
2
+
3
+ //gofront:target both
4
+
5
+ package json
6
+
7
+ import (
8
+ "errors"
9
+ "internal/jsonrt"
10
+ )
11
+
12
+ // Marshal returns the JSON encoding of v.
13
+ //
14
+ // The compiler replaces every call with a function generated for the static
15
+ // type of v, so this body runs only when Marshal is used as a value, which
16
+ // the compiler rejects.
17
+ func Marshal(v any) ([]byte, error) {
18
+ panic("json.Marshal: call sites are rewritten by the compiler")
19
+ }
20
+
21
+ // MarshalIndent is like Marshal but applies Indent to format the output.
22
+ //
23
+ // The compiler replaces every call with a generated function; see Marshal.
24
+ func MarshalIndent(v any, prefix, indent string) ([]byte, error) {
25
+ panic("json.MarshalIndent: call sites are rewritten by the compiler")
26
+ }
27
+
28
+ // Unmarshal parses the JSON-encoded data and stores the result in the value
29
+ // pointed to by v.
30
+ //
31
+ // The compiler replaces every call with a function generated for the static
32
+ // type of v; see Marshal.
33
+ func Unmarshal(data []byte, v any) error {
34
+ panic("json.Unmarshal: call sites are rewritten by the compiler")
35
+ }
36
+
37
+ // Valid reports whether data is a valid JSON encoding.
38
+ func Valid(data []byte) bool {
39
+ return jsonrt.Valid(data)
40
+ }
41
+
42
+ // RawMessage is a raw encoded JSON value. It implements Marshaler and
43
+ // Unmarshaler and can be used to delay JSON decoding or precompute a JSON
44
+ // encoding.
45
+ type RawMessage []byte
46
+
47
+ // MarshalJSON returns m as the JSON encoding of m.
48
+ func (m RawMessage) MarshalJSON() ([]byte, error) {
49
+ if m == nil {
50
+ return []byte("null"), nil
51
+ }
52
+ return m, nil
53
+ }
54
+
55
+ // UnmarshalJSON sets *m to a copy of data.
56
+ func (m *RawMessage) UnmarshalJSON(data []byte) error {
57
+ if m == nil {
58
+ return errors.New("json.RawMessage: UnmarshalJSON on nil pointer")
59
+ }
60
+ *m = append((*m)[0:0], data...)
61
+ return nil
62
+ }
@@ -0,0 +1,174 @@
1
+ //go:build gofront
2
+
3
+ //gofront:target both
4
+
5
+ // Copyright 2011 The Go Authors. All rights reserved.
6
+ // Use of this source code is governed by a BSD-style
7
+ // license that can be found in the LICENSE file.
8
+
9
+ // Package errors implements functions to manipulate errors.
10
+ //
11
+ // New, Unwrap, Is, Join and ErrUnsupported are written in Go over the
12
+ // real package's algorithms. As stores through a pointer target whose type
13
+ // only the compiler knows, which Go source cannot express without
14
+ // reflection: every call is rewritten to a function generated for its
15
+ // target type (src/lower/errors-as.js).
16
+ //
17
+ // Is does not check that target is comparable before comparing, as Go
18
+ // does with reflection: an error whose dynamic type is a slice, map or
19
+ // func panics when it is compared.
20
+ package errors
21
+
22
+ // New returns an error that formats as the given text.
23
+ // Each call to New returns a distinct error value even if the text is identical.
24
+ func New(text string) error {
25
+ return &errorString{text}
26
+ }
27
+
28
+ // errorString is a trivial implementation of error.
29
+ type errorString struct {
30
+ s string
31
+ }
32
+
33
+ func (e *errorString) Error() string {
34
+ return e.s
35
+ }
36
+
37
+ // GofrontTypeName is the type %T prints for the error. Package fmt cannot
38
+ // name the unexported type, so the error says it.
39
+ func (e *errorString) GofrontTypeName() string {
40
+ return "*errors.errorString"
41
+ }
42
+
43
+ // GofrontFmt is how package fmt prints the error with a verb that does not
44
+ // apply to it (%v only reaches it from a failed verb): Go prints the pointer
45
+ // to the struct, whose one field is a string.
46
+ func (e *errorString) GofrontFmt(verb rune) string {
47
+ if verb == 'v' {
48
+ return "&{" + e.s + "}"
49
+ }
50
+ return "&{%!" + string(verb) + "(string=" + e.s + ")}"
51
+ }
52
+
53
+ // ErrUnsupported indicates that a requested operation cannot be performed,
54
+ // because it is unsupported.
55
+ var ErrUnsupported = New("unsupported operation")
56
+
57
+ // Unwrap returns the result of calling the Unwrap method on err, if err's
58
+ // type contains an Unwrap method returning error.
59
+ // Otherwise, Unwrap returns nil.
60
+ //
61
+ // Unwrap only calls a method of the form "Unwrap() error".
62
+ // In particular Unwrap does not unwrap errors returned by [Join].
63
+ func Unwrap(err error) error {
64
+ u, ok := err.(interface {
65
+ Unwrap() error
66
+ })
67
+ if !ok {
68
+ return nil
69
+ }
70
+ return u.Unwrap()
71
+ }
72
+
73
+ // Is reports whether any error in err's tree matches target.
74
+ //
75
+ // The tree consists of err itself, followed by the errors obtained by
76
+ // repeatedly calling its Unwrap() error or Unwrap() []error method.
77
+ // When err wraps multiple errors, Is examines err followed by a
78
+ // depth-first traversal of its children.
79
+ //
80
+ // An error is considered to match a target if it is equal to that target or if
81
+ // it implements a method Is(error) bool such that Is(target) returns true.
82
+ func Is(err, target error) bool {
83
+ if err == nil || target == nil {
84
+ return err == target
85
+ }
86
+ return is(err, target)
87
+ }
88
+
89
+ func is(err, target error) bool {
90
+ for {
91
+ if err == target {
92
+ return true
93
+ }
94
+ if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) {
95
+ return true
96
+ }
97
+ switch x := err.(type) {
98
+ case interface{ Unwrap() error }:
99
+ err = x.Unwrap()
100
+ if err == nil {
101
+ return false
102
+ }
103
+ case interface{ Unwrap() []error }:
104
+ for _, err := range x.Unwrap() {
105
+ if is(err, target) {
106
+ return true
107
+ }
108
+ }
109
+ return false
110
+ default:
111
+ return false
112
+ }
113
+ }
114
+ }
115
+
116
+ // Join returns an error that wraps the given errors.
117
+ // Any nil error values are discarded.
118
+ // Join returns nil if every value in errs is nil.
119
+ // The error formats as the concatenation of the strings obtained
120
+ // by calling the Error method of each element of errs, with a newline
121
+ // between each string.
122
+ //
123
+ // A non-nil error returned by Join implements the Unwrap() []error method.
124
+ func Join(errs ...error) error {
125
+ n := 0
126
+ for _, err := range errs {
127
+ if err != nil {
128
+ n++
129
+ }
130
+ }
131
+ if n == 0 {
132
+ return nil
133
+ }
134
+ e := &joinError{
135
+ errs: make([]error, 0, n),
136
+ }
137
+ for _, err := range errs {
138
+ if err != nil {
139
+ e.errs = append(e.errs, err)
140
+ }
141
+ }
142
+ return e
143
+ }
144
+
145
+ type joinError struct {
146
+ errs []error
147
+ }
148
+
149
+ // GofrontTypeName is the type %T prints for the error (see errorString).
150
+ func (e *joinError) GofrontTypeName() string {
151
+ return "*errors.joinError"
152
+ }
153
+
154
+ func (e *joinError) Error() string {
155
+ s := e.errs[0].Error()
156
+ for _, err := range e.errs[1:] {
157
+ s += "\n" + err.Error()
158
+ }
159
+ return s
160
+ }
161
+
162
+ func (e *joinError) Unwrap() []error {
163
+ return e.errs
164
+ }
165
+
166
+ // As finds the first error in err's tree that matches target, and if one is
167
+ // found, sets target to that error value and returns true.
168
+ //
169
+ // The compiler replaces every call with a generated function for the static
170
+ // type of target, so this body runs only when As is used as a value, which
171
+ // the compiler rejects.
172
+ func As(err error, target any) bool {
173
+ panic("errors.As: call sites are rewritten by the compiler")
174
+ }
@@ -0,0 +1,110 @@
1
+ // Copyright 2018 The Go Authors. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style
3
+ // license that can be found in the LICENSE file.
4
+
5
+ //go:build gofront
6
+
7
+ //gofront:target both
8
+
9
+ package fmt
10
+
11
+ // Errorf formats according to a format specifier and returns the string as a
12
+ // value that satisfies error.
13
+ //
14
+ // If the format specifier includes a %w verb with an error operand,
15
+ // the returned error will implement an Unwrap method returning the operand.
16
+ // If there is more than one %w verb, the returned error will implement an
17
+ // Unwrap method returning a []error containing all the %w operands in the
18
+ // order they appear in the arguments.
19
+ // It is invalid to supply the %w verb with an operand that does not implement
20
+ // the error interface. The %w verb is otherwise a synonym for %v.
21
+ func Errorf(format string, a ...any) error {
22
+ p := newPrinter()
23
+ p.wrapErrs = true
24
+ p.doPrintf(format, a)
25
+ s := string(p.fmt.bytes())
26
+ var err error
27
+ switch len(p.wrappedErrs) {
28
+ case 0:
29
+ err = &plainError{s}
30
+ case 1:
31
+ w := &wrapError{msg: s}
32
+ w.err = describe(a[p.wrappedErrs[0]]).Err
33
+ err = w
34
+ default:
35
+ if p.reordered {
36
+ sortInts(p.wrappedErrs)
37
+ }
38
+ var errs []error
39
+ for i, argNum := range p.wrappedErrs {
40
+ if i > 0 && p.wrappedErrs[i-1] == argNum {
41
+ continue
42
+ }
43
+ if e := describe(a[argNum]).Err; e != nil {
44
+ errs = append(errs, e)
45
+ }
46
+ }
47
+ err = &wrapErrors{s, errs}
48
+ }
49
+ return err
50
+ }
51
+
52
+ // sortInts is an insertion sort; it keeps fmt from importing slices.
53
+ func sortInts(x []int) {
54
+ for i := 1; i < len(x); i++ {
55
+ for j := i; j > 0 && x[j] < x[j-1]; j-- {
56
+ x[j], x[j-1] = x[j-1], x[j]
57
+ }
58
+ }
59
+ }
60
+
61
+ // plainError is what errors.New returns, repeated here so that every fmt
62
+ // user does not also compile package errors.
63
+ type plainError struct {
64
+ s string
65
+ }
66
+
67
+ func (e *plainError) Error() string {
68
+ return e.s
69
+ }
70
+
71
+ // GofrontTypeName is the type %T prints for the error: the one errors.New makes.
72
+ func (e *plainError) GofrontTypeName() string {
73
+ return "*errors.errorString"
74
+ }
75
+
76
+ type wrapError struct {
77
+ msg string
78
+ err error
79
+ }
80
+
81
+ func (e *wrapError) Error() string {
82
+ return e.msg
83
+ }
84
+
85
+ func (e *wrapError) Unwrap() error {
86
+ return e.err
87
+ }
88
+
89
+ type wrapErrors struct {
90
+ msg string
91
+ errs []error
92
+ }
93
+
94
+ func (e *wrapErrors) Error() string {
95
+ return e.msg
96
+ }
97
+
98
+ func (e *wrapErrors) Unwrap() []error {
99
+ return e.errs
100
+ }
101
+
102
+ // GofrontTypeName is the type %T prints for the error (see errors.errorString).
103
+ func (e *wrapError) GofrontTypeName() string {
104
+ return "*fmt.wrapError"
105
+ }
106
+
107
+ // GofrontTypeName is the type %T prints for the error.
108
+ func (e *wrapErrors) GofrontTypeName() string {
109
+ return "*fmt.wrapErrors"
110
+ }