mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: do not allow direct initialization of builtin types (s := string{})
This commit is contained in:
parent
f648e3f10d
commit
2f1810634e
@ -24,7 +24,7 @@ pub fn decode(data string) []byte {
|
||||
unsafe {
|
||||
buffer := malloc(size)
|
||||
n := decode_in_buffer(data, buffer)
|
||||
return array{element_size: 1, data: buffer, len: n, cap: size}
|
||||
return buffer.vbytes(n)
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,7 +70,8 @@ fn alloc_and_encode(src byteptr, len int) string {
|
||||
// the a base64 url encoded `string` passed in `data`.
|
||||
pub fn url_decode(data string) []byte {
|
||||
mut result := data.replace_each(['-', '+', '_', '/'])
|
||||
match result.len % 4 { // Pad with trailing '='s
|
||||
match result.len % 4 {
|
||||
// Pad with trailing '='s
|
||||
2 { result += '==' } // 2 pad chars
|
||||
3 { result += '=' } // 1 pad char
|
||||
else {} // no padding
|
||||
@ -81,7 +82,8 @@ pub fn url_decode(data string) []byte {
|
||||
// url_decode_str is the string variant of url_decode
|
||||
pub fn url_decode_str(data string) string {
|
||||
mut result := data.replace_each(['-', '+', '_', '/'])
|
||||
match result.len % 4 { // Pad with trailing '='s
|
||||
match result.len % 4 {
|
||||
// Pad with trailing '='s
|
||||
2 { result += '==' } // 2 pad chars
|
||||
3 { result += '=' } // 1 pad char
|
||||
else {} // no padding
|
||||
@ -132,19 +134,19 @@ pub fn decode_in_buffer(data &string, buffer byteptr) int {
|
||||
mut char_c := 0
|
||||
mut char_d := 0
|
||||
if i < input_length {
|
||||
char_a = index[unsafe { d[i] }]
|
||||
char_a = base64.index[unsafe { d[i] }]
|
||||
i++
|
||||
}
|
||||
if i < input_length {
|
||||
char_b = index[unsafe { d[i] }]
|
||||
char_b = base64.index[unsafe { d[i] }]
|
||||
i++
|
||||
}
|
||||
if i < input_length {
|
||||
char_c = index[unsafe { d[i] }]
|
||||
char_c = base64.index[unsafe { d[i] }]
|
||||
i++
|
||||
}
|
||||
if i < input_length {
|
||||
char_d = index[unsafe { d[i] }]
|
||||
char_d = base64.index[unsafe { d[i] }]
|
||||
i++
|
||||
}
|
||||
|
||||
@ -180,7 +182,7 @@ fn encode_from_buffer(dest byteptr, src byteptr, src_len int) int {
|
||||
|
||||
mut d := src
|
||||
mut b := dest
|
||||
mut etable := byteptr(enc_table.str)
|
||||
mut etable := byteptr(base64.enc_table.str)
|
||||
for i < input_length {
|
||||
mut octet_a := 0
|
||||
mut octet_b := 0
|
||||
@ -210,7 +212,7 @@ fn encode_from_buffer(dest byteptr, src byteptr, src_len int) int {
|
||||
j += 4
|
||||
}
|
||||
|
||||
padding_length := ending_table[input_length % 3]
|
||||
padding_length := base64.ending_table[input_length % 3]
|
||||
for i = 0; i < padding_length; i++ {
|
||||
unsafe {
|
||||
b[output_length - 1 - i] = `=`
|
||||
|
@ -483,7 +483,7 @@ pub fn read_file_array<T>(path string) []T {
|
||||
a := T{}
|
||||
tsize := int(sizeof(a))
|
||||
// prepare for reading, get current file size
|
||||
mut fp := vfopen(path, 'rb') or { return array{} }
|
||||
mut fp := vfopen(path, 'rb') or { return []T{} }
|
||||
C.fseek(fp, 0, C.SEEK_END)
|
||||
fsize := C.ftell(fp)
|
||||
C.rewind(fp)
|
||||
@ -492,11 +492,13 @@ pub fn read_file_array<T>(path string) []T {
|
||||
buf := unsafe { malloc(fsize) }
|
||||
C.fread(buf, fsize, 1, fp)
|
||||
C.fclose(fp)
|
||||
return array{
|
||||
element_size: tsize
|
||||
data: buf
|
||||
len: len
|
||||
cap: len
|
||||
return unsafe {
|
||||
array{
|
||||
element_size: tsize
|
||||
data: buf
|
||||
len: len
|
||||
cap: len
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1248,7 +1248,6 @@ pub fn (expr Expr) is_blank_ident() bool {
|
||||
pub fn (expr Expr) position() token.Position {
|
||||
// all uncommented have to be implemented
|
||||
match expr {
|
||||
// KEKW2
|
||||
AnonFn {
|
||||
return expr.decl.pos
|
||||
}
|
||||
|
@ -463,6 +463,16 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) table.Type {
|
||||
utyp := c.unwrap_generic(struct_init.typ)
|
||||
c.ensure_type_exists(utyp, struct_init.pos) or {}
|
||||
type_sym := c.table.get_type_symbol(utyp)
|
||||
// Make sure the first letter is capital, do not allow e.g. `x := string{}`,
|
||||
// but `x := T{}` is ok.
|
||||
if !c.is_builtin_mod && !c.inside_unsafe && type_sym.language == .v
|
||||
&& c.cur_generic_types.len == 0 {
|
||||
pos := type_sym.name.last_index('.') or { -1 }
|
||||
first_letter := type_sym.name[pos + 1]
|
||||
if !first_letter.is_capital() {
|
||||
c.error('cannot initialize builtin type `$type_sym.name`', struct_init.pos)
|
||||
}
|
||||
}
|
||||
if type_sym.kind == .sum_type && struct_init.fields.len == 1 {
|
||||
sexpr := struct_init.fields[0].expr.str()
|
||||
c.error('cast to sum type using `${type_sym.name}($sexpr)` not `$type_sym.name{$sexpr}`',
|
||||
|
@ -1,4 +1,4 @@
|
||||
vlib/v/checker/tests/check_generic_int_init.vv:2:9: error: type `int` is private
|
||||
vlib/v/checker/tests/check_generic_int_init.vv:2:9: error: cannot initialize builtin type `int`
|
||||
1 | fn test<T>() T {
|
||||
2 | return T{}
|
||||
| ~~~
|
||||
|
@ -31,7 +31,7 @@ fn test_ct_expressions() {
|
||||
|
||||
fn generic_t_is<O>() O {
|
||||
$if O is string {
|
||||
return 'It\'s a string!'
|
||||
return "It's a string!"
|
||||
} $else {
|
||||
return O{}
|
||||
}
|
||||
@ -41,17 +41,17 @@ fn generic_t_is<O>() O {
|
||||
struct GenericTIsTest {}
|
||||
|
||||
fn test_generic_t_is() {
|
||||
assert generic_t_is<string>() == 'It\'s a string!'
|
||||
assert generic_t_is<string>() == "It's a string!"
|
||||
assert generic_t_is<GenericTIsTest>() == GenericTIsTest{}
|
||||
}
|
||||
|
||||
fn generic_t_is2<T>() ?T {
|
||||
$if T is string {
|
||||
return 'It\'s a string!'
|
||||
return "It's a string!"
|
||||
} $else {
|
||||
return T{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn test_generic_t_is2() {
|
||||
res := generic_t_is2<string>() or {
|
||||
@ -62,7 +62,7 @@ fn test_generic_t_is2() {
|
||||
assert false
|
||||
GenericTIsTest{}
|
||||
}
|
||||
assert res == 'It\'s a string!'
|
||||
assert res == "It's a string!"
|
||||
assert res2 == GenericTIsTest{}
|
||||
}
|
||||
|
||||
@ -123,4 +123,3 @@ fn test_generic_t_is_with_else_if() {
|
||||
x := generic_t_is_with_else_if<User>()
|
||||
assert x == ['name', 'age']
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user