Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into fix_sumtype_field_name
Browse files Browse the repository at this point in the history
  • Loading branch information
felipensp committed May 19, 2024
2 parents 1672631 + f56b2b6 commit 47300b3
Show file tree
Hide file tree
Showing 49 changed files with 656 additions and 122 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/tools_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ jobs:
- uses: actions/checkout@v4
- name: Build V
run: make -j4 && ./v -showcc -o v cmd/v && ./v doctor
- name: Code in cmd/ is formatted
run: ./v fmt -verify cmd/
- name: Test
run: ./v test-self cmd
- name: Test (-cstrict)
Expand Down
2 changes: 1 addition & 1 deletion cmd/tools/modules/vgit/vgit.v
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub fn check_v_commit_timestamp_before_self_rebuilding(v_timestamp u64) {
}

pub fn validate_commit_exists(commit string) {
if commit.len == 0 {
if commit != '' {
return
}
cmd := 'git cat-file -t "${commit}" ' // windows's cmd.exe does not support ' for quoting
Expand Down
64 changes: 38 additions & 26 deletions cmd/tools/vdoc/files.v
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,18 @@ mut:
}

fn get_modules(path string) []string {
mut ignore_rules := IgnoreRules{}
mut modules := map[string]bool{}
for p in get_paths(path, mut ignore_rules) {
for p in get_paths(path, IgnoreRules.get(path)) {
modules[os.dir(p)] = true
}
mut res := modules.keys()
res.sort()
return res
}

fn get_paths(path string, mut ignore_rules IgnoreRules) []string {
fn get_paths(path string, ignore_rules IgnoreRules) []string {
mut res := []string{}
outer: for p in os.ls(path) or { return [] } {
ignore_rules.get(path)
fp := os.join_path(path, p)
if fp in ignore_rules.paths {
continue
Expand All @@ -45,7 +43,7 @@ fn get_paths(path string, mut ignore_rules IgnoreRules) []string {
}
}
if is_dir {
res << get_paths(fp, mut ignore_rules)
res << get_paths(fp, ignore_rules)
continue
}
if p.ends_with('.v') {
Expand All @@ -55,30 +53,44 @@ fn get_paths(path string, mut ignore_rules IgnoreRules) []string {
return res
}

fn (mut ignore_rules IgnoreRules) get(path string) {
ignore_content := os.read_file(os.join_path(path, '.vdocignore')) or { return }
if ignore_content.trim_space() == '' {
return
}
rules := ignore_content.split_into_lines().map(it.trim_space())
for rule in rules {
if rule.starts_with('#') {
continue
fn IgnoreRules.get(path string) IgnoreRules {
mut res := IgnoreRules{}
mut vdocignore_paths := []string{}
mut vdocignore_paths_ref := &vdocignore_paths
os.walk(path, fn [vdocignore_paths_ref] (p string) {
if os.file_name(p) == '.vdocignore' {
unsafe {
vdocignore_paths_ref << p
}
}
if rule.contains('*.') || rule.contains('**') {
// Skip wildcards that are defined in an ignore file.
// For now, only add a basic implementation in `get_paths`
// that can handle the default `*_test.v` pattern.
eprintln('vdoc: Wildcards in ignore rules are not yet supported.')
})
for ignore_path in vdocignore_paths {
ignore_content := os.read_file(ignore_path) or { continue }
if ignore_content.trim_space() == '' {
continue
}
if rule.starts_with('/') {
// Similar to `.gitignore`, a pattern starting with `/` should only ignore
// the pattern relative to the directory of the `.vdocignore` file.
// `/a` should ignore `/a` but not `/b/a`. While `a` should ignore `/a` and `/b/a`.
ignore_rules.paths[os.join_path(path, rule.trim_left('/'))] = true
} else {
ignore_rules.patterns[path] << rule
rules := ignore_content.split_into_lines().map(it.trim_space())
for rule in rules {
if rule.starts_with('#') {
continue
}
if rule.contains('*.') || rule.contains('**') {
// Skip wildcards that are defined in an ignore file.
// For now, only add a basic implementation in `get_paths`
// that can handle the default `*_test.v` pattern.
eprintln('vdoc: Wildcards in ignore rules are not yet supported.')
continue
}
p := os.dir(ignore_path)
if rule.starts_with('/') {
// Similar to `.gitignore`, a pattern starting with `/` should only ignore
// the pattern relative to the directory of the `.vdocignore` file.
// `/a` should ignore `/a` but not `/b/a`. While `a` should ignore `/a` and `/b/a`.
res.paths[os.join_path(p, rule.trim_left('/'))] = true
} else {
res.patterns[p] << rule
}
}
}
return res
}
2 changes: 1 addition & 1 deletion cmd/tools/vdoc/html.v
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@ fn doc_node_html(dn doc.DocNode, link string, head bool, include_examples bool,
} else {
dnw.write_string('${tabs(3)}<div class="title"><${head_tag}>${dn.kind} ${sym_name}${hash_link}</${head_tag}>')
}
if link.len != 0 {
if link != '' {
dnw.write_string('<a class="link" rel="noreferrer" target="_blank" href="${link}">${link_svg}</a>')
}
dnw.write_string('</div>\n')
Expand Down
32 changes: 24 additions & 8 deletions cmd/tools/vdoc/vdoc_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,18 @@ module main
import os
import arrays

const tpath = os.join_path(os.vtmp_dir(), 'vod_test_module')

fn testsuite_begin() {
os.rmdir_all(tpath) or {}
os.mkdir_all(tpath)!
os.chdir(tpath)!
}

fn testsuite_end() {
os.rmdir_all(tpath) or {}
}

fn test_trim_doc_node_description() {
mod := 'foo'
mut readme := '## Description
Expand All @@ -20,16 +32,20 @@ It also assists with composing and testing baz.'
assert res2 == res
}

fn test_get_module_list() {
tpath := os.join_path(os.vtmp_dir(), 'vod_test_module')
os.rmdir_all(tpath) or {}
os.mkdir_all(tpath)!
defer {
os.rmdir_all(tpath) or {}
fn test_ignore_rules() {
os.write_file('.vdocignore', ['pattern1', 'pattern2', '/path1'].join_lines())!
os.mkdir('subdir')!
os.write_file(os.join_path('subdir', '.vdocignore'), ['pattern3', '/path2'].join_lines())!
rules := IgnoreRules.get('.')
assert rules.patterns['.'] == ['pattern1', 'pattern2']
assert rules.patterns['./subdir'] == ['pattern3']
assert rules.paths == {
'./path1': true
'./subdir/path2': true
}
}

os.chdir(tpath)!

fn test_get_module_list() {
// For information on leading slash rules, refer to the comments in `IgnoreRules.get`.
ignore_rules := ['bravo', '/echo', '/foxtrot/golf', 'hotel.v/', 'india/juliett']
os.write_file('.vdocignore', ignore_rules.join_lines())!
Expand Down
12 changes: 12 additions & 0 deletions cmd/tools/vvet/tests/empty_string.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
cmd/tools/vvet/tests/empty_string.vv:3: notice: Use `foo == ''` instead of `foo.len < 1`
cmd/tools/vvet/tests/empty_string.vv:4: notice: Use `foo != ''` instead of `foo.len > 0`
cmd/tools/vvet/tests/empty_string.vv:4: notice: Use `foo == ''` instead of `foo.len == 0`
cmd/tools/vvet/tests/empty_string.vv:4: notice: Use `foo != ''` instead of `foo.len != 0`
cmd/tools/vvet/tests/empty_string.vv:7: notice: Use `'' == bar` instead of `1 > bar.len`
cmd/tools/vvet/tests/empty_string.vv:8: notice: Use `'' != bar` instead of `0 < bar.len`
cmd/tools/vvet/tests/empty_string.vv:8: notice: Use `'' == bar` instead of `0 == bar.len`
cmd/tools/vvet/tests/empty_string.vv:8: notice: Use `'' != bar` instead of `0 != bar.len`
cmd/tools/vvet/tests/empty_string.vv:10: notice: Use `foo == ''` instead of `foo.len < 1`
cmd/tools/vvet/tests/empty_string.vv:10: notice: Use `bar != ''` instead of `bar.len > 0`
cmd/tools/vvet/tests/empty_string.vv:10: notice: Use `foo == ''` instead of `foo.len == 0`
cmd/tools/vvet/tests/empty_string.vv:10: notice: Use `bar == ''` instead of `bar.len == 0`
21 changes: 21 additions & 0 deletions cmd/tools/vvet/tests/empty_string.vv
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
fn main() {
foo := 'foo'
_ := foo.len < 1
_ := foo.len > 0 || foo.len == 0 || foo.len != 0

bar := 'bar'
_ := 1 > bar.len
_ := 0 < bar.len || 0 == bar.len || 0 != bar.len

if foo.len < 1 || bar.len > 0 || (foo.len == 0 && bar.len == 0) {
}

// Should not notify when `.len` is used with other types.
baz := ['baz']
_ := baz.len == 0

foobar := {
'foo': 'bar'
}
_ := foobar.len < 1
}
42 changes: 42 additions & 0 deletions cmd/tools/vvet/vvet.v
Original file line number Diff line number Diff line change
Expand Up @@ -289,8 +289,12 @@ fn (mut vt Vet) expr(expr ast.Expr) {
}
ast.InfixExpr {
vt.vet_in_condition(expr)
vt.vet_empty_str(expr)
vt.expr(expr.right)
}
ast.ParExpr {
vt.expr(expr.expr)
}
ast.CallExpr {
vt.expr(expr.left)
vt.exprs(expr.args.map(it.expr))
Expand Down Expand Up @@ -320,6 +324,44 @@ fn (mut vt Vet) const_decl(stmt ast.ConstDecl) {
}
}

fn (mut vt Vet) vet_empty_str(expr ast.InfixExpr) {
if expr.left is ast.InfixExpr {
vt.expr(expr.left)
} else if expr.right is ast.InfixExpr {
vt.expr(expr.right)
} else if expr.left is ast.SelectorExpr && expr.right is ast.IntegerLiteral {
operand := (expr.left as ast.SelectorExpr) // TODO: remove as-casts when multiple conds can be smart-casted.
if operand.expr is ast.Ident && operand.expr.info.typ == ast.string_type_idx
&& operand.field_name == 'len' {
if expr.op != .lt && expr.right.val == '0' {
// Case: `var.len > 0`, `var.len == 0`, `var.len != 0`
op := if expr.op == .gt { '!=' } else { expr.op.str() }
vt.notice("Use `${operand.expr.name} ${op} ''` instead of `${operand.expr.name}.len ${expr.op} 0`",
expr.pos.line_nr, .unknown)
} else if expr.op == .lt && expr.right.val == '1' {
// Case: `var.len < 1`
vt.notice("Use `${operand.expr.name} == ''` instead of `${operand.expr.name}.len ${expr.op} 1`",
expr.pos.line_nr, .unknown)
}
}
} else if expr.left is ast.IntegerLiteral && expr.right is ast.SelectorExpr {
operand := expr.right
if operand.expr is ast.Ident && operand.expr.info.typ == ast.string_type_idx
&& operand.field_name == 'len' {
if expr.op != .gt && (expr.left as ast.IntegerLiteral).val == '0' {
// Case: `0 < var.len`, `0 == var.len`, `0 != var.len`
op := if expr.op == .lt { '!=' } else { expr.op.str() }
vt.notice("Use `'' ${op} ${operand.expr.name}` instead of `0 ${expr.op} ${operand.expr.name}.len`",
expr.pos.line_nr, .unknown)
} else if expr.op == .gt && (expr.left as ast.IntegerLiteral).val == '1' {
// Case: `1 > var.len`
vt.notice("Use `'' == ${operand.expr.name}` instead of `1 ${expr.op} ${operand.expr.name}.len`",
expr.pos.line_nr, .unknown)
}
}
}
}

fn (vt &Vet) vprintln(s string) {
if !vt.opt.is_verbose {
return
Expand Down
7 changes: 6 additions & 1 deletion vlib/builtin/js/builtin.v
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub fn (err IError) str() string {
err.msg()
}
MessageError {
err.msg()
err.str()
}
else {
// >> Hack to allow old style custom error implementations
Expand Down Expand Up @@ -68,6 +68,11 @@ pub:
code int
}

// str returns the message and code of the MessageError
pub fn (err MessageError) str() string {
return err.msg
}

// msg returns the message of the MessageError
pub fn (err MessageError) msg() string {
return err.msg
Expand Down
2 changes: 1 addition & 1 deletion vlib/builtin/linux_bare/linux_syscalls.v
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ fn sys_dup2(oldfd int, newfd int) (i64, Errno) {

// 59 sys_execve
fn sys_execve(filename &u8, argv []&u8, envp []&u8) int {
return int(sys_call3(59, u64(filename), argv.data, envp.data))
return int(sys_call3(59, u64(filename), u64(argv.data), u64(envp.data)))
}

// 60 sys_exit
Expand Down
13 changes: 9 additions & 4 deletions vlib/builtin/result.v
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub fn (err IError) str() string {
err.msg()
}
MessageError {
err.msg()
(*err).str()
}
else {
// >> Hack to allow old style custom error implementations
Expand Down Expand Up @@ -70,15 +70,20 @@ pub:
code int
}

// msg returns the message of MessageError
pub fn (err MessageError) msg() string {
// str returns both the .msg and .code of MessageError, when .code is != 0
pub fn (err MessageError) str() string {
if err.code > 0 {
return '${err.msg}; code: ${err.code}'
}
return err.msg
}

// code returns the code of MessageError
// msg returns only the message of MessageError
pub fn (err MessageError) msg() string {
return err.msg
}

// code returns only the code of MessageError
pub fn (err MessageError) code() int {
return err.code
}
Expand Down
6 changes: 4 additions & 2 deletions vlib/dlmalloc/dlmalloc.v
Original file line number Diff line number Diff line change
Expand Up @@ -1048,7 +1048,8 @@ fn (mut dl Dlmalloc) init_bins() {

@[unsafe]
fn (mut dl Dlmalloc) init_top(ptr &Chunk, size_ usize) {
offset := align_offset_usize(ptr.to_mem())
pmem := ptr.to_mem()
offset := align_offset_usize(usize(pmem))
mut p := ptr.plus_offset(offset)

size := size_ - offset
Expand Down Expand Up @@ -1301,7 +1302,8 @@ fn (mut dl Dlmalloc) add_segment(tbase voidptr, tsize usize, flags u32) {
ssize := pad_request(sizeof(Segment))
mut offset := ssize + sizeof(usize) * 4 + malloc_alignment() - 1
rawsp := voidptr(usize(old_end) - offset)
offset = align_offset_usize((&Chunk(rawsp)).to_mem())
pmem := (&Chunk(rawsp)).to_mem()
offset = align_offset_usize(usize(pmem))
asp := voidptr(usize(rawsp) + offset)
csp := if asp < voidptr(usize(old_top) + min_chunk_size()) { old_top } else { asp }
mut sp := &Chunk(csp)
Expand Down
Loading

0 comments on commit 47300b3

Please sign in to comment.