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