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

more precise support for internal module tests

This commit is contained in:
Delyan Angelov
2020-04-01 00:42:30 +03:00
committed by GitHub
parent 2ac074655f
commit 5b990078f9
5 changed files with 68 additions and 31 deletions

View File

@@ -35,7 +35,7 @@ enum Pass {
pub struct V {
pub mut:
mod_file_cacher &ModFileCacher // used during lookup for v.mod to support @VROOT
mod_file_cacher &builder.ModFileCacher // used during lookup for v.mod to support @VROOT
out_name_c string // name of the temporary C file
files []string // all V files that need to be parsed and compiled
compiled_dir string // contains os.real_path() of the dir of the final file beeing compiled, or the dir itself when doing `v .`
@@ -68,7 +68,7 @@ pub fn new_v(pref &pref.Preferences) &V {
compiled_dir:=if os.is_dir(rdir) { rdir } else { os.dir(rdir) }
return &V{
mod_file_cacher: new_mod_file_cacher()
mod_file_cacher: builder.new_mod_file_cacher()
compiled_dir:compiled_dir// if os.is_dir(rdir) { rdir } else { os.dir(rdir) }
table: new_table(pref.obfuscate)
out_name_c: out_name_c
@@ -746,8 +746,18 @@ pub fn (v &V) get_user_files() []string {
tcontent := os.read_file(dir)or{
panic('$dir does not exist')
}
if tcontent.contains('module ') && !tcontent.contains('module main') {
is_internal_module_test = true
slines := tcontent.trim_space().split_into_lines()
for sline in slines {
line := sline.trim_space()
if line.len > 2 {
if line[0] == `/` && line[1] == `/` {
continue
}
if line.starts_with('module ') && !line.starts_with('module main') {
is_internal_module_test = true
break
}
}
}
}
if is_internal_module_test {

View File

@@ -1,145 +0,0 @@
module compiler
import os
// This file provides a caching mechanism for seeking quickly whether a
// given folder has a v.mod file in it or in any of its parent folders.
//
// ModFileCacher.get(folder) works in such a way, that given this tree:
// examples/hanoi.v
// vlib/v.mod
// vlib/compiler/tests/project_with_c_code/mod1/v.mod
// vlib/compiler/tests/project_with_c_code/mod1/wrapper.v
// -----------------
// ModFileCacher.get('examples')
// => ModFileAndFolder{'', 'examples'}
// ModFileCacher.get('vlib/compiler/tests')
// => ModFileAndFolder{'vlib/v.mod', 'vlib'}
// ModFileCacher.get('vlib/compiler')
// => ModFileAndFolder{'vlib/v.mod', 'vlib'}
// ModFileCacher.get('vlib/project_with_c_code/mod1')
// => ModFileAndFolder{'vlib/project_with_c_code/mod1/v.mod', 'vlib/project_with_c_code/mod1'}
struct ModFileAndFolder {
// vmod_file contains the full path of the found 'v.mod' file, or ''
// if no 'v.mod' file was found in file_path_dir, or in its parent folders.
vmod_file string
// vmod_folder contains the file_path_dir, if there is no 'v.mod' file in
// *any* of the parent folders, otherwise it is the first parent folder,
// where a v.mod file was found.
vmod_folder string
}
struct ModFileCacher {
mut:
cache map[string]ModFileAndFolder
// folder_files caches os.ls(key)
folder_files map[string][]string
}
fn new_mod_file_cacher() &ModFileCacher {
return &ModFileCacher{}
}
fn (mcache &ModFileCacher) dump() {
$if debug {
eprintln('ModFileCacher DUMP:')
eprintln(' ModFileCacher.cache:')
for k,v in mcache.cache {
eprintln(' K: ${k:-32s} | V: "${v.vmod_file:32s}" | "${v.vmod_folder:32s}" ')
}
eprintln(' ModFileCacher.folder_files:')
for k,v in mcache.folder_files {
eprintln(' K: ${k:-32s} | V: ${v.str()}')
}
}
}
fn (mcache mut ModFileCacher) get(mfolder string) ModFileAndFolder {
if mfolder in mcache.cache {
return mcache.cache[ mfolder ]
}
traversed_folders, res := mcache.traverse( mfolder )
for tfolder in traversed_folders {
mcache.add( tfolder, res )
}
return res
}
fn (cacher mut ModFileCacher) add(path string, result ModFileAndFolder) {
cacher.cache[ path ] = result
}
fn (mcache mut ModFileCacher) traverse(mfolder string) ([]string, ModFileAndFolder) {
mut cfolder := mfolder
mut folders_so_far := [cfolder]
mut levels := 0
for {
if levels > 255 {
break
}
if cfolder == '/' || cfolder == '' {
break
}
if cfolder in mcache.cache {
res := mcache.cache[ cfolder ]
if res.vmod_file.len == 0 {
mcache.mark_folders_as_vmod_free( folders_so_far )
}else{
mcache.mark_folders_with_vmod( folders_so_far, res )
}
return []string, res
}
files := mcache.get_files( cfolder )
if 'v.mod' in files {
// TODO: actually read the v.mod file and parse its contents to see
// if its source folder is different
res := ModFileAndFolder{ vmod_file: os.join_path( cfolder, 'v.mod'), vmod_folder: cfolder }
return folders_so_far, res
}
if mcache.check_for_stop( cfolder, files ) {
break
}
cfolder = os.base_dir( cfolder )
folders_so_far << cfolder
levels++
}
mcache.mark_folders_as_vmod_free( folders_so_far )
return [mfolder], ModFileAndFolder{ vmod_file: '', vmod_folder: mfolder }
}
fn (mcache mut ModFileCacher) mark_folders_with_vmod( folders_so_far []string, vmod ModFileAndFolder ) {
for f in folders_so_far {
mcache.add( f, vmod )
}
}
fn (mcache mut ModFileCacher) mark_folders_as_vmod_free( folders_so_far []string ) {
// No need to check these folders anymore,
// because their parents do not contain v.mod files
for f in folders_so_far {
mcache.add( f, ModFileAndFolder{ vmod_file: '', vmod_folder: f } )
}
}
const ( MOD_FILE_STOP_PATHS = ['.git', '.hg', '.svn', '.v.mod.stop' ] )
fn (mcache &ModFileCacher) check_for_stop(cfolder string, files []string) bool {
for i in MOD_FILE_STOP_PATHS {
if i in files {
return true
}
}
return false
}
fn (mcache mut ModFileCacher) get_files(cfolder string) []string {
if cfolder in mcache.folder_files {
return mcache.folder_files[ cfolder ]
}
files := os.ls(cfolder) or { return [] }
mcache.folder_files[ cfolder ] = files
return files
}