all: add .pos fields to all AST nodes, to avoid wrong positions in error messages
parent
25912673a9
commit
9eb655e65c
|
@ -21,6 +21,8 @@ pub type Stmt = AssertStmt | AssignStmt | Block | BranchStmt | CompFor | ConstDe
|
|||
GotoLabel | GotoStmt | HashStmt | Import | InterfaceDecl | Module | Return | SqlStmt |
|
||||
StructDecl | TypeDecl
|
||||
|
||||
// NB: when you add a new Expr or Stmt type with a .pos field, remember to update
|
||||
// the .position() token.Position methods too.
|
||||
pub type ScopeObject = ConstField | GlobalField | Var
|
||||
|
||||
pub struct Type {
|
||||
|
@ -276,7 +278,8 @@ pub mut:
|
|||
// break, continue
|
||||
pub struct BranchStmt {
|
||||
pub:
|
||||
tok token.Token
|
||||
kind token.Kind
|
||||
pos token.Position
|
||||
}
|
||||
|
||||
pub struct CallExpr {
|
||||
|
@ -591,6 +594,7 @@ pub:
|
|||
val_var string
|
||||
stmts []Stmt
|
||||
kind CompForKind
|
||||
pos token.Position
|
||||
pub mut:
|
||||
// expr Expr
|
||||
typ table.Type
|
||||
|
@ -738,6 +742,7 @@ pub:
|
|||
pub struct DeferStmt {
|
||||
pub:
|
||||
stmts []Stmt
|
||||
pos token.Position
|
||||
pub mut:
|
||||
ifdef string
|
||||
}
|
||||
|
@ -746,21 +751,25 @@ pub mut:
|
|||
pub struct ParExpr {
|
||||
pub:
|
||||
expr Expr
|
||||
pos token.Position
|
||||
}
|
||||
|
||||
pub struct GoStmt {
|
||||
pub:
|
||||
call_expr Expr
|
||||
pos token.Position
|
||||
}
|
||||
|
||||
pub struct GotoLabel {
|
||||
pub:
|
||||
name string
|
||||
pos token.Position
|
||||
}
|
||||
|
||||
pub struct GotoStmt {
|
||||
pub:
|
||||
name string
|
||||
pos token.Position
|
||||
}
|
||||
|
||||
pub struct ArrayInit {
|
||||
|
@ -813,6 +822,7 @@ pub:
|
|||
high Expr
|
||||
has_high bool
|
||||
has_low bool
|
||||
pos token.Position
|
||||
}
|
||||
|
||||
// NB: &string(x) gets parsed as ast.PrefixExpr{ right: ast.CastExpr{...} }
|
||||
|
@ -848,6 +858,7 @@ pub struct IfGuardExpr {
|
|||
pub:
|
||||
var_name string
|
||||
expr Expr
|
||||
pos token.Position
|
||||
pub mut:
|
||||
expr_type table.Type
|
||||
}
|
||||
|
@ -905,6 +916,7 @@ pub:
|
|||
pub struct TypeOf {
|
||||
pub:
|
||||
expr Expr
|
||||
pos token.Position
|
||||
pub mut:
|
||||
expr_type table.Type
|
||||
}
|
||||
|
@ -920,6 +932,7 @@ pub:
|
|||
pub struct ConcatExpr {
|
||||
pub:
|
||||
vals []Expr
|
||||
pos token.Position
|
||||
pub mut:
|
||||
return_type table.Type
|
||||
}
|
||||
|
@ -1006,9 +1019,15 @@ pub fn (expr Expr) position() token.Position {
|
|||
AnonFn {
|
||||
return expr.decl.pos
|
||||
}
|
||||
ArrayInit, AsCast, Assoc, BoolLiteral, CallExpr, CastExpr, CharLiteral, Comment, EnumVal, FloatLiteral, Ident, IfExpr, IndexExpr, IntegerLiteral, MapInit, MatchExpr, None, PostfixExpr, PrefixExpr, SelectExpr, SelectorExpr, SizeOf, StringLiteral, StringInterLiteral, StructInit, Likely {
|
||||
ArrayInit, AsCast, Assoc, BoolLiteral, CallExpr, CastExpr, ChanInit, CharLiteral, ConcatExpr, Comment, EnumVal, FloatLiteral, Ident, IfExpr, IndexExpr, IntegerLiteral, Likely, LockExpr, MapInit, MatchExpr, None, OrExpr, ParExpr, PostfixExpr, PrefixExpr, RangeExpr, SelectExpr, SelectorExpr, SizeOf, SqlExpr, StringInterLiteral, StringLiteral, StructInit, Type, TypeOf, UnsafeExpr {
|
||||
return expr.pos
|
||||
}
|
||||
IfGuardExpr {
|
||||
return expr.expr.position()
|
||||
}
|
||||
ComptimeCall {
|
||||
return expr.left.position()
|
||||
}
|
||||
InfixExpr {
|
||||
left_pos := expr.left.position()
|
||||
right_pos := expr.right.position()
|
||||
|
@ -1021,17 +1040,12 @@ pub fn (expr Expr) position() token.Position {
|
|||
len: right_pos.pos - left_pos.pos + right_pos.len
|
||||
}
|
||||
}
|
||||
/*
|
||||
ast.Ident {}
|
||||
ast.IfGuardExpr {}
|
||||
ast.None {}
|
||||
ast.ParExpr {}
|
||||
ast.Type {}
|
||||
ast.TypeOf {}
|
||||
*/
|
||||
else {
|
||||
CTempVar {
|
||||
return token.Position{}
|
||||
}
|
||||
// Please, do NOT use else{} here.
|
||||
// This match is exhaustive *on purpose*, to help force
|
||||
// maintaining/implementing proper .pos fields.
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1083,13 +1097,14 @@ pub:
|
|||
|
||||
pub fn (stmt Stmt) position() token.Position {
|
||||
match stmt {
|
||||
AssertStmt, AssignStmt, Block, ConstDecl, EnumDecl, ExprStmt, FnDecl, ForCStmt, ForInStmt, ForStmt, Import, Return, StructDecl, GlobalDecl, HashStmt, InterfaceDecl, Module { return stmt.pos }
|
||||
AssertStmt, AssignStmt, Block, BranchStmt, CompFor, ConstDecl, DeferStmt, EnumDecl, ExprStmt, FnDecl, ForCStmt, ForInStmt, ForStmt, GotoLabel, GotoStmt, Import, Return, StructDecl, GlobalDecl, HashStmt, InterfaceDecl, Module, SqlStmt { return stmt.pos }
|
||||
GoStmt { return stmt.call_expr.position() }
|
||||
BranchStmt { return token.Position{stmt.tok.len, stmt.tok.line_nr, stmt.tok.pos} }
|
||||
TypeDecl { match stmt {
|
||||
AliasTypeDecl, FnTypeDecl, SumTypeDecl { return stmt.pos }
|
||||
} }
|
||||
else { return token.Position{} }
|
||||
// Please, do NOT use else{} here.
|
||||
// This match is exhaustive *on purpose*, to help force
|
||||
// maintaining/implementing proper .pos fields.
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1667,9 +1667,9 @@ pub fn (mut c Checker) check_or_expr(or_expr ast.OrExpr, ret_type table.Type, ex
|
|||
return
|
||||
}
|
||||
ast.BranchStmt {
|
||||
if last_stmt.tok.kind !in [.key_continue, .key_break] {
|
||||
if last_stmt.kind !in [.key_continue, .key_break] {
|
||||
c.error('only break/continue is allowed as a branch statement in the end of an `or {}` block',
|
||||
last_stmt.tok.position())
|
||||
last_stmt.pos)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -2324,7 +2324,7 @@ fn (mut c Checker) stmt(node ast.Stmt) {
|
|||
}
|
||||
ast.BranchStmt {
|
||||
if c.in_for_count == 0 {
|
||||
c.error('$node.tok.lit statement not within a loop', node.tok.position())
|
||||
c.error('$node.kind.str() statement not within a loop', node.pos)
|
||||
}
|
||||
}
|
||||
ast.CompFor {
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
vlib/v/checker/tests/prefix_expr_decl_assign_err.vv:2:5: error: non-name on the left side of `:=`
|
||||
1 | fn main() {
|
||||
2 | &a := 12
|
||||
| ^
|
||||
3 | (*d) := 14
|
||||
4 | }
|
||||
vlib/v/checker/tests/prefix_expr_decl_assign_err.vv:1:1: error: non-name `(*d)` on left side of `:=`
|
||||
1 | fn main() {
|
||||
| ^
|
||||
2 | &a := 12
|
||||
3 | (*d) := 14
|
||||
vlib/v/checker/tests/prefix_expr_decl_assign_err.vv:2:5: error: non-name on the left side of `:=`
|
||||
1 | fn main() {
|
||||
2 | &a := 12
|
||||
| ^
|
||||
3 | (*d) := 14
|
||||
4 | }
|
||||
vlib/v/checker/tests/prefix_expr_decl_assign_err.vv:3:10: error: non-name `(*d)` on left side of `:=`
|
||||
1 | fn main() {
|
||||
2 | &a := 12
|
||||
3 | (*d) := 14
|
||||
| ~~
|
||||
4 | }
|
||||
|
|
|
@ -301,7 +301,7 @@ pub fn (mut f Fmt) stmt(node ast.Stmt) {
|
|||
f.writeln('}')
|
||||
}
|
||||
ast.BranchStmt {
|
||||
match node.tok.kind {
|
||||
match node.kind {
|
||||
.key_break { f.writeln('break') }
|
||||
.key_continue { f.writeln('continue') }
|
||||
else {}
|
||||
|
|
|
@ -794,9 +794,9 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
|||
g.writeln('}')
|
||||
}
|
||||
ast.BranchStmt {
|
||||
g.write_v_source_line_info(node.tok.position())
|
||||
g.write_v_source_line_info(node.pos)
|
||||
// continue or break
|
||||
g.write(node.tok.kind.str())
|
||||
g.write(node.kind.str())
|
||||
g.writeln(';')
|
||||
}
|
||||
ast.ConstDecl {
|
||||
|
|
|
@ -771,7 +771,7 @@ fn (mut g JsGen) gen_block(it ast.Block) {
|
|||
|
||||
fn (mut g JsGen) gen_branch_stmt(it ast.BranchStmt) {
|
||||
// continue or break
|
||||
g.write(it.tok.kind.str())
|
||||
g.write(it.kind.str())
|
||||
g.writeln(';')
|
||||
}
|
||||
|
||||
|
|
|
@ -139,12 +139,14 @@ fn (mut p Parser) comp_for() ast.CompFor {
|
|||
} else {
|
||||
p.error('unknown kind `$for_val`, available are: `methods` or `fields`')
|
||||
}
|
||||
spos := p.tok.position()
|
||||
stmts := p.parse_block()
|
||||
return ast.CompFor{
|
||||
val_var: val_var
|
||||
stmts: stmts
|
||||
kind: kind
|
||||
typ: typ
|
||||
pos: spos.extend(p.tok.position())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -230,6 +230,7 @@ fn (mut p Parser) match_expr() ast.MatchExpr {
|
|||
types << parsed_type
|
||||
exprs << ast.Type{
|
||||
typ: parsed_type
|
||||
pos: p.tok.position()
|
||||
}
|
||||
if p.tok.kind != .comma {
|
||||
break
|
||||
|
@ -298,6 +299,7 @@ fn (mut p Parser) match_expr() ast.MatchExpr {
|
|||
high: expr2
|
||||
has_low: true
|
||||
has_high: true
|
||||
pos: p.tok.position()
|
||||
}
|
||||
} else {
|
||||
exprs << expr
|
||||
|
|
|
@ -585,10 +585,12 @@ pub fn (mut p Parser) stmt(is_top_level bool) ast.Stmt {
|
|||
}
|
||||
if p.peek_tok.kind == .colon {
|
||||
// `label:`
|
||||
spos := p.tok.position()
|
||||
name := p.check_name()
|
||||
p.next()
|
||||
return ast.GotoLabel{
|
||||
name: name
|
||||
pos: spos.extend(p.tok.position())
|
||||
}
|
||||
} else if p.peek_tok.kind == .name {
|
||||
p.error_with_pos('unexpected name `$p.peek_tok.lit`', p.peek_tok.position())
|
||||
|
@ -624,7 +626,8 @@ pub fn (mut p Parser) stmt(is_top_level bool) ast.Stmt {
|
|||
tok := p.tok
|
||||
p.next()
|
||||
return ast.BranchStmt{
|
||||
tok: tok
|
||||
kind: tok.kind
|
||||
pos: tok.position()
|
||||
}
|
||||
}
|
||||
.key_unsafe {
|
||||
|
@ -635,25 +638,31 @@ pub fn (mut p Parser) stmt(is_top_level bool) ast.Stmt {
|
|||
}
|
||||
.key_defer {
|
||||
p.next()
|
||||
spos := p.tok.position()
|
||||
stmts := p.parse_block()
|
||||
return ast.DeferStmt{
|
||||
stmts: stmts
|
||||
pos: spos.extend(p.tok.position())
|
||||
}
|
||||
}
|
||||
.key_go {
|
||||
p.next()
|
||||
spos := p.tok.position()
|
||||
expr := p.expr(0)
|
||||
// mut call_expr := &ast.CallExpr(0) // TODO
|
||||
// { call_expr = it }
|
||||
return ast.GoStmt{
|
||||
call_expr: expr
|
||||
pos: spos.extend(p.tok.position())
|
||||
}
|
||||
}
|
||||
.key_goto {
|
||||
p.next()
|
||||
spos := p.tok.position()
|
||||
name := p.check_name()
|
||||
return ast.GotoStmt{
|
||||
name: name
|
||||
pos: spos
|
||||
}
|
||||
}
|
||||
.key_const {
|
||||
|
@ -766,27 +775,6 @@ fn (mut p Parser) parse_attr() table.Attr {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
fn (mut p Parser) range_expr(low ast.Expr) ast.Expr {
|
||||
// ,table.Type) {
|
||||
if p.tok.kind != .dotdot {
|
||||
p.next()
|
||||
}
|
||||
p.check(.dotdot)
|
||||
mut high := ast.Expr{}
|
||||
if p.tok.kind != .rsbr {
|
||||
high = p.expr(0)
|
||||
// if typ.typ.kind != .int {
|
||||
// p.error('non-integer index `$typ.typ.name`')
|
||||
// }
|
||||
}
|
||||
node := ast.RangeExpr{
|
||||
low: low
|
||||
high: high
|
||||
}
|
||||
return node
|
||||
}
|
||||
*/
|
||||
pub fn (mut p Parser) error(s string) {
|
||||
p.error_with_pos(s, p.tok.position())
|
||||
}
|
||||
|
@ -877,6 +865,7 @@ fn (mut p Parser) parse_multi_expr(is_top_level bool) ast.Stmt {
|
|||
return ast.ExprStmt{
|
||||
expr: ast.ConcatExpr{
|
||||
vals: left
|
||||
pos: tok.position()
|
||||
}
|
||||
pos: tok.position()
|
||||
comments: left_comments
|
||||
|
@ -967,6 +956,7 @@ pub fn (mut p Parser) name_expr() ast.Expr {
|
|||
}
|
||||
return ast.MapInit{
|
||||
typ: map_type
|
||||
pos: p.tok.position()
|
||||
}
|
||||
}
|
||||
// `chan typ{...}`
|
||||
|
@ -1153,6 +1143,7 @@ fn (mut p Parser) index_expr(left ast.Expr) ast.IndexExpr {
|
|||
low: ast.Expr{}
|
||||
high: high
|
||||
has_high: true
|
||||
pos: pos
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1176,6 +1167,7 @@ fn (mut p Parser) index_expr(left ast.Expr) ast.IndexExpr {
|
|||
high: high
|
||||
has_high: has_high
|
||||
has_low: has_low
|
||||
pos: pos
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,6 +85,7 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr {
|
|||
p.check(.rpar)
|
||||
node = ast.ParExpr{
|
||||
expr: node
|
||||
pos: p.tok.position()
|
||||
}
|
||||
}
|
||||
.key_if {
|
||||
|
@ -151,12 +152,14 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr {
|
|||
p.check(.rpar)
|
||||
}
|
||||
.key_typeof {
|
||||
spos := p.tok.position()
|
||||
p.next()
|
||||
p.check(.lpar)
|
||||
expr := p.expr(0)
|
||||
p.check(.rpar)
|
||||
node = ast.TypeOf{
|
||||
expr: expr
|
||||
pos: spos.extend(p.tok.position())
|
||||
}
|
||||
}
|
||||
.key_likely, .key_unlikely {
|
||||
|
|
Loading…
Reference in New Issue