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.
Files changed (178) hide show
  1. package/README.md +3 -3
  2. package/package.json +6 -5
  3. package/src/backend/js/expressions.js +1157 -408
  4. package/src/backend/js/index.js +327 -153
  5. package/src/backend/js/natives.js +383 -0
  6. package/src/backend/js/runtime.js +559 -2552
  7. package/src/backend/js/statements.js +670 -158
  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 +298 -19
  11. package/src/backend/shared/fixed-float.js +20 -0
  12. package/src/backend/shared/fmt-types.js +91 -170
  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 +884 -256
  16. package/src/backend/wasm/emit-exprs.js +185 -77
  17. package/src/backend/wasm/emit-maps.js +17 -367
  18. package/src/backend/wasm/emit-shared.js +4 -1
  19. package/src/backend/wasm/emit-stmts.js +524 -240
  20. package/src/backend/wasm/emit.js +176 -38
  21. package/src/backend/wasm/globals.js +48 -8
  22. package/src/backend/wasm/glue.js +2 -4
  23. package/src/backend/wasm/index.js +44 -530
  24. package/src/backend/wasm/method-expr.js +12 -1
  25. package/src/backend/wasm/module-emitter.js +299 -770
  26. package/src/backend/wasm/monomorph.js +139 -8
  27. package/src/backend/wasm/natives.js +600 -0
  28. package/src/backend/wasm/prescan.js +5 -153
  29. package/src/backend/wasm/prune-funcs.js +89 -0
  30. package/src/backend/wasm/stdlib/index.js +2 -32
  31. package/src/backend/wasm/types.js +97 -20
  32. package/src/backend/wasm/variadic.js +9 -4
  33. package/src/cli/cli-core.js +5 -1
  34. package/src/cli/test-runner.js +115 -342
  35. package/src/compiler.js +113 -130
  36. package/src/lexer/lexer.js +106 -11
  37. package/src/lexer/templ-lexer.js +61 -18
  38. package/src/lexer/tokens.js +1 -0
  39. package/src/link/stdlib.js +355 -132
  40. package/src/link/type-names.js +204 -0
  41. package/src/link/wasm.js +30 -6
  42. package/src/lower/bounds.js +153 -0
  43. package/src/lower/captures.js +92 -33
  44. package/src/lower/embedding.js +62 -5
  45. package/src/lower/errors-as.js +196 -0
  46. package/src/lower/fmt-formatters.js +929 -0
  47. package/src/lower/functions.js +225 -7
  48. package/src/lower/gen-types.js +293 -0
  49. package/src/lower/index.js +14 -2
  50. package/src/lower/json-codecs.js +334 -245
  51. package/src/lower/ownership.js +25 -7
  52. package/src/lower/reachability.js +69 -51
  53. package/src/lower/walk.js +12 -0
  54. package/src/parser/declarations.js +30 -5
  55. package/src/parser/expressions.js +111 -57
  56. package/src/parser/statements.js +108 -0
  57. package/src/parser/templ.js +44 -5
  58. package/src/parser/types.js +12 -0
  59. package/src/resolver.js +1 -2
  60. package/src/typechecker/assignability.js +214 -19
  61. package/src/typechecker/const-fold.js +70 -27
  62. package/src/typechecker/constants.js +156 -8
  63. package/src/typechecker/expressions.js +490 -108
  64. package/src/typechecker/index.js +346 -42
  65. package/src/typechecker/init-order.js +136 -40
  66. package/src/typechecker/operand-text.js +41 -0
  67. package/src/typechecker/resolve.js +490 -65
  68. package/src/typechecker/statements.js +288 -27
  69. package/src/typechecker/stdlib/excluded.js +9 -5
  70. package/src/typechecker/stdlib/index.js +25 -9
  71. package/src/typechecker/termination.js +10 -1
  72. package/src/typechecker/types.js +287 -575
  73. package/stdlib/bytes/buffer.go +479 -0
  74. package/stdlib/bytes/bytes.go +1010 -0
  75. package/stdlib/bytes/reader.go +161 -0
  76. package/stdlib/context/context.go +115 -0
  77. package/stdlib/crypto/rand/rand.go +34 -0
  78. package/stdlib/crypto/sha256/sha256.go +249 -0
  79. package/stdlib/encoding/base64/base64.go +331 -0
  80. package/stdlib/encoding/binary/binary.go +332 -0
  81. package/stdlib/encoding/hex/hex.go +140 -0
  82. package/stdlib/encoding/json/json.go +62 -0
  83. package/stdlib/errors/errors.go +174 -0
  84. package/stdlib/fmt/errors.go +110 -0
  85. package/stdlib/fmt/format.go +732 -0
  86. package/stdlib/fmt/print.go +1232 -0
  87. package/stdlib/gom/gom.go +293 -0
  88. package/stdlib/html/html.go +251 -0
  89. package/stdlib/internal/fmtrt/fmtrt.go +163 -0
  90. package/stdlib/internal/jsonrt/dec.go +171 -38
  91. package/stdlib/internal/jsonrt/enc.go +186 -36
  92. package/stdlib/internal/jsonrt/scanner.go +17 -8
  93. package/stdlib/io/io.go +157 -1
  94. package/stdlib/maps/maps.go +131 -0
  95. package/stdlib/math/bits/bits.go +507 -0
  96. package/stdlib/math/extra.go +16 -14
  97. package/stdlib/math/math.go +439 -0
  98. package/stdlib/math/rand/rand.go +297 -0
  99. package/stdlib/os/os.go +93 -0
  100. package/stdlib/path/filepath/filepath.go +47 -0
  101. package/stdlib/path/path.go +394 -0
  102. package/stdlib/regexp/regexp.go +231 -0
  103. package/stdlib/slices/slices.go +526 -0
  104. package/stdlib/slices/sort.go +209 -0
  105. package/stdlib/slices/zsort_cmp.go +480 -0
  106. package/stdlib/slices/zsort_ordered.go +482 -0
  107. package/stdlib/sort/sort.go +391 -452
  108. package/stdlib/sort/zsort_func.go +480 -0
  109. package/stdlib/sort/zsort_iface.go +480 -0
  110. package/stdlib/strconv/float.go +1699 -0
  111. package/stdlib/strconv/isprint.go +752 -0
  112. package/stdlib/strconv/quote.go +235 -50
  113. package/stdlib/strconv/strconv.go +616 -0
  114. package/stdlib/strings/builder.go +95 -0
  115. package/stdlib/strings/reader.go +163 -0
  116. package/stdlib/strings/replacer.go +102 -0
  117. package/stdlib/strings/strings.go +807 -0
  118. package/stdlib/sync/sync.go +268 -0
  119. package/stdlib/testing/async_js.go +61 -0
  120. package/stdlib/testing/benchmark.go +297 -0
  121. package/stdlib/testing/testing.go +523 -0
  122. package/stdlib/time/duration.go +233 -0
  123. package/stdlib/time/format.go +745 -0
  124. package/stdlib/time/parse.go +790 -0
  125. package/stdlib/time/sleep_js.go +63 -0
  126. package/stdlib/time/time.go +834 -0
  127. package/stdlib/unicode/unicode.go +141 -3
  128. package/stdlib/unicode/utf8/utf8.go +464 -0
  129. package/src/backend/js/fmt-runtime.js +0 -573
  130. package/src/backend/js/stdlib/base64.js +0 -12
  131. package/src/backend/js/stdlib/binary.js +0 -102
  132. package/src/backend/js/stdlib/bits.js +0 -119
  133. package/src/backend/js/stdlib/builder.js +0 -98
  134. package/src/backend/js/stdlib/bytes.js +0 -368
  135. package/src/backend/js/stdlib/errors.js +0 -45
  136. package/src/backend/js/stdlib/fmt.js +0 -517
  137. package/src/backend/js/stdlib/gom.js +0 -155
  138. package/src/backend/js/stdlib/hex.js +0 -17
  139. package/src/backend/js/stdlib/html.js +0 -20
  140. package/src/backend/js/stdlib/io.js +0 -137
  141. package/src/backend/js/stdlib/json.js +0 -1167
  142. package/src/backend/js/stdlib/maps.js +0 -37
  143. package/src/backend/js/stdlib/math.js +0 -85
  144. package/src/backend/js/stdlib/os.js +0 -13
  145. package/src/backend/js/stdlib/path.js +0 -48
  146. package/src/backend/js/stdlib/rand.js +0 -32
  147. package/src/backend/js/stdlib/regexp.js +0 -54
  148. package/src/backend/js/stdlib/sha256.js +0 -12
  149. package/src/backend/js/stdlib/shared.js +0 -17
  150. package/src/backend/js/stdlib/simd.js +0 -34
  151. package/src/backend/js/stdlib/slices.js +0 -107
  152. package/src/backend/js/stdlib/sort.js +0 -30
  153. package/src/backend/js/stdlib/strconv.js +0 -79
  154. package/src/backend/js/stdlib/strings.js +0 -301
  155. package/src/backend/js/stdlib/sync.js +0 -13
  156. package/src/backend/js/stdlib/testing.js +0 -41
  157. package/src/backend/js/stdlib/time.js +0 -152
  158. package/src/backend/js/stdlib/unicode.js +0 -25
  159. package/src/backend/js/stdlib/utf8.js +0 -26
  160. package/src/backend/wasm/stdlib/bytes.js +0 -6716
  161. package/src/backend/wasm/stdlib/core.js +0 -10278
  162. package/src/backend/wasm/stdlib/io.js +0 -3578
  163. package/src/backend/wasm/stdlib/packages.js +0 -2402
  164. package/src/backend/wasm/stdlib/pure.js +0 -720
  165. package/src/backend/wasm/stdlib/time.js +0 -2229
  166. package/src/typechecker/stdlib/core.js +0 -1079
  167. package/src/typechecker/stdlib/extended.js +0 -1210
  168. package/stdlib/bytes/iter.go +0 -192
  169. package/stdlib/bytes/search.go +0 -240
  170. package/stdlib/bytes/split.go +0 -218
  171. package/stdlib/errors/overlay.go +0 -12
  172. package/stdlib/maps/iter.go +0 -65
  173. package/stdlib/slices/extra.go +0 -73
  174. package/stdlib/slices/iter.go +0 -113
  175. package/stdlib/strings/extra.go +0 -35
  176. package/stdlib/strings/iter.go +0 -122
  177. package/stdlib/sync/extra.go +0 -105
  178. package/stdlib/unicode/utf8/bytes.go +0 -239
@@ -13,6 +13,144 @@ const (
13
13
  Version = "15.0.0"
14
14
  )
15
15
 
16
+ // Classes of unicode_is, the host's answer for runes above ASCII.
17
+ const (
18
+ classLetter = iota
19
+ classDigit
20
+ classSpace
21
+ classUpper
22
+ classLower
23
+ classPunct
24
+ classControl
25
+ classPrint
26
+ classGraphic
27
+ )
28
+
29
+ // hostIs reports whether the host's Unicode tables place r in the class.
30
+ //
31
+ //gofront:intrinsic unicode_is
32
+ func hostIs(r rune, class int) bool
33
+
34
+ // hostToUpper is the host's upper case mapping of r; a letter whose upper
35
+ // case spans several code points stays as it is.
36
+ //
37
+ //gofront:intrinsic unicode_to_upper
38
+ func hostToUpper(r rune) rune
39
+
40
+ // hostToLower is the host's lower case mapping of r.
41
+ //
42
+ //gofront:intrinsic unicode_to_lower
43
+ func hostToLower(r rune) rune
44
+
45
+ func isValid(r rune) bool { return r >= 0 && r <= MaxRune }
46
+
47
+ // IsLetter reports whether the rune is a letter (category L).
48
+ func IsLetter(r rune) bool {
49
+ if r < 0x80 {
50
+ return 'a' <= r && r <= 'z' || 'A' <= r && r <= 'Z'
51
+ }
52
+ return isValid(r) && hostIs(r, classLetter)
53
+ }
54
+
55
+ // IsDigit reports whether the rune is a decimal digit.
56
+ func IsDigit(r rune) bool {
57
+ if r < 0x80 {
58
+ return '0' <= r && r <= '9'
59
+ }
60
+ return isValid(r) && hostIs(r, classDigit)
61
+ }
62
+
63
+ // IsSpace reports whether the rune is a space character as defined by
64
+ // Unicode's White Space property.
65
+ func IsSpace(r rune) bool {
66
+ if r < 0x80 {
67
+ return r == ' ' || '\t' <= r && r <= '\r'
68
+ }
69
+ return isValid(r) && hostIs(r, classSpace)
70
+ }
71
+
72
+ // IsUpper reports whether the rune is an upper case letter.
73
+ func IsUpper(r rune) bool {
74
+ if r < 0x80 {
75
+ return 'A' <= r && r <= 'Z'
76
+ }
77
+ return isValid(r) && hostIs(r, classUpper)
78
+ }
79
+
80
+ // IsLower reports whether the rune is a lower case letter.
81
+ func IsLower(r rune) bool {
82
+ if r < 0x80 {
83
+ return 'a' <= r && r <= 'z'
84
+ }
85
+ return isValid(r) && hostIs(r, classLower)
86
+ }
87
+
88
+ // IsPunct reports whether the rune is a Unicode punctuation character
89
+ // (category P).
90
+ func IsPunct(r rune) bool {
91
+ if r < 0x80 {
92
+ switch r {
93
+ case '!', '"', '#', '%', '&', '\'', '(', ')', '*', ',', '-', '.', '/',
94
+ ':', ';', '?', '@', '[', '\\', ']', '_', '{', '}':
95
+ return true
96
+ }
97
+ return false
98
+ }
99
+ return isValid(r) && hostIs(r, classPunct)
100
+ }
101
+
102
+ // IsControl reports whether the rune is a control character.
103
+ func IsControl(r rune) bool {
104
+ if r < 0x80 {
105
+ return r >= 0 && r < ' ' || r == 0x7F
106
+ }
107
+ return isValid(r) && hostIs(r, classControl)
108
+ }
109
+
110
+ // IsPrint reports whether the rune is printable.
111
+ func IsPrint(r rune) bool {
112
+ if r < 0x80 {
113
+ return ' ' <= r && r <= '~'
114
+ }
115
+ return isValid(r) && !IsSpace(r) && hostIs(r, classPrint)
116
+ }
117
+
118
+ // IsGraphic reports whether the rune is a graphic character.
119
+ func IsGraphic(r rune) bool {
120
+ if r < 0x80 {
121
+ return ' ' <= r && r <= '~'
122
+ }
123
+ return isValid(r) && hostIs(r, classGraphic)
124
+ }
125
+
126
+ // ToUpper maps the rune to upper case.
127
+ func ToUpper(r rune) rune {
128
+ if r < 0x80 {
129
+ if 'a' <= r && r <= 'z' {
130
+ return r - ('a' - 'A')
131
+ }
132
+ return r
133
+ }
134
+ if !isValid(r) {
135
+ return r
136
+ }
137
+ return hostToUpper(r)
138
+ }
139
+
140
+ // ToLower maps the rune to lower case.
141
+ func ToLower(r rune) rune {
142
+ if r < 0x80 {
143
+ if 'A' <= r && r <= 'Z' {
144
+ return r + ('a' - 'A')
145
+ }
146
+ return r
147
+ }
148
+ if !isValid(r) {
149
+ return r
150
+ }
151
+ return hostToLower(r)
152
+ }
153
+
16
154
  // ToTitle maps the rune to title case.
17
155
  func ToTitle(r rune) rune {
18
156
  if r <= MaxASCII {
@@ -34,7 +172,7 @@ func ToTitle(r rune) rune {
34
172
  if 0x10D0 <= r && r <= 0x10FF {
35
173
  return r
36
174
  }
37
- return rune(ToUpper(int(r)))
175
+ return ToUpper(r)
38
176
  }
39
177
 
40
178
  type foldPair struct {
@@ -105,8 +243,8 @@ func SimpleFold(r rune) rune {
105
243
  if lo < len(caseOrbit) && rune(caseOrbit[lo].From) == r {
106
244
  return rune(caseOrbit[lo].To)
107
245
  }
108
- if l := rune(ToLower(int(r))); l != r {
246
+ if l := ToLower(r); l != r {
109
247
  return l
110
248
  }
111
- return rune(ToUpper(int(r)))
249
+ return ToUpper(r)
112
250
  }
@@ -0,0 +1,464 @@
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 utf8 implements functions and constants to support text encoded in
10
+ // UTF-8. It includes functions to translate between runes and UTF-8 byte sequences.
11
+ // See https://en.wikipedia.org/wiki/UTF-8
12
+ package utf8
13
+
14
+ // The conditions RuneError==unicode.ReplacementChar and
15
+ // MaxRune==unicode.MaxRune are verified in the tests.
16
+ // Defining them locally avoids this package depending on package unicode.
17
+
18
+ // Numbers fundamental to the encoding.
19
+ const (
20
+ RuneError = '\uFFFD' // the "error" Rune or "Unicode replacement character"
21
+ RuneSelf = 0x80 // characters below RuneSelf are represented as themselves in a single byte.
22
+ MaxRune = '\U0010FFFF' // Maximum valid Unicode code point.
23
+ UTFMax = 4 // maximum number of bytes of a UTF-8 encoded Unicode character.
24
+ )
25
+
26
+ // Code points in the surrogate range are not valid for UTF-8.
27
+ const (
28
+ surrogateMin = 0xD800
29
+ surrogateMax = 0xDFFF
30
+ )
31
+
32
+ const (
33
+ t1 = 0b00000000
34
+ tx = 0b10000000
35
+ t2 = 0b11000000
36
+ t3 = 0b11100000
37
+ t4 = 0b11110000
38
+ t5 = 0b11111000
39
+
40
+ maskx = 0b00111111
41
+ mask2 = 0b00011111
42
+ mask3 = 0b00001111
43
+ mask4 = 0b00000111
44
+
45
+ rune1Max = 1<<7 - 1
46
+ rune2Max = 1<<11 - 1
47
+ rune3Max = 1<<16 - 1
48
+
49
+ // The default lowest and highest continuation byte.
50
+ locb = 0b10000000
51
+ hicb = 0b10111111
52
+
53
+ // These names of these constants are chosen to give nice alignment in the
54
+ // table below. The first nibble is an index into acceptRanges or F for
55
+ // special one-byte cases. The second nibble is the Rune length or the
56
+ // Status for the special one-byte case.
57
+ xx = 0xF1 // invalid: size 1
58
+ as = 0xF0 // ASCII: size 1
59
+ s1 = 0x02 // accept 0, size 2
60
+ s2 = 0x13 // accept 1, size 3
61
+ s3 = 0x03 // accept 0, size 3
62
+ s4 = 0x23 // accept 2, size 3
63
+ s5 = 0x34 // accept 3, size 4
64
+ s6 = 0x04 // accept 0, size 4
65
+ s7 = 0x44 // accept 4, size 4
66
+ )
67
+
68
+ const (
69
+ runeErrorByte0 = t3 | (RuneError >> 12)
70
+ runeErrorByte1 = tx | (RuneError>>6)&maskx
71
+ runeErrorByte2 = tx | RuneError&maskx
72
+ )
73
+
74
+ // first is information about the first byte in a UTF-8 sequence.
75
+ var first = [256]uint8{
76
+ // 1 2 3 4 5 6 7 8 9 A B C D E F
77
+ as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x00-0x0F
78
+ as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x10-0x1F
79
+ as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x20-0x2F
80
+ as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x30-0x3F
81
+ as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x40-0x4F
82
+ as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x50-0x5F
83
+ as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x60-0x6F
84
+ as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x70-0x7F
85
+ // 1 2 3 4 5 6 7 8 9 A B C D E F
86
+ xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0x80-0x8F
87
+ xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0x90-0x9F
88
+ xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0xA0-0xAF
89
+ xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0xB0-0xBF
90
+ xx, xx, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, // 0xC0-0xCF
91
+ s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, // 0xD0-0xDF
92
+ s2, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s4, s3, s3, // 0xE0-0xEF
93
+ s5, s6, s6, s6, s7, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0xF0-0xFF
94
+ }
95
+
96
+ // acceptRange gives the range of valid values for the second byte in a UTF-8
97
+ // sequence.
98
+ type acceptRange struct {
99
+ lo uint8 // lowest value for second byte.
100
+ hi uint8 // highest value for second byte.
101
+ }
102
+
103
+ // acceptRanges has size 16 to avoid bounds checks in the code that uses it.
104
+ var acceptRanges = [16]acceptRange{
105
+ 0: {locb, hicb},
106
+ 1: {0xA0, hicb},
107
+ 2: {locb, 0x9F},
108
+ 3: {0x90, hicb},
109
+ 4: {locb, 0x8F},
110
+ }
111
+
112
+ // GoFront strings are JavaScript strings, indexed by UTF-16 code unit. The
113
+ // *InString functions therefore decode code points and report widths in
114
+ // code units, so that "s = s[size:]" walks a string as in Go; only for
115
+ // ASCII text do the widths equal Go's byte counts.
116
+
117
+ func isHigh(c rune) bool { return c >= 0xD800 && c <= 0xDBFF }
118
+ func isLow(c rune) bool { return c >= 0xDC00 && c <= 0xDFFF }
119
+
120
+ // FullRune reports whether the bytes in p begin with a full UTF-8 encoding of a rune.
121
+ // An invalid encoding is considered a full Rune since it will convert as a width-1 error rune.
122
+ func FullRune(p []byte) bool {
123
+ n := len(p)
124
+ if n == 0 {
125
+ return false
126
+ }
127
+ x := first[p[0]]
128
+ if n >= int(x&7) {
129
+ return true // ASCII, invalid or valid.
130
+ }
131
+ // Must be short or invalid.
132
+ accept := acceptRanges[x>>4]
133
+ if n > 1 && (p[1] < accept.lo || accept.hi < p[1]) {
134
+ return true
135
+ } else if n > 2 && (p[2] < locb || hicb < p[2]) {
136
+ return true
137
+ }
138
+ return false
139
+ }
140
+
141
+ // FullRuneInString is like FullRune but its input is a string.
142
+ func FullRuneInString(s string) bool {
143
+ return len(s) > 1 || (len(s) == 1 && !isHigh(rune(s[0])))
144
+ }
145
+
146
+ // DecodeRune unpacks the first UTF-8 encoding in p and returns the rune and
147
+ // its width in bytes. If p is empty it returns ([RuneError], 0). Otherwise, if
148
+ // the encoding is invalid, it returns (RuneError, 1). Both are impossible
149
+ // results for correct, non-empty UTF-8.
150
+ //
151
+ // An encoding is invalid if it is incorrect UTF-8, encodes a rune that is
152
+ // out of range, or is not the shortest possible UTF-8 encoding for the
153
+ // value. No other validation is performed.
154
+ func DecodeRune(p []byte) (r rune, size int) {
155
+ // Inlineable fast path for ASCII characters; see #48195.
156
+ // This implementation is weird but effective at rendering the
157
+ // function inlineable.
158
+ for _, b := range p {
159
+ if b < RuneSelf {
160
+ return rune(b), 1
161
+ }
162
+ break
163
+ }
164
+ r, size = decodeRuneSlow(p)
165
+ return
166
+ }
167
+
168
+ func decodeRuneSlow(p []byte) (r rune, size int) {
169
+ n := len(p)
170
+ if n < 1 {
171
+ return RuneError, 0
172
+ }
173
+ p0 := p[0]
174
+ x := first[p0]
175
+ if x >= as {
176
+ // The following code simulates an additional check for x == xx and
177
+ // handling the ASCII and invalid cases accordingly. This mask-and-or
178
+ // approach prevents an additional branch.
179
+ mask := rune(x) << 31 >> 31 // Create 0x0000 or 0xFFFF.
180
+ return rune(p[0])&^mask | RuneError&mask, 1
181
+ }
182
+ sz := int(x & 7)
183
+ accept := acceptRanges[x>>4]
184
+ if n < sz {
185
+ return RuneError, 1
186
+ }
187
+ b1 := p[1]
188
+ if b1 < accept.lo || accept.hi < b1 {
189
+ return RuneError, 1
190
+ }
191
+ if sz <= 2 { // <= instead of == to help the compiler eliminate some bounds checks
192
+ return rune(p0&mask2)<<6 | rune(b1&maskx), 2
193
+ }
194
+ b2 := p[2]
195
+ if b2 < locb || hicb < b2 {
196
+ return RuneError, 1
197
+ }
198
+ if sz <= 3 {
199
+ return rune(p0&mask3)<<12 | rune(b1&maskx)<<6 | rune(b2&maskx), 3
200
+ }
201
+ b3 := p[3]
202
+ if b3 < locb || hicb < b3 {
203
+ return RuneError, 1
204
+ }
205
+ return rune(p0&mask4)<<18 | rune(b1&maskx)<<12 | rune(b2&maskx)<<6 | rune(b3&maskx), 4
206
+ }
207
+
208
+ // DecodeRuneInString is like [DecodeRune] but its input is a string. If s is
209
+ // empty it returns ([RuneError], 0). Otherwise, if the encoding is invalid, it
210
+ // returns (RuneError, 1). Both are impossible results for correct, non-empty
211
+ // UTF-8.
212
+ //
213
+ // An encoding is invalid if it is incorrect UTF-8, encodes a rune that is
214
+ // out of range, or is not the shortest possible UTF-8 encoding for the
215
+ // value. No other validation is performed.
216
+ func DecodeRuneInString(s string) (r rune, size int) {
217
+ if len(s) == 0 {
218
+ return RuneError, 0
219
+ }
220
+ c := rune(s[0])
221
+ if isHigh(c) && len(s) > 1 && isLow(rune(s[1])) {
222
+ return (c-0xD800)<<10 + (rune(s[1]) - 0xDC00) + 0x10000, 2
223
+ }
224
+ if isHigh(c) || isLow(c) {
225
+ return RuneError, 1
226
+ }
227
+ return c, 1
228
+ }
229
+
230
+ // DecodeLastRune unpacks the last UTF-8 encoding in p and returns the rune and
231
+ // its width in bytes. If p is empty it returns ([RuneError], 0). Otherwise, if
232
+ // the encoding is invalid, it returns (RuneError, 1). Both are impossible
233
+ // results for correct, non-empty UTF-8.
234
+ //
235
+ // An encoding is invalid if it is incorrect UTF-8, encodes a rune that is
236
+ // out of range, or is not the shortest possible UTF-8 encoding for the
237
+ // value. No other validation is performed.
238
+ func DecodeLastRune(p []byte) (r rune, size int) {
239
+ end := len(p)
240
+ if end == 0 {
241
+ return RuneError, 0
242
+ }
243
+ start := end - 1
244
+ r = rune(p[start])
245
+ if r < RuneSelf {
246
+ return r, 1
247
+ }
248
+ // guard against O(n^2) behavior when traversing
249
+ // backwards through strings with long sequences of
250
+ // invalid UTF-8.
251
+ lim := end - UTFMax
252
+ if lim < 0 {
253
+ lim = 0
254
+ }
255
+ for start--; start >= lim; start-- {
256
+ if RuneStart(p[start]) {
257
+ break
258
+ }
259
+ }
260
+ if start < 0 {
261
+ start = 0
262
+ }
263
+ r, size = DecodeRune(p[start:end])
264
+ if start+size != end {
265
+ return RuneError, 1
266
+ }
267
+ return r, size
268
+ }
269
+
270
+ // DecodeLastRuneInString is like [DecodeLastRune] but its input is a string. If
271
+ // s is empty it returns ([RuneError], 0). Otherwise, if the encoding is invalid,
272
+ // it returns (RuneError, 1). Both are impossible results for correct,
273
+ // non-empty UTF-8.
274
+ //
275
+ // An encoding is invalid if it is incorrect UTF-8, encodes a rune that is
276
+ // out of range, or is not the shortest possible UTF-8 encoding for the
277
+ // value. No other validation is performed.
278
+ func DecodeLastRuneInString(s string) (r rune, size int) {
279
+ end := len(s)
280
+ if end == 0 {
281
+ return RuneError, 0
282
+ }
283
+ c := rune(s[end-1])
284
+ if isLow(c) && end > 1 && isHigh(rune(s[end-2])) {
285
+ return (rune(s[end-2])-0xD800)<<10 + (c - 0xDC00) + 0x10000, 2
286
+ }
287
+ if isHigh(c) || isLow(c) {
288
+ return RuneError, 1
289
+ }
290
+ return c, 1
291
+ }
292
+
293
+ // RuneLen returns the number of bytes in the UTF-8 encoding of the rune.
294
+ // It returns -1 if the rune is not a valid value to encode in UTF-8.
295
+ func RuneLen(r rune) int {
296
+ switch {
297
+ case r < 0:
298
+ return -1
299
+ case r <= rune1Max:
300
+ return 1
301
+ case r <= rune2Max:
302
+ return 2
303
+ case surrogateMin <= r && r <= surrogateMax:
304
+ return -1
305
+ case r <= rune3Max:
306
+ return 3
307
+ case r <= MaxRune:
308
+ return 4
309
+ }
310
+ return -1
311
+ }
312
+
313
+ // EncodeRune writes into p (which must be large enough) the UTF-8 encoding of the rune.
314
+ // If the rune is out of range, it writes the encoding of [RuneError].
315
+ // It returns the number of bytes written.
316
+ func EncodeRune(p []byte, r rune) int {
317
+ // This function is inlineable for fast handling of ASCII.
318
+ if uint32(r) <= rune1Max {
319
+ p[0] = byte(r)
320
+ return 1
321
+ }
322
+ return encodeRuneNonASCII(p, r)
323
+ }
324
+
325
+ func encodeRuneNonASCII(p []byte, r rune) int {
326
+ // Negative values are erroneous. Making it unsigned addresses the problem.
327
+ switch i := uint32(r); {
328
+ case i <= rune2Max:
329
+ _ = p[1] // eliminate bounds checks
330
+ p[0] = t2 | byte(r>>6)
331
+ p[1] = tx | byte(r)&maskx
332
+ return 2
333
+ case i < surrogateMin, surrogateMax < i && i <= rune3Max:
334
+ _ = p[2] // eliminate bounds checks
335
+ p[0] = t3 | byte(r>>12)
336
+ p[1] = tx | byte(r>>6)&maskx
337
+ p[2] = tx | byte(r)&maskx
338
+ return 3
339
+ case i > rune3Max && i <= MaxRune:
340
+ _ = p[3] // eliminate bounds checks
341
+ p[0] = t4 | byte(r>>18)
342
+ p[1] = tx | byte(r>>12)&maskx
343
+ p[2] = tx | byte(r>>6)&maskx
344
+ p[3] = tx | byte(r)&maskx
345
+ return 4
346
+ default:
347
+ _ = p[2] // eliminate bounds checks
348
+ p[0] = runeErrorByte0
349
+ p[1] = runeErrorByte1
350
+ p[2] = runeErrorByte2
351
+ return 3
352
+ }
353
+ }
354
+
355
+ // AppendRune appends the UTF-8 encoding of r to the end of p and
356
+ // returns the extended buffer. If the rune is out of range,
357
+ // it appends the encoding of [RuneError].
358
+ func AppendRune(p []byte, r rune) []byte {
359
+ // This function is inlineable for fast handling of ASCII.
360
+ if uint32(r) <= rune1Max {
361
+ return append(p, byte(r))
362
+ }
363
+ return appendRuneNonASCII(p, r)
364
+ }
365
+
366
+ func appendRuneNonASCII(p []byte, r rune) []byte {
367
+ // Negative values are erroneous. Making it unsigned addresses the problem.
368
+ switch i := uint32(r); {
369
+ case i <= rune2Max:
370
+ return append(p, t2|byte(r>>6), tx|byte(r)&maskx)
371
+ case i < surrogateMin, surrogateMax < i && i <= rune3Max:
372
+ return append(p, t3|byte(r>>12), tx|byte(r>>6)&maskx, tx|byte(r)&maskx)
373
+ case i > rune3Max && i <= MaxRune:
374
+ return append(p, t4|byte(r>>18), tx|byte(r>>12)&maskx, tx|byte(r>>6)&maskx, tx|byte(r)&maskx)
375
+ default:
376
+ return append(p, runeErrorByte0, runeErrorByte1, runeErrorByte2)
377
+ }
378
+ }
379
+
380
+ // RuneCount returns the number of runes in p. Erroneous and short
381
+ // encodings are treated as single runes of width 1 byte.
382
+ func RuneCount(p []byte) int {
383
+ n := 0
384
+ for i := 0; i < len(p); n++ {
385
+ if p[i] < RuneSelf {
386
+ i++
387
+ continue
388
+ }
389
+ _, size := DecodeRune(p[i:])
390
+ i += size
391
+ }
392
+ return n
393
+ }
394
+
395
+ // RuneCountInString is like [RuneCount] but its input is a string.
396
+ //
397
+ //gofront:native utf8.RuneCountInString
398
+ func RuneCountInString(s string) (n int) {
399
+ return len([]rune(s))
400
+ }
401
+
402
+ // RuneStart reports whether the byte could be the first byte of an encoded,
403
+ // possibly invalid rune. Second and subsequent bytes always have the top two
404
+ // bits set to 10.
405
+ func RuneStart(b byte) bool { return b&0xC0 != 0x80 }
406
+
407
+ // Valid reports whether p consists entirely of valid UTF-8-encoded runes.
408
+ func Valid(p []byte) bool {
409
+ for len(p) > 0 {
410
+ p0 := p[0]
411
+ if p0 < RuneSelf {
412
+ p = p[1:]
413
+ continue
414
+ }
415
+ x := first[p0]
416
+ size := int(x & 7)
417
+ accept := acceptRanges[x>>4]
418
+ switch size {
419
+ case 2:
420
+ if len(p) < 2 || p[1] < accept.lo || accept.hi < p[1] {
421
+ return false
422
+ }
423
+ p = p[2:]
424
+ case 3:
425
+ if len(p) < 3 || p[1] < accept.lo || accept.hi < p[1] || p[2] < locb || hicb < p[2] {
426
+ return false
427
+ }
428
+ p = p[3:]
429
+ case 4:
430
+ if len(p) < 4 || p[1] < accept.lo || accept.hi < p[1] || p[2] < locb || hicb < p[2] || p[3] < locb || hicb < p[3] {
431
+ return false
432
+ }
433
+ p = p[4:]
434
+ default:
435
+ return false // illegal starter byte
436
+ }
437
+ }
438
+ return true
439
+ }
440
+
441
+ // ValidString reports whether s consists entirely of valid UTF-8-encoded runes.
442
+ func ValidString(s string) bool {
443
+ for i := 0; i < len(s); i++ {
444
+ c := rune(s[i])
445
+ if isHigh(c) && i+1 < len(s) && isLow(rune(s[i+1])) {
446
+ i++
447
+ } else if isHigh(c) || isLow(c) {
448
+ return false
449
+ }
450
+ }
451
+ return true
452
+ }
453
+
454
+ // ValidRune reports whether r can be legally encoded as UTF-8.
455
+ // Code points that are out of range or a surrogate half are illegal.
456
+ func ValidRune(r rune) bool {
457
+ switch {
458
+ case 0 <= r && r < surrogateMin:
459
+ return true
460
+ case surrogateMax < r && r <= MaxRune:
461
+ return true
462
+ }
463
+ return false
464
+ }