Skip to content

Commit b055769

Browse files
authored
parser,checker: vls skip unrelated files (#25531)
1 parent 443f667 commit b055769

5 files changed

Lines changed: 107 additions & 16 deletions

File tree

‎vlib/v/checker/autocomplete.v‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ fn (c &Checker) vls_gen_type_details(mut details []Detail, sym ast.TypeSymbol) {
284284
method_ret_type := c.table.sym(method.return_type)
285285
details << Detail{
286286
kind: .method
287-
label: c.build_fn_summary(method)
287+
label: method.name
288288
detail: method_ret_type.name
289289
}
290290
}

‎vlib/v/checker/checker.v‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,10 @@ pub fn (mut c Checker) check_files(ast_files []&ast.File) {
354354
mut files_from_main_module := []&ast.File{}
355355
for i in 0 .. ast_files.len {
356356
mut file := ast_files[i]
357+
if c.pref.is_vls && file.path != c.pref.path {
358+
// in `vls` mode, only check the user file
359+
continue
360+
}
357361
c.timers.start('checker_check ${file.path}')
358362
c.check(mut file)
359363
if file.mod.name == 'no_main' {

‎vlib/v/parser/fn.v‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,11 @@ run them via `v file.v` instead',
681681
p.inside_fn = true
682682
p.inside_unsafe_fn = is_unsafe
683683
p.cur_fn_scope = p.scope
684-
stmts = p.parse_block_no_scope(true)
684+
if p.is_vls_skip_file {
685+
p.skip_scope()
686+
} else {
687+
stmts = p.parse_block_no_scope(true)
688+
}
685689
p.cur_fn_scope = last_fn_scope
686690
p.inside_unsafe_fn = false
687691
p.inside_fn = false

‎vlib/v/parser/parser.v‎

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ mut:
116116
generic_type_level int // to avoid infinite recursion segfaults due to compiler bugs in ensure_type_exists
117117
main_already_defined bool // TODO move to checker
118118
is_vls bool
119+
is_vls_skip_file bool // in `vls` mode, skip parse and check for unrelated files, such as `vlib`
119120
inside_import_section bool
120121
cur_comments []ast.Comment // comments between other stmts
121122
pub mut:
@@ -177,16 +178,17 @@ pub fn parse_text(text string, path string, mut table ast.Table, comments_mode s
177178
eprintln('> ${@MOD}.${@FN} comments_mode: ${comments_mode:-20} | path: ${path:-20} | text: ${text}')
178179
}
179180
mut p := Parser{
180-
scanner: scanner.new_scanner(text, comments_mode, pref_)
181-
table: table
182-
pref: pref_
183-
is_vls: pref_.is_vls
184-
scope: &ast.Scope{
181+
scanner: scanner.new_scanner(text, comments_mode, pref_)
182+
table: table
183+
pref: pref_
184+
is_vls: pref_.is_vls
185+
is_vls_skip_file: pref_.is_vls && path != pref_.path
186+
scope: &ast.Scope{
185187
start_pos: 0
186188
parent: table.global_scope
187189
}
188-
errors: []errors.Error{}
189-
warnings: []errors.Warning{}
190+
errors: []errors.Error{}
191+
warnings: []errors.Warning{}
190192
}
191193
p.set_path(path)
192194
mut res := p.parse()
@@ -269,14 +271,15 @@ pub fn parse_file(path string, mut table ast.Table, comments_mode scanner.Commen
269271
pref: pref_
270272
// Only set vls mode if it's the file the user requested via `v -vls-mode file.v`
271273
// Otherwise we'd be parsing entire stdlib in vls mode
272-
is_vls: pref_.is_vls && path == pref_.path
273-
scope: &ast.Scope{
274+
is_vls: pref_.is_vls && path == pref_.path
275+
is_vls_skip_file: pref_.is_vls && path != pref_.path
276+
scope: &ast.Scope{
274277
start_pos: 0
275278
parent: table.global_scope
276279
}
277-
errors: []errors.Error{}
278-
warnings: []errors.Warning{}
279-
file_idx: file_idx
280+
errors: []errors.Error{}
281+
warnings: []errors.Warning{}
282+
file_idx: file_idx
280283
}
281284
p.set_path(path)
282285
res := p.parse()
@@ -318,7 +321,9 @@ pub fn (mut p Parser) parse() &ast.File {
318321
}
319322
for {
320323
if p.tok.kind == .eof {
321-
p.check_unused_imports()
324+
if !p.is_vls_skip_file {
325+
p.check_unused_imports()
326+
}
322327
break
323328
}
324329
stmt := p.top_stmt()

‎vlib/v/tests/vls/autocomplete_module_test.v‎

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ import term
33
import v.util.diff
44

55
const vroot = os.real_path(@VMODROOT)
6+
const tmp_dir = os.real_path(os.temp_dir())
67

78
const text_file_orig = os.join_path(vroot, 'vlib', 'v', 'tests', 'vls', 'sample_text.vv')
8-
const text_file = os.join_path(os.temp_dir(), 'sample_text.v')
9+
const text_file = os.join_path(tmp_dir, 'sample_text.v')
10+
const text_file_result = $if windows { text_file.replace('\\', '/') } $else { text_file }
911

1012
fn testsuite_begin() {
1113
eprintln('testsuite_begin, text_file = ${text_file}')
@@ -33,6 +35,82 @@ const test_data = [
3335
{"kind":21,"label":"public_const1","detail":"","documentation":""}
3436
]}'
3537
},
38+
TestData{
39+
cmd: 'v -w -vls-mode -check -json-errors ${os.quoted_path(text_file)}'
40+
output: '[
41+
{
42+
"path":"${text_file}",
43+
"message":"undefined ident: `a`",
44+
"line_nr":14,
45+
"col":4,
46+
"len":0
47+
}
48+
,
49+
{
50+
"path":"${text_file}",
51+
"message":"operator `+=` not defined on left operand type `void`",
52+
"line_nr":14,
53+
"col":4,
54+
"len":0
55+
}
56+
,
57+
{
58+
"path":"${text_file}",
59+
"message":"cannot assign to `a`: expected `void`, not `int`",
60+
"line_nr":14,
61+
"col":9,
62+
"len":0
63+
}
64+
,
65+
{
66+
"path":"${text_file}",
67+
"message":"undefined ident: `s`",
68+
"line_nr":18,
69+
"col":2,
70+
"len":0
71+
}
72+
]
73+
'
74+
},
75+
TestData{
76+
cmd: 'v -check -nocolor -vls-mode ${os.quoted_path(text_file)}'
77+
output: '${text_file_result}:14:4: error: undefined ident: `a`
78+
12 | // add add `val` to `a`
79+
13 | fn (mut m MyS) add(val int) {
80+
14 | m.a += val
81+
| ^
82+
15 | }
83+
16 |
84+
${text_file_result}:14:4: error: operator `+=` not defined on left operand type `void`
85+
12 | // add add `val` to `a`
86+
13 | fn (mut m MyS) add(val int) {
87+
14 | m.a += val
88+
| ^
89+
15 | }
90+
16 |
91+
${text_file_result}:14:9: error: cannot assign to `a`: expected `void`, not `int`
92+
12 | // add add `val` to `a`
93+
13 | fn (mut m MyS) add(val int) {
94+
14 | m.a += val
95+
| ~~~
96+
15 | }
97+
16 |
98+
${text_file_result}:18:2: error: undefined ident: `s`
99+
16 |
100+
17 | fn main() {
101+
18 | s.
102+
| ^
103+
19 | //sample_mod2.
104+
20 | //mut k := MyS{}
105+
${text_file_result}:5:8: warning: module \'sample_mod2 (v.tests.vls.sample_mod2)\' is imported but never used
106+
3 |
107+
4 | import v.tests.vls.sample_mod1 as s
108+
5 | import v.tests.vls.sample_mod2
109+
| ~~~~~~~~~~~~~~~~~~~~~~~
110+
6 |
111+
7 | struct MyS{
112+
'
113+
},
36114
]
37115

38116
fn test_main() {

0 commit comments

Comments
 (0)