From 1e856c0f94c648194d23e07fdd426a597e8ff2f5 Mon Sep 17 00:00:00 2001 From: zakuro Date: Tue, 4 May 2021 17:31:31 +0900 Subject: [PATCH] parser: improve error message for `mod.unknownsubmod.Type` (#9976) --- vlib/v/parser/parse_type.v | 30 ++++++++++++++----- .../tests/struct_field_unknown_module_a.out | 5 ++++ .../tests/struct_field_unknown_module_a.vv | 3 ++ .../tests/struct_field_unknown_module_b.out | 5 ++++ .../tests/struct_field_unknown_module_b.vv | 3 ++ .../tests/struct_field_unknown_module_c.out | 6 ++++ .../tests/struct_field_unknown_module_c.vv | 5 ++++ 7 files changed, 49 insertions(+), 8 deletions(-) create mode 100644 vlib/v/parser/tests/struct_field_unknown_module_a.out create mode 100644 vlib/v/parser/tests/struct_field_unknown_module_a.vv create mode 100644 vlib/v/parser/tests/struct_field_unknown_module_b.out create mode 100644 vlib/v/parser/tests/struct_field_unknown_module_b.vv create mode 100644 vlib/v/parser/tests/struct_field_unknown_module_c.out create mode 100644 vlib/v/parser/tests/struct_field_unknown_module_c.vv diff --git a/vlib/v/parser/parse_type.v b/vlib/v/parser/parse_type.v index 30c70003fe..3b39ecfbe1 100644 --- a/vlib/v/parser/parse_type.v +++ b/vlib/v/parser/parse_type.v @@ -330,17 +330,31 @@ pub fn (mut p Parser) parse_any_type(language ast.Language, is_ptr bool, check_d } else if p.peek_tok.kind == .dot && check_dot { // `module.Type` // /if !(p.tok.lit in p.table.imports) { - if !p.known_import(name) { - p.error('unknown module `$p.tok.lit`') - return 0 - } - if p.tok.lit in p.imports { - p.register_used_import(p.tok.lit) - } + mut mod := name + mut mod_pos := p.tok.position() p.next() p.check(.dot) + mut mod_last_part := mod + for p.peek_tok.kind == .dot { + mod_pos = mod_pos.extend(p.tok.position()) + mod_last_part = p.tok.lit + mod += '.$mod_last_part' + p.next() + p.check(.dot) + } + if !p.known_import(mod) { + mut msg := 'unknown module `$mod`' + if mod.len > mod_last_part.len && p.known_import(mod_last_part) { + msg += '; did you mean `$mod_last_part`?' + } + p.error_with_pos(msg, mod_pos) + return 0 + } + if mod in p.imports { + p.register_used_import(mod) + } // prefix with full module - name = '${p.imports[name]}.$p.tok.lit' + name = '${p.imports[mod]}.$p.tok.lit' if p.tok.lit.len > 0 && !p.tok.lit[0].is_capital() { p.error('imported types must start with a capital letter') return 0 diff --git a/vlib/v/parser/tests/struct_field_unknown_module_a.out b/vlib/v/parser/tests/struct_field_unknown_module_a.out new file mode 100644 index 0000000000..81ac9db4bd --- /dev/null +++ b/vlib/v/parser/tests/struct_field_unknown_module_a.out @@ -0,0 +1,5 @@ +vlib/v/parser/tests/struct_field_unknown_module_a.vv:2:7: error: unknown module `ui` + 1 | struct Inter { + 2 | code ui.KeyCode + | ~~ + 3 | } diff --git a/vlib/v/parser/tests/struct_field_unknown_module_a.vv b/vlib/v/parser/tests/struct_field_unknown_module_a.vv new file mode 100644 index 0000000000..31058d548d --- /dev/null +++ b/vlib/v/parser/tests/struct_field_unknown_module_a.vv @@ -0,0 +1,3 @@ +struct Inter { + code ui.KeyCode +} diff --git a/vlib/v/parser/tests/struct_field_unknown_module_b.out b/vlib/v/parser/tests/struct_field_unknown_module_b.out new file mode 100644 index 0000000000..e4679791a9 --- /dev/null +++ b/vlib/v/parser/tests/struct_field_unknown_module_b.out @@ -0,0 +1,5 @@ +vlib/v/parser/tests/struct_field_unknown_module_b.vv:2:7: error: unknown module `term.unknownmod` + 1 | struct Inter { + 2 | code term.unknownmod.KeyCode + | ~~~~~~~~~~~~~~~ + 3 | } diff --git a/vlib/v/parser/tests/struct_field_unknown_module_b.vv b/vlib/v/parser/tests/struct_field_unknown_module_b.vv new file mode 100644 index 0000000000..3193a7caa1 --- /dev/null +++ b/vlib/v/parser/tests/struct_field_unknown_module_b.vv @@ -0,0 +1,3 @@ +struct Inter { + code term.unknownmod.KeyCode +} diff --git a/vlib/v/parser/tests/struct_field_unknown_module_c.out b/vlib/v/parser/tests/struct_field_unknown_module_c.out new file mode 100644 index 0000000000..84bd41e5c3 --- /dev/null +++ b/vlib/v/parser/tests/struct_field_unknown_module_c.out @@ -0,0 +1,6 @@ +vlib/v/parser/tests/struct_field_unknown_module_c.vv:4:7: error: unknown module `term.ui`; did you mean `ui`? + 2 | + 3 | struct Inter { + 4 | code term.ui.KeyCode + | ~~~~~~~ + 5 | } diff --git a/vlib/v/parser/tests/struct_field_unknown_module_c.vv b/vlib/v/parser/tests/struct_field_unknown_module_c.vv new file mode 100644 index 0000000000..cce4940851 --- /dev/null +++ b/vlib/v/parser/tests/struct_field_unknown_module_c.vv @@ -0,0 +1,5 @@ +import term.ui + +struct Inter { + code term.ui.KeyCode +}