compiler: improve module import error messages
parent
64349b5006
commit
9defbf989d
|
@ -216,21 +216,28 @@ fn (v mut V) add_parser(parser Parser) {
|
|||
v.parsers << parser
|
||||
}
|
||||
|
||||
// find existing parser or create new one. returns v.parsers index
|
||||
fn (v mut V) parse(file string, pass Pass) int {
|
||||
//println('parse($file, $pass)')
|
||||
fn (v &V) get_file_parser_index(file string) ?int {
|
||||
for i, p in v.parsers {
|
||||
if os.realpath(p.file_path) == os.realpath(file) {
|
||||
v.parsers[i].parse(pass)
|
||||
//if v.parsers[i].pref.autofree { v.parsers[i].scanner.text.free() free(v.parsers[i].scanner) }
|
||||
return i
|
||||
}
|
||||
}
|
||||
mut p := v.new_parser_from_file(file)
|
||||
p.parse(pass)
|
||||
//if p.pref.autofree { p.scanner.text.free() free(p.scanner) }
|
||||
v.add_parser(p)
|
||||
return v.parsers.len-1
|
||||
return error('parser for "$file" not found')
|
||||
}
|
||||
|
||||
// find existing parser or create new one. returns v.parsers index
|
||||
fn (v mut V) parse(file string, pass Pass) int {
|
||||
//println('parse($file, $pass)')
|
||||
pidx := v.get_file_parser_index(file) or {
|
||||
mut p := v.new_parser_from_file(file)
|
||||
p.parse(pass)
|
||||
//if p.pref.autofree { p.scanner.text.free() free(p.scanner) }
|
||||
v.add_parser(p)
|
||||
return v.parsers.len-1
|
||||
}
|
||||
v.parsers[pidx].parse(pass)
|
||||
//if v.parsers[i].pref.autofree { v.parsers[i].scanner.text.free() free(v.parsers[i].scanner) }
|
||||
return pidx
|
||||
}
|
||||
|
||||
|
||||
|
@ -622,7 +629,8 @@ fn (v mut V) add_v_files_to_compile() {
|
|||
// continue
|
||||
// }
|
||||
// standard module
|
||||
vfiles := v.v_files_from_dir(v.find_module_path(mod))
|
||||
mod_path := v.find_module_path(mod) or { verror(err) break }
|
||||
vfiles := v.v_files_from_dir(mod_path)
|
||||
for file in vfiles {
|
||||
v.files << file
|
||||
}
|
||||
|
@ -694,10 +702,15 @@ fn (v mut V) parse_lib_imports() {
|
|||
for _, fit in v.table.file_imports {
|
||||
if fit.file_path in done_fits { continue }
|
||||
for _, mod in fit.imports {
|
||||
import_path := v.find_module_path(mod)
|
||||
import_path := v.find_module_path(mod) or {
|
||||
pidx := v.get_file_parser_index(fit.file_path) or { verror(err) break }
|
||||
v.parsers[pidx].error_with_token_index('cannot import module "$mod" (not found)', fit.get_import_tok_idx(mod))
|
||||
break
|
||||
}
|
||||
vfiles := v.v_files_from_dir(import_path)
|
||||
if vfiles.len == 0 {
|
||||
verror('cannot import module $mod (no .v files in "$import_path")')
|
||||
pidx := v.get_file_parser_index(fit.file_path) or { verror(err) break }
|
||||
v.parsers[pidx].error_with_token_index('cannot import module "$mod" (no .v files in "$import_path")', fit.get_import_tok_idx(mod))
|
||||
}
|
||||
// Add all imports referenced by these libs
|
||||
for file in vfiles {
|
||||
|
@ -706,7 +719,7 @@ fn (v mut V) parse_lib_imports() {
|
|||
done_imports << file
|
||||
p_mod := v.parsers[pid].import_table.module_name
|
||||
if p_mod != mod {
|
||||
verror('bad module name: $file was imported as `$mod` but it is defined as module `$p_mod`')
|
||||
v.parsers[pid].error_with_token_index('bad module definition: $fit.file_path imports module "$mod" but $file is defined as module `$p_mod`', 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ fn (v &V) module_path(mod string) string {
|
|||
// 'strings' => 'VROOT/vlib/strings'
|
||||
// 'installed_mod' => '~/.vmodules/installed_mod'
|
||||
// 'local_mod' => '/path/to/current/dir/local_mod'
|
||||
fn (v &V) find_module_path(mod string) string {
|
||||
fn (v &V) find_module_path(mod string) ?string {
|
||||
mod_path := v.module_path(mod)
|
||||
// First check for local modules in the same directory
|
||||
mut import_path := os.getwd() + '${os.PathSeparator}$mod_path'
|
||||
|
@ -55,7 +55,7 @@ fn (v &V) find_module_path(mod string) string {
|
|||
if !os.dir_exists(import_path) {
|
||||
import_path = '$v_modules_path${os.PathSeparator}$mod_path'
|
||||
if !os.dir_exists(import_path){
|
||||
verror('module "$mod" not found')
|
||||
return error('module "$mod" not found')
|
||||
}
|
||||
}
|
||||
return import_path
|
||||
|
|
|
@ -437,6 +437,7 @@ fn (p mut Parser) import_statement() {
|
|||
if p.peek() == .number { // && p.scanner.text[p.scanner.pos + 1] == `.` {
|
||||
p.error('bad import format. module/submodule names cannot begin with a number')
|
||||
}
|
||||
import_tok_idx := p.token_idx-1
|
||||
mut mod := p.check_name().trim_space()
|
||||
mut mod_alias := mod
|
||||
// submodule support
|
||||
|
@ -457,7 +458,7 @@ fn (p mut Parser) import_statement() {
|
|||
mod_alias = p.check_name()
|
||||
}
|
||||
// add import to file scope import table
|
||||
p.import_table.register_alias(mod_alias, mod)
|
||||
p.import_table.register_alias(mod_alias, mod, import_tok_idx)
|
||||
// Make sure there are no duplicate imports
|
||||
if mod in p.table.imports {
|
||||
return
|
||||
|
|
|
@ -53,10 +53,11 @@ mut:
|
|||
// Holds import information scoped to the parsed file
|
||||
struct FileImportTable {
|
||||
mut:
|
||||
module_name string
|
||||
file_path string
|
||||
imports map[string]string // alias => module
|
||||
used_imports []string // alias
|
||||
module_name string
|
||||
file_path string
|
||||
imports map[string]string // alias => module
|
||||
used_imports []string // alias
|
||||
import_tok_idx map[string]int // module => idx
|
||||
}
|
||||
|
||||
enum AccessMod {
|
||||
|
@ -896,11 +897,11 @@ fn (fit &FileImportTable) known_import(mod string) bool {
|
|||
return mod in fit.imports || fit.is_aliased(mod)
|
||||
}
|
||||
|
||||
fn (fit mut FileImportTable) register_import(mod string) {
|
||||
fit.register_alias(mod, mod)
|
||||
fn (fit mut FileImportTable) register_import(mod string, tok_idx int) {
|
||||
fit.register_alias(mod, mod, tok_idx)
|
||||
}
|
||||
|
||||
fn (fit mut FileImportTable) register_alias(alias string, mod string) {
|
||||
fn (fit mut FileImportTable) register_alias(alias string, mod string, tok_idx int) {
|
||||
// NOTE: come back here
|
||||
// if alias in fit.imports && fit.imports[alias] == mod {}
|
||||
if alias in fit.imports && fit.imports[alias] != mod {
|
||||
|
@ -919,6 +920,11 @@ fn (fit mut FileImportTable) register_alias(alias string, mod string) {
|
|||
}
|
||||
}
|
||||
fit.imports[alias] = mod
|
||||
fit.import_tok_idx[mod] = tok_idx
|
||||
}
|
||||
|
||||
fn (fit &FileImportTable) get_import_tok_idx(mod string) int {
|
||||
return fit.import_tok_idx[mod]
|
||||
}
|
||||
|
||||
fn (fit &FileImportTable) known_alias(alias string) bool {
|
||||
|
|
Loading…
Reference in New Issue