ast, parser: add additional pos info for FnDecl and InterfaceDecl nodes (#9603)
parent
6ed50e7678
commit
07b1dc66dd
|
@ -259,6 +259,7 @@ pub:
|
||||||
pub struct InterfaceDecl {
|
pub struct InterfaceDecl {
|
||||||
pub:
|
pub:
|
||||||
name string
|
name string
|
||||||
|
name_pos token.Position
|
||||||
field_names []string
|
field_names []string
|
||||||
is_pub bool
|
is_pub bool
|
||||||
methods []FnDecl
|
methods []FnDecl
|
||||||
|
@ -365,7 +366,6 @@ pub:
|
||||||
language Language
|
language Language
|
||||||
no_body bool // just a definition `fn C.malloc()`
|
no_body bool // just a definition `fn C.malloc()`
|
||||||
is_builtin bool // this function is defined in builtin/strconv
|
is_builtin bool // this function is defined in builtin/strconv
|
||||||
pos token.Position // function declaration position
|
|
||||||
body_pos token.Position // function bodys position
|
body_pos token.Position // function bodys position
|
||||||
file string
|
file string
|
||||||
generic_params []GenericParam
|
generic_params []GenericParam
|
||||||
|
@ -373,15 +373,17 @@ pub:
|
||||||
attrs []Attr
|
attrs []Attr
|
||||||
skip_gen bool // this function doesn't need to be generated (for example [if foo])
|
skip_gen bool // this function doesn't need to be generated (for example [if foo])
|
||||||
pub mut:
|
pub mut:
|
||||||
stmts []Stmt
|
stmts []Stmt
|
||||||
defer_stmts []DeferStmt
|
defer_stmts []DeferStmt
|
||||||
return_type Type
|
return_type Type
|
||||||
has_return bool
|
return_type_pos token.Position // `string` in `fn (u User) name() string` position
|
||||||
comments []Comment // comments *after* the header, but *before* `{`; used for InterfaceDecl
|
has_return bool
|
||||||
next_comments []Comment // coments that are one line after the decl; used for InterfaceDecl
|
comments []Comment // comments *after* the header, but *before* `{`; used for InterfaceDecl
|
||||||
source_file &File = 0
|
next_comments []Comment // coments that are one line after the decl; used for InterfaceDecl
|
||||||
scope &Scope
|
source_file &File = 0
|
||||||
label_names []string
|
scope &Scope
|
||||||
|
label_names []string
|
||||||
|
pos token.Position // function declaration position
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct GenericParam {
|
pub struct GenericParam {
|
||||||
|
@ -1603,7 +1605,7 @@ pub fn (node Node) position() token.Position {
|
||||||
StructField {
|
StructField {
|
||||||
return node.pos.extend(node.type_pos)
|
return node.pos.extend(node.type_pos)
|
||||||
}
|
}
|
||||||
MatchBranch, SelectBranch, EnumField, ConstField, StructInitField, GlobalField, Param {
|
MatchBranch, SelectBranch, EnumField, ConstField, StructInitField, GlobalField, CallArg {
|
||||||
return node.pos
|
return node.pos
|
||||||
}
|
}
|
||||||
IfBranch {
|
IfBranch {
|
||||||
|
@ -1625,6 +1627,9 @@ pub fn (node Node) position() token.Position {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Param {
|
||||||
|
return node.pos.extend(node.type_pos)
|
||||||
|
}
|
||||||
File {
|
File {
|
||||||
mut pos := token.Position{}
|
mut pos := token.Position{}
|
||||||
if node.stmts.len > 0 {
|
if node.stmts.len > 0 {
|
||||||
|
@ -1634,9 +1639,6 @@ pub fn (node Node) position() token.Position {
|
||||||
}
|
}
|
||||||
return pos
|
return pos
|
||||||
}
|
}
|
||||||
CallArg {
|
|
||||||
return node.pos
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1719,7 +1721,8 @@ pub fn (node Node) children() []Node {
|
||||||
children << node.expr
|
children << node.expr
|
||||||
}
|
}
|
||||||
InterfaceDecl {
|
InterfaceDecl {
|
||||||
return node.methods.map(Node(Stmt(it)))
|
children << node.methods.map(Node(Stmt(it)))
|
||||||
|
children << node.fields.map(Node(it))
|
||||||
}
|
}
|
||||||
AssignStmt {
|
AssignStmt {
|
||||||
children << node.left.map(Node(it))
|
children << node.left.map(Node(it))
|
||||||
|
|
|
@ -353,7 +353,7 @@ pub fn (mut c Checker) interface_decl(decl ast.InterfaceDecl) {
|
||||||
for method in decl.methods {
|
for method in decl.methods {
|
||||||
c.check_valid_snake_case(method.name, 'method name', method.pos)
|
c.check_valid_snake_case(method.name, 'method name', method.pos)
|
||||||
if method.return_type != ast.Type(0) {
|
if method.return_type != ast.Type(0) {
|
||||||
c.ensure_type_exists(method.return_type, method.pos) or { return }
|
c.ensure_type_exists(method.return_type, method.return_type_pos) or { return }
|
||||||
}
|
}
|
||||||
for param in method.params {
|
for param in method.params {
|
||||||
c.ensure_type_exists(param.typ, param.pos) or { return }
|
c.ensure_type_exists(param.typ, param.pos) or { return }
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
vlib/v/checker/tests/interface_return_parameter_err.vv:2:5: error: unknown type `Baz`.
|
vlib/v/checker/tests/interface_return_parameter_err.vv:2:17: error: unknown type `Baz`.
|
||||||
Did you mean `Foo`?
|
Did you mean `Foo`?
|
||||||
1 | interface Foo {
|
1 | interface Foo {
|
||||||
2 | bar(string) []Baz
|
2 | bar(string) []Baz
|
||||||
| ~~~~~~~~~~~
|
| ~~~~~
|
||||||
3 | bar2(Bax) string
|
3 | bar2(Bax) string
|
||||||
4 | }
|
4 | }
|
||||||
vlib/v/checker/tests/interface_return_parameter_err.vv:3:10: error: unknown type `Bax`.
|
vlib/v/checker/tests/interface_return_parameter_err.vv:3:10: error: unknown type `Bax`.
|
||||||
|
|
|
@ -293,12 +293,14 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Return type
|
// Return type
|
||||||
|
mut return_type_pos := p.tok.position()
|
||||||
mut return_type := ast.void_type
|
mut return_type := ast.void_type
|
||||||
// don't confuse token on the next line: fn decl, [attribute]
|
// don't confuse token on the next line: fn decl, [attribute]
|
||||||
same_line := p.tok.line_nr == p.prev_tok.line_nr
|
same_line := p.tok.line_nr == p.prev_tok.line_nr
|
||||||
if (p.tok.kind.is_start_of_type() && (same_line || p.tok.kind != .lsbr))
|
if (p.tok.kind.is_start_of_type() && (same_line || p.tok.kind != .lsbr))
|
||||||
|| (same_line && p.tok.kind == .key_fn) {
|
|| (same_line && p.tok.kind == .key_fn) {
|
||||||
return_type = p.parse_type()
|
return_type = p.parse_type()
|
||||||
|
return_type_pos = return_type_pos.extend(p.prev_tok.position())
|
||||||
}
|
}
|
||||||
mut type_sym_method_idx := 0
|
mut type_sym_method_idx := 0
|
||||||
no_body := p.tok.kind != .lcbr
|
no_body := p.tok.kind != .lcbr
|
||||||
|
@ -398,6 +400,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
||||||
mod: p.mod
|
mod: p.mod
|
||||||
stmts: stmts
|
stmts: stmts
|
||||||
return_type: return_type
|
return_type: return_type
|
||||||
|
return_type_pos: return_type_pos
|
||||||
params: params
|
params: params
|
||||||
is_manualfree: is_manualfree
|
is_manualfree: is_manualfree
|
||||||
is_deprecated: is_deprecated
|
is_deprecated: is_deprecated
|
||||||
|
@ -574,10 +577,12 @@ fn (mut p Parser) anon_fn() ast.AnonFn {
|
||||||
}
|
}
|
||||||
mut same_line := p.tok.line_nr == p.prev_tok.line_nr
|
mut same_line := p.tok.line_nr == p.prev_tok.line_nr
|
||||||
mut return_type := ast.void_type
|
mut return_type := ast.void_type
|
||||||
|
mut return_type_pos := p.tok.position()
|
||||||
// lpar: multiple return types
|
// lpar: multiple return types
|
||||||
if same_line {
|
if same_line {
|
||||||
if p.tok.kind.is_start_of_type() {
|
if p.tok.kind.is_start_of_type() {
|
||||||
return_type = p.parse_type()
|
return_type = p.parse_type()
|
||||||
|
return_type_pos = return_type_pos.extend(p.tok.position())
|
||||||
} else if p.tok.kind != .lcbr {
|
} else if p.tok.kind != .lcbr {
|
||||||
p.error_with_pos('expected return type, not $p.tok for anonymous function',
|
p.error_with_pos('expected return type, not $p.tok for anonymous function',
|
||||||
p.tok.position())
|
p.tok.position())
|
||||||
|
@ -618,6 +623,7 @@ fn (mut p Parser) anon_fn() ast.AnonFn {
|
||||||
mod: p.mod
|
mod: p.mod
|
||||||
stmts: stmts
|
stmts: stmts
|
||||||
return_type: return_type
|
return_type: return_type
|
||||||
|
return_type_pos: return_type_pos
|
||||||
params: args
|
params: args
|
||||||
is_variadic: is_variadic
|
is_variadic: is_variadic
|
||||||
is_method: false
|
is_method: false
|
||||||
|
|
|
@ -518,7 +518,10 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl {
|
||||||
scope: p.scope
|
scope: p.scope
|
||||||
}
|
}
|
||||||
if p.tok.kind.is_start_of_type() && p.tok.line_nr == line_nr {
|
if p.tok.kind.is_start_of_type() && p.tok.line_nr == line_nr {
|
||||||
|
method.return_type_pos = p.tok.position()
|
||||||
method.return_type = p.parse_type()
|
method.return_type = p.parse_type()
|
||||||
|
method.return_type_pos = method.return_type_pos.extend(p.tok.position())
|
||||||
|
method.pos = method.pos.extend(method.return_type_pos)
|
||||||
}
|
}
|
||||||
mcomments := p.eat_comments(same_line: true)
|
mcomments := p.eat_comments(same_line: true)
|
||||||
mnext_comments := p.eat_comments({})
|
mnext_comments := p.eat_comments({})
|
||||||
|
@ -577,5 +580,6 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl {
|
||||||
pos: pos
|
pos: pos
|
||||||
pre_comments: pre_comments
|
pre_comments: pre_comments
|
||||||
mut_pos: mut_pos
|
mut_pos: mut_pos
|
||||||
|
name_pos: name_pos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue