Skip to content

Commit 07b1dc6

Browse files
authored
ast, parser: add additional pos info for FnDecl and InterfaceDecl nodes (#9603)
1 parent 6ed50e7 commit 07b1dc6

File tree

5 files changed

+31
-18
lines changed

5 files changed

+31
-18
lines changed

vlib/v/ast/ast.v

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ pub:
259259
pub struct InterfaceDecl {
260260
pub:
261261
name string
262+
name_pos token.Position
262263
field_names []string
263264
is_pub bool
264265
methods []FnDecl
@@ -365,23 +366,24 @@ pub:
365366
language Language
366367
no_body bool // just a definition `fn C.malloc()`
367368
is_builtin bool // this function is defined in builtin/strconv
368-
pos token.Position // function declaration position
369369
body_pos token.Position // function bodys position
370370
file string
371371
generic_params []GenericParam
372372
is_direct_arr bool // direct array access
373373
attrs []Attr
374374
skip_gen bool // this function doesn't need to be generated (for example [if foo])
375375
pub mut:
376-
stmts []Stmt
377-
defer_stmts []DeferStmt
378-
return_type Type
379-
has_return bool
380-
comments []Comment // comments *after* the header, but *before* `{`; used for InterfaceDecl
381-
next_comments []Comment // coments that are one line after the decl; used for InterfaceDecl
382-
source_file &File = 0
383-
scope &Scope
384-
label_names []string
376+
stmts []Stmt
377+
defer_stmts []DeferStmt
378+
return_type Type
379+
return_type_pos token.Position // `string` in `fn (u User) name() string` position
380+
has_return bool
381+
comments []Comment // comments *after* the header, but *before* `{`; used for InterfaceDecl
382+
next_comments []Comment // coments that are one line after the decl; used for InterfaceDecl
383+
source_file &File = 0
384+
scope &Scope
385+
label_names []string
386+
pos token.Position // function declaration position
385387
}
386388

387389
pub struct GenericParam {
@@ -1603,7 +1605,7 @@ pub fn (node Node) position() token.Position {
16031605
StructField {
16041606
return node.pos.extend(node.type_pos)
16051607
}
1606-
MatchBranch, SelectBranch, EnumField, ConstField, StructInitField, GlobalField, Param {
1608+
MatchBranch, SelectBranch, EnumField, ConstField, StructInitField, GlobalField, CallArg {
16071609
return node.pos
16081610
}
16091611
IfBranch {
@@ -1625,6 +1627,9 @@ pub fn (node Node) position() token.Position {
16251627
}
16261628
}
16271629
}
1630+
Param {
1631+
return node.pos.extend(node.type_pos)
1632+
}
16281633
File {
16291634
mut pos := token.Position{}
16301635
if node.stmts.len > 0 {
@@ -1634,9 +1639,6 @@ pub fn (node Node) position() token.Position {
16341639
}
16351640
return pos
16361641
}
1637-
CallArg {
1638-
return node.pos
1639-
}
16401642
}
16411643
}
16421644

@@ -1719,7 +1721,8 @@ pub fn (node Node) children() []Node {
17191721
children << node.expr
17201722
}
17211723
InterfaceDecl {
1722-
return node.methods.map(Node(Stmt(it)))
1724+
children << node.methods.map(Node(Stmt(it)))
1725+
children << node.fields.map(Node(it))
17231726
}
17241727
AssignStmt {
17251728
children << node.left.map(Node(it))

vlib/v/checker/checker.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ pub fn (mut c Checker) interface_decl(decl ast.InterfaceDecl) {
353353
for method in decl.methods {
354354
c.check_valid_snake_case(method.name, 'method name', method.pos)
355355
if method.return_type != ast.Type(0) {
356-
c.ensure_type_exists(method.return_type, method.pos) or { return }
356+
c.ensure_type_exists(method.return_type, method.return_type_pos) or { return }
357357
}
358358
for param in method.params {
359359
c.ensure_type_exists(param.typ, param.pos) or { return }

vlib/v/checker/tests/interface_return_parameter_err.out

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
vlib/v/checker/tests/interface_return_parameter_err.vv:2:5: error: unknown type `Baz`.
1+
vlib/v/checker/tests/interface_return_parameter_err.vv:2:17: error: unknown type `Baz`.
22
Did you mean `Foo`?
33
1 | interface Foo {
44
2 | bar(string) []Baz
5-
| ~~~~~~~~~~~
5+
| ~~~~~
66
3 | bar2(Bax) string
77
4 | }
88
vlib/v/checker/tests/interface_return_parameter_err.vv:3:10: error: unknown type `Bax`.

vlib/v/parser/fn.v

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,12 +293,14 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
293293
}
294294
}
295295
// Return type
296+
mut return_type_pos := p.tok.position()
296297
mut return_type := ast.void_type
297298
// don't confuse token on the next line: fn decl, [attribute]
298299
same_line := p.tok.line_nr == p.prev_tok.line_nr
299300
if (p.tok.kind.is_start_of_type() && (same_line || p.tok.kind != .lsbr))
300301
|| (same_line && p.tok.kind == .key_fn) {
301302
return_type = p.parse_type()
303+
return_type_pos = return_type_pos.extend(p.prev_tok.position())
302304
}
303305
mut type_sym_method_idx := 0
304306
no_body := p.tok.kind != .lcbr
@@ -398,6 +400,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
398400
mod: p.mod
399401
stmts: stmts
400402
return_type: return_type
403+
return_type_pos: return_type_pos
401404
params: params
402405
is_manualfree: is_manualfree
403406
is_deprecated: is_deprecated
@@ -574,10 +577,12 @@ fn (mut p Parser) anon_fn() ast.AnonFn {
574577
}
575578
mut same_line := p.tok.line_nr == p.prev_tok.line_nr
576579
mut return_type := ast.void_type
580+
mut return_type_pos := p.tok.position()
577581
// lpar: multiple return types
578582
if same_line {
579583
if p.tok.kind.is_start_of_type() {
580584
return_type = p.parse_type()
585+
return_type_pos = return_type_pos.extend(p.tok.position())
581586
} else if p.tok.kind != .lcbr {
582587
p.error_with_pos('expected return type, not $p.tok for anonymous function',
583588
p.tok.position())
@@ -618,6 +623,7 @@ fn (mut p Parser) anon_fn() ast.AnonFn {
618623
mod: p.mod
619624
stmts: stmts
620625
return_type: return_type
626+
return_type_pos: return_type_pos
621627
params: args
622628
is_variadic: is_variadic
623629
is_method: false

vlib/v/parser/struct.v

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,10 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl {
518518
scope: p.scope
519519
}
520520
if p.tok.kind.is_start_of_type() && p.tok.line_nr == line_nr {
521+
method.return_type_pos = p.tok.position()
521522
method.return_type = p.parse_type()
523+
method.return_type_pos = method.return_type_pos.extend(p.tok.position())
524+
method.pos = method.pos.extend(method.return_type_pos)
522525
}
523526
mcomments := p.eat_comments(same_line: true)
524527
mnext_comments := p.eat_comments({})
@@ -577,5 +580,6 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl {
577580
pos: pos
578581
pre_comments: pre_comments
579582
mut_pos: mut_pos
583+
name_pos: name_pos
580584
}
581585
}

0 commit comments

Comments
 (0)