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

v: forbid function parameter names, shadowing imported module names (#17210)

This commit is contained in:
ChAoS_UnItY 2023-02-09 02:37:04 +08:00 committed by GitHub
parent c16549b6fd
commit 404a9aa442
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 381 additions and 230 deletions

View File

@ -47,17 +47,6 @@ jobs:
../v -prod . ../v -prod .
cd .. cd ..
- name: Build VEX
run: |
echo "Install Vex"
v install nedpals.vex
echo "Compile all of the Vex examples"
v should-compile-all ~/.vmodules/nedpals/vex/examples
echo "Compile the simple Vex example with -skip-unused"
v -skip-unused ~/.vmodules/nedpals/vex/examples/simple_example.v
echo "Run Vex Tests"
v test ~/.vmodules/nedpals/vex
- name: Build vlang/pdf - name: Build vlang/pdf
run: | run: |
v install pdf v install pdf
@ -172,3 +161,15 @@ jobs:
v install pcre v install pcre
echo "Execute Tests" echo "Execute Tests"
cd /tmp/adventofcode && v run verify.v cd /tmp/adventofcode && v run verify.v
# - name: Build VEX
# run: |
# echo "Install Vex"
# v install nedpals.vex
# echo "Compile all of the Vex examples"
# v should-compile-all ~/.vmodules/nedpals/vex/examples
# echo "Compile the simple Vex example with -skip-unused"
# v -skip-unused ~/.vmodules/nedpals/vex/examples/simple_example.v
# echo "Run Vex Tests"
# v test ~/.vmodules/nedpals/vex

View File

@ -19,10 +19,10 @@ fn main() {
fn process_files(files []string) ! { fn process_files(files []string) ! {
mut table := ast.new_table() mut table := ast.new_table()
mut pref := pref.new_preferences() mut pref_ := pref.new_preferences()
pref.is_fmt = true pref_.is_fmt = true
pref.skip_warnings = true pref_.skip_warnings = true
pref.output_mode = .silent pref_.output_mode = .silent
mut sw := time.new_stopwatch() mut sw := time.new_stopwatch()
mut total_us := i64(0) mut total_us := i64(0)
mut total_bytes := i64(0) mut total_bytes := i64(0)
@ -35,7 +35,7 @@ fn process_files(files []string) ! {
continue continue
} }
// do not measure the scanning, but only the parsing: // do not measure the scanning, but only the parsing:
mut p := new_parser(f, .skip_comments, table, pref) mut p := new_parser(f, .skip_comments, table, pref_)
/// ///
sw.restart() sw.restart()
_ := p.parse() _ := p.parse()
@ -49,12 +49,12 @@ fn process_files(files []string) ! {
println('${total_us:10}us ${total_tokens:10} ${total_bytes:10} ${(f64(total_tokens) / total_bytes):7.3} | speed: ${(f64(total_bytes) / total_us):2.5f} MB/s') println('${total_us:10}us ${total_tokens:10} ${total_bytes:10} ${(f64(total_tokens) / total_bytes):7.3} | speed: ${(f64(total_bytes) / total_us):2.5f} MB/s')
} }
fn new_parser(path string, comments_mode scanner.CommentsMode, table &ast.Table, pref &pref.Preferences) &parser.Parser { fn new_parser(path string, comments_mode scanner.CommentsMode, table &ast.Table, pref_ &pref.Preferences) &parser.Parser {
mut p := &parser.Parser{ mut p := &parser.Parser{
scanner: scanner.new_scanner_file(path, comments_mode, pref) or { panic(err) } scanner: scanner.new_scanner_file(path, comments_mode, pref_) or { panic(err) }
comments_mode: comments_mode comments_mode: comments_mode
table: table table: table
pref: pref pref: pref_
scope: &ast.Scope{ scope: &ast.Scope{
start_pos: 0 start_pos: 0
parent: table.global_scope parent: table.global_scope

View File

@ -15,10 +15,10 @@ fn main() {
} }
fn process_files(files []string) ! { fn process_files(files []string) ! {
mut pref := pref.new_preferences() mut pref_ := pref.new_preferences()
pref.is_fmt = true pref_.is_fmt = true
pref.skip_warnings = true pref_.skip_warnings = true
pref.output_mode = .silent pref_.output_mode = .silent
mut sw := time.new_stopwatch() mut sw := time.new_stopwatch()
mut total_us := i64(0) mut total_us := i64(0)
mut total_bytes := i64(0) mut total_bytes := i64(0)
@ -31,7 +31,7 @@ fn process_files(files []string) ! {
continue continue
} }
sw.restart() sw.restart()
s := scanner.new_scanner_file(f, .skip_comments, pref)! s := scanner.new_scanner_file(f, .skip_comments, pref_)!
f_us := sw.elapsed().microseconds() f_us := sw.elapsed().microseconds()
total_us += f_us total_us += f_us
total_bytes += s.text.len total_bytes += s.text.len

View File

@ -108,7 +108,7 @@ fn add_item_to_array(obj &C.cJSON, item &C.cJSON) {
C.cJSON_AddItemToArray(obj, item) C.cJSON_AddItemToArray(obj, item)
} }
fn json_print(json &C.cJSON) string { fn json_print(json_ &C.cJSON) string {
s := C.cJSON_Print(json) s := C.cJSON_Print(json_)
return unsafe { tos3(s) } return unsafe { tos3(s) }
} }

View File

@ -120,15 +120,15 @@ fn json(file string) string {
// use as permissive preferences as possible, so that `v ast` // use as permissive preferences as possible, so that `v ast`
// can print the AST of arbitrary V files, even .vsh or ones // can print the AST of arbitrary V files, even .vsh or ones
// that require globals: // that require globals:
mut pref := &pref.Preferences{} mut pref_ := &pref.Preferences{}
pref.fill_with_defaults() pref_.fill_with_defaults()
pref.enable_globals = true pref_.enable_globals = true
pref.is_fmt = true pref_.is_fmt = true
// //
mut t := Tree{ mut t := Tree{
root: new_object() root: new_object()
table: ast.new_table() table: ast.new_table()
pref: pref pref: pref_
} }
// parse file with comment // parse file with comment
ast_file := parser.parse_file(file, t.table, .parse_comments, t.pref) ast_file := parser.parse_file(file, t.table, .parse_comments, t.pref)
@ -359,9 +359,9 @@ fn (t Tree) imports(nodes []ast.Import) &Node {
return import_array return import_array
} }
fn (t Tree) errors(errors []errors.Error) &Node { fn (t Tree) errors(errors_ []errors.Error) &Node {
mut errs := new_array() mut errs := new_array()
for e in errors { for e in errors_ {
obj := new_object() obj := new_object()
obj.add_terse('message', t.string_node(e.message)) obj.add_terse('message', t.string_node(e.message))
obj.add_terse('file_path', t.string_node(e.file_path)) obj.add_terse('file_path', t.string_node(e.file_path))

View File

@ -232,9 +232,9 @@ fn (mut foptions FormatOptions) post_process_file(file string, formatted_file_pa
} }
diff_cmd := foptions.find_diff_cmd() diff_cmd := foptions.find_diff_cmd()
foptions.vlog('Using diff command: ${diff_cmd}') foptions.vlog('Using diff command: ${diff_cmd}')
diff := diff.color_compare_files(diff_cmd, file, formatted_file_path) diff_ := diff.color_compare_files(diff_cmd, file, formatted_file_path)
if diff.len > 0 { if diff_.len > 0 {
println(diff) println(diff_)
} }
return return
} }

View File

@ -301,13 +301,13 @@ fn vpm_install_from_vcs(module_names []string, vcs_key string) {
vmod_path := os.join_path(final_module_path, 'v.mod') vmod_path := os.join_path(final_module_path, 'v.mod')
if os.exists(vmod_path) { if os.exists(vmod_path) {
data := os.read_file(vmod_path) or { return } data := os.read_file(vmod_path) or { return }
vmod := parse_vmod(data) or { vmod_ := parse_vmod(data) or {
eprintln(err) eprintln(err)
return return
} }
minfo := mod_name_info(vmod.name) minfo := mod_name_info(vmod_.name)
if final_module_path != minfo.final_module_path { if final_module_path != minfo.final_module_path {
println('Relocating module from "${name}" to "${vmod.name}" ( "${minfo.final_module_path}" ) ...') println('Relocating module from "${name}" to "${vmod_.name}" ( "${minfo.final_module_path}" ) ...')
if os.exists(minfo.final_module_path) { if os.exists(minfo.final_module_path) {
eprintln('Warning module "${minfo.final_module_path}" already exsits!') eprintln('Warning module "${minfo.final_module_path}" already exsits!')
eprintln('Removing module "${minfo.final_module_path}" ...') eprintln('Removing module "${minfo.final_module_path}" ...')
@ -330,10 +330,10 @@ fn vpm_install_from_vcs(module_names []string, vcs_key string) {
} }
continue continue
} }
println('Module "${name}" relocated to "${vmod.name}" successfully.') println('Module "${name}" relocated to "${vmod_.name}" successfully.')
final_module_path = minfo.final_module_path final_module_path = minfo.final_module_path
} }
name = vmod.name name = vmod_.name
} }
resolve_dependencies(name, final_module_path, module_names) resolve_dependencies(name, final_module_path, module_names)
} }
@ -646,13 +646,13 @@ fn resolve_dependencies(name string, module_path string, module_names []string)
return return
} }
data := os.read_file(vmod_path) or { return } data := os.read_file(vmod_path) or { return }
vmod := parse_vmod(data) or { vmod_ := parse_vmod(data) or {
eprintln(err) eprintln(err)
return return
} }
mut deps := []string{} mut deps := []string{}
// filter out dependencies that were already specified by the user // filter out dependencies that were already specified by the user
for d in vmod.deps { for d in vmod_.deps {
if d !in module_names { if d !in module_names {
deps << d deps << d
} }
@ -666,11 +666,11 @@ fn resolve_dependencies(name string, module_path string, module_names []string)
fn parse_vmod(data string) !Vmod { fn parse_vmod(data string) !Vmod {
manifest := vmod.decode(data) or { return error('Parsing v.mod file failed, ${err}') } manifest := vmod.decode(data) or { return error('Parsing v.mod file failed, ${err}') }
mut vmod := Vmod{} mut vmod_ := Vmod{}
vmod.name = manifest.name vmod_.name = manifest.name
vmod.version = manifest.version vmod_.version = manifest.version
vmod.deps = manifest.dependencies vmod_.deps = manifest.dependencies
return vmod return vmod_
} }
fn get_working_server_url() string { fn get_working_server_url() string {

View File

@ -13,13 +13,13 @@ fn main() {
fp.description('\nScan .v source files, and print the V tokens contained in them.') fp.description('\nScan .v source files, and print the V tokens contained in them.')
fp.arguments_description('PATH [PATH]...') fp.arguments_description('PATH [PATH]...')
fp.limit_free_args_to_at_least(1)! fp.limit_free_args_to_at_least(1)!
pref := pref.new_preferences() pref_ := pref.new_preferences()
mut all_paths := fp.remaining_parameters() mut all_paths := fp.remaining_parameters()
for path in all_paths { for path in all_paths {
mut scanner := scanner.new_scanner_file(path, .parse_comments, pref)! mut scanner_ := scanner.new_scanner_file(path, .parse_comments, pref_)!
mut tok := token.Token{} mut tok := token.Token{}
for tok.kind != .eof { for tok.kind != .eof {
tok = scanner.scan() tok = scanner_.scan()
pos := tok.pos() pos := tok.pos()
location := '${path}:${pos.line_nr + 1}:${pos.col + 1}:' location := '${path}:${pos.line_nr + 1}:${pos.col + 1}:'
println('${location:-32} | pos: ${pos.pos:-5} | ${tok.debug()}') println('${location:-32} | pos: ${pos.pos:-5} | ${tok.debug()}')

View File

@ -1,5 +1,5 @@
import db.sqlite import db.sqlite
import db.mysql import db.mysql as sql
import db.pg import db.pg
[table: 'modules'] [table: 'modules']
@ -74,7 +74,7 @@ fn sqlite3_array() {
} }
fn mysql_array() { fn mysql_array() {
mut db := mysql.Connection{ mut db := sql.Connection{
host: 'localhost' host: 'localhost'
port: 3306 port: 3306
username: 'root' username: 'root'
@ -186,7 +186,7 @@ fn sqlite3() {
} }
fn mysql() { fn mysql() {
mut conn := mysql.Connection{ mut conn := sql.Connection{
host: 'localhost' host: 'localhost'
port: 3306 port: 3306
username: 'root' username: 'root'

View File

@ -1,15 +1,15 @@
module deflate module deflate
import compress import compress as compr
// compresses an array of bytes using deflate and returns the compressed bytes in a new array // compresses an array of bytes using deflate and returns the compressed bytes in a new array
// Example: compressed := deflate.compress(b)? // Example: compressed := deflate.compress(b)?
pub fn compress(data []u8) ![]u8 { pub fn compress(data []u8) ![]u8 {
return compress.compress(data, 0) return compr.compress(data, 0)
} }
// decompresses an array of bytes using deflate and returns the decompressed bytes in a new array // decompresses an array of bytes using deflate and returns the decompressed bytes in a new array
// Example: decompressed := deflate.decompress(b)? // Example: decompressed := deflate.decompress(b)?
pub fn decompress(data []u8) ![]u8 { pub fn decompress(data []u8) ![]u8 {
return compress.decompress(data, 0) return compr.decompress(data, 0)
} }

View File

@ -3,13 +3,13 @@
module gzip module gzip
import compress import compress as compr
import hash.crc32 import hash.crc32
// compresses an array of bytes using gzip and returns the compressed bytes in a new array // compresses an array of bytes using gzip and returns the compressed bytes in a new array
// Example: compressed := gzip.compress(b)? // Example: compressed := gzip.compress(b)?
pub fn compress(data []u8) ![]u8 { pub fn compress(data []u8) ![]u8 {
compressed := compress.compress(data, 0)! compressed := compr.compress(data, 0)!
// header // header
mut result := [ mut result := [
u8(0x1f), // magic numbers (1F 8B) u8(0x1f), // magic numbers (1F 8B)
@ -139,7 +139,7 @@ pub fn decompress(data []u8, params DecompressParams) ![]u8 {
gzip_header := validate(data, params)! gzip_header := validate(data, params)!
header_length := gzip_header.length header_length := gzip_header.length
decompressed := compress.decompress(data[header_length..data.len - 8], 0)! decompressed := compr.decompress(data[header_length..data.len - 8], 0)!
length_expected := (u32(data[data.len - 4]) << 24) | (u32(data[data.len - 3]) << 16) | (u32(data[data.len - 2]) << 8) | data[data.len - 1] length_expected := (u32(data[data.len - 4]) << 24) | (u32(data[data.len - 3]) << 16) | (u32(data[data.len - 2]) << 8) | data[data.len - 1]
if params.verify_length && decompressed.len != length_expected { if params.verify_length && decompressed.len != length_expected {
return error('length verification failed, got ${decompressed.len}, expected ${length_expected}') return error('length verification failed, got ${decompressed.len}, expected ${length_expected}')

View File

@ -1,17 +1,17 @@
module zlib module zlib
import compress import compress as compr
// compresses an array of bytes using zlib and returns the compressed bytes in a new array // compresses an array of bytes using zlib and returns the compressed bytes in a new array
// Example: compressed := zlib.compress(b)? // Example: compressed := zlib.compress(b)?
pub fn compress(data []u8) ![]u8 { pub fn compress(data []u8) ![]u8 {
// flags = TDEFL_WRITE_ZLIB_HEADER (0x01000) // flags = TDEFL_WRITE_ZLIB_HEADER (0x01000)
return compress.compress(data, 0x01000) return compr.compress(data, 0x01000)
} }
// decompresses an array of bytes using zlib and returns the decompressed bytes in a new array // decompresses an array of bytes using zlib and returns the decompressed bytes in a new array
// Example: decompressed := zlib.decompress(b)? // Example: decompressed := zlib.decompress(b)?
pub fn decompress(data []u8) ![]u8 { pub fn decompress(data []u8) ![]u8 {
// flags = TINFL_FLAG_PARSE_ZLIB_HEADER (0x1) // flags = TINFL_FLAG_PARSE_ZLIB_HEADER (0x1)
return compress.decompress(data, 0x1) return compr.decompress(data, 0x1)
} }

View File

@ -411,14 +411,14 @@ pub fn (mut rng PRNG) exponential(lambda f64) f64 {
// optional and the entire array is shuffled by default. Leave the end as 0 to // optional and the entire array is shuffled by default. Leave the end as 0 to
// shuffle all elements until the end. // shuffle all elements until the end.
[direct_array_access] [direct_array_access]
pub fn (mut rng PRNG) shuffle[T](mut a []T, config config.ShuffleConfigStruct) ! { pub fn (mut rng PRNG) shuffle[T](mut a []T, config_ config.ShuffleConfigStruct) ! {
config.validate_for(a)! config_.validate_for(a)!
new_end := if config.end == 0 { a.len } else { config.end } new_end := if config_.end == 0 { a.len } else { config_.end }
// We implement the Fisher-Yates shuffle: // We implement the Fisher-Yates shuffle:
// https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm // https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm
for i in config.start .. new_end - 2 { for i in config_.start .. new_end - 2 {
x := rng.int_in_range(i, new_end) or { i } x := rng.int_in_range(i, new_end) or { i }
// swap // swap
a_i := a[i] a_i := a[i]
@ -429,9 +429,9 @@ pub fn (mut rng PRNG) shuffle[T](mut a []T, config config.ShuffleConfigStruct) !
// shuffle_clone returns a random permutation of the elements in `a`. // shuffle_clone returns a random permutation of the elements in `a`.
// The permutation is done on a fresh clone of `a`, so `a` remains unchanged. // The permutation is done on a fresh clone of `a`, so `a` remains unchanged.
pub fn (mut rng PRNG) shuffle_clone[T](a []T, config config.ShuffleConfigStruct) ![]T { pub fn (mut rng PRNG) shuffle_clone[T](a []T, config_ config.ShuffleConfigStruct) ![]T {
mut res := a.clone() mut res := a.clone()
rng.shuffle[T](mut res, config)! rng.shuffle[T](mut res, config_)!
return res return res
} }
@ -475,10 +475,10 @@ __global default_rng &PRNG
// new_default returns a new instance of the default RNG. If the seed is not provided, the current time will be used to seed the instance. // new_default returns a new instance of the default RNG. If the seed is not provided, the current time will be used to seed the instance.
[manualfree] [manualfree]
pub fn new_default(config config.PRNGConfigStruct) &PRNG { pub fn new_default(config_ config.PRNGConfigStruct) &PRNG {
mut rng := &wyrand.WyRandRNG{} mut rng := &wyrand.WyRandRNG{}
rng.seed(config.seed_) rng.seed(config_.seed_)
unsafe { config.seed_.free() } unsafe { config_.seed_.free() }
return &PRNG(rng) return &PRNG(rng)
} }
@ -680,14 +680,14 @@ pub fn ascii(len int) string {
// shuffle randomly permutates the elements in `a`. The range for shuffling is // shuffle randomly permutates the elements in `a`. The range for shuffling is
// optional and the entire array is shuffled by default. Leave the end as 0 to // optional and the entire array is shuffled by default. Leave the end as 0 to
// shuffle all elements until the end. // shuffle all elements until the end.
pub fn shuffle[T](mut a []T, config config.ShuffleConfigStruct) ! { pub fn shuffle[T](mut a []T, config_ config.ShuffleConfigStruct) ! {
default_rng.shuffle[T](mut a, config)! default_rng.shuffle[T](mut a, config_)!
} }
// shuffle_clone returns a random permutation of the elements in `a`. // shuffle_clone returns a random permutation of the elements in `a`.
// The permutation is done on a fresh clone of `a`, so `a` remains unchanged. // The permutation is done on a fresh clone of `a`, so `a` remains unchanged.
pub fn shuffle_clone[T](a []T, config config.ShuffleConfigStruct) ![]T { pub fn shuffle_clone[T](a []T, config_ config.ShuffleConfigStruct) ![]T {
return default_rng.shuffle_clone[T](a, config) return default_rng.shuffle_clone[T](a, config_)
} }
// choose samples k elements from the array without replacement. // choose samples k elements from the array without replacement.
@ -716,13 +716,13 @@ pub fn bernoulli(p f64) !bool {
// normal returns a normally distributed pseudorandom f64 in range `[0, 1)`. // normal returns a normally distributed pseudorandom f64 in range `[0, 1)`.
// NOTE: Use normal_pair() instead if you're generating a lot of normal variates. // NOTE: Use normal_pair() instead if you're generating a lot of normal variates.
pub fn normal(conf config.NormalConfigStruct) !f64 { pub fn normal(config_ config.NormalConfigStruct) !f64 {
return default_rng.normal(conf) return default_rng.normal(config_)
} }
// normal_pair returns a pair of normally distributed pseudorandom f64 in range `[0, 1)`. // normal_pair returns a pair of normally distributed pseudorandom f64 in range `[0, 1)`.
pub fn normal_pair(conf config.NormalConfigStruct) !(f64, f64) { pub fn normal_pair(config_ config.NormalConfigStruct) !(f64, f64) {
return default_rng.normal_pair(conf) return default_rng.normal_pair(config_)
} }
// binomial returns the number of successful trials out of n when the // binomial returns the number of successful trials out of n when the

View File

@ -29,9 +29,9 @@ const (
u64_iter_count = calculate_iterations_for(64) u64_iter_count = calculate_iterations_for(64)
) )
fn calculate_iterations_for(bits int) int { fn calculate_iterations_for(bits_ int) int {
base := bits / sys.rand_bitsize base := bits_ / sys.rand_bitsize
extra := if bits % sys.rand_bitsize == 0 { 0 } else { 1 } extra := if bits_ % sys.rand_bitsize == 0 { 0 } else { 1 }
return base + extra return base + extra
} }

View File

@ -160,15 +160,15 @@ fn (mut p Parser) peek(n int) !token.Token {
if n <= p.tokens.len { if n <= p.tokens.len {
return p.tokens[n - 1] return p.tokens[n - 1]
} else { } else {
mut token := token.Token{} mut token_ := token.Token{}
mut count := n - p.tokens.len mut count := n - p.tokens.len
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'buffering ${count} tokens...') util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'buffering ${count} tokens...')
for token.kind != .eof && count != 0 { for token_.kind != .eof && count != 0 {
token = p.scanner.scan()! token_ = p.scanner.scan()!
p.tokens << token p.tokens << token_
count-- count--
} }
return token return token_
} }
} }
} }

View File

@ -84,9 +84,9 @@ pub fn parse_file(path string) !Doc {
scanner: scanner.new_scanner(scanner_config)! scanner: scanner.new_scanner(scanner_config)!
} }
mut p := parser.new_parser(parser_config) mut p := parser.new_parser(parser_config)
ast := p.parse()! ast_ := p.parse()!
return Doc{ return Doc{
ast: ast ast: ast_
} }
} }
@ -102,9 +102,9 @@ pub fn parse_text(text string) !Doc {
scanner: scanner.new_scanner(scanner_config)! scanner: scanner.new_scanner(scanner_config)!
} }
mut p := parser.new_parser(parser_config) mut p := parser.new_parser(parser_config)
ast := p.parse()! ast_ := p.parse()!
return Doc{ return Doc{
ast: ast ast: ast_
} }
} }
@ -122,9 +122,9 @@ pub fn parse(toml string) !Doc {
scanner: scanner.new_scanner(scanner_config)! scanner: scanner.new_scanner(scanner_config)!
} }
mut p := parser.new_parser(parser_config) mut p := parser.new_parser(parser_config)
ast := p.parse()! ast_ := p.parse()!
return Doc{ return Doc{
ast: ast ast: ast_
} }
} }

View File

@ -43,7 +43,7 @@ a new preference is created:
```v ```v
import v.pref import v.pref
pref := &pref.Preferences{} pref_ := &pref.Preferences{}
``` ```
and a new scope is created: and a new scope is created:

View File

@ -28,11 +28,11 @@ struct T08 {
} }
fn test_type_size() { fn test_type_size() {
mut pref := pref.new_preferences() mut pref_ := pref.new_preferences()
$if x64 { $if x64 {
pref.m64 = true pref_.m64 = true
} }
mut b := builder.new_builder(pref) mut b := builder.new_builder(pref_)
mut files := b.get_builtin_files() mut files := b.get_builtin_files()
b.set_module_lookup_paths() b.set_module_lookup_paths()
parser.parse_files(files, b.table, b.pref) parser.parse_files(files, b.table, b.pref)

View File

@ -46,22 +46,22 @@ pub mut:
executable_exists bool // if the executable already exists, don't remove new executable after `v run` executable_exists bool // if the executable already exists, don't remove new executable after `v run`
} }
pub fn new_builder(pref &pref.Preferences) Builder { pub fn new_builder(pref_ &pref.Preferences) Builder {
rdir := os.real_path(pref.path) rdir := os.real_path(pref_.path)
compiled_dir := if os.is_dir(rdir) { rdir } else { os.dir(rdir) } compiled_dir := if os.is_dir(rdir) { rdir } else { os.dir(rdir) }
mut table := ast.new_table() mut table := ast.new_table()
table.is_fmt = false table.is_fmt = false
if pref.use_color == .always { if pref_.use_color == .always {
util.emanager.set_support_color(true) util.emanager.set_support_color(true)
} }
if pref.use_color == .never { if pref_.use_color == .never {
util.emanager.set_support_color(false) util.emanager.set_support_color(false)
} }
table.pointer_size = if pref.m64 { 8 } else { 4 } table.pointer_size = if pref_.m64 { 8 } else { 4 }
mut msvc := MsvcResult{} mut msvc := MsvcResult{}
$if windows { $if windows {
msvc = find_msvc(pref.m64) or { msvc = find_msvc(pref_.m64) or {
if pref.ccompiler == 'msvc' { if pref_.ccompiler == 'msvc' {
// verror('cannot find MSVC on this OS') // verror('cannot find MSVC on this OS')
} }
MsvcResult{ MsvcResult{
@ -69,19 +69,19 @@ pub fn new_builder(pref &pref.Preferences) Builder {
} }
} }
} }
util.timing_set_should_print(pref.show_timings || pref.is_verbose) util.timing_set_should_print(pref_.show_timings || pref_.is_verbose)
if pref.show_callgraph || pref.show_depgraph { if pref_.show_callgraph || pref_.show_depgraph {
dotgraph.start_digraph() dotgraph.start_digraph()
} }
mut executable_name := pref.out_name mut executable_name := pref_.out_name
$if windows { $if windows {
executable_name += '.exe' executable_name += '.exe'
} }
return Builder{ return 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_with_table(table, pref) transformer: transformer.new_transformer_with_table(table, pref_)
compiled_dir: compiled_dir compiled_dir: compiled_dir
cached_msvc: msvc cached_msvc: msvc
executable_exists: os.is_file(executable_name) executable_exists: os.is_file(executable_name)

View File

@ -10,10 +10,10 @@ import v.checker
pub type FnBackend = fn (mut b Builder) pub type FnBackend = fn (mut b Builder)
pub fn compile(command string, pref &pref.Preferences, backend_cb FnBackend) { pub fn compile(command string, pref_ &pref.Preferences, backend_cb FnBackend) {
check_if_output_folder_is_writable(pref) check_if_output_folder_is_writable(pref_)
// 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_)
if b.should_rebuild() { if b.should_rebuild() {
b.rebuild(backend_cb) b.rebuild(backend_cb)
} }
@ -23,12 +23,12 @@ pub fn compile(command string, pref &pref.Preferences, backend_cb FnBackend) {
b.run_compiled_executable_and_exit() b.run_compiled_executable_and_exit()
} }
fn check_if_output_folder_is_writable(pref &pref.Preferences) { fn check_if_output_folder_is_writable(pref_ &pref.Preferences) {
odir := os.dir(pref.out_name) odir := os.dir(pref_.out_name)
// When pref.out_name is just the name of an executable, i.e. `./v -o executable main.v` // When pref.out_name is just the name of an executable, i.e. `./v -o executable main.v`
// without a folder component, just use the current folder instead: // without a folder component, just use the current folder instead:
mut output_folder := odir mut output_folder := odir
if odir.len == pref.out_name.len { if odir.len == pref_.out_name.len {
output_folder = os.getwd() output_folder = os.getwd()
} }
os.ensure_folder_is_writable(output_folder) or { os.ensure_folder_is_writable(output_folder) or {

View File

@ -7,11 +7,11 @@ import v.dotgraph
// callgraph.show walks the AST, starting at main() and prints a DOT output describing the calls // callgraph.show walks the AST, starting at main() and prints a DOT output describing the calls
// that function make transitively // that function make transitively
pub fn show(mut table ast.Table, pref &pref.Preferences, ast_files []&ast.File) { pub fn show(mut table ast.Table, pref_ &pref.Preferences, ast_files []&ast.File) {
mut mapper := &Mapper{ mut mapper := &Mapper{
pref: pref pref: pref_
table: table table: table
dg: dotgraph.new('CallGraph', 'CallGraph for ${pref.path}', 'green') dg: dotgraph.new('CallGraph', 'CallGraph for ${pref_.path}', 'green')
} }
// Node14 [shape="box",label="PrivateBase",URL="$classPrivateBase.html"]; // Node14 [shape="box",label="PrivateBase",URL="$classPrivateBase.html"];
// Node15 -> Node9 [dir=back,color="midnightblue",fontsize=10,style="solid"]; // Node15 -> Node9 [dir=back,color="midnightblue",fontsize=10,style="solid"];

View File

@ -312,7 +312,7 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
} }
} }
// Check if variable name is already registered as imported module symbol // Check if variable name is already registered as imported module symbol
if c.file.imports.any(it.mod == left.name) { if c.check_import_sym_conflict(left.name) {
c.error('duplicate of an import symbol `${left.name}`', left.pos) c.error('duplicate of an import symbol `${left.name}`', left.pos)
} }
} }

View File

@ -117,16 +117,16 @@ mut:
goto_labels map[string]ast.GotoLabel // to check for unused goto labels goto_labels map[string]ast.GotoLabel // to check for unused goto labels
} }
pub fn new_checker(table &ast.Table, pref &pref.Preferences) &Checker { pub fn new_checker(table &ast.Table, pref_ &pref.Preferences) &Checker {
mut timers_should_print := false mut timers_should_print := false
$if time_checking ? { $if time_checking ? {
timers_should_print = true timers_should_print = true
} }
return &Checker{ return &Checker{
table: table table: table
pref: pref pref: pref_
timers: util.new_timers(should_print: timers_should_print, label: 'checker') timers: util.new_timers(should_print: timers_should_print, label: 'checker')
match_exhaustive_cutoff_limit: pref.checker_match_exhaustive_cutoff_limit match_exhaustive_cutoff_limit: pref_.checker_match_exhaustive_cutoff_limit
} }
} }
@ -4509,3 +4509,17 @@ fn (mut c Checker) deprecate_old_isreftype_and_sizeof_of_a_guessed_type(is_guess
pos) pos)
} }
} }
fn (c &Checker) check_import_sym_conflict(ident string) bool {
for import_sym in c.file.imports {
// Check if alias exists or not
if !import_sym.alias.is_blank() {
if import_sym.alias == ident {
return true
}
} else if import_sym.mod == ident {
return true
}
}
return false
}

View File

@ -249,6 +249,14 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
} }
} }
} }
// Check if parameter name is already registered as imported module symbol
if c.check_import_sym_conflict(param.name) {
c.error('duplicate of an import symbol `${param.name}`', param.pos)
}
}
// Check if function name is already registered as imported module symbol
if !node.is_method && c.check_import_sym_conflict(node.short_name) {
c.error('duplicate of an import symbol `${node.short_name}`', node.pos)
} }
} }
if node.language == .v && node.name.after_char(`.`) == 'init' && !node.is_method if node.language == .v && node.name.after_char(`.`) == 'init' && !node.is_method

View File

@ -0,0 +1,80 @@
vlib/v/checker/tests/fn_param_import_sym_conflict.vv:1:8: warning: module 'arrays' is imported but never used
1 | import arrays
| ~~~~~~
2 | import maps
3 | import strings as strs
vlib/v/checker/tests/fn_param_import_sym_conflict.vv:2:8: warning: module 'maps' is imported but never used
1 | import arrays
2 | import maps
| ~~~~
3 | import strings as strs
4 |
vlib/v/checker/tests/fn_param_import_sym_conflict.vv:3:8: warning: module 'strs (strings)' is imported but never used
1 | import arrays
2 | import maps
3 | import strings as strs
| ~~~~~~~
4 |
5 | // FnDecl
vlib/v/checker/tests/fn_param_import_sym_conflict.vv:6:6: error: duplicate of an import symbol `arrays`
4 |
5 | // FnDecl
6 | fn x(arrays []int) {
| ~~~~~~
7 | }
8 |
vlib/v/checker/tests/fn_param_import_sym_conflict.vv:9:1: error: duplicate of an import symbol `maps`
7 | }
8 |
9 | fn maps() {
| ~~~~~~~~~
10 | }
11 |
vlib/v/checker/tests/fn_param_import_sym_conflict.vv:12:9: error: duplicate of an import symbol `arrays`
10 | }
11 |
12 | fn maps(arrays []int) {
| ~~~~~~
13 | }
14 |
vlib/v/checker/tests/fn_param_import_sym_conflict.vv:18:1: error: duplicate of an import symbol `strs`
16 | }
17 |
18 | fn strs() {
| ~~~~~~~~~
19 | }
20 |
vlib/v/checker/tests/fn_param_import_sym_conflict.vv:24:5: error: duplicate of an import symbol `arrays`
22 | struct Foo {}
23 |
24 | fn (arrays Foo) x() {
| ~~~~~~
25 | }
26 |
vlib/v/checker/tests/fn_param_import_sym_conflict.vv:27:5: error: duplicate of an import symbol `arrays`
25 | }
26 |
27 | fn (arrays Foo) y(maps []int) {
| ~~~~~~
28 | }
29 |
vlib/v/checker/tests/fn_param_import_sym_conflict.vv:30:16: error: duplicate of an import symbol `arrays`
28 | }
29 |
30 | fn (foo Foo) z(arrays []int) {
| ~~~~~~
31 | }
32 |
vlib/v/checker/tests/fn_param_import_sym_conflict.vv:33:5: error: duplicate of an import symbol `arrays`
31 | }
32 |
33 | fn (arrays Foo) maps() {
| ~~~~~~
34 | }
35 |
vlib/v/checker/tests/fn_param_import_sym_conflict.vv:47:11: error: duplicate of an import symbol `arrays`
45 | // AnonFn
46 | fn y() {
47 | _ := fn (arrays []int) {}
| ~~~~~~
48 | }

View File

@ -0,0 +1,48 @@
import arrays
import maps
import strings as strs
// FnDecl
fn x(arrays []int) {
}
fn maps() {
}
fn maps(arrays []int) {
}
fn strings() {
}
fn strs() {
}
// FnDecl with receiver
struct Foo {}
fn (arrays Foo) x() {
}
fn (arrays Foo) y(maps []int) {
}
fn (foo Foo) z(arrays []int) {
}
fn (arrays Foo) maps() {
}
fn (foo Foo) arrays() {
}
fn (foo Foo) strings() {
}
fn (foo Foo) strs() {
}
// AnonFn
fn y() {
_ := fn (arrays []int) {}
}

View File

@ -147,12 +147,12 @@ pub mut:
pub fn new_vdoc_preferences() &pref.Preferences { pub fn new_vdoc_preferences() &pref.Preferences {
// vdoc should be able to parse as much user code as possible // vdoc should be able to parse as much user code as possible
// so its preferences should be permissive: // so its preferences should be permissive:
mut pref := &pref.Preferences{ mut pref_ := &pref.Preferences{
enable_globals: true enable_globals: true
is_fmt: true is_fmt: true
} }
pref.fill_with_defaults() pref_.fill_with_defaults()
return pref return pref_
} }
// new creates a new instance of a `Doc` struct. // new creates a new instance of a `Doc` struct.

View File

@ -7,10 +7,10 @@ import v.ast
import v.pref import v.pref
import v.util import v.util
pub fn new_eval(table &ast.Table, pref &pref.Preferences) Eval { pub fn new_eval(table &ast.Table, pref_ &pref.Preferences) Eval {
return Eval{ return Eval{
table: table table: table
pref: pref pref: pref_
} }
} }

View File

@ -61,11 +61,11 @@ pub struct FmtOptions {
source_text string source_text string
} }
pub fn fmt(file ast.File, table &ast.Table, pref &pref.Preferences, is_debug bool, options FmtOptions) string { pub fn fmt(file ast.File, table &ast.Table, pref_ &pref.Preferences, is_debug bool, options FmtOptions) string {
mut f := Fmt{ mut f := Fmt{
file: file file: file
table: table table: table
pref: pref pref: pref_
is_debug: is_debug is_debug: is_debug
out: strings.new_builder(1000) out: strings.new_builder(1000)
out_imports: strings.new_builder(200) out_imports: strings.new_builder(200)

View File

@ -254,13 +254,13 @@ struct GlobalConstDef {
is_precomputed bool // can be declared as a const in C: primitive, and a simple definition is_precomputed bool // can be declared as a const in C: primitive, and a simple definition
} }
pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) (string, string, string, []int) { pub fn gen(files []&ast.File, table &ast.Table, pref_ &pref.Preferences) (string, string, string, []int) {
// println('start cgen2') // println('start cgen2')
mut module_built := '' mut module_built := ''
if pref.build_mode == .build_module { if pref_.build_mode == .build_module {
for file in files { for file in files {
if file.path.contains(pref.path) if file.path.contains(pref_.path)
&& file.mod.short_name == pref.path.all_after_last(os.path_separator).trim_right(os.path_separator) { && file.mod.short_name == pref_.path.all_after_last(os.path_separator).trim_right(os.path_separator) {
module_built = file.mod.name module_built = file.mod.name
break break
} }
@ -300,19 +300,19 @@ pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) (string,
json_forward_decls: strings.new_builder(100) json_forward_decls: strings.new_builder(100)
sql_buf: strings.new_builder(100) sql_buf: strings.new_builder(100)
table: table table: table
pref: pref pref: pref_
fn_decl: 0 fn_decl: 0
is_autofree: pref.autofree is_autofree: pref_.autofree
indent: -1 indent: -1
module_built: module_built module_built: module_built
timers_should_print: timers_should_print timers_should_print: timers_should_print
timers: util.new_timers(should_print: timers_should_print, label: 'global_cgen') timers: util.new_timers(should_print: timers_should_print, label: 'global_cgen')
inner_loop: &ast.empty_stmt inner_loop: &ast.empty_stmt
field_data_type: ast.Type(table.find_type_idx('FieldData')) field_data_type: ast.Type(table.find_type_idx('FieldData'))
is_cc_msvc: pref.ccompiler == 'msvc' is_cc_msvc: pref_.ccompiler == 'msvc'
use_segfault_handler: !('no_segfault_handler' in pref.compile_defines use_segfault_handler: !('no_segfault_handler' in pref_.compile_defines
|| pref.os in [.wasm32, .wasm32_emscripten]) || pref_.os in [.wasm32, .wasm32_emscripten])
static_modifier: if pref.parallel_cc { 'static' } else { '' } static_modifier: if pref_.parallel_cc { 'static' } else { '' }
has_reflection: 'v.reflection' in table.modules has_reflection: 'v.reflection' in table.modules
reflection_funcs: strings.new_builder(100) reflection_funcs: strings.new_builder(100)
reflection_others: strings.new_builder(100) reflection_others: strings.new_builder(100)
@ -330,7 +330,7 @@ pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) (string,
*/ */
// anon fn may include assert and thus this needs // anon fn may include assert and thus this needs
// to be included before any test contents are written // to be included before any test contents are written
if pref.is_test { if pref_.is_test {
global_g.write_tests_definitions() global_g.write_tests_definitions()
} }
@ -342,7 +342,7 @@ pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) (string,
util.timing_measure('cgen init') util.timing_measure('cgen init')
global_g.tests_inited = false global_g.tests_inited = false
global_g.file = files.last() global_g.file = files.last()
if !pref.no_parallel { if !pref_.no_parallel {
util.timing_start('cgen parallel processing') util.timing_start('cgen parallel processing')
mut pp := pool.new_pool_processor(callback: cgen_process_one_file_cb) mut pp := pool.new_pool_processor(callback: cgen_process_one_file_cb)
pp.set_shared_context(global_g) // TODO: make global_g shared pp.set_shared_context(global_g) // TODO: make global_g shared

View File

@ -61,9 +61,9 @@ static inline void __sort_ptr(uintptr_t a[], bool b[], int l) {
// Inspired from Chris Wellons's work // Inspired from Chris Wellons's work
// https://nullprogram.com/blog/2017/01/08/ // https://nullprogram.com/blog/2017/01/08/
fn c_closure_helpers(pref &pref.Preferences) string { fn c_closure_helpers(pref_ &pref.Preferences) string {
mut builder := strings.new_builder(2048) mut builder := strings.new_builder(2048)
if pref.os != .windows { if pref_.os != .windows {
builder.writeln('#include <sys/mman.h>') builder.writeln('#include <sys/mman.h>')
} }

View File

@ -45,10 +45,10 @@ pub mut:
nlines int nlines int
} }
pub fn gen(files []&ast.File, table &ast.Table, out_file string, pref &pref.Preferences) (int, int) { pub fn gen(files []&ast.File, table &ast.Table, out_file string, pref_ &pref.Preferences) (int, int) {
mut g := Gen{ mut g := Gen{
table: table table: table
pref: pref pref: pref_
// is_debug: is_debug // is_debug: is_debug
out: strings.new_builder(1000) out: strings.new_builder(1000)
out_imports: strings.new_builder(200) out_imports: strings.new_builder(200)

View File

@ -100,11 +100,11 @@ fn (mut g JsGen) write_tests_definitions() {
g.definitions.writeln('globalThis.g_test_fails = 0;') g.definitions.writeln('globalThis.g_test_fails = 0;')
} }
pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) string { pub fn gen(files []&ast.File, table &ast.Table, pref_ &pref.Preferences) string {
mut g := &JsGen{ mut g := &JsGen{
definitions: strings.new_builder(100) definitions: strings.new_builder(100)
table: table table: table
pref: pref pref: pref_
fn_decl: 0 fn_decl: 0
empty_line: true empty_line: true
doc: 0 doc: 0
@ -115,7 +115,7 @@ pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) string {
} }
g.doc = new_jsdoc(g) g.doc = new_jsdoc(g)
// TODO: Add '[-no]-jsdoc' flag // TODO: Add '[-no]-jsdoc' flag
if pref.is_prod { if g.pref.is_prod {
g.enable_doc = false g.enable_doc = false
g.is_vlines_enabled = false g.is_vlines_enabled = false
} }

View File

@ -223,8 +223,8 @@ fn get_backend(arch pref.Arch) !CodeGen {
return error('unsupported architecture') return error('unsupported architecture')
} }
pub fn gen(files []&ast.File, table &ast.Table, out_name string, pref &pref.Preferences) (int, int) { pub fn gen(files []&ast.File, table &ast.Table, out_name string, pref_ &pref.Preferences) (int, int) {
exe_name := if pref.os == .windows && !out_name.ends_with('.exe') { exe_name := if pref_.os == .windows && !out_name.ends_with('.exe') {
out_name + '.exe' out_name + '.exe'
} else { } else {
out_name out_name
@ -233,16 +233,16 @@ pub fn gen(files []&ast.File, table &ast.Table, out_name string, pref &pref.Pref
table: table table: table
sect_header_name_pos: 0 sect_header_name_pos: 0
out_name: exe_name out_name: exe_name
pref: pref pref: pref_
files: files files: files
// TODO: workaround, needs to support recursive init // TODO: workaround, needs to support recursive init
code_gen: get_backend(pref.arch) or { code_gen: get_backend(pref_.arch) or {
eprintln('No available backend for this configuration. Use `-a arm64` or `-a amd64`.') eprintln('No available backend for this configuration. Use `-a arm64` or `-a amd64`.')
exit(1) exit(1)
} }
labels: 0 labels: 0
structs: []Struct{len: table.type_symbols.len} structs: []Struct{len: table.type_symbols.len}
eval: eval.new_eval(table, pref) eval: eval.new_eval(table, pref_)
} }
g.code_gen.g = g g.code_gen.g = g
g.generate_header() g.generate_header()

View File

@ -7,7 +7,7 @@ import v.util
import v.pref import v.pref
// mark_used walks the AST, starting at main() and marks all used fns transitively // mark_used walks the AST, starting at main() and marks all used fns transitively
pub fn mark_used(mut table ast.Table, pref &pref.Preferences, ast_files []&ast.File) { pub fn mark_used(mut table ast.Table, pref_ &pref.Preferences, ast_files []&ast.File) {
mut all_fns, all_consts, all_globals := all_fn_const_and_global(ast_files) mut all_fns, all_consts, all_globals := all_fn_const_and_global(ast_files)
util.timing_start(@METHOD) util.timing_start(@METHOD)
defer { defer {
@ -126,7 +126,7 @@ pub fn mark_used(mut table ast.Table, pref &pref.Preferences, ast_files []&ast.F
'v.embed_file.find_index_entry_by_path', 'v.embed_file.find_index_entry_by_path',
] ]
if pref.is_bare { if pref_.is_bare {
all_fn_root_names << [ all_fn_root_names << [
'strlen', 'strlen',
'memcmp', 'memcmp',
@ -137,7 +137,7 @@ pub fn mark_used(mut table ast.Table, pref &pref.Preferences, ast_files []&ast.F
] ]
} }
is_noscan_whitelisted := pref.gc_mode in [.boehm_full_opt, .boehm_incr_opt] is_noscan_whitelisted := pref_.gc_mode in [.boehm_full_opt, .boehm_incr_opt]
for k, mut mfn in all_fns { for k, mut mfn in all_fns {
$if trace_skip_unused_all_fns ? { $if trace_skip_unused_all_fns ? {
@ -186,7 +186,7 @@ pub fn mark_used(mut table ast.Table, pref &pref.Preferences, ast_files []&ast.F
all_fn_root_names << k all_fn_root_names << k
continue continue
} }
if pref.is_prof { if pref_.is_prof {
if k.starts_with('time.vpc_now') || k.starts_with('v.profile.') { if k.starts_with('time.vpc_now') || k.starts_with('v.profile.') {
// needed for -profile // needed for -profile
all_fn_root_names << k all_fn_root_names << k
@ -210,7 +210,7 @@ pub fn mark_used(mut table ast.Table, pref &pref.Preferences, ast_files []&ast.F
continue continue
} }
// testing framework: // testing framework:
if pref.is_test { if pref_.is_test {
if k.starts_with('test_') || k.contains('.test_') { if k.starts_with('test_') || k.contains('.test_') {
all_fn_root_names << k all_fn_root_names << k
continue continue
@ -223,7 +223,7 @@ pub fn mark_used(mut table ast.Table, pref &pref.Preferences, ast_files []&ast.F
} }
// public/exported functions can not be skipped, // public/exported functions can not be skipped,
// especially when producing a shared library: // especially when producing a shared library:
if mfn.is_pub && pref.is_shared { if mfn.is_pub && pref_.is_shared {
all_fn_root_names << k all_fn_root_names << k
continue continue
} }
@ -232,19 +232,19 @@ pub fn mark_used(mut table ast.Table, pref &pref.Preferences, ast_files []&ast.F
all_fn_root_names << k all_fn_root_names << k
continue continue
} }
if pref.prealloc && k.starts_with('prealloc_') { if pref_.prealloc && k.starts_with('prealloc_') {
all_fn_root_names << k all_fn_root_names << k
continue continue
} }
} }
// handle assertions and testing framework callbacks: // handle assertions and testing framework callbacks:
if pref.is_debug { if pref_.is_debug {
all_fn_root_names << 'panic_debug' all_fn_root_names << 'panic_debug'
} }
all_fn_root_names << 'panic_option_not_set' all_fn_root_names << 'panic_option_not_set'
all_fn_root_names << 'panic_result_not_set' all_fn_root_names << 'panic_result_not_set'
if pref.is_test { if pref_.is_test {
all_fn_root_names << 'main.cb_assertion_ok' all_fn_root_names << 'main.cb_assertion_ok'
all_fn_root_names << 'main.cb_assertion_failed' all_fn_root_names << 'main.cb_assertion_failed'
if benched_tests_sym := table.find_sym('main.BenchedTests') { if benched_tests_sym := table.find_sym('main.BenchedTests') {
@ -333,7 +333,7 @@ pub fn mark_used(mut table ast.Table, pref &pref.Preferences, ast_files []&ast.F
} }
// handle -live main programs: // handle -live main programs:
if pref.is_livemain { if pref_.is_livemain {
all_fn_root_names << 'v.live.executable.start_reloader' all_fn_root_names << 'v.live.executable.start_reloader'
all_fn_root_names << 'v.live.executable.new_live_reload_info' all_fn_root_names << 'v.live.executable.new_live_reload_info'
} }
@ -344,7 +344,7 @@ pub fn mark_used(mut table ast.Table, pref &pref.Preferences, ast_files []&ast.F
all_fns: all_fns all_fns: all_fns
all_consts: all_consts all_consts: all_consts
all_globals: all_globals all_globals: all_globals
pref: pref pref: pref_
} }
// println( all_fns.keys() ) // println( all_fns.keys() )
walker.mark_markused_fns() // tagged with `[markused]` walker.mark_markused_fns() // tagged with `[markused]`
@ -367,7 +367,7 @@ pub fn mark_used(mut table ast.Table, pref &pref.Preferences, ast_files []&ast.F
|| k.starts_with('map_') { || k.starts_with('map_') {
walker.fn_decl(mut mfn) walker.fn_decl(mut mfn)
} }
if pref.gc_mode in [.boehm_full_opt, .boehm_incr_opt] { if pref_.gc_mode in [.boehm_full_opt, .boehm_incr_opt] {
if k in ['new_map_noscan_key', 'new_map_noscan_value', 'new_map_noscan_key_value', if k in ['new_map_noscan_key', 'new_map_noscan_value', 'new_map_noscan_key_value',
'new_map_init_noscan_key', 'new_map_init_noscan_value', 'new_map_init_noscan_key', 'new_map_init_noscan_value',
'new_map_init_noscan_key_value'] { 'new_map_init_noscan_key_value'] {
@ -397,10 +397,10 @@ pub fn mark_used(mut table ast.Table, pref &pref.Preferences, ast_files []&ast.F
} }
for kcon, con in all_consts { for kcon, con in all_consts {
if pref.is_shared && con.is_pub { if pref_.is_shared && con.is_pub {
walker.mark_const_as_used(kcon) walker.mark_const_as_used(kcon)
} }
if !pref.is_shared && con.is_pub && con.name.starts_with('main.') { if !pref_.is_shared && con.is_pub && con.name.starts_with('main.') {
walker.mark_const_as_used(kcon) walker.mark_const_as_used(kcon)
} }
} }

View File

@ -126,15 +126,15 @@ pub fn parse_stmt(text string, table &ast.Table, scope &ast.Scope) ast.Stmt {
return p.stmt(false) return p.stmt(false)
} }
pub fn parse_comptime(tmpl_path string, text string, table &ast.Table, pref &pref.Preferences, scope &ast.Scope) &ast.File { pub fn parse_comptime(tmpl_path string, text string, table &ast.Table, pref_ &pref.Preferences, scope &ast.Scope) &ast.File {
$if trace_parse_comptime ? { $if trace_parse_comptime ? {
eprintln('> ${@MOD}.${@FN} text: ${text}') eprintln('> ${@MOD}.${@FN} text: ${text}')
} }
mut p := Parser{ mut p := Parser{
file_name: tmpl_path file_name: tmpl_path
scanner: scanner.new_scanner(text, .skip_comments, pref) scanner: scanner.new_scanner(text, .skip_comments, pref_)
table: table table: table
pref: pref pref: pref_
scope: scope scope: scope
errors: []errors.Error{} errors: []errors.Error{}
warnings: []errors.Warning{} warnings: []errors.Warning{}
@ -144,15 +144,15 @@ pub fn parse_comptime(tmpl_path string, text string, table &ast.Table, pref &pre
return res return res
} }
pub fn parse_text(text string, path string, table &ast.Table, comments_mode scanner.CommentsMode, pref &pref.Preferences) &ast.File { pub fn parse_text(text string, path string, table &ast.Table, comments_mode scanner.CommentsMode, pref_ &pref.Preferences) &ast.File {
$if trace_parse_text ? { $if trace_parse_text ? {
eprintln('> ${@MOD}.${@FN} comments_mode: ${comments_mode:-20} | path: ${path:-20} | text: ${text}') eprintln('> ${@MOD}.${@FN} comments_mode: ${comments_mode:-20} | path: ${path:-20} | text: ${text}')
} }
mut p := Parser{ mut p := Parser{
scanner: scanner.new_scanner(text, comments_mode, pref) scanner: scanner.new_scanner(text, comments_mode, pref_)
comments_mode: comments_mode comments_mode: comments_mode
table: table table: table
pref: pref pref: pref_
scope: &ast.Scope{ scope: &ast.Scope{
start_pos: 0 start_pos: 0
parent: table.global_scope parent: table.global_scope
@ -222,7 +222,7 @@ pub fn (mut p Parser) set_path(path string) {
} }
} }
pub fn parse_file(path string, table &ast.Table, comments_mode scanner.CommentsMode, pref &pref.Preferences) &ast.File { pub fn parse_file(path string, table &ast.Table, comments_mode scanner.CommentsMode, pref_ &pref.Preferences) &ast.File {
// Note: when comments_mode == .toplevel_comments, // Note: when comments_mode == .toplevel_comments,
// the parser gives feedback to the scanner about toplevel statements, so that the scanner can skip // the parser gives feedback to the scanner about toplevel statements, so that the scanner can skip
// all the tricky inner comments. This is needed because we do not have a good general solution // all the tricky inner comments. This is needed because we do not have a good general solution
@ -231,10 +231,10 @@ pub fn parse_file(path string, table &ast.Table, comments_mode scanner.CommentsM
eprintln('> ${@MOD}.${@FN} comments_mode: ${comments_mode:-20} | path: ${path}') eprintln('> ${@MOD}.${@FN} comments_mode: ${comments_mode:-20} | path: ${path}')
} }
mut p := Parser{ mut p := Parser{
scanner: scanner.new_scanner_file(path, comments_mode, pref) or { panic(err) } scanner: scanner.new_scanner_file(path, comments_mode, pref_) or { panic(err) }
comments_mode: comments_mode comments_mode: comments_mode
table: table table: table
pref: pref pref: pref_
scope: &ast.Scope{ scope: &ast.Scope{
start_pos: 0 start_pos: 0
parent: table.global_scope parent: table.global_scope
@ -248,7 +248,7 @@ pub fn parse_file(path string, table &ast.Table, comments_mode scanner.CommentsM
return res return res
} }
pub fn parse_vet_file(path string, table_ &ast.Table, pref &pref.Preferences) (&ast.File, []vet.Error) { pub fn parse_vet_file(path string, table_ &ast.Table, pref_ &pref.Preferences) (&ast.File, []vet.Error) {
$if trace_parse_vet_file ? { $if trace_parse_vet_file ? {
eprintln('> ${@MOD}.${@FN} path: ${path}') eprintln('> ${@MOD}.${@FN} path: ${path}')
} }
@ -256,10 +256,10 @@ pub fn parse_vet_file(path string, table_ &ast.Table, pref &pref.Preferences) (&
parent: 0 parent: 0
} }
mut p := Parser{ mut p := Parser{
scanner: scanner.new_scanner_file(path, .parse_comments, pref) or { panic(err) } scanner: scanner.new_scanner_file(path, .parse_comments, pref_) or { panic(err) }
comments_mode: .parse_comments comments_mode: .parse_comments
table: table_ table: table_
pref: pref pref: pref_
scope: &ast.Scope{ scope: &ast.Scope{
start_pos: 0 start_pos: 0
parent: global_scope parent: global_scope
@ -335,12 +335,12 @@ pub fn (mut p Parser) parse() &ast.File {
} }
p.scope.end_pos = p.tok.pos p.scope.end_pos = p.tok.pos
mut errors := p.errors.clone() mut errors_ := p.errors.clone()
mut warnings := p.warnings.clone() mut warnings := p.warnings.clone()
mut notices := p.notices.clone() mut notices := p.notices.clone()
if p.pref.check_only { if p.pref.check_only {
errors << p.scanner.errors errors_ << p.scanner.errors
warnings << p.scanner.warnings warnings << p.scanner.warnings
notices << p.scanner.notices notices << p.scanner.notices
} }
@ -366,7 +366,7 @@ pub fn (mut p Parser) parse() &ast.File {
stmts: stmts stmts: stmts
scope: p.scope scope: p.scope
global_scope: p.table.global_scope global_scope: p.table.global_scope
errors: errors errors: errors_
warnings: warnings warnings: warnings
notices: notices notices: notices
global_labels: p.global_labels global_labels: p.global_labels
@ -406,7 +406,7 @@ fn (mut q Queue) run() {
} }
} }
*/ */
pub fn parse_files(paths []string, table &ast.Table, pref &pref.Preferences) []&ast.File { pub fn parse_files(paths []string, table &ast.Table, pref_ &pref.Preferences) []&ast.File {
mut timers := util.new_timers(should_print: false, label: 'parse_files: ${paths}') mut timers := util.new_timers(should_print: false, label: 'parse_files: ${paths}')
$if time_parsing ? { $if time_parsing ? {
timers.should_print = true timers.should_print = true
@ -438,7 +438,7 @@ pub fn parse_files(paths []string, table &ast.Table, pref &pref.Preferences) []&
mut files := []&ast.File{cap: paths.len} mut files := []&ast.File{cap: paths.len}
for path in paths { for path in paths {
timers.start('parse_file ${path}') timers.start('parse_file ${path}')
files << parse_file(path, table, .skip_comments, pref) files << parse_file(path, table, .skip_comments, pref_)
timers.show('parse_file ${path}') timers.show('parse_file ${path}')
} }
if codegen_files.len > 0 { if codegen_files.len > 0 {

View File

@ -77,8 +77,8 @@ x := 10
table := ast.new_table() table := ast.new_table()
vpref := &pref.Preferences{} vpref := &pref.Preferences{}
prog := parse_file(s, table, .skip_comments, vpref) prog := parse_file(s, table, .skip_comments, vpref)
mut checker := checker.new_checker(table, vpref) mut checker_ := checker.new_checker(table, vpref)
checker.check(prog) checker_.check(prog)
res, _, _, _ := c.gen([prog], table, vpref) res, _, _, _ := c.gen([prog], table, vpref)
println(res) println(res)
} }
@ -105,8 +105,8 @@ fn test_one() {
scope: scope scope: scope
global_scope: scope global_scope: scope
} }
mut checker := checker.new_checker(table, vpref) mut checker_ := checker.new_checker(table, vpref)
checker.check(program) checker_.check(program)
mut res, _, _, _ := c.gen([program], table, vpref) mut res, _, _, _ := c.gen([program], table, vpref)
res = res.replace('\n', '').trim_space().after('#endif') res = res.replace('\n', '').trim_space().after('#endif')
println(res) println(res)

View File

@ -106,19 +106,19 @@ pub enum CommentsMode {
} }
// new scanner from file. // new scanner from file.
pub fn new_scanner_file(file_path string, comments_mode CommentsMode, pref &pref.Preferences) !&Scanner { pub fn new_scanner_file(file_path string, comments_mode CommentsMode, pref_ &pref.Preferences) !&Scanner {
if !os.is_file(file_path) { if !os.is_file(file_path) {
return error('${file_path} is not a .v file') return error('${file_path} is not a .v file')
} }
raw_text := util.read_file(file_path) or { return err } raw_text := util.read_file(file_path) or { return err }
mut s := &Scanner{ mut s := &Scanner{
pref: pref pref: pref_
text: raw_text text: raw_text
all_tokens: []token.Token{cap: raw_text.len / 3} all_tokens: []token.Token{cap: raw_text.len / 3}
is_print_line_on_error: true is_print_line_on_error: true
is_print_colored_error: true is_print_colored_error: true
is_print_rel_paths_on_error: true is_print_rel_paths_on_error: true
is_fmt: pref.is_fmt is_fmt: pref_.is_fmt
comments_mode: comments_mode comments_mode: comments_mode
file_path: file_path file_path: file_path
file_base: os.base(file_path) file_base: os.base(file_path)
@ -128,15 +128,15 @@ pub fn new_scanner_file(file_path string, comments_mode CommentsMode, pref &pref
} }
// new scanner from string. // new scanner from string.
pub fn new_scanner(text string, comments_mode CommentsMode, pref &pref.Preferences) &Scanner { pub fn new_scanner(text string, comments_mode CommentsMode, pref_ &pref.Preferences) &Scanner {
mut s := &Scanner{ mut s := &Scanner{
pref: pref pref: pref_
text: text text: text
all_tokens: []token.Token{cap: text.len / 3} all_tokens: []token.Token{cap: text.len / 3}
is_print_line_on_error: true is_print_line_on_error: true
is_print_colored_error: true is_print_colored_error: true
is_print_rel_paths_on_error: true is_print_rel_paths_on_error: true
is_fmt: pref.is_fmt is_fmt: pref_.is_fmt
comments_mode: comments_mode comments_mode: comments_mode
file_path: 'internal_memory' file_path: 'internal_memory'
file_base: 'internal_memory' file_base: 'internal_memory'

View File

@ -71,14 +71,14 @@ pub fn run_repl_file(wd string, vexec string, file string) !string {
file_expected := '${file}.expected.txt' file_expected := '${file}.expected.txt'
os.write_file(file_result, result) or { panic(err) } os.write_file(file_result, result) or { panic(err) }
os.write_file(file_expected, output) or { panic(err) } os.write_file(file_expected, output) or { panic(err) }
diff := diff_files(file_expected, file_result) diff_ := diff_files(file_expected, file_result)
return error('Difference found in REPL file: ${file} return error('Difference found in REPL file: ${file}
====> Expected : ====> Expected :
|${output}| |${output}|
====> Got : ====> Got :
|${result}| |${result}|
====> Diff : ====> Diff :
${diff} ${diff_}
') ')
} else { } else {
return file.replace('./', '') return file.replace('./', '')
@ -103,14 +103,14 @@ pub fn run_prod_file(wd string, vexec string, file string) !string {
if result != expected_content { if result != expected_content {
file_result := '${file}.result.txt' file_result := '${file}.result.txt'
os.write_file(file_result, result) or { panic(err) } os.write_file(file_result, result) or { panic(err) }
diff := diff_files(file_result, file_expected) diff_ := diff_files(file_result, file_expected)
return error('Difference found in test: ${file} return error('Difference found in test: ${file}
====> Got : ====> Got :
|${result}| |${result}|
====> Expected : ====> Expected :
|${expected_content}| |${expected_content}|
====> Diff : ====> Diff :
${diff} ${diff_}
') ')
} else { } else {
return 'Prod file ${file} is OK' return 'Prod file ${file} is OK'

View File

@ -171,20 +171,20 @@ fn test_cross_assign_of_big_int() {
fn test_cross_assign_of_reserved_name_variable() { fn test_cross_assign_of_reserved_name_variable() {
mut small := 1 mut small := 1
mut big := 2 mut big_ := 2
mut sum := 2 mut sum := 2
for big < 4_000_000 { for big_ < 4_000_000 {
small, big = big, small + big small, big_ = big_, small + big_
if big % 2 == 0 { if big_ % 2 == 0 {
sum += big sum += big_
} }
} }
println(small) println(small)
assert small == 3524578 assert small == 3524578
println(big) println(big_)
assert big == 5702887 assert big_ == 5702887
println(sum) println(sum)
assert sum == 4613732 assert sum == 4613732

View File

@ -1,8 +1,8 @@
import time import time
struct Game { struct Game {
update fn (mut time.Time) = fn (mut time time.Time) {} update fn (mut time.Time) = fn (mut time_ time.Time) {}
draw fn (mut time.Time) = fn (mut time time.Time) {} draw fn (mut time.Time) = fn (mut time_ time.Time) {}
mut: mut:
time time.Time time time.Time
} }

View File

@ -9,13 +9,13 @@ fn test_main() {
} }
assert 'main' == main.a assert 'main' == main.a
test := test.Test{ test_ := test.Test{
a: 'test' a: 'test'
} }
assert 'test' == test.a assert 'test' == test_.a
test2 := test2.Test2{ test2_ := test2.Test2{
a: 'test2' a: 'test2'
} }
assert 'test2' == test2.a assert 'test2' == test2_.a
} }

View File

@ -42,14 +42,14 @@ fn server() ! {
return true return true
})! })!
s.on_message(fn (mut ws ws.Client, msg &RawMessage) ! { s.on_message(fn (mut ws_ ws.Client, msg &RawMessage) ! {
mut transport := WsTransport{} mut transport := WsTransport{}
mut ws_client := new_ws_client(transport)! mut ws_client := new_ws_client(transport)!
_ := ws_client _ := ws_client
}) })
s.on_close(fn (mut ws ws.Client, code int, reason string) ! { s.on_close(fn (mut ws_ ws.Client, code int, reason string) ! {
println('client (${ws.id}) closed connection') println('client (${ws_.id}) closed connection')
}) })
s.listen() or { println('error on server listen: ${err}') } s.listen() or { println('error on server listen: ${err}') }

View File

@ -13,9 +13,9 @@ mut:
is_assert bool is_assert bool
} }
pub fn new_transformer(pref &pref.Preferences) &Transformer { pub fn new_transformer(pref_ &pref.Preferences) &Transformer {
return &Transformer{ return &Transformer{
pref: pref pref: pref_
index: &IndexState{ index: &IndexState{
saved_key_vals: [][]KeyVal{cap: 1000} saved_key_vals: [][]KeyVal{cap: 1000}
saved_disabled: []bool{cap: 1000} saved_disabled: []bool{cap: 1000}
@ -23,8 +23,8 @@ pub fn new_transformer(pref &pref.Preferences) &Transformer {
} }
} }
pub fn new_transformer_with_table(table &ast.Table, pref &pref.Preferences) &Transformer { pub fn new_transformer_with_table(table &ast.Table, pref_ &pref.Preferences) &Transformer {
mut transformer := new_transformer(pref) mut transformer := new_transformer(pref_)
transformer.table = table transformer.table = table
return transformer return transformer
} }

View File

@ -16,22 +16,22 @@ fn trace_qualify(callfn string, mod string, file_path string, kind_res string, r
// 2022-01-30 TODO: this seems to always just return `mod` itself, for modules inside the V main folder. // 2022-01-30 TODO: this seems to always just return `mod` itself, for modules inside the V main folder.
// 2022-01-30 It does also return `mod` itself, for stuff installed in ~/.vmodules like `vls` but for // 2022-01-30 It does also return `mod` itself, for stuff installed in ~/.vmodules like `vls` but for
// 2022-01-30 other reasons (see res 2 below). // 2022-01-30 other reasons (see res 2 below).
pub fn qualify_import(pref &pref.Preferences, mod string, file_path string) string { pub fn qualify_import(pref_ &pref.Preferences, mod string, file_path string) string {
// comments are from workdir: /v/vls // comments are from workdir: /v/vls
mut mod_paths := pref.lookup_path.clone() mut mod_paths := pref_.lookup_path.clone()
mod_paths << os.vmodules_paths() mod_paths << os.vmodules_paths()
mod_path := mod.replace('.', os.path_separator) mod_path := mod.replace('.', os.path_separator)
for search_path in mod_paths { for search_path in mod_paths {
try_path := os.join_path_single(search_path, mod_path) try_path := os.join_path_single(search_path, mod_path)
if os.is_dir(try_path) { if os.is_dir(try_path) {
if m1 := mod_path_to_full_name(pref, mod, try_path) { if m1 := mod_path_to_full_name(pref_, mod, try_path) {
trace_qualify(@FN, mod, file_path, 'import_res 1', m1, try_path) trace_qualify(@FN, mod, file_path, 'import_res 1', m1, try_path)
// > qualify_import: term | file_path: /v/vls/server/diagnostics.v | => import_res 1: term ; /v/cleanv/vlib/term // > qualify_import: term | file_path: /v/vls/server/diagnostics.v | => import_res 1: term ; /v/cleanv/vlib/term
return m1 return m1
} }
} }
} }
if m1 := mod_path_to_full_name(pref, mod, file_path) { if m1 := mod_path_to_full_name(pref_, mod, file_path) {
trace_qualify(@FN, mod, file_path, 'import_res 2', m1, file_path) trace_qualify(@FN, mod, file_path, 'import_res 2', m1, file_path)
// > qualify_module: analyzer | file_path: /v/vls/analyzer/store.v | => module_res 2: analyzer ; clean_file_path - getwd == mod // > qualify_module: analyzer | file_path: /v/vls/analyzer/store.v | => module_res 2: analyzer ; clean_file_path - getwd == mod
// > qualify_import: analyzer.depgraph | file_path: /v/vls/analyzer/store.v | => import_res 2: analyzer.depgraph ; /v/vls/analyzer/store.v // > qualify_import: analyzer.depgraph | file_path: /v/vls/analyzer/store.v | => import_res 2: analyzer.depgraph ; /v/vls/analyzer/store.v
@ -51,7 +51,7 @@ pub fn qualify_import(pref &pref.Preferences, mod string, file_path string) stri
// 2022-01-30 qualify_module - used by V's parser to find the full module name // 2022-01-30 qualify_module - used by V's parser to find the full module name
// 2022-01-30 i.e. when parsing `module textscanner`, inside vlib/strings/textscanner/textscanner.v // 2022-01-30 i.e. when parsing `module textscanner`, inside vlib/strings/textscanner/textscanner.v
// 2022-01-30 it will return `strings.textscanner` // 2022-01-30 it will return `strings.textscanner`
pub fn qualify_module(pref &pref.Preferences, mod string, file_path string) string { pub fn qualify_module(pref_ &pref.Preferences, mod string, file_path string) string {
if mod == 'main' { if mod == 'main' {
trace_qualify(@FN, mod, file_path, 'module_res 1', mod, 'main') trace_qualify(@FN, mod, file_path, 'module_res 1', mod, 'main')
return mod return mod
@ -68,7 +68,7 @@ pub fn qualify_module(pref &pref.Preferences, mod string, file_path string) stri
trace_qualify(@FN, mod, file_path, 'module_res 2', mod, 'clean_file_path - getwd == mod, clean_file_path: ${clean_file_path}') trace_qualify(@FN, mod, file_path, 'module_res 2', mod, 'clean_file_path - getwd == mod, clean_file_path: ${clean_file_path}')
return mod return mod
} }
if m1 := mod_path_to_full_name(pref, mod, clean_file_path) { if m1 := mod_path_to_full_name(pref_, mod, clean_file_path) {
trace_qualify(@FN, mod, file_path, 'module_res 3', m1, 'm1 == f(${clean_file_path})') trace_qualify(@FN, mod, file_path, 'module_res 3', m1, 'm1 == f(${clean_file_path})')
// > qualify_module: net | file_path: /v/cleanv/vlib/net/util.v | => module_res 3: net ; m1 == f(/v/cleanv/vlib/net) // > qualify_module: net | file_path: /v/cleanv/vlib/net/util.v | => module_res 3: net ; m1 == f(/v/cleanv/vlib/net)
// > qualify_module: term | file_path: /v/cleanv/vlib/term/control.v | => module_res 3: term ; m1 == f(/v/cleanv/vlib/term) // > qualify_module: term | file_path: /v/cleanv/vlib/term/control.v | => module_res 3: term ; m1 == f(/v/cleanv/vlib/term)
@ -96,11 +96,11 @@ pub fn qualify_module(pref &pref.Preferences, mod string, file_path string) stri
// 2022-01-30 just on windows, because while `vlib\v\checker\tests\modules\deprecated_module` works, // 2022-01-30 just on windows, because while `vlib\v\checker\tests\modules\deprecated_module` works,
// 2022-01-30 it leads to path differences, and the / version on windows triggers a module lookip bug, // 2022-01-30 it leads to path differences, and the / version on windows triggers a module lookip bug,
// 2022-01-30 leading to completely different errors) // 2022-01-30 leading to completely different errors)
fn mod_path_to_full_name(pref &pref.Preferences, mod string, path string) !string { fn mod_path_to_full_name(pref_ &pref.Preferences, mod string, path string) !string {
// TODO: explore using `pref.lookup_path` & `os.vmodules_paths()` // TODO: explore using `pref.lookup_path` & `os.vmodules_paths()`
// absolute paths instead of 'vlib' & '.vmodules' // absolute paths instead of 'vlib' & '.vmodules'
mut vmod_folders := ['vlib', '.vmodules', 'modules'] mut vmod_folders := ['vlib', '.vmodules', 'modules']
bases := pref.lookup_path.map(os.base(it)) bases := pref_.lookup_path.map(os.base(it))
for base in bases { for base in bases {
if base !in vmod_folders { if base !in vmod_folders {
vmod_folders << base vmod_folders << base
@ -157,8 +157,8 @@ fn mod_path_to_full_name(pref &pref.Preferences, mod string, path string) !strin
} }
} }
} }
if os.is_abs_path(pref.path) && os.is_abs_path(path) && os.is_dir(path) { // && path.contains(mod ) if os.is_abs_path(pref_.path) && os.is_abs_path(path) && os.is_dir(path) { // && path.contains(mod )
rel_mod_path := path.replace(pref.path.all_before_last(os.path_separator) + rel_mod_path := path.replace(pref_.path.all_before_last(os.path_separator) +
os.path_separator, '') os.path_separator, '')
if rel_mod_path != path { if rel_mod_path != path {
full_mod_name := rel_mod_path.replace(os.path_separator, '.') full_mod_name := rel_mod_path.replace(os.path_separator, '.')