builtin: change IError `msg` and `code` to methods + fix vlib, add a deprecation notice for the old usages (#13041)
parent
61024d4b75
commit
9d0a5942ac
|
@ -14,41 +14,85 @@ pub fn panic(s string) {
|
||||||
|
|
||||||
// IError holds information about an error instance
|
// IError holds information about an error instance
|
||||||
pub interface IError {
|
pub interface IError {
|
||||||
|
// >> Hack to allow old style custom error implementations
|
||||||
|
// TODO: remove once deprecation period for `IError` methods has ended
|
||||||
msg string
|
msg string
|
||||||
code int
|
code int // <<
|
||||||
|
msg() string
|
||||||
|
code() int
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error is the default implementation of IError, that is returned by e.g. `error()`
|
pub fn (err IError) str() string {
|
||||||
|
return match err {
|
||||||
|
None__ {
|
||||||
|
'none'
|
||||||
|
}
|
||||||
|
Error {
|
||||||
|
err.msg()
|
||||||
|
}
|
||||||
|
MessageError {
|
||||||
|
err.msg()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// >> Hack to allow old style custom error implementations
|
||||||
|
// TODO: can be removed once the checker 'hacks' are merged (so `vc` has them included)
|
||||||
|
if !isnil(err.msg) {
|
||||||
|
'$err.type_name(): $err.msg'
|
||||||
|
} else {
|
||||||
|
// <<
|
||||||
|
'$err.type_name(): $err.msg()'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error is the empty default implementation of `IError`.
|
||||||
pub struct Error {
|
pub struct Error {
|
||||||
|
// >> Hack to allow old style custom error implementations
|
||||||
|
// TODO: can be removed once the checker 'hacks' are merged (so `vc` has them included)
|
||||||
|
msg string
|
||||||
|
code int
|
||||||
|
/// <<
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (err Error) msg() string {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (err Error) code() int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MessageError is the default implementation of the `IError` interface that is returned by the `error()` function
|
||||||
|
struct MessageError {
|
||||||
pub:
|
pub:
|
||||||
msg string
|
msg string
|
||||||
code int
|
code int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn (err MessageError) msg() string {
|
||||||
|
return err.msg
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (err MessageError) code() int {
|
||||||
|
return err.code
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const none__ = IError(&None__{})
|
||||||
|
|
||||||
struct None__ {
|
struct None__ {
|
||||||
msg string
|
Error
|
||||||
code int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (_ None__) str() string {
|
fn (_ None__) str() string {
|
||||||
return 'none'
|
return 'none'
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const none__ = IError(None__{'', 0})
|
|
||||||
|
|
||||||
pub struct Option {
|
pub struct Option {
|
||||||
state byte
|
state byte
|
||||||
err IError = none__
|
err IError = none__
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (err IError) str() string {
|
|
||||||
return match err {
|
|
||||||
None__ { 'none' }
|
|
||||||
Error { err.msg }
|
|
||||||
else { 'Error: $err.msg' }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (o Option) str() string {
|
pub fn (o Option) str() string {
|
||||||
if o.state == 0 {
|
if o.state == 0 {
|
||||||
return 'Option{ ok }'
|
return 'Option{ ok }'
|
||||||
|
@ -69,7 +113,7 @@ fn trace_error(x string) {
|
||||||
[inline]
|
[inline]
|
||||||
pub fn error(message string) IError {
|
pub fn error(message string) IError {
|
||||||
// trace_error(message)
|
// trace_error(message)
|
||||||
return &Error{
|
return &MessageError{
|
||||||
msg: message
|
msg: message
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,7 +123,7 @@ pub fn error(message string) IError {
|
||||||
[inline]
|
[inline]
|
||||||
pub fn error_with_code(message string, code int) IError {
|
pub fn error_with_code(message string, code int) IError {
|
||||||
// trace_error('$message | code: $code')
|
// trace_error('$message | code: $code')
|
||||||
return &Error{
|
return &MessageError{
|
||||||
msg: message
|
msg: message
|
||||||
code: code
|
code: code
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ struct C.IError {
|
||||||
[unsafe]
|
[unsafe]
|
||||||
pub fn (ie &IError) free() {
|
pub fn (ie &IError) free() {
|
||||||
unsafe {
|
unsafe {
|
||||||
ie.msg.free()
|
|
||||||
cie := &C.IError(ie)
|
cie := &C.IError(ie)
|
||||||
free(cie._object)
|
free(cie._object)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,30 +5,79 @@ module builtin
|
||||||
|
|
||||||
// IError holds information about an error instance
|
// IError holds information about an error instance
|
||||||
pub interface IError {
|
pub interface IError {
|
||||||
|
// >> Hack to allow old style custom error implementations
|
||||||
|
// TODO: remove once deprecation period for `IError` methods has ended
|
||||||
msg string
|
msg string
|
||||||
code int
|
code int // <<
|
||||||
|
msg() string
|
||||||
|
code() int
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error is the default implementation of IError, that is returned by e.g. `error()`
|
pub fn (err IError) str() string {
|
||||||
|
return match err {
|
||||||
|
None__ {
|
||||||
|
'none'
|
||||||
|
}
|
||||||
|
Error {
|
||||||
|
err.msg()
|
||||||
|
}
|
||||||
|
MessageError {
|
||||||
|
err.msg()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// >> Hack to allow old style custom error implementations
|
||||||
|
// TODO: can be removed once the checker 'hacks' are merged (so `vc` has them included)
|
||||||
|
if !isnil(err.msg) {
|
||||||
|
'$err.type_name(): $err.msg'
|
||||||
|
} else {
|
||||||
|
// <<
|
||||||
|
'$err.type_name(): $err.msg()'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error is the empty default implementation of `IError`.
|
||||||
pub struct Error {
|
pub struct Error {
|
||||||
|
// >> Hack to allow old style custom error implementations
|
||||||
|
// TODO: can be removed once the checker 'hacks' are merged (so `vc` has them included)
|
||||||
|
msg string
|
||||||
|
code int
|
||||||
|
/// <<
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (err Error) msg() string {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (err Error) code() int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MessageError is the default implementation of the `IError` interface that is returned by the `error()` function
|
||||||
|
struct MessageError {
|
||||||
pub:
|
pub:
|
||||||
msg string
|
msg string
|
||||||
code int
|
code int
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (err IError) str() string {
|
pub fn (err MessageError) msg() string {
|
||||||
return match err {
|
return err.msg
|
||||||
None__ { 'none' }
|
}
|
||||||
Error { err.msg }
|
|
||||||
else { '$err.type_name(): $err.msg' }
|
pub fn (err MessageError) code() int {
|
||||||
}
|
return err.code
|
||||||
|
}
|
||||||
|
|
||||||
|
[unsafe]
|
||||||
|
pub fn (err &MessageError) free() {
|
||||||
|
unsafe { err.msg.free() }
|
||||||
}
|
}
|
||||||
|
|
||||||
const none__ = IError(&None__{})
|
const none__ = IError(&None__{})
|
||||||
|
|
||||||
struct None__ {
|
struct None__ {
|
||||||
msg string
|
Error
|
||||||
code int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (_ None__) str() string {
|
fn (_ None__) str() string {
|
||||||
|
@ -45,7 +94,7 @@ fn trace_error(x string) {
|
||||||
[inline]
|
[inline]
|
||||||
pub fn error(message string) IError {
|
pub fn error(message string) IError {
|
||||||
trace_error(message)
|
trace_error(message)
|
||||||
return &Error{
|
return &MessageError{
|
||||||
msg: message
|
msg: message
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,7 +104,7 @@ pub fn error(message string) IError {
|
||||||
[inline]
|
[inline]
|
||||||
pub fn error_with_code(message string, code int) IError {
|
pub fn error_with_code(message string, code int) IError {
|
||||||
trace_error('$message | code: $code')
|
trace_error('$message | code: $code')
|
||||||
return &Error{
|
return &MessageError{
|
||||||
msg: message
|
msg: message
|
||||||
code: code
|
code: code
|
||||||
}
|
}
|
||||||
|
@ -78,16 +127,6 @@ fn opt_ok(data voidptr, mut option Option, size int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[unsafe]
|
|
||||||
pub fn (e &Error) free() {
|
|
||||||
unsafe { e.msg.free() }
|
|
||||||
}
|
|
||||||
|
|
||||||
[unsafe]
|
|
||||||
pub fn (n &None__) free() {
|
|
||||||
unsafe { n.msg.free() }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (_ none) str() string {
|
pub fn (_ none) str() string {
|
||||||
return 'none'
|
return 'none'
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,6 @@ fn test_crypto_bcrypt() {
|
||||||
bcrypt.compare_hash_and_password('password'.bytes(), hash.bytes()) or { panic(err) }
|
bcrypt.compare_hash_and_password('password'.bytes(), hash.bytes()) or { panic(err) }
|
||||||
|
|
||||||
bcrypt.compare_hash_and_password('password2'.bytes(), hash.bytes()) or {
|
bcrypt.compare_hash_and_password('password2'.bytes(), hash.bytes()) or {
|
||||||
assert err == error('mismatched hash and password')
|
assert err.msg() == 'mismatched hash and password'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
module rand
|
module rand
|
||||||
|
|
||||||
struct ReadError {
|
struct ReadError {
|
||||||
msg string = 'crypto.rand.read() error reading random bytes'
|
Error
|
||||||
code int
|
}
|
||||||
|
|
||||||
|
pub fn (err ReadError) msg() string {
|
||||||
|
return 'crypto.rand.read() error reading random bytes'
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,23 +11,28 @@ pub:
|
||||||
}
|
}
|
||||||
|
|
||||||
struct UnkownFlagError {
|
struct UnkownFlagError {
|
||||||
msg string
|
Error
|
||||||
code int
|
flag string
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MinimumArgsCountError {
|
fn (err UnkownFlagError) msg() string {
|
||||||
msg string
|
return 'Unknown flag `$err.flag`'
|
||||||
code int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MaximumArgsCountError {
|
struct ArgsCountError {
|
||||||
msg string
|
Error
|
||||||
code int
|
got int
|
||||||
|
want int
|
||||||
}
|
}
|
||||||
|
|
||||||
struct NoArgsExpectedError {
|
fn (err ArgsCountError) msg() string {
|
||||||
msg string
|
if err.want == 0 {
|
||||||
code int
|
return 'Expected no arguments, but got $err.got'
|
||||||
|
} else if err.got > err.want {
|
||||||
|
return 'Expected at most $err.want arguments, but got $err.got'
|
||||||
|
} else {
|
||||||
|
return 'Expected at least $err.want arguments, but got $err.got'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// free frees the resources associated with a given Flag
|
// free frees the resources associated with a given Flag
|
||||||
|
@ -616,24 +621,27 @@ pub fn (mut fs FlagParser) finalize() ?[]string {
|
||||||
for a in remaining {
|
for a in remaining {
|
||||||
if (a.len >= 2 && a[..2] == '--') || (a.len == 2 && a[0] == `-`) {
|
if (a.len >= 2 && a[..2] == '--') || (a.len == 2 && a[0] == `-`) {
|
||||||
return IError(&UnkownFlagError{
|
return IError(&UnkownFlagError{
|
||||||
msg: 'Unknown flag `$a`'
|
flag: a
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if remaining.len < fs.min_free_args && fs.min_free_args > 0 {
|
if remaining.len < fs.min_free_args && fs.min_free_args > 0 {
|
||||||
return IError(&MinimumArgsCountError{
|
return IError(&ArgsCountError{
|
||||||
msg: 'Expected at least $fs.min_free_args arguments, but given $remaining.len'
|
want: fs.min_free_args
|
||||||
|
got: remaining.len
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if remaining.len > fs.max_free_args && fs.max_free_args > 0 {
|
if remaining.len > fs.max_free_args && fs.max_free_args > 0 {
|
||||||
return IError(&MaximumArgsCountError{
|
return IError(&ArgsCountError{
|
||||||
msg: 'Expected at most $fs.max_free_args arguments, but given $remaining.len'
|
want: fs.max_free_args
|
||||||
|
got: remaining.len
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if remaining.len > 0 && fs.max_free_args == 0 && fs.min_free_args == 0 {
|
if remaining.len > 0 && fs.max_free_args == 0 && fs.min_free_args == 0 {
|
||||||
return IError(&NoArgsExpectedError{
|
return IError(&ArgsCountError{
|
||||||
msg: 'Expected no arguments, but given $remaining.len'
|
want: 0
|
||||||
|
got: remaining.len
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
remaining << fs.all_after_dashdash
|
remaining << fs.all_after_dashdash
|
||||||
|
@ -647,7 +655,7 @@ pub fn (mut fs FlagParser) finalize() ?[]string {
|
||||||
// you want more control over the error handling.
|
// you want more control over the error handling.
|
||||||
pub fn (mut fs FlagParser) remaining_parameters() []string {
|
pub fn (mut fs FlagParser) remaining_parameters() []string {
|
||||||
return fs.finalize() or {
|
return fs.finalize() or {
|
||||||
eprintln(err.msg)
|
eprintln(err.msg())
|
||||||
println(fs.usage())
|
println(fs.usage())
|
||||||
exit(1)
|
exit(1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,7 +137,7 @@ fn test_finalize_returns_error_for_unknown_flags_long() {
|
||||||
mut fp := flag.new_flag_parser(['--known', '--unknown'])
|
mut fp := flag.new_flag_parser(['--known', '--unknown'])
|
||||||
fp.bool('known', 0, false, '')
|
fp.bool('known', 0, false, '')
|
||||||
finalized := fp.finalize() or {
|
finalized := fp.finalize() or {
|
||||||
assert err.msg == 'Unknown flag `--unknown`'
|
assert err.msg() == 'Unknown flag `--unknown`'
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
assert finalized.len < 0 // expect error to be returned
|
assert finalized.len < 0 // expect error to be returned
|
||||||
|
@ -147,7 +147,7 @@ fn test_finalize_returns_error_for_unknown_flags_short() {
|
||||||
mut fp := flag.new_flag_parser(['--known', '-x'])
|
mut fp := flag.new_flag_parser(['--known', '-x'])
|
||||||
fp.bool('known', 0, false, '')
|
fp.bool('known', 0, false, '')
|
||||||
finalized := fp.finalize() or {
|
finalized := fp.finalize() or {
|
||||||
assert err.msg == 'Unknown flag `-x`'
|
assert err.msg() == 'Unknown flag `-x`'
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
assert finalized.len < 0 // expect error to be returned
|
assert finalized.len < 0 // expect error to be returned
|
||||||
|
@ -210,7 +210,7 @@ fn test_error_for_to_few_free_args() ? {
|
||||||
mut fp1 := flag.new_flag_parser(['a', 'b', 'c'])
|
mut fp1 := flag.new_flag_parser(['a', 'b', 'c'])
|
||||||
fp1.limit_free_args(5, 6) ?
|
fp1.limit_free_args(5, 6) ?
|
||||||
args := fp1.finalize() or {
|
args := fp1.finalize() or {
|
||||||
assert err.msg.starts_with('Expected at least 5 arguments')
|
assert err.msg().starts_with('Expected at least 5 arguments')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
assert args.len < 0 // expect an error and need to use args
|
assert args.len < 0 // expect an error and need to use args
|
||||||
|
@ -220,7 +220,7 @@ fn test_error_for_to_much_free_args() ? {
|
||||||
mut fp1 := flag.new_flag_parser(['a', 'b', 'c'])
|
mut fp1 := flag.new_flag_parser(['a', 'b', 'c'])
|
||||||
fp1.limit_free_args(1, 2) ?
|
fp1.limit_free_args(1, 2) ?
|
||||||
args := fp1.finalize() or {
|
args := fp1.finalize() or {
|
||||||
assert err.msg.starts_with('Expected at most 2 arguments')
|
assert err.msg().starts_with('Expected at most 2 arguments')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
assert args.len < 0 // expect an error and need to use args
|
assert args.len < 0 // expect an error and need to use args
|
||||||
|
@ -230,7 +230,7 @@ fn test_could_expect_no_free_args() ? {
|
||||||
mut fp1 := flag.new_flag_parser(['a'])
|
mut fp1 := flag.new_flag_parser(['a'])
|
||||||
fp1.limit_free_args(0, 0) ?
|
fp1.limit_free_args(0, 0) ?
|
||||||
args := fp1.finalize() or {
|
args := fp1.finalize() or {
|
||||||
assert err.msg.starts_with('Expected no arguments')
|
assert err.msg().starts_with('Expected no arguments')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
assert args.len < 0 // expect an error and need to use args
|
assert args.len < 0 // expect an error and need to use args
|
||||||
|
|
|
@ -24,7 +24,7 @@ pub fn temp_file(tfo TempFileOptions) ?(os.File, string) {
|
||||||
' could not create temporary file in "$d". Please ensure write permissions.')
|
' could not create temporary file in "$d". Please ensure write permissions.')
|
||||||
}
|
}
|
||||||
d = d.trim_right(os.path_separator)
|
d = d.trim_right(os.path_separator)
|
||||||
prefix, suffix := prefix_and_suffix(tfo.pattern) or { return error(@FN + ' ' + err.msg) }
|
prefix, suffix := prefix_and_suffix(tfo.pattern) or { return error(@FN + ' $err.msg()') }
|
||||||
for retry := 0; retry < util.retries; retry++ {
|
for retry := 0; retry < util.retries; retry++ {
|
||||||
path := os.join_path(d, prefix + random_number() + suffix)
|
path := os.join_path(d, prefix + random_number() + suffix)
|
||||||
mut mode := 'rw+'
|
mut mode := 'rw+'
|
||||||
|
@ -57,7 +57,7 @@ pub fn temp_dir(tdo TempFileOptions) ?string {
|
||||||
' could not create temporary directory "$d". Please ensure write permissions.')
|
' could not create temporary directory "$d". Please ensure write permissions.')
|
||||||
}
|
}
|
||||||
d = d.trim_right(os.path_separator)
|
d = d.trim_right(os.path_separator)
|
||||||
prefix, suffix := prefix_and_suffix(tdo.pattern) or { return error(@FN + ' ' + err.msg) }
|
prefix, suffix := prefix_and_suffix(tdo.pattern) or { return error(@FN + ' $err.msg()') }
|
||||||
for retry := 0; retry < util.retries; retry++ {
|
for retry := 0; retry < util.retries; retry++ {
|
||||||
path := os.join_path(d, prefix + random_number() + suffix)
|
path := os.join_path(d, prefix + random_number() + suffix)
|
||||||
os.mkdir_all(path) or { continue }
|
os.mkdir_all(path) or { continue }
|
||||||
|
|
|
@ -14,7 +14,7 @@ mut:
|
||||||
fn test_json_decode_fails_to_decode_unrecognised_array_of_dicts() {
|
fn test_json_decode_fails_to_decode_unrecognised_array_of_dicts() {
|
||||||
data := '[{"twins":[{"id":123,"seed":"abcde","pubkey":"xyzasd"},{"id":456,"seed":"dfgdfgdfgd","pubkey":"skjldskljh45sdf"}]}]'
|
data := '[{"twins":[{"id":123,"seed":"abcde","pubkey":"xyzasd"},{"id":456,"seed":"dfgdfgdfgd","pubkey":"skjldskljh45sdf"}]}]'
|
||||||
json.decode(TestTwins, data) or {
|
json.decode(TestTwins, data) or {
|
||||||
assert err.msg == "expected field 'twins' is missing"
|
assert err.msg() == "expected field 'twins' is missing"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
assert false
|
assert false
|
||||||
|
|
|
@ -333,7 +333,7 @@ fn test_errors() {
|
||||||
data := '{"countries":[{"cities":[{"name":"London"},{"name":"Manchester"}],"name":"UK"},{"cities":{"name":"Donlon"},"name":"KU"}],"users":{"Foo":{"age":10,"nums":[1,2,3],"lastName":"Johnson","IsRegistered":true,"type":0,"pet_animals":"little foo"},"Boo":{"age":20,"nums":[5,3,1],"lastName":"Smith","IsRegistered":false,"type":4,"pet_animals":"little boo"}},"extra":{"2":{"n1":2,"n2":4,"n3":8,"n4":16},"3":{"n1":3,"n2":9,"n3":27,"n4":81}}}'
|
data := '{"countries":[{"cities":[{"name":"London"},{"name":"Manchester"}],"name":"UK"},{"cities":{"name":"Donlon"},"name":"KU"}],"users":{"Foo":{"age":10,"nums":[1,2,3],"lastName":"Johnson","IsRegistered":true,"type":0,"pet_animals":"little foo"},"Boo":{"age":20,"nums":[5,3,1],"lastName":"Smith","IsRegistered":false,"type":4,"pet_animals":"little boo"}},"extra":{"2":{"n1":2,"n2":4,"n3":8,"n4":16},"3":{"n1":3,"n2":9,"n3":27,"n4":81}}}'
|
||||||
json.decode(Data, data) or {
|
json.decode(Data, data) or {
|
||||||
println(err)
|
println(err)
|
||||||
assert err.msg.starts_with('Json element is not an array:')
|
assert err.msg().starts_with('Json element is not an array:')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
assert false
|
assert false
|
||||||
|
@ -342,7 +342,7 @@ fn test_errors() {
|
||||||
data := '{"countries":[{"cities":[{"name":"London"},{"name":"Manchester"}],"name":"UK"},{"cities":[{"name":"Donlon"},{"name":"Termanches"}],"name":"KU"}],"users":[{"age":10,"nums":[1,2,3],"lastName":"Johnson","IsRegistered":true,"type":0,"pet_animals":"little foo"},{"age":20,"nums":[5,3,1],"lastName":"Smith","IsRegistered":false,"type":4,"pet_animals":"little boo"}],"extra":{"2":{"n1":2,"n2":4,"n3":8,"n4":16},"3":{"n1":3,"n2":9,"n3":27,"n4":81}}}'
|
data := '{"countries":[{"cities":[{"name":"London"},{"name":"Manchester"}],"name":"UK"},{"cities":[{"name":"Donlon"},{"name":"Termanches"}],"name":"KU"}],"users":[{"age":10,"nums":[1,2,3],"lastName":"Johnson","IsRegistered":true,"type":0,"pet_animals":"little foo"},{"age":20,"nums":[5,3,1],"lastName":"Smith","IsRegistered":false,"type":4,"pet_animals":"little boo"}],"extra":{"2":{"n1":2,"n2":4,"n3":8,"n4":16},"3":{"n1":3,"n2":9,"n3":27,"n4":81}}}'
|
||||||
json.decode(Data, data) or {
|
json.decode(Data, data) or {
|
||||||
println(err)
|
println(err)
|
||||||
assert err.msg.starts_with('Json element is not an object:')
|
assert err.msg().starts_with('Json element is not an object:')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
assert false
|
assert false
|
||||||
|
|
|
@ -20,8 +20,7 @@ pub enum ConnectionFlag {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SQLError {
|
struct SQLError {
|
||||||
msg string
|
MessageError
|
||||||
code int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Documentation
|
// TODO: Documentation
|
||||||
|
|
|
@ -21,7 +21,7 @@ pub const (
|
||||||
)
|
)
|
||||||
|
|
||||||
pub fn socket_error_message(potential_code int, s string) ?int {
|
pub fn socket_error_message(potential_code int, s string) ?int {
|
||||||
return socket_error(potential_code) or { return error('$err.msg; $s') }
|
return socket_error(potential_code) or { return error('$err.msg(); $s') }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn socket_error(potential_code int) ?int {
|
pub fn socket_error(potential_code int) ?int {
|
||||||
|
|
|
@ -627,18 +627,25 @@ fn (mut h Header) add_key(key string) {
|
||||||
|
|
||||||
// Custom error struct for invalid header tokens
|
// Custom error struct for invalid header tokens
|
||||||
struct HeaderKeyError {
|
struct HeaderKeyError {
|
||||||
msg string
|
Error
|
||||||
code int
|
code int
|
||||||
header string
|
header string
|
||||||
invalid_char byte
|
invalid_char byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn (err HeaderKeyError) msg() string {
|
||||||
|
return "Invalid header key: '$err.header'"
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (err HeaderKeyError) code() int {
|
||||||
|
return err.code
|
||||||
|
}
|
||||||
|
|
||||||
// is_valid checks if the header token contains all valid bytes
|
// is_valid checks if the header token contains all valid bytes
|
||||||
fn is_valid(header string) ? {
|
fn is_valid(header string) ? {
|
||||||
for _, c in header {
|
for _, c in header {
|
||||||
if int(c) >= 128 || !is_token(c) {
|
if int(c) >= 128 || !is_token(c) {
|
||||||
return IError(HeaderKeyError{
|
return IError(HeaderKeyError{
|
||||||
msg: "Invalid header key: '$header'"
|
|
||||||
code: 1
|
code: 1
|
||||||
header: header
|
header: header
|
||||||
invalid_char: c
|
invalid_char: c
|
||||||
|
@ -647,7 +654,6 @@ fn is_valid(header string) ? {
|
||||||
}
|
}
|
||||||
if header.len == 0 {
|
if header.len == 0 {
|
||||||
return IError(HeaderKeyError{
|
return IError(HeaderKeyError{
|
||||||
msg: "Invalid header key: '$header'"
|
|
||||||
code: 2
|
code: 2
|
||||||
header: header
|
header: header
|
||||||
invalid_char: 0
|
invalid_char: 0
|
||||||
|
|
|
@ -261,15 +261,20 @@ pub:
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct UnexpectedExtraAttributeError {
|
pub struct UnexpectedExtraAttributeError {
|
||||||
pub:
|
Error
|
||||||
msg string
|
attributes []string
|
||||||
code int
|
}
|
||||||
|
|
||||||
|
pub fn (err UnexpectedExtraAttributeError) msg() string {
|
||||||
|
return 'Encountered unexpected extra attributes: $err.attributes'
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MultiplePathAttributesError {
|
pub struct MultiplePathAttributesError {
|
||||||
pub:
|
Error
|
||||||
msg string = 'Expected at most one path attribute'
|
}
|
||||||
code int
|
|
||||||
|
pub fn (err MultiplePathAttributesError) msg() string {
|
||||||
|
return 'Expected at most one path attribute'
|
||||||
}
|
}
|
||||||
|
|
||||||
// multipart_form_body converts form and file data into a multipart/form
|
// multipart_form_body converts form and file data into a multipart/form
|
||||||
|
|
|
@ -48,7 +48,7 @@ pub fn (mut s Server) listen_and_serve() ? {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
mut conn := s.listener.accept() or {
|
mut conn := s.listener.accept() or {
|
||||||
if err.msg != 'net: op timed out' {
|
if err.msg() != 'net: op timed out' {
|
||||||
eprintln('accept() failed: $err; skipping')
|
eprintln('accept() failed: $err; skipping')
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -21,13 +21,13 @@ mut:
|
||||||
|
|
||||||
pub fn dial_tcp(address string) ?&TcpConn {
|
pub fn dial_tcp(address string) ?&TcpConn {
|
||||||
addrs := resolve_addrs_fuzzy(address, .tcp) or {
|
addrs := resolve_addrs_fuzzy(address, .tcp) or {
|
||||||
return error('$err.msg; could not resolve address $address in dial_tcp')
|
return error('$err.msg(); could not resolve address $address in dial_tcp')
|
||||||
}
|
}
|
||||||
|
|
||||||
// Very simple dialer
|
// Very simple dialer
|
||||||
for addr in addrs {
|
for addr in addrs {
|
||||||
mut s := new_tcp_socket(addr.family()) or {
|
mut s := new_tcp_socket(addr.family()) or {
|
||||||
return error('$err.msg; could not create new tcp socket in dial_tcp')
|
return error('$err.msg(); could not create new tcp socket in dial_tcp')
|
||||||
}
|
}
|
||||||
s.connect(addr) or {
|
s.connect(addr) or {
|
||||||
// Connection failed
|
// Connection failed
|
||||||
|
@ -215,10 +215,10 @@ mut:
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn listen_tcp(family AddrFamily, saddr string) ?&TcpListener {
|
pub fn listen_tcp(family AddrFamily, saddr string) ?&TcpListener {
|
||||||
s := new_tcp_socket(family) or { return error('$err.msg; could not create new socket') }
|
s := new_tcp_socket(family) or { return error('$err.msg(); could not create new socket') }
|
||||||
|
|
||||||
addrs := resolve_addrs(saddr, family, .tcp) or {
|
addrs := resolve_addrs(saddr, family, .tcp) or {
|
||||||
return error('$err.msg; could not resolve address $saddr')
|
return error('$err.msg(); could not resolve address $saddr')
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(logic to pick here)
|
// TODO(logic to pick here)
|
||||||
|
|
|
@ -410,7 +410,7 @@ fn split_by_scheme(rawurl string) ?[]string {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_scheme(rawurl string) ?string {
|
fn get_scheme(rawurl string) ?string {
|
||||||
split := split_by_scheme(rawurl) or { return err.msg }
|
split := split_by_scheme(rawurl) or { return err.msg() }
|
||||||
return split[0]
|
return split[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -593,9 +593,9 @@ fn parse_host(host string) ?string {
|
||||||
// We do impose some restrictions on the zone, to avoid stupidity
|
// We do impose some restrictions on the zone, to avoid stupidity
|
||||||
// like newlines.
|
// like newlines.
|
||||||
if zone := host[..i].index('%25') {
|
if zone := host[..i].index('%25') {
|
||||||
host1 := unescape(host[..zone], .encode_host) or { return err.msg }
|
host1 := unescape(host[..zone], .encode_host) or { return err.msg() }
|
||||||
host2 := unescape(host[zone..i], .encode_zone) or { return err.msg }
|
host2 := unescape(host[zone..i], .encode_zone) or { return err.msg() }
|
||||||
host3 := unescape(host[i..], .encode_host) or { return err.msg }
|
host3 := unescape(host[i..], .encode_host) or { return err.msg() }
|
||||||
return host1 + host2 + host3
|
return host1 + host2 + host3
|
||||||
}
|
}
|
||||||
if idx := host.last_index(':') {
|
if idx := host.last_index(':') {
|
||||||
|
@ -606,7 +606,7 @@ fn parse_host(host string) ?string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
h := unescape(host, .encode_host) or { return err.msg }
|
h := unescape(host, .encode_host) or { return err.msg() }
|
||||||
return h
|
return h
|
||||||
// host = h
|
// host = h
|
||||||
// return host
|
// return host
|
||||||
|
|
|
@ -122,7 +122,7 @@ fn (mut s Server) serve_client(mut c Client) ? {
|
||||||
}
|
}
|
||||||
s.setup_callbacks(mut server_client)
|
s.setup_callbacks(mut server_client)
|
||||||
c.listen() or {
|
c.listen() or {
|
||||||
s.logger.error(err.msg)
|
s.logger.error(err.msg())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -478,22 +478,28 @@ pub fn (mut f File) flush() {
|
||||||
C.fflush(f.cfile)
|
C.fflush(f.cfile)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ErrFileNotOpened {
|
pub struct FileNotOpenedError {
|
||||||
msg string = 'os: file not opened'
|
Error
|
||||||
code int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ErrSizeOfTypeIs0 {
|
pub fn (err FileNotOpenedError) msg() string {
|
||||||
msg string = 'os: size of type is 0'
|
return 'os: file not opened'
|
||||||
code int
|
}
|
||||||
|
|
||||||
|
pub struct SizeOfTypeIs0Error {
|
||||||
|
Error
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (err SizeOfTypeIs0Error) msg() string {
|
||||||
|
return 'os: size of type is 0'
|
||||||
}
|
}
|
||||||
|
|
||||||
fn error_file_not_opened() IError {
|
fn error_file_not_opened() IError {
|
||||||
return IError(&ErrFileNotOpened{})
|
return IError(&FileNotOpenedError{})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn error_size_of_type_0() IError {
|
fn error_size_of_type_0() IError {
|
||||||
return IError(&ErrSizeOfTypeIs0{})
|
return IError(&SizeOfTypeIs0Error{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// read_struct reads a single struct of type `T`
|
// read_struct reads a single struct of type `T`
|
||||||
|
|
|
@ -273,7 +273,7 @@ fn test_write_raw_at_negative_pos() ? {
|
||||||
if _ := f.write_raw_at(another_point, -1) {
|
if _ := f.write_raw_at(another_point, -1) {
|
||||||
assert false
|
assert false
|
||||||
}
|
}
|
||||||
f.write_raw_at(another_point, -234) or { assert err.msg == 'Invalid argument' }
|
f.write_raw_at(another_point, -234) or { assert err.msg() == 'Invalid argument' }
|
||||||
f.close()
|
f.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,7 +328,7 @@ fn test_read_raw_at_negative_pos() ? {
|
||||||
if _ := f.read_raw_at<Point>(-1) {
|
if _ := f.read_raw_at<Point>(-1) {
|
||||||
assert false
|
assert false
|
||||||
}
|
}
|
||||||
f.read_raw_at<Point>(-234) or { assert err.msg == 'Invalid argument' }
|
f.read_raw_at<Point>(-234) or { assert err.msg() == 'Invalid argument' }
|
||||||
f.close()
|
f.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
17
vlib/os/os.v
17
vlib/os/os.v
|
@ -150,12 +150,12 @@ pub fn rmdir_all(path string) ? {
|
||||||
for item in items {
|
for item in items {
|
||||||
fullpath := join_path_single(path, item)
|
fullpath := join_path_single(path, item)
|
||||||
if is_dir(fullpath) && !is_link(fullpath) {
|
if is_dir(fullpath) && !is_link(fullpath) {
|
||||||
rmdir_all(fullpath) or { ret_err = err.msg }
|
rmdir_all(fullpath) or { ret_err = err.msg() }
|
||||||
} else {
|
} else {
|
||||||
rm(fullpath) or { ret_err = err.msg }
|
rm(fullpath) or { ret_err = err.msg() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rmdir(path) or { ret_err = err.msg }
|
rmdir(path) or { ret_err = err.msg() }
|
||||||
if ret_err.len > 0 {
|
if ret_err.len > 0 {
|
||||||
return error(ret_err)
|
return error(ret_err)
|
||||||
}
|
}
|
||||||
|
@ -404,13 +404,16 @@ fn executable_fallback() string {
|
||||||
return exepath
|
return exepath
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ErrExecutableNotFound {
|
pub struct ExecutableNotFoundError {
|
||||||
msg string = 'os: failed to find executable'
|
Error
|
||||||
code int
|
}
|
||||||
|
|
||||||
|
pub fn (err ExecutableNotFoundError) msg() string {
|
||||||
|
return 'os: failed to find executable'
|
||||||
}
|
}
|
||||||
|
|
||||||
fn error_failed_to_find_executable() IError {
|
fn error_failed_to_find_executable() IError {
|
||||||
return IError(&ErrExecutableNotFound{})
|
return IError(&ExecutableNotFoundError{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// find_exe_path walks the environment PATH, just like most shell do, it returns
|
// find_exe_path walks the environment PATH, just like most shell do, it returns
|
||||||
|
|
|
@ -35,7 +35,7 @@ fn test_open_file() {
|
||||||
filename := './test1.txt'
|
filename := './test1.txt'
|
||||||
hello := 'hello world!'
|
hello := 'hello world!'
|
||||||
os.open_file(filename, 'r+', 0o666) or {
|
os.open_file(filename, 'r+', 0o666) or {
|
||||||
assert err.msg == 'No such file or directory'
|
assert err.msg() == 'No such file or directory'
|
||||||
os.File{}
|
os.File{}
|
||||||
}
|
}
|
||||||
mut file := os.open_file(filename, 'w+', 0o666) or { panic(err) }
|
mut file := os.open_file(filename, 'w+', 0o666) or { panic(err) }
|
||||||
|
@ -51,7 +51,7 @@ fn test_open_file_binary() {
|
||||||
filename := './test1.dat'
|
filename := './test1.dat'
|
||||||
hello := 'hello \n world!'
|
hello := 'hello \n world!'
|
||||||
os.open_file(filename, 'r+', 0o666) or {
|
os.open_file(filename, 'r+', 0o666) or {
|
||||||
assert err.msg == 'No such file or directory'
|
assert err.msg() == 'No such file or directory'
|
||||||
os.File{}
|
os.File{}
|
||||||
}
|
}
|
||||||
mut file := os.open_file(filename, 'wb+', 0o666) or { panic(err) }
|
mut file := os.open_file(filename, 'wb+', 0o666) or { panic(err) }
|
||||||
|
|
|
@ -20,7 +20,7 @@ fn test_signal_opt_invalid_argument() {
|
||||||
assert false
|
assert false
|
||||||
}
|
}
|
||||||
os.signal_opt(.kill, default_handler) or {
|
os.signal_opt(.kill, default_handler) or {
|
||||||
assert err.msg == 'Invalid argument'
|
assert err.msg() == 'Invalid argument'
|
||||||
assert err.code == 22
|
assert err.code == 22
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,14 +29,8 @@ struct Range {
|
||||||
comparator_sets []ComparatorSet
|
comparator_sets []ComparatorSet
|
||||||
}
|
}
|
||||||
|
|
||||||
struct InvalidComparatorCountError {
|
|
||||||
msg string
|
|
||||||
code int
|
|
||||||
}
|
|
||||||
|
|
||||||
struct InvalidComparatorFormatError {
|
struct InvalidComparatorFormatError {
|
||||||
msg string
|
MessageError
|
||||||
code int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (r Range) satisfies(ver Version) bool {
|
fn (r Range) satisfies(ver Version) bool {
|
||||||
|
|
|
@ -20,13 +20,20 @@ pub enum Increment {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct EmptyInputError {
|
struct EmptyInputError {
|
||||||
msg string = 'Empty input'
|
Error
|
||||||
code int
|
}
|
||||||
|
|
||||||
|
pub fn (err EmptyInputError) msg() string {
|
||||||
|
return 'Empty input'
|
||||||
}
|
}
|
||||||
|
|
||||||
struct InvalidVersionFormatError {
|
struct InvalidVersionFormatError {
|
||||||
msg string
|
Error
|
||||||
code int
|
input string
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (err InvalidVersionFormatError) msg() string {
|
||||||
|
return 'Invalid version format for input "$err.input"'
|
||||||
}
|
}
|
||||||
|
|
||||||
// * Constructor.
|
// * Constructor.
|
||||||
|
@ -38,7 +45,7 @@ pub fn from(input string) ?Version {
|
||||||
raw_version := parse(input)
|
raw_version := parse(input)
|
||||||
version := raw_version.validate() or {
|
version := raw_version.validate() or {
|
||||||
return IError(&InvalidVersionFormatError{
|
return IError(&InvalidVersionFormatError{
|
||||||
msg: 'Invalid version format for input "$input"'
|
input: input
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return version
|
return version
|
||||||
|
|
|
@ -33,8 +33,7 @@ struct Stmt {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SQLError {
|
struct SQLError {
|
||||||
msg string
|
MessageError
|
||||||
code int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -14,7 +14,7 @@ fn do_rec_calc_send(chs []chan i64, mut sem sync.Semaphore) {
|
||||||
mut msg := ''
|
mut msg := ''
|
||||||
for {
|
for {
|
||||||
mut s := get_val_from_chan(chs[0]) or {
|
mut s := get_val_from_chan(chs[0]) or {
|
||||||
msg = err.msg
|
msg = err.msg()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
s++
|
s++
|
||||||
|
|
|
@ -4,13 +4,16 @@
|
||||||
module time
|
module time
|
||||||
|
|
||||||
pub struct TimeParseError {
|
pub struct TimeParseError {
|
||||||
msg string
|
Error
|
||||||
code int
|
code int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn (err TimeParseError) msg() string {
|
||||||
|
return 'Invalid time format code: $err.code'
|
||||||
|
}
|
||||||
|
|
||||||
fn error_invalid_time(code int) IError {
|
fn error_invalid_time(code int) IError {
|
||||||
return TimeParseError{
|
return TimeParseError{
|
||||||
msg: 'Invalid time format code: $code'
|
|
||||||
code: code
|
code: code
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -477,14 +477,14 @@ fn (c Checker) check_quoted_escapes(q ast.Quoted) ? {
|
||||||
c.check_unicode_escape(s.text[pos..pos + 11]) or {
|
c.check_unicode_escape(s.text[pos..pos + 11]) or {
|
||||||
st := s.state()
|
st := s.state()
|
||||||
return error(@MOD + '.' + @STRUCT + '.' + @FN +
|
return error(@MOD + '.' + @STRUCT + '.' + @FN +
|
||||||
' escaped Unicode is invalid. $err.msg.capitalize() ($st.line_nr,$st.col) in ...${c.excerpt(q.pos)}...')
|
' escaped Unicode is invalid. $err.msg().capitalize() ($st.line_nr,$st.col) in ...${c.excerpt(q.pos)}...')
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pos := s.state().pos
|
pos := s.state().pos
|
||||||
c.check_unicode_escape(s.text[pos..]) or {
|
c.check_unicode_escape(s.text[pos..]) or {
|
||||||
st := s.state()
|
st := s.state()
|
||||||
return error(@MOD + '.' + @STRUCT + '.' + @FN +
|
return error(@MOD + '.' + @STRUCT + '.' + @FN +
|
||||||
' escaped Unicode is invalid. $err.msg.capitalize() ($st.line_nr,$st.col) in ...${c.excerpt(q.pos)}...')
|
' escaped Unicode is invalid. $err.msg().capitalize() ($st.line_nr,$st.col) in ...${c.excerpt(q.pos)}...')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ pub fn (c Config) read_input() ?string {
|
||||||
if os.is_file(c.file_path) {
|
if os.is_file(c.file_path) {
|
||||||
text = os.read_file(c.file_path) or {
|
text = os.read_file(c.file_path) or {
|
||||||
return error(@MOD + '.' + @STRUCT + '.' + @FN +
|
return error(@MOD + '.' + @STRUCT + '.' + @FN +
|
||||||
' Could not read "$c.file_path": "$err.msg"')
|
' Could not read "$c.file_path": "$err.msg()"')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return text
|
return text
|
||||||
|
|
|
@ -55,7 +55,7 @@ pub fn new_scanner(config Config) ?&Scanner {
|
||||||
if os.is_file(file_path) {
|
if os.is_file(file_path) {
|
||||||
text = os.read_file(file_path) or {
|
text = os.read_file(file_path) or {
|
||||||
return error(@MOD + '.' + @STRUCT + '.' + @FN +
|
return error(@MOD + '.' + @STRUCT + '.' + @FN +
|
||||||
' Could not read "$file_path": "$err.msg"')
|
' Could not read "$file_path": "$err.msg()"')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mut s := &Scanner{
|
mut s := &Scanner{
|
||||||
|
|
|
@ -155,12 +155,12 @@ fn test_alexcrichton_toml_rs() ? {
|
||||||
|
|
||||||
v_normalized_json := run([jq, '-S', '-f "$jq_normalize_path"', v_toml_json_path]) or {
|
v_normalized_json := run([jq, '-S', '-f "$jq_normalize_path"', v_toml_json_path]) or {
|
||||||
contents := os.read_file(v_toml_json_path) ?
|
contents := os.read_file(v_toml_json_path) ?
|
||||||
panic(err.msg + '\n$contents')
|
panic(err.msg() + '\n$contents')
|
||||||
}
|
}
|
||||||
alexcrichton_normalized_json := run([jq, '-S', '-f "$jq_normalize_path"',
|
alexcrichton_normalized_json := run([jq, '-S', '-f "$jq_normalize_path"',
|
||||||
alexcrichton_toml_json_path]) or {
|
alexcrichton_toml_json_path]) or {
|
||||||
contents := os.read_file(v_toml_json_path) ?
|
contents := os.read_file(v_toml_json_path) ?
|
||||||
panic(err.msg + '\n$contents')
|
panic(err.msg() + '\n$contents')
|
||||||
}
|
}
|
||||||
|
|
||||||
assert alexcrichton_normalized_json == v_normalized_json
|
assert alexcrichton_normalized_json == v_normalized_json
|
||||||
|
@ -199,7 +199,7 @@ fn test_alexcrichton_toml_rs() ? {
|
||||||
assert false
|
assert false
|
||||||
} else {
|
} else {
|
||||||
if !hide_oks {
|
if !hide_oks {
|
||||||
println(' $err.msg')
|
println(' $err.msg()')
|
||||||
}
|
}
|
||||||
assert true
|
assert true
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,11 +141,11 @@ fn test_burnt_sushi_tomltest() ? {
|
||||||
|
|
||||||
v_normalized_json := run([jq, '-S', '-f "$jq_normalize_path"', v_toml_json_path]) or {
|
v_normalized_json := run([jq, '-S', '-f "$jq_normalize_path"', v_toml_json_path]) or {
|
||||||
contents := os.read_file(v_toml_json_path) ?
|
contents := os.read_file(v_toml_json_path) ?
|
||||||
panic(err.msg + '\n$contents')
|
panic(err.msg() + '\n$contents')
|
||||||
}
|
}
|
||||||
bs_normalized_json := run([jq, '-S', '-f "$jq_normalize_path"', bs_toml_json_path]) or {
|
bs_normalized_json := run([jq, '-S', '-f "$jq_normalize_path"', bs_toml_json_path]) or {
|
||||||
contents := os.read_file(v_toml_json_path) ?
|
contents := os.read_file(v_toml_json_path) ?
|
||||||
panic(err.msg + '\n$contents')
|
panic(err.msg() + '\n$contents')
|
||||||
}
|
}
|
||||||
|
|
||||||
assert bs_normalized_json == v_normalized_json
|
assert bs_normalized_json == v_normalized_json
|
||||||
|
@ -182,7 +182,7 @@ fn test_burnt_sushi_tomltest() ? {
|
||||||
assert false
|
assert false
|
||||||
} else {
|
} else {
|
||||||
if !hide_oks {
|
if !hide_oks {
|
||||||
println(' $err.msg')
|
println(' $err.msg()')
|
||||||
}
|
}
|
||||||
assert true
|
assert true
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,7 +181,7 @@ fn test_iarna_toml_spec_tests() ? {
|
||||||
// NOTE there's known errors with the python convertion method.
|
// NOTE there's known errors with the python convertion method.
|
||||||
// For now we just ignore them as it's a broken tool - not a wrong test-case.
|
// For now we just ignore them as it's a broken tool - not a wrong test-case.
|
||||||
// Uncomment this print to see/check them.
|
// Uncomment this print to see/check them.
|
||||||
// eprintln(err.msg + '\n$contents')
|
// eprintln(err.msg() + '\n$contents')
|
||||||
e++
|
e++
|
||||||
println('ERR [${i + 1}/$valid_test_files.len] "$valid_test_file" EXCEPTION [$e/$valid_value_exceptions.len]...')
|
println('ERR [${i + 1}/$valid_test_files.len] "$valid_test_file" EXCEPTION [$e/$valid_value_exceptions.len]...')
|
||||||
continue
|
continue
|
||||||
|
@ -208,12 +208,12 @@ fn test_iarna_toml_spec_tests() ? {
|
||||||
|
|
||||||
v_normalized_json := run([jq, '-S', '-f "$jq_normalize_path"', v_toml_json_path]) or {
|
v_normalized_json := run([jq, '-S', '-f "$jq_normalize_path"', v_toml_json_path]) or {
|
||||||
contents := os.read_file(v_toml_json_path) ?
|
contents := os.read_file(v_toml_json_path) ?
|
||||||
panic(err.msg + '\n$contents')
|
panic(err.msg() + '\n$contents')
|
||||||
}
|
}
|
||||||
cmd := [jq, '-S', '-f "$jq_normalize_path"', iarna_toml_json_path]
|
cmd := [jq, '-S', '-f "$jq_normalize_path"', iarna_toml_json_path]
|
||||||
iarna_normalized_json := run(cmd) or {
|
iarna_normalized_json := run(cmd) or {
|
||||||
contents := os.read_file(v_toml_json_path) ?
|
contents := os.read_file(v_toml_json_path) ?
|
||||||
panic(err.msg + '\n$contents\n\ncmd: ${cmd.join(' ')}')
|
panic(err.msg() + '\n$contents\n\ncmd: ${cmd.join(' ')}')
|
||||||
}
|
}
|
||||||
|
|
||||||
assert iarna_normalized_json == v_normalized_json
|
assert iarna_normalized_json == v_normalized_json
|
||||||
|
@ -250,7 +250,7 @@ fn test_iarna_toml_spec_tests() ? {
|
||||||
assert false
|
assert false
|
||||||
} else {
|
} else {
|
||||||
if !hide_oks {
|
if !hide_oks {
|
||||||
println(' $err.msg')
|
println(' $err.msg()')
|
||||||
}
|
}
|
||||||
assert true
|
assert true
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,13 +37,13 @@ fn test_toml_with_bom() {
|
||||||
// Re-cycle bad_toml_doc
|
// Re-cycle bad_toml_doc
|
||||||
mut bad_toml_doc := empty_toml_document
|
mut bad_toml_doc := empty_toml_document
|
||||||
bad_toml_doc = toml.parse(toml_text_with_utf16_bom) or {
|
bad_toml_doc = toml.parse(toml_text_with_utf16_bom) or {
|
||||||
println(' $err.msg')
|
println(' $err.msg()')
|
||||||
assert true
|
assert true
|
||||||
empty_toml_document
|
empty_toml_document
|
||||||
}
|
}
|
||||||
|
|
||||||
bad_toml_doc = toml.parse(toml_text_with_utf32_bom) or {
|
bad_toml_doc = toml.parse(toml_text_with_utf32_bom) or {
|
||||||
println(' $err.msg')
|
println(' $err.msg()')
|
||||||
assert true
|
assert true
|
||||||
empty_toml_document
|
empty_toml_document
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,7 +183,6 @@ pub:
|
||||||
pub struct StringInterLiteral {
|
pub struct StringInterLiteral {
|
||||||
pub:
|
pub:
|
||||||
vals []string
|
vals []string
|
||||||
exprs []Expr
|
|
||||||
fwidths []int
|
fwidths []int
|
||||||
precisions []int
|
precisions []int
|
||||||
pluss []bool
|
pluss []bool
|
||||||
|
@ -191,6 +190,7 @@ pub:
|
||||||
fmt_poss []token.Pos
|
fmt_poss []token.Pos
|
||||||
pos token.Pos
|
pos token.Pos
|
||||||
pub mut:
|
pub mut:
|
||||||
|
exprs []Expr
|
||||||
expr_types []Type
|
expr_types []Type
|
||||||
fmts []byte
|
fmts []byte
|
||||||
need_fmts []bool // an explicit non-default fmt required, e.g. `x`
|
need_fmts []bool // an explicit non-default fmt required, e.g. `x`
|
||||||
|
|
|
@ -69,7 +69,7 @@ pub fn new_builder(pref &pref.Preferences) Builder {
|
||||||
pref: pref
|
pref: pref
|
||||||
table: table
|
table: table
|
||||||
checker: checker.new_checker(table, pref)
|
checker: checker.new_checker(table, pref)
|
||||||
transformer: transformer.new_transformer(pref)
|
transformer: transformer.new_transformer_with_table(table, pref)
|
||||||
compiled_dir: compiled_dir
|
compiled_dir: compiled_dir
|
||||||
cached_msvc: msvc
|
cached_msvc: msvc
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,11 +36,12 @@ pub fn compile_c(mut b builder.Builder) {
|
||||||
|
|
||||||
pub fn gen_c(mut b builder.Builder, v_files []string) string {
|
pub fn gen_c(mut b builder.Builder, v_files []string) string {
|
||||||
b.front_and_middle_stages(v_files) or {
|
b.front_and_middle_stages(v_files) or {
|
||||||
if err.code != 9999 {
|
if err.code() != 9999 {
|
||||||
builder.verror(err.msg)
|
builder.verror(err.msg())
|
||||||
}
|
}
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
|
|
||||||
util.timing_start('C GEN')
|
util.timing_start('C GEN')
|
||||||
res := c.gen(b.parsed_files, b.table, b.pref)
|
res := c.gen(b.parsed_files, b.table, b.pref)
|
||||||
util.timing_measure('C GEN')
|
util.timing_measure('C GEN')
|
||||||
|
|
|
@ -22,7 +22,7 @@ pub fn compile(command string, pref &pref.Preferences, backend_cb FnBackend) {
|
||||||
}
|
}
|
||||||
os.is_writable_folder(output_folder) or {
|
os.is_writable_folder(output_folder) or {
|
||||||
// An early error here, is better than an unclear C error later:
|
// An early error here, is better than an unclear C error later:
|
||||||
verror(err.msg)
|
verror(err.msg())
|
||||||
}
|
}
|
||||||
// Construct the V object from command line arguments
|
// Construct the V object from command line arguments
|
||||||
mut b := new_builder(pref)
|
mut b := new_builder(pref)
|
||||||
|
|
|
@ -181,7 +181,7 @@ fn (mut b Builder) rebuild_cached_module(vexe string, imp_path string) string {
|
||||||
}
|
}
|
||||||
b.v_build_module(vexe, imp_path)
|
b.v_build_module(vexe, imp_path)
|
||||||
rebuilded_o := b.pref.cache_manager.exists('.o', imp_path) or {
|
rebuilded_o := b.pref.cache_manager.exists('.o', imp_path) or {
|
||||||
panic('could not rebuild cache module for $imp_path, error: $err.msg')
|
panic('could not rebuild cache module for $imp_path, error: $err.msg()')
|
||||||
}
|
}
|
||||||
return rebuilded_o
|
return rebuilded_o
|
||||||
}
|
}
|
||||||
|
|
|
@ -535,7 +535,7 @@ pub fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
|
||||||
node.pos)
|
node.pos)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
c.error('cannot assign to `$left`: $err.msg', right.pos())
|
c.error('cannot assign to `$left`: $err.msg()', right.pos())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -612,7 +612,7 @@ pub fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
|
||||||
if left_sym.kind !in [.sum_type, .interface_] {
|
if left_sym.kind !in [.sum_type, .interface_] {
|
||||||
elem_type := right_final.array_info().elem_type
|
elem_type := right_final.array_info().elem_type
|
||||||
c.check_expected(left_type, elem_type) or {
|
c.check_expected(left_type, elem_type) or {
|
||||||
c.error('left operand to `$node.op` does not match the array element type: $err.msg',
|
c.error('left operand to `$node.op` does not match the array element type: $err.msg()',
|
||||||
left_right_pos)
|
left_right_pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -620,7 +620,7 @@ pub fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
|
||||||
.map {
|
.map {
|
||||||
map_info := right_final.map_info()
|
map_info := right_final.map_info()
|
||||||
c.check_expected(left_type, map_info.key_type) or {
|
c.check_expected(left_type, map_info.key_type) or {
|
||||||
c.error('left operand to `$node.op` does not match the map key type: $err.msg',
|
c.error('left operand to `$node.op` does not match the map key type: $err.msg()',
|
||||||
left_right_pos)
|
left_right_pos)
|
||||||
}
|
}
|
||||||
node.left_type = map_info.key_type
|
node.left_type = map_info.key_type
|
||||||
|
@ -1306,6 +1306,15 @@ fn (mut c Checker) type_implements(typ ast.Type, interface_type ast.Type, pos to
|
||||||
// Verify methods
|
// Verify methods
|
||||||
for imethod in imethods {
|
for imethod in imethods {
|
||||||
method := c.table.find_method_with_embeds(typ_sym, imethod.name) or {
|
method := c.table.find_method_with_embeds(typ_sym, imethod.name) or {
|
||||||
|
// >> Hack to allow old style custom error implementations
|
||||||
|
// TODO: remove once deprecation period for `IError` methods has ended
|
||||||
|
if inter_sym.name == 'IError' && (imethod.name == 'msg' || imethod.name == 'code') {
|
||||||
|
c.note("`$styp` doesn't implement method `$imethod.name` of interface `$inter_sym.name`. The usage of fields is being deprecated in favor of methods.",
|
||||||
|
pos)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// <<
|
||||||
|
|
||||||
typ_sym.find_method_with_generic_parent(imethod.name) or {
|
typ_sym.find_method_with_generic_parent(imethod.name) or {
|
||||||
c.error("`$styp` doesn't implement method `$imethod.name` of interface `$inter_sym.name`",
|
c.error("`$styp` doesn't implement method `$imethod.name` of interface `$inter_sym.name`",
|
||||||
pos)
|
pos)
|
||||||
|
@ -1343,8 +1352,15 @@ fn (mut c Checker) type_implements(typ ast.Type, interface_type ast.Type, pos to
|
||||||
}
|
}
|
||||||
// voidptr is an escape hatch, it should be allowed to be passed
|
// voidptr is an escape hatch, it should be allowed to be passed
|
||||||
if utyp != ast.voidptr_type {
|
if utyp != ast.voidptr_type {
|
||||||
c.error("`$styp` doesn't implement field `$ifield.name` of interface `$inter_sym.name`",
|
// >> Hack to allow old style custom error implementations
|
||||||
pos)
|
// TODO: remove once deprecation period for `IError` methods has ended
|
||||||
|
if inter_sym.name == 'IError' && (ifield.name == 'msg' || ifield.name == 'code') {
|
||||||
|
// do nothing, necessary warnings are already printed
|
||||||
|
} else {
|
||||||
|
// <<
|
||||||
|
c.error("`$styp` doesn't implement field `$ifield.name` of interface `$inter_sym.name`",
|
||||||
|
pos)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inter_sym.info.types << utyp
|
inter_sym.info.types << utyp
|
||||||
|
@ -1571,15 +1587,15 @@ pub fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
|
||||||
has_field = true
|
has_field = true
|
||||||
mut embed_types := []ast.Type{}
|
mut embed_types := []ast.Type{}
|
||||||
field, embed_types = c.table.find_field_from_embeds(sym, field_name) or {
|
field, embed_types = c.table.find_field_from_embeds(sym, field_name) or {
|
||||||
if err.msg != '' {
|
if err.msg() != '' {
|
||||||
c.error(err.msg, node.pos)
|
c.error(err.msg(), node.pos)
|
||||||
}
|
}
|
||||||
has_field = false
|
has_field = false
|
||||||
ast.StructField{}, []ast.Type{}
|
ast.StructField{}, []ast.Type{}
|
||||||
}
|
}
|
||||||
node.from_embed_types = embed_types
|
node.from_embed_types = embed_types
|
||||||
if sym.kind in [.aggregate, .sum_type] {
|
if sym.kind in [.aggregate, .sum_type] {
|
||||||
unknown_field_msg = err.msg
|
unknown_field_msg = err.msg()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !c.inside_unsafe {
|
if !c.inside_unsafe {
|
||||||
|
@ -1600,8 +1616,8 @@ pub fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
|
||||||
has_field = true
|
has_field = true
|
||||||
mut embed_types := []ast.Type{}
|
mut embed_types := []ast.Type{}
|
||||||
field, embed_types = c.table.find_field_from_embeds(gs, field_name) or {
|
field, embed_types = c.table.find_field_from_embeds(gs, field_name) or {
|
||||||
if err.msg != '' {
|
if err.msg() != '' {
|
||||||
c.error(err.msg, node.pos)
|
c.error(err.msg(), node.pos)
|
||||||
}
|
}
|
||||||
has_field = false
|
has_field = false
|
||||||
ast.StructField{}, []ast.Type{}
|
ast.StructField{}, []ast.Type{}
|
||||||
|
@ -1636,6 +1652,20 @@ pub fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
|
||||||
suggestion := util.new_suggestion(field_name, sym.info.fields.map(it.name))
|
suggestion := util.new_suggestion(field_name, sym.info.fields.map(it.name))
|
||||||
c.error(suggestion.say(unknown_field_msg), node.pos)
|
c.error(suggestion.say(unknown_field_msg), node.pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// >> Hack to allow old style custom error implementations
|
||||||
|
// TODO: remove once deprecation period for `IError` methods has ended
|
||||||
|
if sym.name == 'IError' && (field_name == 'msg' || field_name == 'code') {
|
||||||
|
method := c.table.find_method(sym, field_name) or {
|
||||||
|
c.error('invalid `IError` interface implementation: $err', node.pos)
|
||||||
|
return ast.void_type
|
||||||
|
}
|
||||||
|
c.note('the `.$field_name` field on `IError` is deprecated, use `.${field_name}()` instead.',
|
||||||
|
node.pos)
|
||||||
|
return method.return_type
|
||||||
|
}
|
||||||
|
// <<<
|
||||||
|
|
||||||
c.error(unknown_field_msg, node.pos)
|
c.error(unknown_field_msg, node.pos)
|
||||||
}
|
}
|
||||||
return ast.void_type
|
return ast.void_type
|
||||||
|
@ -2128,7 +2158,7 @@ fn (mut c Checker) hash_stmt(mut node ast.HashStmt) {
|
||||||
if flag.contains('@VROOT') {
|
if flag.contains('@VROOT') {
|
||||||
// c.note(checker.vroot_is_deprecated_message, node.pos)
|
// c.note(checker.vroot_is_deprecated_message, node.pos)
|
||||||
vroot := util.resolve_vmodroot(flag.replace('@VROOT', '@VMODROOT'), c.file.path) or {
|
vroot := util.resolve_vmodroot(flag.replace('@VROOT', '@VMODROOT'), c.file.path) or {
|
||||||
c.error(err.msg, node.pos)
|
c.error(err.msg(), node.pos)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
node.val = 'include $vroot'
|
node.val = 'include $vroot'
|
||||||
|
@ -2143,7 +2173,7 @@ fn (mut c Checker) hash_stmt(mut node ast.HashStmt) {
|
||||||
}
|
}
|
||||||
if flag.contains('@VMODROOT') {
|
if flag.contains('@VMODROOT') {
|
||||||
vroot := util.resolve_vmodroot(flag, c.file.path) or {
|
vroot := util.resolve_vmodroot(flag, c.file.path) or {
|
||||||
c.error(err.msg, node.pos)
|
c.error(err.msg(), node.pos)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
node.val = 'include $vroot'
|
node.val = 'include $vroot'
|
||||||
|
@ -2152,7 +2182,7 @@ fn (mut c Checker) hash_stmt(mut node ast.HashStmt) {
|
||||||
}
|
}
|
||||||
if flag.contains('\$env(') {
|
if flag.contains('\$env(') {
|
||||||
env := util.resolve_env_value(flag, true) or {
|
env := util.resolve_env_value(flag, true) or {
|
||||||
c.error(err.msg, node.pos)
|
c.error(err.msg(), node.pos)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
node.main = env
|
node.main = env
|
||||||
|
@ -2171,15 +2201,15 @@ fn (mut c Checker) hash_stmt(mut node ast.HashStmt) {
|
||||||
'--cflags --libs $node.main'.split(' ')
|
'--cflags --libs $node.main'.split(' ')
|
||||||
}
|
}
|
||||||
mut m := pkgconfig.main(args) or {
|
mut m := pkgconfig.main(args) or {
|
||||||
c.error(err.msg, node.pos)
|
c.error(err.msg(), node.pos)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cflags := m.run() or {
|
cflags := m.run() or {
|
||||||
c.error(err.msg, node.pos)
|
c.error(err.msg(), node.pos)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.table.parse_cflag(cflags, c.mod, c.pref.compile_defines_all) or {
|
c.table.parse_cflag(cflags, c.mod, c.pref.compile_defines_all) or {
|
||||||
c.error(err.msg, node.pos)
|
c.error(err.msg(), node.pos)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2189,7 +2219,7 @@ fn (mut c Checker) hash_stmt(mut node ast.HashStmt) {
|
||||||
if flag.contains('@VROOT') {
|
if flag.contains('@VROOT') {
|
||||||
// c.note(checker.vroot_is_deprecated_message, node.pos)
|
// c.note(checker.vroot_is_deprecated_message, node.pos)
|
||||||
flag = util.resolve_vmodroot(flag.replace('@VROOT', '@VMODROOT'), c.file.path) or {
|
flag = util.resolve_vmodroot(flag.replace('@VROOT', '@VMODROOT'), c.file.path) or {
|
||||||
c.error(err.msg, node.pos)
|
c.error(err.msg(), node.pos)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2199,13 +2229,13 @@ fn (mut c Checker) hash_stmt(mut node ast.HashStmt) {
|
||||||
}
|
}
|
||||||
if flag.contains('@VMODROOT') {
|
if flag.contains('@VMODROOT') {
|
||||||
flag = util.resolve_vmodroot(flag, c.file.path) or {
|
flag = util.resolve_vmodroot(flag, c.file.path) or {
|
||||||
c.error(err.msg, node.pos)
|
c.error(err.msg(), node.pos)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if flag.contains('\$env(') {
|
if flag.contains('\$env(') {
|
||||||
flag = util.resolve_env_value(flag, true) or {
|
flag = util.resolve_env_value(flag, true) or {
|
||||||
c.error(err.msg, node.pos)
|
c.error(err.msg(), node.pos)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2219,7 +2249,7 @@ fn (mut c Checker) hash_stmt(mut node ast.HashStmt) {
|
||||||
}
|
}
|
||||||
// println('adding flag "$flag"')
|
// println('adding flag "$flag"')
|
||||||
c.table.parse_cflag(flag, c.mod, c.pref.compile_defines_all) or {
|
c.table.parse_cflag(flag, c.mod, c.pref.compile_defines_all) or {
|
||||||
c.error(err.msg, node.pos)
|
c.error(err.msg(), node.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -3016,14 +3046,6 @@ pub fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
|
||||||
typ: typ
|
typ: typ
|
||||||
is_optional: is_optional
|
is_optional: is_optional
|
||||||
}
|
}
|
||||||
if typ == ast.error_type && c.expected_type == ast.string_type
|
|
||||||
&& !c.using_new_err_struct && !c.inside_selector_expr
|
|
||||||
&& !c.inside_println_arg && !c.file.mod.name.contains('v.')
|
|
||||||
&& !c.is_builtin_mod {
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <- TODO: remove; this prevents a failure in the `performance-regressions` CI job
|
|
||||||
c.warn('string errors are deprecated; use `err.msg` instead',
|
|
||||||
node.pos)
|
|
||||||
}
|
|
||||||
// if typ == ast.t_type {
|
// if typ == ast.t_type {
|
||||||
// sym := c.table.sym(c.cur_generic_type)
|
// sym := c.table.sym(c.cur_generic_type)
|
||||||
// println('IDENT T unresolved $node.name typ=$sym.name')
|
// println('IDENT T unresolved $node.name typ=$sym.name')
|
||||||
|
|
|
@ -12,7 +12,7 @@ fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) ast.Type {
|
||||||
node.left_type = c.expr(node.left)
|
node.left_type = c.expr(node.left)
|
||||||
if node.is_env {
|
if node.is_env {
|
||||||
env_value := util.resolve_env_value("\$env('$node.args_var')", false) or {
|
env_value := util.resolve_env_value("\$env('$node.args_var')", false) or {
|
||||||
c.error(err.msg, node.env_pos)
|
c.error(err.msg(), node.env_pos)
|
||||||
return ast.string_type
|
return ast.string_type
|
||||||
}
|
}
|
||||||
node.env_value = env_value
|
node.env_value = env_value
|
||||||
|
@ -476,7 +476,7 @@ fn (mut c Checker) comptime_if_branch(cond ast.Expr, pos token.Pos) bool {
|
||||||
left_type := c.expr(cond.left)
|
left_type := c.expr(cond.left)
|
||||||
right_type := c.expr(cond.right)
|
right_type := c.expr(cond.right)
|
||||||
expr := c.find_definition(cond.left) or {
|
expr := c.find_definition(cond.left) or {
|
||||||
c.error(err.msg, cond.left.pos)
|
c.error(err.msg(), cond.left.pos)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if !c.check_types(right_type, left_type) {
|
if !c.check_types(right_type, left_type) {
|
||||||
|
@ -558,7 +558,7 @@ fn (mut c Checker) comptime_if_branch(cond ast.Expr, pos token.Pos) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
expr := c.find_obj_definition(cond.obj) or {
|
expr := c.find_obj_definition(cond.obj) or {
|
||||||
c.error(err.msg, cond.pos)
|
c.error(err.msg(), cond.pos)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if !c.check_types(typ, ast.bool_type) {
|
if !c.check_types(typ, ast.bool_type) {
|
||||||
|
@ -573,7 +573,7 @@ fn (mut c Checker) comptime_if_branch(cond ast.Expr, pos token.Pos) bool {
|
||||||
ast.ComptimeCall {
|
ast.ComptimeCall {
|
||||||
if cond.is_pkgconfig {
|
if cond.is_pkgconfig {
|
||||||
mut m := pkgconfig.main([cond.args_var]) or {
|
mut m := pkgconfig.main([cond.args_var]) or {
|
||||||
c.error(err.msg, cond.pos)
|
c.error(err.msg(), cond.pos)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
m.run() or { return true }
|
m.run() or { return true }
|
||||||
|
|
|
@ -22,7 +22,7 @@ pub fn (mut c Checker) array_init(mut node ast.ArrayInit) ast.Type {
|
||||||
default_typ := c.check_expr_opt_call(default_expr, c.expr(default_expr))
|
default_typ := c.check_expr_opt_call(default_expr, c.expr(default_expr))
|
||||||
node.default_type = default_typ
|
node.default_type = default_typ
|
||||||
c.check_expected(default_typ, node.elem_type) or {
|
c.check_expected(default_typ, node.elem_type) or {
|
||||||
c.error(err.msg, default_expr.pos())
|
c.error(err.msg(), default_expr.pos())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if node.has_len {
|
if node.has_len {
|
||||||
|
@ -117,7 +117,7 @@ pub fn (mut c Checker) array_init(mut node ast.ArrayInit) ast.Type {
|
||||||
}
|
}
|
||||||
if expr !is ast.TypeNode {
|
if expr !is ast.TypeNode {
|
||||||
c.check_expected(typ, elem_type) or {
|
c.check_expected(typ, elem_type) or {
|
||||||
c.error('invalid array element: $err.msg', expr.pos())
|
c.error('invalid array element: $err.msg()', expr.pos())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -894,7 +894,7 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.error('$err.msg in argument ${i + 1} to `$fn_name`', call_arg.pos)
|
c.error('$err.msg() in argument ${i + 1} to `$fn_name`', call_arg.pos)
|
||||||
}
|
}
|
||||||
// Warn about automatic (de)referencing, which will be removed soon.
|
// Warn about automatic (de)referencing, which will be removed soon.
|
||||||
if func.language != .c && !c.inside_unsafe && typ.nr_muls() != param.typ.nr_muls()
|
if func.language != .c && !c.inside_unsafe && typ.nr_muls() != param.typ.nr_muls()
|
||||||
|
@ -936,7 +936,7 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
c.check_expected_call_arg(utyp, unwrap_typ, node.language, call_arg) or {
|
c.check_expected_call_arg(utyp, unwrap_typ, node.language, call_arg) or {
|
||||||
c.error('$err.msg in argument ${i + 1} to `$fn_name`', call_arg.pos)
|
c.error('$err.msg() in argument ${i + 1} to `$fn_name`', call_arg.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1143,8 +1143,8 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
|
||||||
has_method = true
|
has_method = true
|
||||||
mut embed_types := []ast.Type{}
|
mut embed_types := []ast.Type{}
|
||||||
method, embed_types = c.table.find_method_from_embeds(left_sym, method_name) or {
|
method, embed_types = c.table.find_method_from_embeds(left_sym, method_name) or {
|
||||||
if err.msg != '' {
|
if err.msg() != '' {
|
||||||
c.error(err.msg, node.pos)
|
c.error(err.msg(), node.pos)
|
||||||
}
|
}
|
||||||
has_method = false
|
has_method = false
|
||||||
ast.Fn{}, []ast.Type{}
|
ast.Fn{}, []ast.Type{}
|
||||||
|
@ -1156,7 +1156,7 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
|
||||||
}
|
}
|
||||||
if left_sym.kind == .aggregate {
|
if left_sym.kind == .aggregate {
|
||||||
// the error message contains the problematic type
|
// the error message contains the problematic type
|
||||||
unknown_method_msg = err.msg
|
unknown_method_msg = err.msg()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if has_method {
|
if has_method {
|
||||||
|
@ -1285,7 +1285,7 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
|
||||||
// continue
|
// continue
|
||||||
// }
|
// }
|
||||||
if got_arg_typ != ast.void_type {
|
if got_arg_typ != ast.void_type {
|
||||||
c.error('$err.msg in argument ${i + 1} to `${left_sym.name}.$method_name`',
|
c.error('$err.msg() in argument ${i + 1} to `${left_sym.name}.$method_name`',
|
||||||
arg.pos)
|
arg.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1432,7 +1432,7 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
|
||||||
c.check_expected_call_arg(targ, c.unwrap_generic(exp_arg_typ), node.language,
|
c.check_expected_call_arg(targ, c.unwrap_generic(exp_arg_typ), node.language,
|
||||||
arg) or {
|
arg) or {
|
||||||
if targ != ast.void_type {
|
if targ != ast.void_type {
|
||||||
c.error('$err.msg in argument ${i + 1} to `${left_sym.name}.$method_name`',
|
c.error('$err.msg() in argument ${i + 1} to `${left_sym.name}.$method_name`',
|
||||||
arg.pos)
|
arg.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1666,7 +1666,7 @@ fn (mut c Checker) map_builtin_method_call(mut node ast.CallExpr, left_type ast.
|
||||||
info := left_sym.info as ast.Map
|
info := left_sym.info as ast.Map
|
||||||
arg_type := c.expr(node.args[0].expr)
|
arg_type := c.expr(node.args[0].expr)
|
||||||
c.check_expected_call_arg(arg_type, info.key_type, node.language, node.args[0]) or {
|
c.check_expected_call_arg(arg_type, info.key_type, node.language, node.args[0]) or {
|
||||||
c.error('$err.msg in argument 1 to `Map.delete`', node.args[0].pos)
|
c.error('$err.msg() in argument 1 to `Map.delete`', node.args[0].pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {}
|
else {}
|
||||||
|
|
|
@ -203,7 +203,7 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type {
|
||||||
}
|
}
|
||||||
for st in branch.stmts {
|
for st in branch.stmts {
|
||||||
// must not contain C statements
|
// must not contain C statements
|
||||||
st.check_c_expr() or { c.error('`if` expression branch has $err.msg', st.pos) }
|
st.check_c_expr() or { c.error('`if` expression branch has $err.msg()', st.pos) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if mut branch.cond is ast.IfGuardExpr {
|
if mut branch.cond is ast.IfGuardExpr {
|
||||||
|
|
|
@ -41,7 +41,7 @@ pub fn (mut c Checker) match_expr(mut node ast.MatchExpr) ast.Type {
|
||||||
for st in branch.stmts[0..branch.stmts.len - 1] {
|
for st in branch.stmts[0..branch.stmts.len - 1] {
|
||||||
// must not contain C statements
|
// must not contain C statements
|
||||||
st.check_c_expr() or {
|
st.check_c_expr() or {
|
||||||
c.error('`match` expression branch has $err.msg', st.pos)
|
c.error('`match` expression branch has $err.msg()', st.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if ret_type != ast.void_type {
|
} else if ret_type != ast.void_type {
|
||||||
|
|
|
@ -81,7 +81,7 @@ pub fn (mut c Checker) struct_decl(mut node ast.StructDecl) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
c.error('incompatible initializer for field `$field.name`: $err.msg',
|
c.error('incompatible initializer for field `$field.name`: $err.msg()',
|
||||||
field.default_expr.pos())
|
field.default_expr.pos())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -300,7 +300,7 @@ pub fn (mut c Checker) struct_init(mut node ast.StructInit) ast.Type {
|
||||||
}
|
}
|
||||||
} else if expr_type != ast.void_type && expr_type_sym.kind != .placeholder {
|
} else if expr_type != ast.void_type && expr_type_sym.kind != .placeholder {
|
||||||
c.check_expected(c.unwrap_generic(expr_type), c.unwrap_generic(field_info.typ)) or {
|
c.check_expected(c.unwrap_generic(expr_type), c.unwrap_generic(field_info.typ)) or {
|
||||||
c.error('cannot assign to field `$field_info.name`: $err.msg',
|
c.error('cannot assign to field `$field_info.name`: $err.msg()',
|
||||||
field.pos)
|
field.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ fn test_get_parent_mod_on_root_folder() {
|
||||||
// TODO: add an equivalent windows check for c:\
|
// TODO: add an equivalent windows check for c:\
|
||||||
$if !windows {
|
$if !windows {
|
||||||
assert '---' == get_parent_mod('/') or {
|
assert '---' == get_parent_mod('/') or {
|
||||||
assert err.msg == 'root folder reached'
|
assert err.msg() == 'root folder reached'
|
||||||
'---'
|
'---'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ fn test_get_parent_mod_on_root_folder() {
|
||||||
fn test_get_parent_mod_current_folder() {
|
fn test_get_parent_mod_current_folder() {
|
||||||
// TODO: this should may be return '' reliably on windows too:
|
// TODO: this should may be return '' reliably on windows too:
|
||||||
// assert '' == get_parent_mod('.') or {
|
// assert '' == get_parent_mod('.') or {
|
||||||
// assert err.msg == 'No V files found.'
|
// assert err.msg() == 'No V files found.'
|
||||||
// '---'
|
// '---'
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ fn test_get_parent_mod_on_temp_dir() ? {
|
||||||
|
|
||||||
fn test_get_parent_mod_normal_cases() ? {
|
fn test_get_parent_mod_normal_cases() ? {
|
||||||
assert '---' == get_parent_mod(os.join_path(@VMODROOT, 'vlib/v')) or {
|
assert '---' == get_parent_mod(os.join_path(@VMODROOT, 'vlib/v')) or {
|
||||||
assert err.msg == 'No V files found.'
|
assert err.msg() == 'No V files found.'
|
||||||
'---'
|
'---'
|
||||||
}
|
}
|
||||||
// TODO: WTF?
|
// TODO: WTF?
|
||||||
|
|
|
@ -67,7 +67,7 @@ fn test_fmt() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
vfmt_result_file := os.join_path(tmpfolder, 'vfmt_run_over_$ifilename')
|
vfmt_result_file := os.join_path(tmpfolder, 'vfmt_run_over_$ifilename')
|
||||||
os.write_file(vfmt_result_file, result_ocontent) or { panic(err.msg) }
|
os.write_file(vfmt_result_file, result_ocontent) or { panic(err) }
|
||||||
eprintln(diff.color_compare_files(diff_cmd, opath, vfmt_result_file))
|
eprintln(diff.color_compare_files(diff_cmd, opath, vfmt_result_file))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ fn test_fmt() {
|
||||||
eprintln(fmt_bench.step_message_ok(vrelpath))
|
eprintln(fmt_bench.step_message_ok(vrelpath))
|
||||||
}
|
}
|
||||||
restore_bin2v_placeholder() or {
|
restore_bin2v_placeholder() or {
|
||||||
eprintln('failed restoring vbin2v_keep.vv placeholder: $err.msg')
|
eprintln('failed restoring vbin2v_keep.vv placeholder: $err.msg()')
|
||||||
}
|
}
|
||||||
fmt_bench.stop()
|
fmt_bench.stop()
|
||||||
eprintln(term.h_divider('-'))
|
eprintln(term.h_divider('-'))
|
||||||
|
@ -90,7 +90,7 @@ fn prepare_bin2v_file(mut fmt_bench benchmark.Benchmark) {
|
||||||
fmt_bench.step()
|
fmt_bench.step()
|
||||||
write_bin2v_keep_content() or {
|
write_bin2v_keep_content() or {
|
||||||
fmt_bench.fail()
|
fmt_bench.fail()
|
||||||
eprintln(fmt_bench.step_message_fail('Failed preparing bin2v_keep.vv: $err.msg'))
|
eprintln(fmt_bench.step_message_fail('Failed preparing bin2v_keep.vv: $err.msg()'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fmt_bench.ok()
|
fmt_bench.ok()
|
||||||
|
|
|
@ -34,13 +34,13 @@ fn branches_are_struct_inits() {
|
||||||
|
|
||||||
fn branches_are_call_exprs_with_or_blocks() {
|
fn branches_are_call_exprs_with_or_blocks() {
|
||||||
match 'a' {
|
match 'a' {
|
||||||
'b' { foo() or { panic(err.msg) } }
|
'b' { foo() or { panic(err) } }
|
||||||
}
|
}
|
||||||
match 'a' {
|
match 'a' {
|
||||||
'b' {
|
'b' {
|
||||||
foo() or {
|
foo() or {
|
||||||
// do stuff
|
// do stuff
|
||||||
panic(err.msg)
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ fn branches_are_call_exprs_with_or_blocks() {
|
||||||
'b' {
|
'b' {
|
||||||
foo() or {
|
foo() or {
|
||||||
another_stmt()
|
another_stmt()
|
||||||
panic(err.msg)
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,8 +51,7 @@ fn (mut g Gen) gen_assert_stmt(original_assert_statement ast.AssertStmt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct UnsupportedAssertCtempTransform {
|
struct UnsupportedAssertCtempTransform {
|
||||||
msg string
|
Error
|
||||||
code int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsupported_ctemp_assert_transform = IError(UnsupportedAssertCtempTransform{})
|
const unsupported_ctemp_assert_transform = IError(UnsupportedAssertCtempTransform{})
|
||||||
|
|
|
@ -6122,11 +6122,12 @@ fn (mut g Gen) or_block(var_name string, or_block ast.OrExpr, return_type ast.Ty
|
||||||
} else if or_block.kind == .propagate {
|
} else if or_block.kind == .propagate {
|
||||||
if g.file.mod.name == 'main' && (isnil(g.fn_decl) || g.fn_decl.is_main) {
|
if g.file.mod.name == 'main' && (isnil(g.fn_decl) || g.fn_decl.is_main) {
|
||||||
// In main(), an `opt()?` call is sugar for `opt() or { panic(err) }`
|
// In main(), an `opt()?` call is sugar for `opt() or { panic(err) }`
|
||||||
|
err_msg := 'IError_name_table[${cvar_name}.err._typ]._method_msg(${cvar_name}.err._object)'
|
||||||
if g.pref.is_debug {
|
if g.pref.is_debug {
|
||||||
paline, pafile, pamod, pafn := g.panic_debug_info(or_block.pos)
|
paline, pafile, pamod, pafn := g.panic_debug_info(or_block.pos)
|
||||||
g.writeln('panic_debug($paline, tos3("$pafile"), tos3("$pamod"), tos3("$pafn"), *${cvar_name}.err.msg );')
|
g.writeln('panic_debug($paline, tos3("$pafile"), tos3("$pamod"), tos3("$pafn"), $err_msg );')
|
||||||
} else {
|
} else {
|
||||||
g.writeln('\tpanic_optional_not_set(*${cvar_name}.err.msg);')
|
g.writeln('\tpanic_optional_not_set( $err_msg );')
|
||||||
}
|
}
|
||||||
} else if !isnil(g.fn_decl) && g.fn_decl.is_test {
|
} else if !isnil(g.fn_decl) && g.fn_decl.is_test {
|
||||||
g.gen_failing_error_propagation_for_test_fn(or_block, cvar_name)
|
g.gen_failing_error_propagation_for_test_fn(or_block, cvar_name)
|
||||||
|
@ -6899,6 +6900,16 @@ static inline __shared__$interface_name ${shared_fn_name}(__shared__$cctype* x)
|
||||||
methods_struct.writeln('\t\t._method_${c_name(method.name)} = (void*) $method_call,')
|
methods_struct.writeln('\t\t._method_${c_name(method.name)} = (void*) $method_call,')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// >> Hack to allow old style custom error implementations
|
||||||
|
// TODO: remove once deprecation period for `IError` methods has ended
|
||||||
|
// fix MSVC not handling empty struct inits
|
||||||
|
if methods.len == 0 && interface_name == 'IError' {
|
||||||
|
methods_struct.writeln('\t\t._method_msg = NULL,')
|
||||||
|
methods_struct.writeln('\t\t._method_code = NULL,')
|
||||||
|
}
|
||||||
|
// <<
|
||||||
|
|
||||||
if g.pref.build_mode != .build_module {
|
if g.pref.build_mode != .build_module {
|
||||||
methods_struct.writeln('\t},')
|
methods_struct.writeln('\t},')
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,19 +166,21 @@ pub fn (mut g Gen) write_tests_definitions() {
|
||||||
|
|
||||||
pub fn (mut g Gen) gen_failing_error_propagation_for_test_fn(or_block ast.OrExpr, cvar_name string) {
|
pub fn (mut g Gen) gen_failing_error_propagation_for_test_fn(or_block ast.OrExpr, cvar_name string) {
|
||||||
// in test_() functions, an `opt()?` call is sugar for
|
// in test_() functions, an `opt()?` call is sugar for
|
||||||
// `or { cb_propagate_test_error(@LINE, @FILE, @MOD, @FN, err.msg) }`
|
// `or { cb_propagate_test_error(@LINE, @FILE, @MOD, @FN, err.msg() ) }`
|
||||||
// and the test is considered failed
|
// and the test is considered failed
|
||||||
paline, pafile, pamod, pafn := g.panic_debug_info(or_block.pos)
|
paline, pafile, pamod, pafn := g.panic_debug_info(or_block.pos)
|
||||||
g.writeln('\tmain__TestRunner_name_table[test_runner._typ]._method_fn_error(test_runner._object, $paline, tos3("$pafile"), tos3("$pamod"), tos3("$pafn"), *(${cvar_name}.err.msg) );')
|
err_msg := 'IError_name_table[${cvar_name}.err._typ]._method_msg(${cvar_name}.err._object)'
|
||||||
|
g.writeln('\tmain__TestRunner_name_table[test_runner._typ]._method_fn_error(test_runner._object, $paline, tos3("$pafile"), tos3("$pamod"), tos3("$pafn"), $err_msg );')
|
||||||
g.writeln('\tlongjmp(g_jump_buffer, 1);')
|
g.writeln('\tlongjmp(g_jump_buffer, 1);')
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut g Gen) gen_failing_return_error_for_test_fn(return_stmt ast.Return, cvar_name string) {
|
pub fn (mut g Gen) gen_failing_return_error_for_test_fn(return_stmt ast.Return, cvar_name string) {
|
||||||
// in test_() functions, a `return error('something')` is sugar for
|
// in test_() functions, a `return error('something')` is sugar for
|
||||||
// `or { err := error('something') cb_propagate_test_error(@LINE, @FILE, @MOD, @FN, err.msg) return err }`
|
// `or { err := error('something') cb_propagate_test_error(@LINE, @FILE, @MOD, @FN, err.msg() ) return err }`
|
||||||
// and the test is considered failed
|
// and the test is considered failed
|
||||||
paline, pafile, pamod, pafn := g.panic_debug_info(return_stmt.pos)
|
paline, pafile, pamod, pafn := g.panic_debug_info(return_stmt.pos)
|
||||||
g.writeln('\tmain__TestRunner_name_table[test_runner._typ]._method_fn_error(test_runner._object, $paline, tos3("$pafile"), tos3("$pamod"), tos3("$pafn"), *(${cvar_name}.err.msg) );')
|
err_msg := 'IError_name_table[${cvar_name}.err._typ]._method_msg(${cvar_name}.err._object)'
|
||||||
|
g.writeln('\tmain__TestRunner_name_table[test_runner._typ]._method_fn_error(test_runner._object, $paline, tos3("$pafile"), tos3("$pamod"), tos3("$pafn"), $err_msg );')
|
||||||
g.writeln('\tlongjmp(g_jump_buffer, 1);')
|
g.writeln('\tlongjmp(g_jump_buffer, 1);')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -320,7 +320,7 @@ fn (mut g Gen) comptime_if_cond(cond ast.Expr, pkg_exist bool) bool {
|
||||||
}
|
}
|
||||||
ast.PostfixExpr {
|
ast.PostfixExpr {
|
||||||
ifdef := g.comptime_if_to_ifdef((cond.expr as ast.Ident).name, true) or {
|
ifdef := g.comptime_if_to_ifdef((cond.expr as ast.Ident).name, true) or {
|
||||||
verror(err.msg)
|
verror(err.msg())
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
g.write('defined($ifdef)')
|
g.write('defined($ifdef)')
|
||||||
|
|
|
@ -74,7 +74,7 @@ fn (mut g JsGen) comptime_if_cond(cond ast.Expr, pkg_exist bool) bool {
|
||||||
}
|
}
|
||||||
ast.PostfixExpr {
|
ast.PostfixExpr {
|
||||||
ifdef := g.comptime_if_to_ifdef((cond.expr as ast.Ident).name, true) or {
|
ifdef := g.comptime_if_to_ifdef((cond.expr as ast.Ident).name, true) or {
|
||||||
verror(err.msg)
|
verror(err.msg())
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
g.write('$ifdef')
|
g.write('$ifdef')
|
||||||
|
|
|
@ -1057,8 +1057,7 @@ fn (mut g JsGen) expr(node ast.Expr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct UnsupportedAssertCtempTransform {
|
struct UnsupportedAssertCtempTransform {
|
||||||
msg string
|
Error
|
||||||
code int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsupported_ctemp_assert_transform = IError(UnsupportedAssertCtempTransform{})
|
const unsupported_ctemp_assert_transform = IError(UnsupportedAssertCtempTransform{})
|
||||||
|
|
|
@ -218,7 +218,7 @@ fn (mut p Parser) partial_assign_stmt(left []ast.Expr, left_comments []ast.Comme
|
||||||
if op == .decl_assign {
|
if op == .decl_assign {
|
||||||
// a, b := a + 1, b
|
// a, b := a + 1, b
|
||||||
for r in right {
|
for r in right {
|
||||||
p.check_undefined_variables(left, r) or { return p.error_with_pos(err.msg, pos) }
|
p.check_undefined_variables(left, r) or { return p.error_with_pos(err.msg(), pos) }
|
||||||
}
|
}
|
||||||
} else if left.len > 1 {
|
} else if left.len > 1 {
|
||||||
// a, b = b, a
|
// a, b = b, a
|
||||||
|
|
|
@ -32,6 +32,7 @@ pub fn (mut p Parser) parse_array_type(expecting token.Kind) ast.Type {
|
||||||
fixed_size = const_field.expr.val.int()
|
fixed_size = const_field.expr.val.int()
|
||||||
} else {
|
} else {
|
||||||
if mut const_field.expr is ast.InfixExpr {
|
if mut const_field.expr is ast.InfixExpr {
|
||||||
|
// QUESTION: this should most likely no be done in the parser, right?
|
||||||
mut t := transformer.new_transformer(p.pref)
|
mut t := transformer.new_transformer(p.pref)
|
||||||
folded_expr := t.infix_expr(mut const_field.expr)
|
folded_expr := t.infix_expr(mut const_field.expr)
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ fn (mut p Parser) sql_expr() ast.Expr {
|
||||||
if e.right is ast.Ident {
|
if e.right is ast.Ident {
|
||||||
if !p.scope.known_var(e.right.name) {
|
if !p.scope.known_var(e.right.name) {
|
||||||
p.check_undefined_variables([e.left], e.right) or {
|
p.check_undefined_variables([e.left], e.right) or {
|
||||||
return p.error_with_pos(err.msg, e.right.pos)
|
return p.error_with_pos(err.msg(), e.right.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,9 @@ fn test_dependency_resolution_fails_correctly() {
|
||||||
mut errors := []string{}
|
mut errors := []string{}
|
||||||
for pc in pc_files {
|
for pc in pc_files {
|
||||||
pcname := os.file_name(pc).replace('.pc', '')
|
pcname := os.file_name(pc).replace('.pc', '')
|
||||||
pkgconfig.load(pcname, use_default_paths: false, path: samples_dir) or { errors << err.msg }
|
pkgconfig.load(pcname, use_default_paths: false, path: samples_dir) or {
|
||||||
|
errors << err.msg()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
assert errors.len < pc_files.len
|
assert errors.len < pc_files.len
|
||||||
assert errors == ['could not resolve dependency xyz-unknown-package']
|
assert errors == ['could not resolve dependency xyz-unknown-package']
|
||||||
|
|
|
@ -110,7 +110,7 @@ pub fn new_scanner_file(file_path string, comments_mode CommentsMode, pref &pref
|
||||||
verror('$file_path is not a file')
|
verror('$file_path is not a file')
|
||||||
}
|
}
|
||||||
raw_text := util.read_file(file_path) or {
|
raw_text := util.read_file(file_path) or {
|
||||||
verror(err.msg)
|
verror(err.msg())
|
||||||
return voidptr(0)
|
return voidptr(0)
|
||||||
}
|
}
|
||||||
mut s := &Scanner{
|
mut s := &Scanner{
|
||||||
|
|
|
@ -44,7 +44,7 @@ const return_types = [
|
||||||
ReturnType{
|
ReturnType{
|
||||||
name: '?'
|
name: '?'
|
||||||
init: "error('an error')"
|
init: "error('an error')"
|
||||||
assertion: " or { assert err.msg == 'an error' return }\npanic('got no error')"
|
assertion: " or { assert err.msg() == 'an error' return }\npanic('got no error')"
|
||||||
no_assert_kw: true
|
no_assert_kw: true
|
||||||
},
|
},
|
||||||
ReturnType{
|
ReturnType{
|
||||||
|
|
|
@ -51,7 +51,7 @@ fn test_multiple_ret() {
|
||||||
// none case
|
// none case
|
||||||
wrapper1 := fn () (string, string) {
|
wrapper1 := fn () (string, string) {
|
||||||
res2_1, res2_2 := split_to_two('') or {
|
res2_1, res2_2 := split_to_two('') or {
|
||||||
assert err.msg == ''
|
assert err.msg() == ''
|
||||||
return 'replaced', 'val'
|
return 'replaced', 'val'
|
||||||
}
|
}
|
||||||
return res2_1, res2_2
|
return res2_1, res2_2
|
||||||
|
@ -63,7 +63,7 @@ fn test_multiple_ret() {
|
||||||
// error case
|
// error case
|
||||||
wrapper2 := fn () (string, string) {
|
wrapper2 := fn () (string, string) {
|
||||||
res3_1, res3_2 := split_to_two('fishhouse') or {
|
res3_1, res3_2 := split_to_two('fishhouse') or {
|
||||||
assert err.msg == 'error'
|
assert err.msg() == 'error'
|
||||||
return 'replaced', 'val'
|
return 'replaced', 'val'
|
||||||
}
|
}
|
||||||
return res3_1, res3_2
|
return res3_1, res3_2
|
||||||
|
|
|
@ -26,7 +26,7 @@ fn test_if_expr_of_optional() {
|
||||||
if _ := foo3() {
|
if _ := foo3() {
|
||||||
assert false
|
assert false
|
||||||
} else {
|
} else {
|
||||||
assert err.msg == 'foo3 error'
|
assert err.msg() == 'foo3 error'
|
||||||
}
|
}
|
||||||
|
|
||||||
a4 := foo4() or { panic('error') }
|
a4 := foo4() or { panic('error') }
|
||||||
|
|
|
@ -3,7 +3,7 @@ import os
|
||||||
fn main() {
|
fn main() {
|
||||||
vexe := os.getenv('VEXE')
|
vexe := os.getenv('VEXE')
|
||||||
vroot := os.dir(vexe)
|
vroot := os.dir(vexe)
|
||||||
mut files := os.ls(vroot) or { panic(err.msg) }
|
mut files := os.ls(vroot) or { panic(err) }
|
||||||
files.sort()
|
files.sort()
|
||||||
for file in files {
|
for file in files {
|
||||||
if file.ends_with('.md') {
|
if file.ends_with('.md') {
|
||||||
|
|
|
@ -12,7 +12,7 @@ fn test_lhs_option() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ret_no_opt(n int) int {
|
fn ret_no_opt(n int) int {
|
||||||
return f(n) or { panic(err.msg) }
|
return f(n) or { panic(err) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_opt_return_no_opt() {
|
fn test_opt_return_no_opt() {
|
||||||
|
|
|
@ -7,11 +7,11 @@ fn test_err_with_code() {
|
||||||
assert false
|
assert false
|
||||||
_ := w
|
_ := w
|
||||||
} else {
|
} else {
|
||||||
assert err.msg == 'hi'
|
assert err.msg() == 'hi'
|
||||||
assert err.code == 137
|
assert err.code == 137
|
||||||
}
|
}
|
||||||
v := opt_err_with_code() or {
|
v := opt_err_with_code() or {
|
||||||
assert err.msg == 'hi'
|
assert err.msg() == 'hi'
|
||||||
assert err.code == 137
|
assert err.code == 137
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ fn opt_err() ?string {
|
||||||
|
|
||||||
fn test_err() {
|
fn test_err() {
|
||||||
v := opt_err() or {
|
v := opt_err() or {
|
||||||
assert err.msg == 'hi'
|
assert err.msg() == 'hi'
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
assert false
|
assert false
|
||||||
|
@ -74,7 +74,7 @@ fn test_if_else_opt() {
|
||||||
if _ := err_call(false) {
|
if _ := err_call(false) {
|
||||||
assert false
|
assert false
|
||||||
} else {
|
} else {
|
||||||
assert err.msg.len != 0
|
assert err.msg().len != 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,12 +151,12 @@ fn test_or_return() {
|
||||||
if _ := or_return_error() {
|
if _ := or_return_error() {
|
||||||
assert false
|
assert false
|
||||||
} else {
|
} else {
|
||||||
assert err.msg.len != 0
|
assert err.msg().len != 0
|
||||||
}
|
}
|
||||||
if _ := or_return_none() {
|
if _ := or_return_none() {
|
||||||
assert false
|
assert false
|
||||||
} else {
|
} else {
|
||||||
assert err.msg.len == 0
|
assert err.msg().len == 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,7 +283,7 @@ fn test_optional_void_return_types_of_anon_fn() {
|
||||||
}
|
}
|
||||||
|
|
||||||
f(0) or {
|
f(0) or {
|
||||||
assert err.msg == '0'
|
assert err.msg() == '0'
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -304,7 +304,7 @@ fn test_option_void_return_types_of_anon_fn_in_struct() {
|
||||||
}
|
}
|
||||||
|
|
||||||
foo.f(0) or {
|
foo.f(0) or {
|
||||||
assert err.msg == '0'
|
assert err.msg() == '0'
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ fn foo() ? {
|
||||||
fn test_optional_void() {
|
fn test_optional_void() {
|
||||||
foo() or {
|
foo() or {
|
||||||
println(err)
|
println(err)
|
||||||
assert err.msg == 'something'
|
assert err.msg() == 'something'
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ fn bar() ? {
|
||||||
fn test_optional_void_only_question() {
|
fn test_optional_void_only_question() {
|
||||||
bar() or {
|
bar() or {
|
||||||
println(err)
|
println(err)
|
||||||
assert err.msg == 'bar error'
|
assert err.msg() == 'bar error'
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,12 +38,12 @@ fn option_void(a int) ? {
|
||||||
fn test_optional_void_with_return() {
|
fn test_optional_void_with_return() {
|
||||||
option_void(0) or {
|
option_void(0) or {
|
||||||
println(err)
|
println(err)
|
||||||
assert err.msg == 'zero error'
|
assert err.msg() == 'zero error'
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
option_void(-1) or {
|
option_void(-1) or {
|
||||||
println(err)
|
println(err)
|
||||||
assert err.msg == 'zero error'
|
assert err.msg() == 'zero error'
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
assert true
|
assert true
|
||||||
|
|
|
@ -15,7 +15,7 @@ fn test_all_v_prod_files() {
|
||||||
bmark.step()
|
bmark.step()
|
||||||
fres := runner.run_prod_file(options.wd, options.vexec, file) or {
|
fres := runner.run_prod_file(options.wd, options.vexec, file) or {
|
||||||
bmark.fail()
|
bmark.fail()
|
||||||
eprintln(bmark.step_message_fail(err.msg))
|
eprintln(bmark.step_message_fail(err.msg()))
|
||||||
assert false
|
assert false
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ fn worker_repl(mut p pool.PoolProcessor, idx int, thread_id int) voidptr {
|
||||||
session.bmark.fail()
|
session.bmark.fail()
|
||||||
tls_bench.fail()
|
tls_bench.fail()
|
||||||
os.rmdir_all(tfolder) or { panic(err) }
|
os.rmdir_all(tfolder) or { panic(err) }
|
||||||
eprintln(tls_bench.step_message_fail(err.msg))
|
eprintln(tls_bench.step_message_fail(err.msg()))
|
||||||
assert false
|
assert false
|
||||||
return pool.no_result
|
return pool.no_result
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ pub fn full_path_to_v(dirs_in int) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn diff_files(file_result string, file_expected string) string {
|
fn diff_files(file_result string, file_expected string) string {
|
||||||
diffcmd := diff.find_working_diff_command() or { return err.msg }
|
diffcmd := diff.find_working_diff_command() or { return err.msg() }
|
||||||
return diff.color_compare_files(diffcmd, file_result, file_expected)
|
return diff.color_compare_files(diffcmd, file_result, file_expected)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -374,7 +374,7 @@ fn test_fields_anon_fn_with_optional_void_return_type() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foo.f() or { assert err.msg == 'oops' }
|
foo.f() or { assert err.msg() == 'oops' }
|
||||||
|
|
||||||
foo.g() or { assert false }
|
foo.g() or { assert false }
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ fn test_decode() {
|
||||||
assert data.dependencies[0] == 'hello'
|
assert data.dependencies[0] == 'hello'
|
||||||
assert data.unknown['test'][0] == 'foo'
|
assert data.unknown['test'][0] == 'foo'
|
||||||
vmod.decode('') or {
|
vmod.decode('') or {
|
||||||
assert err.msg == 'vmod: no content.'
|
assert err.msg() == 'vmod: no content.'
|
||||||
exit(0)
|
exit(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,9 @@ pub struct Transformer {
|
||||||
pref &pref.Preferences
|
pref &pref.Preferences
|
||||||
pub mut:
|
pub mut:
|
||||||
index &IndexState
|
index &IndexState
|
||||||
|
table &ast.Table = 0
|
||||||
|
mut:
|
||||||
|
is_assert bool
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_transformer(pref &pref.Preferences) &Transformer {
|
pub fn new_transformer(pref &pref.Preferences) &Transformer {
|
||||||
|
@ -20,6 +23,12 @@ pub fn new_transformer(pref &pref.Preferences) &Transformer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_transformer_with_table(table &ast.Table, pref &pref.Preferences) &Transformer {
|
||||||
|
mut transformer := new_transformer(pref)
|
||||||
|
transformer.table = table
|
||||||
|
return transformer
|
||||||
|
}
|
||||||
|
|
||||||
pub fn (mut t Transformer) transform_files(ast_files []&ast.File) {
|
pub fn (mut t Transformer) transform_files(ast_files []&ast.File) {
|
||||||
for i in 0 .. ast_files.len {
|
for i in 0 .. ast_files.len {
|
||||||
mut file := unsafe { ast_files[i] }
|
mut file := unsafe { ast_files[i] }
|
||||||
|
@ -104,57 +113,6 @@ pub fn (mut t Transformer) find_mut_self_assign(node ast.AssignStmt) {
|
||||||
// even if mutable we can be sure than `a[1] = a[2] is safe
|
// even if mutable we can be sure than `a[1] = a[2] is safe
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut t Transformer) find_assert_len(mut node ast.InfixExpr) ast.Expr {
|
|
||||||
if !t.pref.is_prod {
|
|
||||||
return node
|
|
||||||
}
|
|
||||||
right := t.expr(mut node.right)
|
|
||||||
match right {
|
|
||||||
ast.IntegerLiteral {
|
|
||||||
left := t.expr(mut node.left)
|
|
||||||
if left is ast.SelectorExpr {
|
|
||||||
len := right.val.int()
|
|
||||||
if left.field_name == 'len' {
|
|
||||||
match node.op {
|
|
||||||
.eq { // ==
|
|
||||||
t.index.safe_access(left.expr.str(), len - 1)
|
|
||||||
}
|
|
||||||
.ge { // >=
|
|
||||||
t.index.safe_access(left.expr.str(), len - 1)
|
|
||||||
}
|
|
||||||
.gt { // >
|
|
||||||
t.index.safe_access(left.expr.str(), len)
|
|
||||||
}
|
|
||||||
else {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ast.SelectorExpr {
|
|
||||||
left := t.expr(mut node.left)
|
|
||||||
if left is ast.IntegerLiteral {
|
|
||||||
len := left.val.int()
|
|
||||||
if right.field_name == 'len' {
|
|
||||||
match node.op {
|
|
||||||
.eq { // ==
|
|
||||||
t.index.safe_access(right.expr.str(), len - 1)
|
|
||||||
}
|
|
||||||
.le { // <=
|
|
||||||
t.index.safe_access(right.expr.str(), len - 1)
|
|
||||||
}
|
|
||||||
.lt { // <
|
|
||||||
t.index.safe_access(right.expr.str(), len)
|
|
||||||
}
|
|
||||||
else {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {}
|
|
||||||
}
|
|
||||||
return node
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (mut t Transformer) check_safe_array(mut node ast.IndexExpr) {
|
pub fn (mut t Transformer) check_safe_array(mut node ast.IndexExpr) {
|
||||||
if !t.pref.is_prod {
|
if !t.pref.is_prod {
|
||||||
return
|
return
|
||||||
|
@ -212,14 +170,7 @@ pub fn (mut t Transformer) stmt(mut node ast.Stmt) ast.Stmt {
|
||||||
ast.NodeError {}
|
ast.NodeError {}
|
||||||
ast.AsmStmt {}
|
ast.AsmStmt {}
|
||||||
ast.AssertStmt {
|
ast.AssertStmt {
|
||||||
match mut node.expr {
|
return t.assert_stmt(mut node)
|
||||||
ast.InfixExpr {
|
|
||||||
node.expr = t.find_assert_len(mut node.expr)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
node.expr = t.expr(mut node.expr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ast.AssignStmt {
|
ast.AssignStmt {
|
||||||
t.find_new_array_len(node)
|
t.find_new_array_len(node)
|
||||||
|
@ -312,9 +263,7 @@ pub fn (mut t Transformer) stmt(mut node ast.Stmt) ast.Stmt {
|
||||||
}
|
}
|
||||||
ast.Import {}
|
ast.Import {}
|
||||||
ast.InterfaceDecl {
|
ast.InterfaceDecl {
|
||||||
for mut field in node.fields {
|
return t.interface_decl(mut node)
|
||||||
field.default_expr = t.expr(mut field.default_expr)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ast.Module {}
|
ast.Module {}
|
||||||
ast.Return {
|
ast.Return {
|
||||||
|
@ -333,6 +282,63 @@ pub fn (mut t Transformer) stmt(mut node ast.Stmt) ast.Stmt {
|
||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn (mut t Transformer) assert_stmt(mut node ast.AssertStmt) ast.Stmt {
|
||||||
|
t.is_assert = true
|
||||||
|
node.expr = t.expr(mut node.expr)
|
||||||
|
if !t.pref.is_prod {
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
if mut node.expr is ast.InfixExpr {
|
||||||
|
right := node.expr.right
|
||||||
|
match right {
|
||||||
|
ast.IntegerLiteral {
|
||||||
|
left := node.expr.left
|
||||||
|
if left is ast.SelectorExpr {
|
||||||
|
len := right.val.int()
|
||||||
|
if left.field_name == 'len' {
|
||||||
|
match node.expr.op {
|
||||||
|
.eq { // ==
|
||||||
|
t.index.safe_access(left.expr.str(), len - 1)
|
||||||
|
}
|
||||||
|
.ge { // >=
|
||||||
|
t.index.safe_access(left.expr.str(), len - 1)
|
||||||
|
}
|
||||||
|
.gt { // >
|
||||||
|
t.index.safe_access(left.expr.str(), len)
|
||||||
|
}
|
||||||
|
else {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ast.SelectorExpr {
|
||||||
|
left := node.expr.left
|
||||||
|
if left is ast.IntegerLiteral {
|
||||||
|
len := left.val.int()
|
||||||
|
if right.field_name == 'len' {
|
||||||
|
match node.expr.op {
|
||||||
|
.eq { // ==
|
||||||
|
t.index.safe_access(right.expr.str(), len - 1)
|
||||||
|
}
|
||||||
|
.le { // <=
|
||||||
|
t.index.safe_access(right.expr.str(), len - 1)
|
||||||
|
}
|
||||||
|
.lt { // <
|
||||||
|
t.index.safe_access(right.expr.str(), len)
|
||||||
|
}
|
||||||
|
else {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t.is_assert = false
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
|
||||||
pub fn (mut t Transformer) expr_stmt_if_expr(mut node ast.IfExpr) ast.Expr {
|
pub fn (mut t Transformer) expr_stmt_if_expr(mut node ast.IfExpr) ast.Expr {
|
||||||
mut stop_index, mut unreachable_branches := -1, []int{cap: node.branches.len}
|
mut stop_index, mut unreachable_branches := -1, []int{cap: node.branches.len}
|
||||||
if node.is_comptime {
|
if node.is_comptime {
|
||||||
|
@ -497,6 +503,14 @@ pub fn (mut t Transformer) for_stmt(mut node ast.ForStmt) ast.Stmt {
|
||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn (mut t Transformer) interface_decl(mut node ast.InterfaceDecl) ast.Stmt {
|
||||||
|
for mut field in node.fields {
|
||||||
|
field.default_expr = t.expr(mut field.default_expr)
|
||||||
|
}
|
||||||
|
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
|
||||||
pub fn (mut t Transformer) expr(mut node ast.Expr) ast.Expr {
|
pub fn (mut t Transformer) expr(mut node ast.Expr) ast.Expr {
|
||||||
match mut node {
|
match mut node {
|
||||||
ast.AnonFn {
|
ast.AnonFn {
|
||||||
|
@ -629,6 +643,11 @@ pub fn (mut t Transformer) expr(mut node ast.Expr) ast.Expr {
|
||||||
ast.SqlExpr {
|
ast.SqlExpr {
|
||||||
return t.sql_expr(mut node)
|
return t.sql_expr(mut node)
|
||||||
}
|
}
|
||||||
|
ast.StringInterLiteral {
|
||||||
|
for mut expr in node.exprs {
|
||||||
|
expr = t.expr(mut expr)
|
||||||
|
}
|
||||||
|
}
|
||||||
ast.StructInit {
|
ast.StructInit {
|
||||||
node.update_expr = t.expr(mut node.update_expr)
|
node.update_expr = t.expr(mut node.update_expr)
|
||||||
for mut field in node.fields {
|
for mut field in node.fields {
|
||||||
|
@ -661,7 +680,7 @@ pub fn (mut t Transformer) infix_expr(mut node ast.InfixExpr) ast.Expr {
|
||||||
pos.extend(node.pos)
|
pos.extend(node.pos)
|
||||||
pos.extend(node.right.pos())
|
pos.extend(node.right.pos())
|
||||||
|
|
||||||
if t.pref.is_debug {
|
if t.pref.is_debug || t.is_assert { // never optimize assert statements
|
||||||
return node
|
return node
|
||||||
} else {
|
} else {
|
||||||
match mut node.left {
|
match mut node.left {
|
||||||
|
|
|
@ -34,7 +34,7 @@ fn parse_attrs(name string, attrs []string) ?([]http.Method, string) {
|
||||||
}
|
}
|
||||||
if x.len > 0 {
|
if x.len > 0 {
|
||||||
return IError(http.UnexpectedExtraAttributeError{
|
return IError(http.UnexpectedExtraAttributeError{
|
||||||
msg: 'Encountered unexpected extra attributes: $x'
|
attributes: x
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if methods.len == 0 {
|
if methods.len == 0 {
|
||||||
|
|
|
@ -68,7 +68,7 @@ fn assert_common_headers(received string) {
|
||||||
|
|
||||||
fn test_a_simple_tcp_client_can_connect_to_the_vweb_server() {
|
fn test_a_simple_tcp_client_can_connect_to_the_vweb_server() {
|
||||||
received := simple_tcp_client(path: '/') or {
|
received := simple_tcp_client(path: '/') or {
|
||||||
assert err.msg == ''
|
assert err.msg() == ''
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
assert_common_headers(received)
|
assert_common_headers(received)
|
||||||
|
@ -79,7 +79,7 @@ fn test_a_simple_tcp_client_can_connect_to_the_vweb_server() {
|
||||||
|
|
||||||
fn test_a_simple_tcp_client_simple_route() {
|
fn test_a_simple_tcp_client_simple_route() {
|
||||||
received := simple_tcp_client(path: '/simple') or {
|
received := simple_tcp_client(path: '/simple') or {
|
||||||
assert err.msg == ''
|
assert err.msg() == ''
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
assert_common_headers(received)
|
assert_common_headers(received)
|
||||||
|
@ -92,7 +92,7 @@ fn test_a_simple_tcp_client_zero_content_length() {
|
||||||
// tests that sending a content-length header of 0 doesn't hang on a read timeout
|
// tests that sending a content-length header of 0 doesn't hang on a read timeout
|
||||||
watch := time.new_stopwatch(auto_start: true)
|
watch := time.new_stopwatch(auto_start: true)
|
||||||
simple_tcp_client(path: '/', headers: 'Content-Length: 0\r\n\r\n') or {
|
simple_tcp_client(path: '/', headers: 'Content-Length: 0\r\n\r\n') or {
|
||||||
assert err.msg == ''
|
assert err.msg() == ''
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
assert watch.elapsed() < 1 * time.second
|
assert watch.elapsed() < 1 * time.second
|
||||||
|
@ -100,7 +100,7 @@ fn test_a_simple_tcp_client_zero_content_length() {
|
||||||
|
|
||||||
fn test_a_simple_tcp_client_html_page() {
|
fn test_a_simple_tcp_client_html_page() {
|
||||||
received := simple_tcp_client(path: '/html_page') or {
|
received := simple_tcp_client(path: '/html_page') or {
|
||||||
assert err.msg == ''
|
assert err.msg() == ''
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
assert_common_headers(received)
|
assert_common_headers(received)
|
||||||
|
@ -230,7 +230,7 @@ $contents\r
|
||||||
|
|
||||||
fn test_http_client_shutdown_does_not_work_without_a_cookie() {
|
fn test_http_client_shutdown_does_not_work_without_a_cookie() {
|
||||||
x := http.get('http://$localserver/shutdown') or {
|
x := http.get('http://$localserver/shutdown') or {
|
||||||
assert err.msg == ''
|
assert err.msg() == ''
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
assert x.status() == .not_found
|
assert x.status() == .not_found
|
||||||
|
@ -247,7 +247,7 @@ fn testsuite_end() {
|
||||||
'skey': 'superman'
|
'skey': 'superman'
|
||||||
}
|
}
|
||||||
) or {
|
) or {
|
||||||
assert err.msg == ''
|
assert err.msg() == ''
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
assert x.status() == .ok
|
assert x.status() == .ok
|
||||||
|
|
|
@ -255,7 +255,7 @@ pub fn (mut ctx Context) json_pretty<T>(j T) Result {
|
||||||
pub fn (mut ctx Context) file(f_path string) Result {
|
pub fn (mut ctx Context) file(f_path string) Result {
|
||||||
ext := os.file_ext(f_path)
|
ext := os.file_ext(f_path)
|
||||||
data := os.read_file(f_path) or {
|
data := os.read_file(f_path) or {
|
||||||
eprint(err.msg)
|
eprint(err.msg())
|
||||||
ctx.server_error(500)
|
ctx.server_error(500)
|
||||||
return Result{}
|
return Result{}
|
||||||
}
|
}
|
||||||
|
@ -417,7 +417,7 @@ pub fn run_at<T>(global_app &T, host string, port int) {
|
||||||
request_app.Context = global_app.Context // copy the context ref that contains static files map etc
|
request_app.Context = global_app.Context // copy the context ref that contains static files map etc
|
||||||
mut conn := l.accept() or {
|
mut conn := l.accept() or {
|
||||||
// failures should not panic
|
// failures should not panic
|
||||||
eprintln('accept() failed with error: $err.msg')
|
eprintln('accept() failed with error: $err.msg()')
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
go handle_conn<T>(mut conn, mut request_app, routes)
|
go handle_conn<T>(mut conn, mut request_app, routes)
|
||||||
|
|
|
@ -22,13 +22,11 @@ mut:
|
||||||
}
|
}
|
||||||
|
|
||||||
struct InvalidTokenError {
|
struct InvalidTokenError {
|
||||||
msg string
|
MessageError
|
||||||
code int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct UnknownTokenError {
|
struct UnknownTokenError {
|
||||||
msg string
|
MessageError
|
||||||
code int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut p Parser) next() {
|
fn (mut p Parser) next() {
|
||||||
|
|
|
@ -43,7 +43,7 @@ fn test_raw_decode_null() ? {
|
||||||
|
|
||||||
fn test_raw_decode_invalid() ? {
|
fn test_raw_decode_invalid() ? {
|
||||||
raw_decode('1z') or {
|
raw_decode('1z') or {
|
||||||
assert err.msg == '[x.json2] invalid token `z` (0:17)'
|
assert err.msg() == '[x.json2] invalid token `z` (0:17)'
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
assert false
|
assert false
|
||||||
|
|
Loading…
Reference in New Issue