parser/checker/fmt: optimize scope lookups by storing object with ident & add if expr smartcast support to vfmt (#5935)
parent
ebbc7bd471
commit
d46a89b90d
|
@ -360,6 +360,8 @@ pub mut:
|
||||||
typ table.Type
|
typ table.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: (joe) remove completely, use ident.obj
|
||||||
|
// instead which points to the scope object
|
||||||
pub struct IdentVar {
|
pub struct IdentVar {
|
||||||
pub mut:
|
pub mut:
|
||||||
typ table.Type
|
typ table.Type
|
||||||
|
@ -387,6 +389,7 @@ pub:
|
||||||
tok_kind token.Kind
|
tok_kind token.Kind
|
||||||
pos token.Position
|
pos token.Position
|
||||||
pub mut:
|
pub mut:
|
||||||
|
obj ScopeObject
|
||||||
mod string
|
mod string
|
||||||
name string
|
name string
|
||||||
kind IdentKind
|
kind IdentKind
|
||||||
|
|
|
@ -679,8 +679,7 @@ fn (mut c Checker) fail_if_immutable(expr ast.Expr) (string, token.Position) {
|
||||||
return '', pos
|
return '', pos
|
||||||
}
|
}
|
||||||
ast.Ident {
|
ast.Ident {
|
||||||
scope := c.file.scope.innermost(expr.pos.pos)
|
if expr.obj is ast.Var as v {
|
||||||
if v := scope.find_var(expr.name) {
|
|
||||||
if !v.is_mut && !v.typ.is_ptr() {
|
if !v.is_mut && !v.typ.is_ptr() {
|
||||||
c.error('`$expr.name` is immutable, declare it with `mut` to make it mutable',
|
c.error('`$expr.name` is immutable, declare it with `mut` to make it mutable',
|
||||||
expr.pos)
|
expr.pos)
|
||||||
|
@ -1628,7 +1627,6 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
|
||||||
if is_decl {
|
if is_decl {
|
||||||
c.check_valid_snake_case(left.name, 'variable name', left.pos)
|
c.check_valid_snake_case(left.name, 'variable name', left.pos)
|
||||||
}
|
}
|
||||||
mut scope := c.file.scope.innermost(assign_stmt.pos.pos)
|
|
||||||
mut ident_var_info := left.var_info()
|
mut ident_var_info := left.var_info()
|
||||||
if ident_var_info.share == .shared_t {
|
if ident_var_info.share == .shared_t {
|
||||||
left_type = left_type.set_flag(.shared_f)
|
left_type = left_type.set_flag(.shared_f)
|
||||||
|
@ -1639,7 +1637,13 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
|
||||||
assign_stmt.left_types[i] = left_type
|
assign_stmt.left_types[i] = left_type
|
||||||
ident_var_info.typ = left_type
|
ident_var_info.typ = left_type
|
||||||
left.info = ident_var_info
|
left.info = ident_var_info
|
||||||
scope.update_var_type(left.name, left_type)
|
if left_type != 0 {
|
||||||
|
if left.obj is ast.Var as v {
|
||||||
|
v.typ = left_type
|
||||||
|
} else if left.obj is ast.GlobalDecl as v {
|
||||||
|
v.typ = left_type
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast.PrefixExpr {
|
ast.PrefixExpr {
|
||||||
|
@ -2419,13 +2423,14 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type {
|
||||||
} else if ident.kind == .unresolved {
|
} else if ident.kind == .unresolved {
|
||||||
// first use
|
// first use
|
||||||
start_scope := c.file.scope.innermost(ident.pos.pos)
|
start_scope := c.file.scope.innermost(ident.pos.pos)
|
||||||
if obj := start_scope.find(ident.name) {
|
if obj1 := start_scope.find(ident.name) {
|
||||||
match obj {
|
match obj1 as obj {
|
||||||
ast.GlobalDecl {
|
ast.GlobalDecl {
|
||||||
ident.kind = .global
|
ident.kind = .global
|
||||||
ident.info = ast.IdentVar{
|
ident.info = ast.IdentVar{
|
||||||
typ: obj.typ
|
typ: obj.typ
|
||||||
}
|
}
|
||||||
|
ident.obj = obj1
|
||||||
return obj.typ
|
return obj.typ
|
||||||
}
|
}
|
||||||
ast.Var {
|
ast.Var {
|
||||||
|
@ -2460,6 +2465,7 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type {
|
||||||
// }
|
// }
|
||||||
// } else {
|
// } else {
|
||||||
obj.typ = typ
|
obj.typ = typ
|
||||||
|
ident.obj = obj1
|
||||||
// unwrap optional (`println(x)`)
|
// unwrap optional (`println(x)`)
|
||||||
if is_optional {
|
if is_optional {
|
||||||
return typ.clear_flag(.optional)
|
return typ.clear_flag(.optional)
|
||||||
|
@ -2474,8 +2480,8 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type {
|
||||||
if !name.contains('.') && ident.mod != 'builtin' {
|
if !name.contains('.') && ident.mod != 'builtin' {
|
||||||
name = '${ident.mod}.$ident.name'
|
name = '${ident.mod}.$ident.name'
|
||||||
}
|
}
|
||||||
if obj := c.file.global_scope.find(name) {
|
if obj1 := c.file.global_scope.find(name) {
|
||||||
match obj {
|
match obj1 as obj {
|
||||||
ast.ConstField {
|
ast.ConstField {
|
||||||
mut typ := obj.typ
|
mut typ := obj.typ
|
||||||
if typ == 0 {
|
if typ == 0 {
|
||||||
|
@ -2487,6 +2493,7 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type {
|
||||||
typ: typ
|
typ: typ
|
||||||
}
|
}
|
||||||
obj.typ = typ
|
obj.typ = typ
|
||||||
|
ident.obj = obj1
|
||||||
return typ
|
return typ
|
||||||
}
|
}
|
||||||
else {}
|
else {}
|
||||||
|
@ -2745,10 +2752,9 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, type_sym table.TypeSymbol
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut c Checker) lock_expr(mut node ast.LockExpr) table.Type {
|
pub fn (mut c Checker) lock_expr(mut node ast.LockExpr) table.Type {
|
||||||
scope := c.file.scope.innermost(node.pos.pos)
|
|
||||||
for id in node.lockeds {
|
for id in node.lockeds {
|
||||||
c.ident(mut id)
|
c.ident(mut id)
|
||||||
if v := scope.find_var(id.name) {
|
if id.obj is ast.Var as v {
|
||||||
if v.typ.share() != .shared_t {
|
if v.typ.share() != .shared_t {
|
||||||
c.error('`$id.name` must be declared `shared` to be locked', id.pos)
|
c.error('`$id.name` must be declared `shared` to be locked', id.pos)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1286,10 +1286,25 @@ pub fn (mut f Fmt) if_expr(it ast.IfExpr) {
|
||||||
(it.is_expr || f.is_assign)
|
(it.is_expr || f.is_assign)
|
||||||
f.single_line_if = single_line
|
f.single_line_if = single_line
|
||||||
for i, branch in it.branches {
|
for i, branch in it.branches {
|
||||||
|
// NOTE: taken from checker in if_expr(). used for smartcast
|
||||||
|
mut is_variable := false
|
||||||
|
if branch.cond is ast.InfixExpr {
|
||||||
|
infix := branch.cond as ast.InfixExpr
|
||||||
|
if infix.op == .key_is &&
|
||||||
|
(infix.left is ast.Ident || infix.left is ast.SelectorExpr) &&
|
||||||
|
infix.right is ast.Type {
|
||||||
|
right_expr := infix.right as ast.Type
|
||||||
|
is_variable = if infix.left is ast.Ident { (infix.left as ast.Ident).kind ==
|
||||||
|
.variable } else { true }
|
||||||
|
}
|
||||||
|
}
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
f.comments(branch.comments, {})
|
f.comments(branch.comments, {})
|
||||||
f.write('if ')
|
f.write('if ')
|
||||||
f.expr(branch.cond)
|
f.expr(branch.cond)
|
||||||
|
if is_variable && branch.left_as_name.len > 0 {
|
||||||
|
f.write(' as $branch.left_as_name')
|
||||||
|
}
|
||||||
f.write(' {')
|
f.write(' {')
|
||||||
} else if i < it.branches.len - 1 || !it.has_else {
|
} else if i < it.branches.len - 1 || !it.has_else {
|
||||||
if branch.comments.len > 0 {
|
if branch.comments.len > 0 {
|
||||||
|
@ -1300,6 +1315,9 @@ pub fn (mut f Fmt) if_expr(it ast.IfExpr) {
|
||||||
}
|
}
|
||||||
f.write('else if ')
|
f.write('else if ')
|
||||||
f.expr(branch.cond)
|
f.expr(branch.cond)
|
||||||
|
if is_variable && branch.left_as_name.len > 0 {
|
||||||
|
f.write(' as $branch.left_as_name')
|
||||||
|
}
|
||||||
f.write(' {')
|
f.write(' {')
|
||||||
} else if i == it.branches.len - 1 && it.has_else {
|
} else if i == it.branches.len - 1 && it.has_else {
|
||||||
if branch.comments.len > 0 {
|
if branch.comments.len > 0 {
|
||||||
|
|
|
@ -116,22 +116,16 @@ fn (mut p Parser) partial_assign_stmt(left []ast.Expr, left_comments []ast.Comme
|
||||||
if lx.info is ast.IdentVar {
|
if lx.info is ast.IdentVar {
|
||||||
share = (lx.info as ast.IdentVar).share
|
share = (lx.info as ast.IdentVar).share
|
||||||
}
|
}
|
||||||
if left.len == right.len {
|
mut v := ast.Var{
|
||||||
p.scope.register(lx.name, ast.Var{
|
|
||||||
name: lx.name
|
name: lx.name
|
||||||
expr: right[i]
|
expr: if left.len == right.len { right[i] } else { ast.Expr{} }
|
||||||
share: share
|
share: share
|
||||||
is_mut: lx.is_mut || p.inside_for
|
is_mut: lx.is_mut || p.inside_for
|
||||||
pos: lx.pos
|
pos: lx.pos
|
||||||
})
|
|
||||||
} else {
|
|
||||||
p.scope.register(lx.name, ast.Var{
|
|
||||||
name: lx.name
|
|
||||||
share: share
|
|
||||||
is_mut: lx.is_mut || p.inside_for
|
|
||||||
pos: lx.pos
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
obj := ast.ScopeObject(v)
|
||||||
|
lx.obj = obj
|
||||||
|
p.scope.register(lx.name, obj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast.IndexExpr {
|
ast.IndexExpr {
|
||||||
|
|
|
@ -11,8 +11,10 @@ fn (mut p Parser) lock_expr() ast.LockExpr {
|
||||||
for p.tok.kind == .name {
|
for p.tok.kind == .name {
|
||||||
lockeds << ast.Ident{
|
lockeds << ast.Ident{
|
||||||
language: table.Language.v
|
language: table.Language.v
|
||||||
kind: .variable
|
// kind is set in checker once ident is processed
|
||||||
|
// kind: .variable
|
||||||
pos: p.tok.position()
|
pos: p.tok.position()
|
||||||
|
mod: p.mod
|
||||||
name: p.tok.lit
|
name: p.tok.lit
|
||||||
is_mut: true
|
is_mut: true
|
||||||
info: ast.IdentVar{}
|
info: ast.IdentVar{}
|
||||||
|
|
Loading…
Reference in New Issue