all: comptime_call - update tmpl scope vars with caller scope vars after their properties got updated in checker

pull/13619/head
Joe Conigliaro 2022-03-01 02:13:29 +11:00
parent 0028e557f9
commit 3b6e122d9d
No known key found for this signature in database
GPG Key ID: C12F7136C08206F1
4 changed files with 23 additions and 20 deletions

View File

@ -37,6 +37,7 @@ fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) ast.Type {
} }
mut c2 := new_checker(c.table, pref2) mut c2 := new_checker(c.table, pref2)
c2.check(node.vweb_tmpl) c2.check(node.vweb_tmpl)
mut caller_scope := c.fn_scope.innermost(node.pos.pos)
mut i := 0 // tmp counter var for skipping first three tmpl vars mut i := 0 // tmp counter var for skipping first three tmpl vars
for k, _ in c2.file.scope.children[0].objects { for k, _ in c2.file.scope.children[0].objects {
if i < 2 { if i < 2 {
@ -44,10 +45,17 @@ fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) ast.Type {
i++ i++
continue continue
} }
if k in c.fn_scope.objects && unsafe { c.fn_scope.objects[k] } is ast.Var { tmpl_obj := unsafe { c2.file.scope.children[0].objects[k] }
mut vsc := unsafe { c.fn_scope.objects[k] } as ast.Var if tmpl_obj is ast.Var {
vsc.is_used = true if mut caller_var := caller_scope.find_var(tmpl_obj.name) {
c.fn_scope.objects[k] = vsc // var is used in the tmpl so mark it as used in the caller
caller_var.is_used = true
// update props from the caller scope var to the tmpl scope var
c2.file.scope.children[0].objects[k] = ast.Var{
...(*caller_var)
pos: tmpl_obj.pos
}
}
} }
} }
c.warnings << c2.warnings c.warnings << c2.warnings

View File

@ -3665,8 +3665,10 @@ fn (mut g Gen) ident(node ast.Ident) {
g.write('${name}.val') g.write('${name}.val')
return return
} }
scope := g.file.scope.innermost(node.pos.pos) // TODO: investigate why node.obj is pointing to outdated ScopeObject?
if v := scope.find_var(node.name) { // v := node.obj
// if v is ast.Var {
if v := node.scope.find_var(node.name) {
is_auto_heap = v.is_auto_heap && (!g.is_assign_lhs || g.assign_op != .decl_assign) is_auto_heap = v.is_auto_heap && (!g.is_assign_lhs || g.assign_op != .decl_assign)
if is_auto_heap { if is_auto_heap {
g.write('(*(') g.write('(*(')

View File

@ -117,9 +117,8 @@ fn (mut g Gen) comptime_call(mut node ast.ComptimeCall) {
// try to see if we need to pass a pointer // try to see if we need to pass a pointer
if node.left is ast.Ident { if node.left is ast.Ident {
scope := g.file.scope.innermost(node.pos.pos) if node.left.obj is ast.Var {
if v := scope.find_var(node.left.name) { if m.params[0].typ.is_ptr() && !node.left.obj.typ.is_ptr() {
if m.params[0].typ.is_ptr() && !v.typ.is_ptr() {
g.write('&') g.write('&')
} }
} }

View File

@ -260,21 +260,15 @@ fn (mut p Parser) comptime_call() ast.ComptimeCall {
file.path = tmpl_path file.path = tmpl_path
// copy vars from current fn scope into vweb_tmpl scope // copy vars from current fn scope into vweb_tmpl scope
for stmt in file.stmts { for stmt in file.stmts {
if stmt is ast.FnDecl { if mut stmt is ast.FnDecl {
if stmt.name == 'main.vweb_tmpl_$tmp_fn_name' { if stmt.name == 'main.vweb_tmpl_$tmp_fn_name' {
// mut tmpl_scope := file.scope.innermost(stmt.body_pos.pos)
mut tmpl_scope := stmt.scope
for _, obj in p.scope.objects { for _, obj in p.scope.objects {
if obj is ast.Var { if mut obj is ast.Var {
mut v := obj stmt.scope.register(ast.Var{
v.pos = stmt.body_pos ...obj
tmpl_scope.register(ast.Var{
...v
is_used: true is_used: true
pos: stmt.body_pos
}) })
// set the controller action var to used
// if it's unused in the template it will warn
v.is_used = true
} }
} }
break break