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