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 |
|
GotoLabel | GotoStmt | HashStmt | Import | InterfaceDecl | Module | Return | SqlStmt |
|
||||||
StructDecl | TypeDecl
|
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 type ScopeObject = ConstField | GlobalField | Var
|
||||||
|
|
||||||
pub struct Type {
|
pub struct Type {
|
||||||
|
@ -276,7 +278,8 @@ pub mut:
|
||||||
// break, continue
|
// break, continue
|
||||||
pub struct BranchStmt {
|
pub struct BranchStmt {
|
||||||
pub:
|
pub:
|
||||||
tok token.Token
|
kind token.Kind
|
||||||
|
pos token.Position
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CallExpr {
|
pub struct CallExpr {
|
||||||
|
@ -591,6 +594,7 @@ pub:
|
||||||
val_var string
|
val_var string
|
||||||
stmts []Stmt
|
stmts []Stmt
|
||||||
kind CompForKind
|
kind CompForKind
|
||||||
|
pos token.Position
|
||||||
pub mut:
|
pub mut:
|
||||||
// expr Expr
|
// expr Expr
|
||||||
typ table.Type
|
typ table.Type
|
||||||
|
@ -738,6 +742,7 @@ pub:
|
||||||
pub struct DeferStmt {
|
pub struct DeferStmt {
|
||||||
pub:
|
pub:
|
||||||
stmts []Stmt
|
stmts []Stmt
|
||||||
|
pos token.Position
|
||||||
pub mut:
|
pub mut:
|
||||||
ifdef string
|
ifdef string
|
||||||
}
|
}
|
||||||
|
@ -746,21 +751,25 @@ pub mut:
|
||||||
pub struct ParExpr {
|
pub struct ParExpr {
|
||||||
pub:
|
pub:
|
||||||
expr Expr
|
expr Expr
|
||||||
|
pos token.Position
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct GoStmt {
|
pub struct GoStmt {
|
||||||
pub:
|
pub:
|
||||||
call_expr Expr
|
call_expr Expr
|
||||||
|
pos token.Position
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct GotoLabel {
|
pub struct GotoLabel {
|
||||||
pub:
|
pub:
|
||||||
name string
|
name string
|
||||||
|
pos token.Position
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct GotoStmt {
|
pub struct GotoStmt {
|
||||||
pub:
|
pub:
|
||||||
name string
|
name string
|
||||||
|
pos token.Position
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ArrayInit {
|
pub struct ArrayInit {
|
||||||
|
@ -813,6 +822,7 @@ pub:
|
||||||
high Expr
|
high Expr
|
||||||
has_high bool
|
has_high bool
|
||||||
has_low bool
|
has_low bool
|
||||||
|
pos token.Position
|
||||||
}
|
}
|
||||||
|
|
||||||
// NB: &string(x) gets parsed as ast.PrefixExpr{ right: ast.CastExpr{...} }
|
// NB: &string(x) gets parsed as ast.PrefixExpr{ right: ast.CastExpr{...} }
|
||||||
|
@ -848,6 +858,7 @@ pub struct IfGuardExpr {
|
||||||
pub:
|
pub:
|
||||||
var_name string
|
var_name string
|
||||||
expr Expr
|
expr Expr
|
||||||
|
pos token.Position
|
||||||
pub mut:
|
pub mut:
|
||||||
expr_type table.Type
|
expr_type table.Type
|
||||||
}
|
}
|
||||||
|
@ -905,6 +916,7 @@ pub:
|
||||||
pub struct TypeOf {
|
pub struct TypeOf {
|
||||||
pub:
|
pub:
|
||||||
expr Expr
|
expr Expr
|
||||||
|
pos token.Position
|
||||||
pub mut:
|
pub mut:
|
||||||
expr_type table.Type
|
expr_type table.Type
|
||||||
}
|
}
|
||||||
|
@ -920,6 +932,7 @@ pub:
|
||||||
pub struct ConcatExpr {
|
pub struct ConcatExpr {
|
||||||
pub:
|
pub:
|
||||||
vals []Expr
|
vals []Expr
|
||||||
|
pos token.Position
|
||||||
pub mut:
|
pub mut:
|
||||||
return_type table.Type
|
return_type table.Type
|
||||||
}
|
}
|
||||||
|
@ -1006,9 +1019,15 @@ pub fn (expr Expr) position() token.Position {
|
||||||
AnonFn {
|
AnonFn {
|
||||||
return expr.decl.pos
|
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
|
return expr.pos
|
||||||
}
|
}
|
||||||
|
IfGuardExpr {
|
||||||
|
return expr.expr.position()
|
||||||
|
}
|
||||||
|
ComptimeCall {
|
||||||
|
return expr.left.position()
|
||||||
|
}
|
||||||
InfixExpr {
|
InfixExpr {
|
||||||
left_pos := expr.left.position()
|
left_pos := expr.left.position()
|
||||||
right_pos := expr.right.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
|
len: right_pos.pos - left_pos.pos + right_pos.len
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
CTempVar {
|
||||||
ast.Ident {}
|
|
||||||
ast.IfGuardExpr {}
|
|
||||||
ast.None {}
|
|
||||||
ast.ParExpr {}
|
|
||||||
ast.Type {}
|
|
||||||
ast.TypeOf {}
|
|
||||||
*/
|
|
||||||
else {
|
|
||||||
return token.Position{}
|
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 {
|
pub fn (stmt Stmt) position() token.Position {
|
||||||
match stmt {
|
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() }
|
GoStmt { return stmt.call_expr.position() }
|
||||||
BranchStmt { return token.Position{stmt.tok.len, stmt.tok.line_nr, stmt.tok.pos} }
|
|
||||||
TypeDecl { match stmt {
|
TypeDecl { match stmt {
|
||||||
AliasTypeDecl, FnTypeDecl, SumTypeDecl { return stmt.pos }
|
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
|
return
|
||||||
}
|
}
|
||||||
ast.BranchStmt {
|
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',
|
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
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2324,7 +2324,7 @@ fn (mut c Checker) stmt(node ast.Stmt) {
|
||||||
}
|
}
|
||||||
ast.BranchStmt {
|
ast.BranchStmt {
|
||||||
if c.in_for_count == 0 {
|
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 {
|
ast.CompFor {
|
||||||
|
|
|
@ -4,8 +4,9 @@ vlib/v/checker/tests/prefix_expr_decl_assign_err.vv:2:5: error: non-name on the
|
||||||
| ^
|
| ^
|
||||||
3 | (*d) := 14
|
3 | (*d) := 14
|
||||||
4 | }
|
4 | }
|
||||||
vlib/v/checker/tests/prefix_expr_decl_assign_err.vv:1:1: error: non-name `(*d)` on left side of `:=`
|
vlib/v/checker/tests/prefix_expr_decl_assign_err.vv:3:10: error: non-name `(*d)` on left side of `:=`
|
||||||
1 | fn main() {
|
1 | fn main() {
|
||||||
| ^
|
|
||||||
2 | &a := 12
|
2 | &a := 12
|
||||||
3 | (*d) := 14
|
3 | (*d) := 14
|
||||||
|
| ~~
|
||||||
|
4 | }
|
||||||
|
|
|
@ -301,7 +301,7 @@ pub fn (mut f Fmt) stmt(node ast.Stmt) {
|
||||||
f.writeln('}')
|
f.writeln('}')
|
||||||
}
|
}
|
||||||
ast.BranchStmt {
|
ast.BranchStmt {
|
||||||
match node.tok.kind {
|
match node.kind {
|
||||||
.key_break { f.writeln('break') }
|
.key_break { f.writeln('break') }
|
||||||
.key_continue { f.writeln('continue') }
|
.key_continue { f.writeln('continue') }
|
||||||
else {}
|
else {}
|
||||||
|
|
|
@ -794,9 +794,9 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
||||||
g.writeln('}')
|
g.writeln('}')
|
||||||
}
|
}
|
||||||
ast.BranchStmt {
|
ast.BranchStmt {
|
||||||
g.write_v_source_line_info(node.tok.position())
|
g.write_v_source_line_info(node.pos)
|
||||||
// continue or break
|
// continue or break
|
||||||
g.write(node.tok.kind.str())
|
g.write(node.kind.str())
|
||||||
g.writeln(';')
|
g.writeln(';')
|
||||||
}
|
}
|
||||||
ast.ConstDecl {
|
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) {
|
fn (mut g JsGen) gen_branch_stmt(it ast.BranchStmt) {
|
||||||
// continue or break
|
// continue or break
|
||||||
g.write(it.tok.kind.str())
|
g.write(it.kind.str())
|
||||||
g.writeln(';')
|
g.writeln(';')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -139,12 +139,14 @@ fn (mut p Parser) comp_for() ast.CompFor {
|
||||||
} else {
|
} else {
|
||||||
p.error('unknown kind `$for_val`, available are: `methods` or `fields`')
|
p.error('unknown kind `$for_val`, available are: `methods` or `fields`')
|
||||||
}
|
}
|
||||||
|
spos := p.tok.position()
|
||||||
stmts := p.parse_block()
|
stmts := p.parse_block()
|
||||||
return ast.CompFor{
|
return ast.CompFor{
|
||||||
val_var: val_var
|
val_var: val_var
|
||||||
stmts: stmts
|
stmts: stmts
|
||||||
kind: kind
|
kind: kind
|
||||||
typ: typ
|
typ: typ
|
||||||
|
pos: spos.extend(p.tok.position())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -230,6 +230,7 @@ fn (mut p Parser) match_expr() ast.MatchExpr {
|
||||||
types << parsed_type
|
types << parsed_type
|
||||||
exprs << ast.Type{
|
exprs << ast.Type{
|
||||||
typ: parsed_type
|
typ: parsed_type
|
||||||
|
pos: p.tok.position()
|
||||||
}
|
}
|
||||||
if p.tok.kind != .comma {
|
if p.tok.kind != .comma {
|
||||||
break
|
break
|
||||||
|
@ -298,6 +299,7 @@ fn (mut p Parser) match_expr() ast.MatchExpr {
|
||||||
high: expr2
|
high: expr2
|
||||||
has_low: true
|
has_low: true
|
||||||
has_high: true
|
has_high: true
|
||||||
|
pos: p.tok.position()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
exprs << expr
|
exprs << expr
|
||||||
|
|
|
@ -585,10 +585,12 @@ pub fn (mut p Parser) stmt(is_top_level bool) ast.Stmt {
|
||||||
}
|
}
|
||||||
if p.peek_tok.kind == .colon {
|
if p.peek_tok.kind == .colon {
|
||||||
// `label:`
|
// `label:`
|
||||||
|
spos := p.tok.position()
|
||||||
name := p.check_name()
|
name := p.check_name()
|
||||||
p.next()
|
p.next()
|
||||||
return ast.GotoLabel{
|
return ast.GotoLabel{
|
||||||
name: name
|
name: name
|
||||||
|
pos: spos.extend(p.tok.position())
|
||||||
}
|
}
|
||||||
} else if p.peek_tok.kind == .name {
|
} else if p.peek_tok.kind == .name {
|
||||||
p.error_with_pos('unexpected name `$p.peek_tok.lit`', p.peek_tok.position())
|
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
|
tok := p.tok
|
||||||
p.next()
|
p.next()
|
||||||
return ast.BranchStmt{
|
return ast.BranchStmt{
|
||||||
tok: tok
|
kind: tok.kind
|
||||||
|
pos: tok.position()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.key_unsafe {
|
.key_unsafe {
|
||||||
|
@ -635,25 +638,31 @@ pub fn (mut p Parser) stmt(is_top_level bool) ast.Stmt {
|
||||||
}
|
}
|
||||||
.key_defer {
|
.key_defer {
|
||||||
p.next()
|
p.next()
|
||||||
|
spos := p.tok.position()
|
||||||
stmts := p.parse_block()
|
stmts := p.parse_block()
|
||||||
return ast.DeferStmt{
|
return ast.DeferStmt{
|
||||||
stmts: stmts
|
stmts: stmts
|
||||||
|
pos: spos.extend(p.tok.position())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.key_go {
|
.key_go {
|
||||||
p.next()
|
p.next()
|
||||||
|
spos := p.tok.position()
|
||||||
expr := p.expr(0)
|
expr := p.expr(0)
|
||||||
// mut call_expr := &ast.CallExpr(0) // TODO
|
// mut call_expr := &ast.CallExpr(0) // TODO
|
||||||
// { call_expr = it }
|
// { call_expr = it }
|
||||||
return ast.GoStmt{
|
return ast.GoStmt{
|
||||||
call_expr: expr
|
call_expr: expr
|
||||||
|
pos: spos.extend(p.tok.position())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.key_goto {
|
.key_goto {
|
||||||
p.next()
|
p.next()
|
||||||
|
spos := p.tok.position()
|
||||||
name := p.check_name()
|
name := p.check_name()
|
||||||
return ast.GotoStmt{
|
return ast.GotoStmt{
|
||||||
name: name
|
name: name
|
||||||
|
pos: spos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.key_const {
|
.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) {
|
pub fn (mut p Parser) error(s string) {
|
||||||
p.error_with_pos(s, p.tok.position())
|
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{
|
return ast.ExprStmt{
|
||||||
expr: ast.ConcatExpr{
|
expr: ast.ConcatExpr{
|
||||||
vals: left
|
vals: left
|
||||||
|
pos: tok.position()
|
||||||
}
|
}
|
||||||
pos: tok.position()
|
pos: tok.position()
|
||||||
comments: left_comments
|
comments: left_comments
|
||||||
|
@ -967,6 +956,7 @@ pub fn (mut p Parser) name_expr() ast.Expr {
|
||||||
}
|
}
|
||||||
return ast.MapInit{
|
return ast.MapInit{
|
||||||
typ: map_type
|
typ: map_type
|
||||||
|
pos: p.tok.position()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// `chan typ{...}`
|
// `chan typ{...}`
|
||||||
|
@ -1153,6 +1143,7 @@ fn (mut p Parser) index_expr(left ast.Expr) ast.IndexExpr {
|
||||||
low: ast.Expr{}
|
low: ast.Expr{}
|
||||||
high: high
|
high: high
|
||||||
has_high: true
|
has_high: true
|
||||||
|
pos: pos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1176,6 +1167,7 @@ fn (mut p Parser) index_expr(left ast.Expr) ast.IndexExpr {
|
||||||
high: high
|
high: high
|
||||||
has_high: has_high
|
has_high: has_high
|
||||||
has_low: has_low
|
has_low: has_low
|
||||||
|
pos: pos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,6 +85,7 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr {
|
||||||
p.check(.rpar)
|
p.check(.rpar)
|
||||||
node = ast.ParExpr{
|
node = ast.ParExpr{
|
||||||
expr: node
|
expr: node
|
||||||
|
pos: p.tok.position()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.key_if {
|
.key_if {
|
||||||
|
@ -151,12 +152,14 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr {
|
||||||
p.check(.rpar)
|
p.check(.rpar)
|
||||||
}
|
}
|
||||||
.key_typeof {
|
.key_typeof {
|
||||||
|
spos := p.tok.position()
|
||||||
p.next()
|
p.next()
|
||||||
p.check(.lpar)
|
p.check(.lpar)
|
||||||
expr := p.expr(0)
|
expr := p.expr(0)
|
||||||
p.check(.rpar)
|
p.check(.rpar)
|
||||||
node = ast.TypeOf{
|
node = ast.TypeOf{
|
||||||
expr: expr
|
expr: expr
|
||||||
|
pos: spos.extend(p.tok.position())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.key_likely, .key_unlikely {
|
.key_likely, .key_unlikely {
|
||||||
|
|
Loading…
Reference in New Issue