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

modules: cyclic import detection

This commit is contained in:
joe-conigliaro
2019-07-22 01:53:35 +10:00
committed by Alexander Medvednikov
parent 23c5f88f3e
commit 135f200ea2
4 changed files with 180 additions and 39 deletions

View File

@ -751,16 +751,14 @@ fn (v mut V) add_user_v_files() {
v.log('user_files:')
println(user_files)
}
// To store the import table for user imports
mut user_imports := []FileImportTable
// import tables for user/lib files
mut file_imports := []FileImportTable
// Parse user imports
for file in user_files {
mut p := v.new_parser(file, Pass.imports)
p.parse()
user_imports << *p.import_table
file_imports << *p.import_table
}
// To store the import table for lib imports
mut lib_imports := []FileImportTable
// Parse lib imports
if v.pref.build_mode == .default_mode {
for i := 0; i < v.table.imports.len; i++ {
@ -770,7 +768,7 @@ fn (v mut V) add_user_v_files() {
for file in vfiles {
mut p := v.new_parser(file, Pass.imports)
p.parse()
lib_imports << *p.import_table
file_imports << *p.import_table
}
}
}
@ -789,7 +787,7 @@ fn (v mut V) add_user_v_files() {
for file in vfiles {
mut p := v.new_parser(file, Pass.imports)
p.parse()
lib_imports << *p.import_table
file_imports << *p.import_table
}
}
}
@ -797,38 +795,38 @@ fn (v mut V) add_user_v_files() {
v.log('imports:')
println(v.table.imports)
}
// this order is important for declaration
mut combined_imports := []FileImportTable
for i := lib_imports.len-1; i>=0; i-- {
combined_imports << lib_imports[i]
// graph deps
mut dep_graph := new_mod_dep_graph()
dep_graph.from_import_tables(file_imports)
deps_resolved := dep_graph.resolve()
if !deps_resolved.acyclic {
deps_resolved.display()
panic('Import cycle detected.')
}
for i in user_imports {
combined_imports << i
}
// Only now add all combined lib files
// adding the modules each file imports first
for fit in combined_imports {
for _, mod in fit.imports {
mod_p := v.module_path(mod)
idir := os.getwd()
mut module_path := '$idir/$mod_p'
// If we are in default mode, we don't parse vlib .v files, but header .vh files in
// TmpPath/vlib
// These were generated by vfmt
if v.pref.build_mode == .default_mode || v.pref.build_mode == .build {
module_path = '$ModPath/vlib/$mod_p'
}
if !os.file_exists(module_path) {
module_path = '$v.lang_dir/vlib/$mod_p'
}
vfiles := v.v_files_from_dir(module_path)
for file in vfiles {
if !file in v.files {
v.files << file
}
}
// TODO v.files.append_array(vfiles)
// add imports in correct order
for mod in deps_resolved.imports() {
mod_p := v.module_path(mod)
idir := os.getwd()
mut module_path := '$idir/$mod_p'
// If we are in default mode, we don't parse vlib .v files, but header .vh files in
// TmpPath/vlib
// These were generated by vfmt
if v.pref.build_mode == .default_mode || v.pref.build_mode == .build {
module_path = '$ModPath/vlib/$mod_p'
}
if !os.file_exists(module_path) {
module_path = '$v.lang_dir/vlib/$mod_p'
}
vfiles := v.v_files_from_dir(module_path)
for file in vfiles {
if !file in v.files {
v.files << file
}
}
// TODO v.files.append_array(vfiles)
}
// add remaining files (not mods)
for fit in file_imports {
if !fit.file_path in v.files {
v.files << fit.file_path
}