builtin: deprecate string.last_index/1 for string.index_last/1, and string.last_index_u8/1 for string.index_u8_last/1 (#20095)

This commit is contained in:
Delyan Angelov 2023-12-05 13:56:59 +02:00 committed by GitHub
parent d409d8d66c
commit 4b3109237d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 123 additions and 57 deletions

View file

@ -232,7 +232,7 @@ pub fn (mut obj_part ObjPart) parse_obj_buffer(rows []string, single_material bo
mat_count++
mut part := Part{}
if mat_count > 1 {
li := obj_part.part[obj_part.part.len - 1].name.last_index('_m') or {
li := obj_part.part[obj_part.part.len - 1].name.index_last('_m') or {
obj_part.part[obj_part.part.len - 1].name.len - 1
}
part.name = obj_part.part[obj_part.part.len - 1].name[..li] +

View file

@ -730,7 +730,7 @@ pub fn (s string) replace_each(vals []string) string {
}
// last_index returns the position of the last occurrence of the input string.
fn (s string) last_index_(p string) int {
fn (s string) index_last_(p string) int {
if p.len > s.len || p.len == 0 {
return -1
}
@ -748,15 +748,23 @@ fn (s string) last_index_(p string) int {
return -1
}
// last_index returns the position of the last occurrence of the input string.
pub fn (s string) last_index(p string) ?int {
idx := s.last_index_(p)
// index_last returns the position of the first character of the *last* occurance of the `needle` string in `s`.
pub fn (s string) index_last(needle string) ?int {
idx := s.index_last_(needle)
if idx == -1 {
return none
}
return idx
}
// last_index returns the position of the first character of the *last* occurance of the `needle` string in `s`.
@[deprecated: 'use `.index_last(needle string)` instead']
@[deprecated_after: '2023-12-18']
@[inline]
pub fn (s string) last_index(needle string) ?int {
return s.index_last(needle)
}
pub fn (s string) trim_space() string {
res := ''
#res.str = s.str.trim()
@ -969,6 +977,27 @@ pub fn (s string) index(search string) ?int {
return res
}
// index_u8_last returns the index of the *last* occurrence of the byte `c` (if found) in the string.
// It returns -1, if `c` is not found.
@[direct_array_access]
pub fn (s string) index_u8_last(c u8) int {
for i := s.len - 1; i >= 0; i-- {
if s[i] == c {
return i
}
}
return -1
}
// last_index_u8 returns the index of the last occurrence of byte `c` if found in the string.
// It returns -1, if the byte `c` is not found.
@[deprecated: 'use `.index_u8_last(c u8)` instead']
@[deprecated_after: '2023-12-18']
@[inline]
pub fn (s string) last_index_u8(c u8) int {
return s.index_u8_last(c)
}
pub fn (_rune string) utf32_code() int {
res := 0
#res.val = s.str.charCodeAt()

View file

@ -1152,8 +1152,8 @@ fn (s string) index_(p string) int {
return -1
}
// index returns the position of the first character of the input string.
// It will return `none` if the input string can't be found.
// index returns the position of the first character of the first occurance of the `needle` string in `s`.
// It will return `none` if the `needle` string can't be found in `s`.
pub fn (s string) index(p string) ?int {
idx := s.index_(p)
if idx == -1 {
@ -1162,6 +1162,23 @@ pub fn (s string) index(p string) ?int {
return idx
}
// index_last returns the position of the first character of the *last* occurance of the `needle` string in `s`.
pub fn (s string) index_last(needle string) ?int {
idx := s.index_last_(needle)
if idx == -1 {
return none
}
return idx
}
// last_index returns the position of the first character of the *last* occurance of the `needle` string in `s`.
@[deprecated: 'use `.index_last(needle string)` instead']
@[deprecated_after: '2023-12-18']
@[inline]
pub fn (s string) last_index(needle string) ?int {
return s.index_last(needle)
}
// index_kmp does KMP search.
@[direct_array_access; manualfree]
fn (s string) index_kmp(p string) int {
@ -1209,9 +1226,9 @@ pub fn (s string) index_any(chars string) int {
return -1
}
// last_index returns the position of the last occurrence of the input string.
// index_last_ returns the position of the last occurrence of the given string `p` in `s`.
@[direct_array_access]
fn (s string) last_index_(p string) int {
fn (s string) index_last_(p string) int {
if p.len > s.len || p.len == 0 {
return -1
}
@ -1229,15 +1246,6 @@ fn (s string) last_index_(p string) int {
return -1
}
// last_index returns the position of the last occurrence of the input string.
pub fn (s string) last_index(p string) ?int {
idx := s.last_index_(p)
if idx == -1 {
return none
}
return idx
}
// index_after returns the position of the input string, starting search from `start` position.
@[direct_array_access]
pub fn (s string) index_after(p string, start int) int {
@ -1279,10 +1287,10 @@ pub fn (s string) index_u8(c u8) int {
return -1
}
// last_index_byte returns the index of the last occurrence of byte `c` if found in the string.
// last_index_byte returns -1 if the byte is not found.
// index_u8_last returns the index of the *last* occurrence of the byte `c` (if found) in the string.
// It returns -1, if `c` is not found.
@[direct_array_access]
pub fn (s string) last_index_u8(c u8) int {
pub fn (s string) index_u8_last(c u8) int {
for i := s.len - 1; i >= 0; i-- {
if unsafe { s.str[i] == c } {
return i
@ -1291,6 +1299,15 @@ pub fn (s string) last_index_u8(c u8) int {
return -1
}
// last_index_u8 returns the index of the last occurrence of byte `c` if found in the string.
// It returns -1, if the byte `c` is not found.
@[deprecated: 'use `.index_u8_last(c u8)` instead']
@[deprecated_after: '2023-12-18']
@[inline]
pub fn (s string) last_index_u8(c u8) int {
return s.index_u8_last(c)
}
// count returns the number of occurrences of `substr` in the string.
// count returns -1 if no `substr` could be found.
@[direct_array_access]
@ -1879,7 +1896,7 @@ pub fn (s string) all_before(sub string) string {
// Example: assert '23:34:45.234'.all_before_last(':') == '23:34'
// Example: assert 'abcd'.all_before_last('.') == 'abcd'
pub fn (s string) all_before_last(sub string) string {
pos := s.last_index_(sub)
pos := s.index_last_(sub)
if pos == -1 {
return s.clone()
}
@ -1903,7 +1920,7 @@ pub fn (s string) all_after(sub string) string {
// Example: assert '23:34:45.234'.all_after_last(':') == '45.234'
// Example: assert 'abcd'.all_after_last('z') == 'abcd'
pub fn (s string) all_after_last(sub string) string {
pos := s.last_index_(sub)
pos := s.index_last_(sub)
if pos == -1 {
return s.clone()
}

View file

@ -1233,11 +1233,21 @@ fn test_index_u8() {
//
}
fn test_last_index_u8() {
assert 'abcabca'.last_index_u8(`a`) == 6
assert 'abcabca'.last_index_u8(`c`) == 5
assert 'abcabca'.last_index_u8(`b`) == 4
assert 'Zabcabca'.last_index_u8(`Z`) == 0
fn test_index_last() {
assert 'abcabca'.index_last('ca')? == 5
assert 'abcabca'.index_last('ab')? == 3
assert 'abcabca'.index_last('b')? == 4
assert 'Zabcabca'.index_last('Z')? == 0
x := 'Zabcabca'.index_last('Y')
assert x == none
// TODO: `assert 'Zabcabca'.index_last('Y') == none` is a cgen error, 2023/12/04
}
fn test_index_u8_last() {
assert 'abcabca'.index_u8_last(`a`) == 6
assert 'abcabca'.index_u8_last(`c`) == 5
assert 'abcabca'.index_u8_last(`b`) == 4
assert 'Zabcabca'.index_u8_last(`Z`) == 0
//
assert 'abc'.index_u8(`d`) == -1
assert 'abc'.index_u8(`A`) == -1

View file

@ -79,7 +79,7 @@ fn prefix_and_suffix(pattern string) !(string, string) {
if pat.contains(os.path_separator) {
return error('pattern cannot contain path separators (${os.path_separator}).')
}
pos := pat.last_index('*') or { -1 }
pos := pat.index_u8_last(`*`)
mut prefix := ''
mut suffix := ''
if pos != -1 {

View file

@ -533,7 +533,7 @@ struct ParseAuthorityRes {
}
fn parse_authority(authority string) !ParseAuthorityRes {
i := authority.last_index('@') or { -1 }
i := authority.index_u8_last(`@`)
mut host := ''
mut zuser := user('')
if i < 0 {
@ -574,10 +574,11 @@ fn parse_authority(authority string) !ParseAuthorityRes {
// parse_host parses host as an authority without user
// information. That is, as host[:port].
fn parse_host(host string) !string {
if host.starts_with('[') {
if host.len > 0 && host[0] == `[` {
// parse an IP-Literal in RFC 3986 and RFC 6874.
// E.g., '[fe80::1]', '[fe80::1%25en0]', '[fe80::1]:80'.
mut i := host.last_index(']') or {
mut i := host.index_u8_last(`]`)
if i == -1 {
return error(error_msg("parse_host: missing ']' in host", ''))
}
mut colon_port := host[i + 1..]
@ -597,11 +598,14 @@ fn parse_host(host string) !string {
host3 := unescape(host[i..], .encode_host) or { return err.msg() }
return host1 + host2 + host3
}
} else if i := host.last_index(':') {
colon_port := host[i..]
if !valid_optional_port(colon_port) {
return error(error_msg('parse_host: invalid port ${colon_port} after host ',
''))
} else {
i := host.index_u8_last(`:`)
if i != -1 {
colon_port := host[i..]
if !valid_optional_port(colon_port) {
return error(error_msg('parse_host: invalid port ${colon_port} after host ',
''))
}
}
}
h := unescape(host, .encode_host) or { return err.msg() }
@ -870,7 +874,7 @@ fn resolve_path(base string, ref string) string {
if ref == '' {
full = base
} else if ref[0] != `/` {
i := base.last_index('/') or { -1 }
i := base.index_u8_last(`/`)
full = base[..i + 1] + ref
} else {
full = ref
@ -1004,14 +1008,14 @@ pub fn (u &URL) port() string {
pub fn split_host_port(hostport string) (string, string) {
mut host := hostport
mut port := ''
colon := host.last_index_u8(`:`)
colon := host.index_u8_last(`:`)
if colon != -1 {
if valid_optional_port(host[colon..]) {
port = host[colon + 1..]
host = host[..colon]
}
}
if host.starts_with('[') && host.ends_with(']') {
if host.len > 1 && host[0] == `[` && host.ends_with(']') {
host = host[1..host.len - 1]
}
return host, port

View file

@ -237,12 +237,15 @@ pub fn is_dir_empty(path string) bool {
// ```
pub fn file_ext(opath string) string {
if opath.len < 3 {
return empty_str
return ''
}
path := file_name(opath)
pos := path.last_index(dot_str) or { return empty_str }
pos := path.index_u8_last(`.`)
if pos == -1 {
return ''
}
if pos + 1 >= path.len || pos == 0 {
return empty_str
return ''
}
return path[pos..]
}
@ -258,7 +261,7 @@ pub fn dir(opath string) string {
}
other_separator := if path_separator == '/' { '\\' } else { '/' }
path := opath.replace(other_separator, path_separator)
pos := path.last_index(path_separator) or { return '.' }
pos := path.index_last(path_separator) or { return '.' }
if pos == 0 && path_separator == '/' {
return '/'
}
@ -280,10 +283,10 @@ pub fn base(opath string) string {
}
if path.ends_with(path_separator) {
path2 := path[..path.len - 1]
pos := path2.last_index(path_separator) or { return path2.clone() }
pos := path2.index_last(path_separator) or { return path2.clone() }
return path2[pos + 1..]
}
pos := path.last_index(path_separator) or { return path.clone() }
pos := path.index_last(path_separator) or { return path.clone() }
return path[pos + 1..]
}

View file

@ -19,7 +19,7 @@ fn parse(input string) RawVersion {
mut raw_version := input
mut prerelease := ''
mut metadata := ''
plus_idx := raw_version.last_index('+') or { -1 }
plus_idx := raw_version.index_u8_last(`+`)
if plus_idx > 0 {
metadata = raw_version[(plus_idx + 1)..]
raw_version = raw_version[0..plus_idx]

View file

@ -480,7 +480,7 @@ fn (mut c Checker) check_valid_snake_case(name string, identifier string, pos to
}
fn stripped_name(name string) string {
idx := name.last_index('.') or { -1 }
idx := name.index_last('.') or { -1 }
return name[(idx + 1)..]
}

View file

@ -489,7 +489,7 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini
// but `x := T{}` is ok.
if !c.is_builtin_mod && !c.inside_unsafe && type_sym.language == .v
&& c.table.cur_concrete_types.len == 0 {
pos := type_sym.name.last_index('.') or { -1 }
pos := type_sym.name.index_u8_last(`.`)
first_letter := type_sym.name[pos + 1]
if !first_letter.is_capital()
&& (type_sym.kind != .struct_ || !(type_sym.info as ast.Struct).is_anon)

View file

@ -1,5 +1,5 @@
vlib/v/checker/tests/type_cast_option_err.vv:2:10: error: cannot type cast an Option
1 | fn main() {
2 | println(int('hi'.last_index('i')))
2 | println(int('hi'.index_last('i')))
| ~~~~~~~~~~~~~~~~~~~~~~~~~
3 | }

View file

@ -1,3 +1,3 @@
fn main() {
println(int('hi'.last_index('i')))
println(int('hi'.index_last('i')))
}

View file

@ -306,10 +306,10 @@ pub fn gen(files []&ast.File, table &ast.Table, pref_ &pref.Preferences) string
// calculate final generated location in output based on position
current_segment := g.out.substr(int(sm_pos), int(sourcemap_ns_entry.ns_pos))
current_line += u32(current_segment.count('\n'))
current_column := if last_nl_pos := current_segment.last_index('\n') {
u32(current_segment.len - last_nl_pos - 1)
} else {
u32(0)
mut current_column := u32(0)
last_nl_pos := current_segment.index_u8_last(`\n`)
if last_nl_pos != -1 {
current_column = u32(current_segment.len - last_nl_pos - 1)
}
g.sourcemap.add_mapping(sourcemap_ns_entry.src_path, sourcemap.SourcePosition{
source_line: sourcemap_ns_entry.src_line
@ -541,7 +541,10 @@ pub fn (mut g JsGen) new_tmp_var() string {
// 'fn' => ''
@[inline]
fn get_ns(s string) string {
idx := s.last_index('.') or { return '' }
idx := s.index_u8_last(`.`)
if idx == -1 {
return ''
}
return s.substr(0, idx)
}

View file

@ -127,7 +127,7 @@ fn test_nested_option_with_opt_fn_call_as_last_value() {
fn remove_suffix1(s string) string {
n := s.len
i := s.last_index('.') or { n }
i := s.index_last('.') or { n }
return s[0..i]
}