1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00
v/cmd/tools/vwhere/finder_utils.v

206 lines
4.2 KiB
V
Executable File

module main
import os
import term
import regex
import v.pref
import os.cmdline
// Symbol type to search
enum Symbol {
@fn
@struct
@interface
@enum
@const
var
regexp
}
// Visibility of the symbols to search
enum Visibility {
all
@pub
pri
}
// Mutability of the symbols to search
enum Mutability {
any
yes
not
}
const (
args = os.args[2..]
verbose = '-v' in cmdline.only_options(args)
header = '-h' in cmdline.only_options(args)
format = '-f' in cmdline.only_options(args)
symbols = {
'fn': Symbol.@fn
'struct': .@struct
'interface': .@interface
'enum': .@enum
'const': .@const
'var': .var
'regexp': .regexp
}
visibilities = {
'all': Visibility.all
'pub': .@pub
'pri': .pri
}
mutabilities = {
'any': Mutability.any
'yes': .yes
'not': .not
}
vexe = pref.vexe_path()
vroot = os.dir(vexe)
vmod_dir = os.vmodules_dir()
vmod_paths = os.vmodules_paths()[1..]
current_dir = os.abs_path('.')
color_out = term.can_show_color_on_stdout()
)
fn (mut cfg Symbol) set_from_str(str_in string) {
if str_in !in symbols {
invalid_option(cfg, str_in)
}
cfg = symbols[str_in]
}
fn (mut cfg Visibility) set_from_str(str_in string) {
if str_in !in visibilities {
invalid_option(cfg, str_in)
}
cfg = visibilities[str_in]
}
fn (mut cfg Mutability) set_from_str(str_in string) {
if str_in !in mutabilities {
invalid_option(cfg, str_in)
}
cfg = mutabilities[str_in]
}
type ParamOption = Mutability | Symbol | Visibility
// General helpers
fn invalid_option(invalid ParamOption, arg string) {
match invalid.type_name() {
'Symbol' {
msg := 'First arg (symbol type) must be one of the following:'
make_and_print_error(msg, symbols.keys(), arg)
}
'Visibility' {
msg := '"-vis" (visibility) must be one of the following:'
make_and_print_error(msg, visibilities.keys(), arg)
}
'Mutability' {
msg := '"-mut" (mutability) must be one of the following:'
make_and_print_error(msg, mutabilities.keys(), arg)
}
else {
exit(1)
}
}
}
fn valid_args_quantity_or_show_help() {
if true in [
args.len < 1,
'-help' in os.args,
'--help' in os.args,
os.args[1..] == ['where', 'help'],
] {
os.system('${os.quoted_path(vexe)} help where')
exit(0)
}
}
fn make_and_print_error(msg string, opts []string, arg string) {
eprintln('\n' + maybe_color(term.bright_yellow, msg))
if opts.len > 0 {
eprint(opts.map(maybe_color(term.bright_green, it)).join(' | '))
}
eprintln(' ...can not be ${maybe_color(term.bright_red, arg)}')
exit(1)
}
fn maybe_color(term_color fn (string) string, str string) string {
if color_out {
return term_color(str)
} else {
return str
}
}
fn collect_v_files(path string, recursive bool) ?[]string {
if path.len == 0 {
return error('path cannot be empty')
}
if !os.is_dir(path) {
return error('path does not exist or is not a directory')
}
mut all_files := []string{}
mut entries := os.ls(path)?
mut local_path_separator := os.path_separator
if path.ends_with(os.path_separator) {
local_path_separator = ''
}
for entry in entries {
file := path + local_path_separator + entry
if os.is_dir(file) && !os.is_link(file) && recursive {
all_files << collect_v_files(file, recursive)?
} else if os.exists(file) && (file.ends_with('.v') || file.ends_with('.vsh')) {
all_files << file
}
}
return all_files
}
fn search_within_file(file string, query string, is_const bool, v Visibility, m Mutability) (int, string) {
mut re := regex.regex_opt(query) or { panic(err) }
lines := os.read_lines(file) or { panic(err) }
mut const_found := if is_const { false } else { true }
mut n_line := 1
for line in lines {
if line.starts_with('const') {
const_found = true
}
if re.matches_string(line) && const_found {
words := line.split(' ').map(it.trim('\t'))
match v {
.all {}
.@pub {
if 'pub' !in words {
continue
}
}
.pri {
if 'pub' in words {
continue
}
}
}
match m {
.any {}
.yes {
if 'mut' !in words {
continue
}
}
.not {
if 'mut' in words {
continue
}
}
}
return n_line, line.replace(' {', '')
}
n_line++
}
return 0, ''
}