tools: check formatting of more modules with `v test-cleancode`, colorize `v vet` output

pull/9451/head
Delyan Angelov 2021-03-24 12:39:09 +02:00
parent 9e48826bcb
commit 9b78d7d21d
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
13 changed files with 128 additions and 67 deletions

View File

@ -77,22 +77,9 @@ fn main() {
eprintln('vfmt env_vflags_and_os_args: ' + args.str()) eprintln('vfmt env_vflags_and_os_args: ' + args.str())
eprintln('vfmt possible_files: ' + possible_files.str()) eprintln('vfmt possible_files: ' + possible_files.str())
} }
mut files := []string{} files := util.find_all_v_files(possible_files) or {
for file in possible_files { verror(err.msg)
if os.is_dir(file) { return
files << os.walk_ext(file, '.v')
files << os.walk_ext(file, '.vsh')
continue
}
if !file.ends_with('.v') && !file.ends_with('.vv') && !file.ends_with('.vsh') {
verror('v fmt can only be used on .v files.\nOffending file: "$file"')
continue
}
if !os.exists(file) {
verror('"$file" does not exist')
continue
}
files << file
} }
if is_atty(0) == 0 && files.len == 0 { if is_atty(0) == 0 && files.len == 0 {
foptions.format_pipe() foptions.format_pipe()

View File

@ -16,7 +16,11 @@ const (
'examples/tetris', 'examples/tetris',
'examples/term.ui', 'examples/term.ui',
] ]
verify_known_failing_exceptions = []string{} verify_known_failing_exceptions = [
'vlib/gg/m4/graphic.v' /* has hand crafted meaningful formatting of matrices */,
'vlib/gg/m4/m4_test.v' /* has hand crafted meaningful formatting of matrices */,
'vlib/gg/m4/matrix.v' /* has hand crafted meaningful formatting of matrices */,
]
vfmt_verify_list = [ vfmt_verify_list = [
'cmd/v/v.v', 'cmd/v/v.v',
'cmd/tools/vdoc/', 'cmd/tools/vdoc/',
@ -30,8 +34,13 @@ const (
'vlib/builtin/map.v', 'vlib/builtin/map.v',
'vlib/builtin/int.v', 'vlib/builtin/int.v',
'vlib/builtin/option.v', 'vlib/builtin/option.v',
'vlib/cli/',
'vlib/dl/',
'vlib/flag/',
'vlib/gg/',
'vlib/math/bits/bits.v', 'vlib/math/bits/bits.v',
'vlib/orm/', 'vlib/orm/',
'vlib/runtime/',
'vlib/term/colors.v', 'vlib/term/colors.v',
'vlib/term/term.v', 'vlib/term/term.v',
'vlib/v/ast/', 'vlib/v/ast/',
@ -88,7 +97,8 @@ fn main() {
fn tsession(vargs string, tool_source string, tool_cmd string, tool_args string, flist []string, slist []string) testing.TestSession { fn tsession(vargs string, tool_source string, tool_cmd string, tool_args string, flist []string, slist []string) testing.TestSession {
os.chdir(vroot) os.chdir(vroot)
testing.eheader('Run `$tool_cmd` over most .v files') title_message := 'running $tool_cmd over most .v files'
testing.eheader(title_message)
mut test_session := testing.new_test_session('$vargs $tool_args') mut test_session := testing.new_test_session('$vargs $tool_args')
test_session.files << flist test_session.files << flist
test_session.skip_files << slist test_session.skip_files << slist
@ -97,14 +107,16 @@ fn tsession(vargs string, tool_source string, tool_cmd string, tool_args string,
// in the VTMP from the test session too, so they will be cleaned up // in the VTMP from the test session too, so they will be cleaned up
// at the end // at the end
test_session.test() test_session.test()
eprintln(test_session.benchmark.total_message('running `$tool_cmd` over most .v files')) eprintln(test_session.benchmark.total_message(title_message))
return test_session return test_session
} }
fn v_test_vetting(vargs string) { fn v_test_vetting(vargs string) {
vet_session := tsession(vargs, 'vvet', 'v vet', 'vet', vet_folders, vet_known_failing_exceptions) vet_session := tsession(vargs, 'vvet', 'v vet', 'vet', vet_folders, vet_known_failing_exceptions)
fmt_cmd, fmt_args := if is_fix { 'v fmt -w', 'fmt -w' } else { 'v fmt -verify', 'fmt -verify' } fmt_cmd, fmt_args := if is_fix { 'v fmt -w', 'fmt -w' } else { 'v fmt -verify', 'fmt -verify' }
verify_session := tsession(vargs, 'vfmt.v', fmt_cmd, fmt_args, vfmt_verify_list, verify_known_failing_exceptions) expanded_vfmt_list := util.find_all_v_files(vfmt_verify_list) or { return }
verify_session := tsession(vargs, 'vfmt.v', fmt_cmd, fmt_args, expanded_vfmt_list,
verify_known_failing_exceptions)
// //
if vet_session.benchmark.nfail > 0 || verify_session.benchmark.nfail > 0 { if vet_session.benchmark.nfail > 0 || verify_session.benchmark.nfail > 0 {
eprintln('\n') eprintln('\n')

View File

@ -9,6 +9,7 @@ import v.pref
import v.parser import v.parser
import v.table import v.table
import v.token import v.token
import term
struct Vet { struct Vet {
opt Options opt Options
@ -19,6 +20,7 @@ mut:
struct Options { struct Options {
is_verbose bool is_verbose bool
use_color bool
} }
fn (vet &Vet) vprintln(s string) { fn (vet &Vet) vprintln(s string) {
@ -38,9 +40,23 @@ const is_verbose = '-verbose' in vet_options || '-v' in vet_options
const show_warnings = '-hide-warnings' !in vet_options const show_warnings = '-hide-warnings' !in vet_options
const use_color = should_use_color()
fn should_use_color() bool {
mut color := term.can_show_color_on_stderr()
if '-nocolor' in vet_options {
color = false
}
if '-color' in vet_options {
color = true
}
return color
}
fn main() { fn main() {
opt := Options{ mut opt := Options{
is_verbose: is_verbose is_verbose: is_verbose
use_color: use_color
} }
mut vet := Vet{ mut vet := Vet{
opt: opt opt: opt
@ -97,11 +113,11 @@ fn main() {
errors_vfmt := vet.errors.filter(it.kind == .error && it.fix == .vfmt) errors_vfmt := vet.errors.filter(it.kind == .error && it.fix == .vfmt)
if show_warnings { if show_warnings {
for err in warnings { for err in warnings {
eprintln('$err.file_path:$err.pos.line_nr: warning: $err.message') eprintln(e2string(err))
} }
} }
for err in errors { for err in errors {
eprintln('$err.file_path:$err.pos.line_nr: error: $err.message') eprintln(e2string(err))
} }
if errors_vfmt.len > 0 { if errors_vfmt.len > 0 {
eprintln('NB: You can run `v fmt -w file.v` to fix these automatically') eprintln('NB: You can run `v fmt -w file.v` to fix these automatically')
@ -111,6 +127,20 @@ fn main() {
} }
} }
fn e2string(err vet.Error) string {
mut kind := '$err.kind:'
mut location := '$err.file_path:$err.pos.line_nr:'
if use_color {
kind = match err.kind {
.warning { term.magenta(kind) }
.error { term.red(kind) }
}
kind = term.bold(kind)
location = term.bold(location)
}
return '$location $kind $err.message'
}
fn (mut v Vet) error(msg string, line int, fix vet.FixKind) { fn (mut v Vet) error(msg string, line int, fix vet.FixKind) {
pos := token.Position{ pos := token.Position{
line_nr: line + 1 line_nr: line + 1

View File

@ -1,6 +1,7 @@
module gg module gg
#include "@VROOT/vlib/gg/gg_darwin.m" #include "@VROOT/vlib/gg/gg_darwin.m"
fn C.gg_get_screen_size() Size fn C.gg_get_screen_size() Size
fn C.darwin_draw_string(x int, y int, s string, cfg voidptr) fn C.darwin_draw_string(x int, y int, s string, cfg voidptr)

View File

@ -28,7 +28,9 @@ pub fn (x Vec4) str() string {
// create a Vec4 function passing x,y,z as parameteres. w is set to 1 // create a Vec4 function passing x,y,z as parameteres. w is set to 1
pub fn vec3(x f32, y f32, z f32) Vec4 { pub fn vec3(x f32, y f32, z f32) Vec4 {
return m4.Vec4{e:[x, y, z, 1]!} return Vec4{
e: [x, y, z, 1]!
}
} }
// Remove all the raw zeros // Remove all the raw zeros
@ -47,12 +49,14 @@ pub fn (a Vec4) clean() Vec4 {
// Set all elements to value // Set all elements to value
pub fn (mut x Vec4) copy(value f32) { pub fn (mut x Vec4) copy(value f32) {
x.e = [ value, value, value, value, ]! x.e = [value, value, value, value]!
} }
// Scale the vector using a scalar // Scale the vector using a scalar
pub fn (x Vec4) mul_scalar(value f32) Vec4 { pub fn (x Vec4) mul_scalar(value f32) Vec4 {
return Vec4{ e: [ x.e[0] * value, x.e[1] * value, x.e[2] * value, x.e[3] * value, ]! } return Vec4{
e: [x.e[0] * value, x.e[1] * value, x.e[2] * value, x.e[3] * value]!
}
} }
// Reciprocal of the vector // Reciprocal of the vector

View File

@ -261,7 +261,9 @@ pub fn system_font_path() string {
mut fonts := ['Ubuntu-R.ttf', 'Arial.ttf', 'LiberationSans-Regular.ttf', 'NotoSans-Regular.ttf', mut fonts := ['Ubuntu-R.ttf', 'Arial.ttf', 'LiberationSans-Regular.ttf', 'NotoSans-Regular.ttf',
'FreeSans.ttf', 'DejaVuSans.ttf'] 'FreeSans.ttf', 'DejaVuSans.ttf']
$if macos { $if macos {
fonts = ['/System/Library/Fonts/SFNS.ttf', '/System/Library/Fonts/SFNSText.ttf', '/Library/Fonts/Arial.ttf'] fonts = ['/System/Library/Fonts/SFNS.ttf', '/System/Library/Fonts/SFNSText.ttf',
'/Library/Fonts/Arial.ttf',
]
for font in fonts { for font in fonts {
if os.is_file(font) { if os.is_file(font) {
return font return font
@ -269,8 +271,10 @@ pub fn system_font_path() string {
} }
} }
$if android { $if android {
xml_files := ['/system/etc/system_fonts.xml', '/system/etc/fonts.xml', '/etc/system_fonts.xml', xml_files := ['/system/etc/system_fonts.xml', '/system/etc/fonts.xml',
'/etc/fonts.xml', '/data/fonts/fonts.xml', '/etc/fallback_fonts.xml'] '/etc/system_fonts.xml', '/etc/fonts.xml', '/data/fonts/fonts.xml',
'/etc/fallback_fonts.xml',
]
font_locations := ['/system/fonts', '/data/fonts'] font_locations := ['/system/fonts', '/data/fonts']
for xml_file in xml_files { for xml_file in xml_files {
if os.is_file(xml_file) && os.is_readable(xml_file) { if os.is_file(xml_file) && os.is_readable(xml_file) {

View File

@ -25,7 +25,7 @@ const (
// ReadAllConfig allows options to be passed for the behaviour // ReadAllConfig allows options to be passed for the behaviour
// of read_all // of read_all
pub struct ReadAllConfig { pub struct ReadAllConfig {
reader Reader reader Reader
read_to_end_of_stream bool read_to_end_of_stream bool
} }
@ -35,18 +35,16 @@ pub fn read_all(config ReadAllConfig) ?[]byte {
r := config.reader r := config.reader
read_till_eof := config.read_to_end_of_stream read_till_eof := config.read_to_end_of_stream
mut b := []byte{len: read_all_len} mut b := []byte{len: io.read_all_len}
mut read := 0 mut read := 0
for { for {
new_read := r.read(mut b[read..]) or { new_read := r.read(mut b[read..]) or { break }
break
}
read += new_read read += new_read
if !read_till_eof && read == 0 { if !read_till_eof && read == 0 {
break break
} }
if b.len == read { if b.len == read {
unsafe { b.grow_len(read_all_grow_len) } unsafe { b.grow_len(io.read_all_grow_len) }
} }
} }
return b[..read] return b[..read]
@ -55,18 +53,16 @@ pub fn read_all(config ReadAllConfig) ?[]byte {
// read_any reads any available bytes from a reader // read_any reads any available bytes from a reader
// (until the reader returns a read of 0 length) // (until the reader returns a read of 0 length)
pub fn read_any(r Reader) ?[]byte { pub fn read_any(r Reader) ?[]byte {
mut b := []byte{len: read_all_len} mut b := []byte{len: io.read_all_len}
mut read := 0 mut read := 0
for { for {
new_read := r.read(mut b[read..]) or { new_read := r.read(mut b[read..]) or { break }
break
}
read += new_read read += new_read
if new_read == 0 { if new_read == 0 {
break break
} }
if b.len == read { if b.len == read {
unsafe { b.grow_len(read_all_grow_len) } unsafe { b.grow_len(io.read_all_grow_len) }
} }
} }
return b[..read] return b[..read]

View File

@ -4,7 +4,7 @@ struct Buf {
pub: pub:
bytes []byte bytes []byte
mut: mut:
i int i int
} }
fn (mut b Buf) read(mut buf []byte) ?int { fn (mut b Buf) read(mut buf []byte) ?int {
@ -39,7 +39,7 @@ fn test_read_all_huge() {
} }
struct StringReader { struct StringReader {
text string text string
mut: mut:
place int place int
} }
@ -58,17 +58,15 @@ const (
) )
fn test_stringreader() { fn test_stringreader() {
text := '12345\n'.repeat(newline_count) text := '12345\n'.repeat(io.newline_count)
mut s := StringReader{ mut s := StringReader{
text: text text: text
} }
mut r := new_buffered_reader({ mut r := new_buffered_reader(reader: make_reader(s))
reader: make_reader(s)
})
for i := 0; true; i++ { for i := 0; true; i++ {
if _ := r.read_line() { if _ := r.read_line() {
} else { } else {
assert i == newline_count assert i == io.newline_count
break break
} }
} }
@ -85,24 +83,22 @@ fn test_stringreader() {
} }
fn test_stringreader2() { fn test_stringreader2() {
text := '12345\r\n'.repeat(newline_count) text := '12345\r\n'.repeat(io.newline_count)
mut s := StringReader{ mut s := StringReader{
text: text text: text
} }
mut r := new_buffered_reader({ mut r := new_buffered_reader(reader: make_reader(s))
reader: make_reader(s)
})
for i := 0; true; i++ { for i := 0; true; i++ {
if _ := r.read_line() { if _ := r.read_line() {
} else { } else {
assert i == newline_count assert i == io.newline_count
break break
} }
} }
if _ := r.read_line() { if _ := r.read_line() {
assert false assert false
} }
leftover := read_all(reader: io.make_reader(r)) or { leftover := read_all(reader: make_reader(r)) or {
assert false assert false
panic('bad') panic('bad')
} }
@ -116,9 +112,7 @@ fn test_leftover() {
mut s := StringReader{ mut s := StringReader{
text: text text: text
} }
mut r := new_buffered_reader({ mut r := new_buffered_reader(reader: make_reader(s))
reader: make_reader(s)
})
_ := r.read_line() or { _ := r.read_line() or {
assert false assert false
panic('bad') panic('bad')

View File

@ -6,8 +6,10 @@ module runtime
//$if linux { //$if linux {
fn C.sysconf(name int) i64 fn C.sysconf(name int) i64
//} //}
//$if windows { //$if windows {
fn C.GetCurrentProcessorNumber() u32 fn C.GetCurrentProcessorNumber() u32
//} //}

View File

@ -22,24 +22,32 @@ pub fn nr_jobs() int {
// is_32bit returns true if the current executable is running on a 32 bit system. // is_32bit returns true if the current executable is running on a 32 bit system.
pub fn is_32bit() bool { pub fn is_32bit() bool {
$if x32 { return true } $if x32 {
return true
}
return false return false
} }
// is_64bit returns true if the current executable is running on a 64 bit system. // is_64bit returns true if the current executable is running on a 64 bit system.
pub fn is_64bit() bool { pub fn is_64bit() bool {
$if x64 { return true } $if x64 {
return true
}
return false return false
} }
// is_little_endian returns true if the current executable is running on a little-endian system. // is_little_endian returns true if the current executable is running on a little-endian system.
pub fn is_little_endian() bool { pub fn is_little_endian() bool {
$if little_endian { return true } $if little_endian {
return true
}
return false return false
} }
// is_big_endian returns true if the current executable is running on a big-endian system. // is_big_endian returns true if the current executable is running on a big-endian system.
pub fn is_big_endian() bool { pub fn is_big_endian() bool {
$if big_endian { return true } $if big_endian {
return true
}
return false return false
} }

View File

@ -10,30 +10,30 @@ fn test_nr_jobs() {
assert nr_jobs > 0 assert nr_jobs > 0
} }
fn test_is_32bit(){ fn test_is_32bit() {
x := runtime.is_32bit().str() x := runtime.is_32bit().str()
assert x == 'true' || x == 'false' assert x == 'true' || x == 'false'
} }
fn test_is_64bit(){ fn test_is_64bit() {
x := runtime.is_64bit().str() x := runtime.is_64bit().str()
assert x == 'true' || x == 'false' assert x == 'true' || x == 'false'
} }
fn test_is_little_endian(){ fn test_is_little_endian() {
x := runtime.is_little_endian().str() x := runtime.is_little_endian().str()
assert x == 'true' || x == 'false' assert x == 'true' || x == 'false'
} }
fn test_is_big_endian(){ fn test_is_big_endian() {
x := runtime.is_big_endian().str() x := runtime.is_big_endian().str()
assert x == 'true' || x == 'false' assert x == 'true' || x == 'false'
} }
fn test_is_big_endian_different_than_is_little_endian(){ fn test_is_big_endian_different_than_is_little_endian() {
assert runtime.is_big_endian() != runtime.is_little_endian() assert runtime.is_big_endian() != runtime.is_little_endian()
} }
fn test_is_32bit_different_than_is_64bit(){ fn test_is_32bit_different_than_is_64bit() {
assert runtime.is_32bit() != runtime.is_64bit() assert runtime.is_32bit() != runtime.is_64bit()
} }

View File

@ -4,8 +4,9 @@ import os
[typedef] [typedef]
struct C.SYSTEM_INFO { struct C.SYSTEM_INFO {
dwNumberOfProcessors u32 dwNumberOfProcessors u32
} }
fn C.GetSystemInfo(&C.SYSTEM_INFO) fn C.GetSystemInfo(&C.SYSTEM_INFO)
// nr_cpus returns the number of virtual CPU cores found on the system. // nr_cpus returns the number of virtual CPU cores found on the system.

View File

@ -556,3 +556,25 @@ pub fn should_bundle_module(mod string) bool {
return mod in util.bundle_modules return mod in util.bundle_modules
|| (mod.contains('.') && mod.all_before('.') in util.bundle_modules) || (mod.contains('.') && mod.all_before('.') in util.bundle_modules)
} }
// find_all_v_files - given a list of files/folders, finds all .v/.vsh files
// if some of the files/folders on the list does not exist, or a file is not
// a .v or .vsh file, returns an error instead.
pub fn find_all_v_files(roots []string) ?[]string {
mut files := []string{}
for file in roots {
if os.is_dir(file) {
files << os.walk_ext(file, '.v')
files << os.walk_ext(file, '.vsh')
continue
}
if !file.ends_with('.v') && !file.ends_with('.vv') && !file.ends_with('.vsh') {
return error('v fmt can only be used on .v files.\nOffending file: "$file"')
}
if !os.exists(file) {
return error('"$file" does not exist')
}
files << file
}
return files
}