tmpl: fix $tmpl comptime operation only working in return statement (#11541)

pull/11553/head^2
05st 2021-09-19 15:22:26 -05:00 committed by GitHub
parent 2534946ead
commit f9f4867c25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 8 deletions

View File

@ -4829,6 +4829,12 @@ fn (mut g Gen) gen_optional_error(target_type ast.Type, expr ast.Expr) {
fn (mut g Gen) return_stmt(node ast.Return) {
g.write_v_source_line_info(node.pos)
g.inside_return = true
defer {
g.inside_return = false
}
if node.exprs.len > 0 {
// skip `return $vweb.html()`
if node.exprs[0] is ast.ComptimeCall {
@ -4838,10 +4844,6 @@ fn (mut g Gen) return_stmt(node ast.Return) {
}
}
g.inside_return = true
defer {
g.inside_return = false
}
// got to do a correct check for multireturn
sym := g.table.get_type_symbol(g.fn_decl.return_type)
fn_return_is_multi := sym.kind == .multi_return

View File

@ -42,6 +42,12 @@ fn (mut g Gen) comptime_call(node ast.ComptimeCall) {
}
if node.is_vweb {
is_html := node.method_name == 'html'
mut cur_line := ''
if !is_html {
cur_line = g.go_before_stmt(0)
}
for stmt in node.vweb_tmpl.stmts {
if stmt is ast.FnDecl {
// insert stmts from vweb_tmpl fn
@ -49,19 +55,24 @@ fn (mut g Gen) comptime_call(node ast.ComptimeCall) {
if is_html {
g.inside_vweb_tmpl = true
}
g.stmts(stmt.stmts)
g.stmts(stmt.stmts.filter(it !is ast.Return))
g.inside_vweb_tmpl = false
break
}
}
}
if is_html {
// return vweb html template
g.writeln('vweb__Context_html(&app->Context, _tmpl_res_$g.fn_decl.name); strings__Builder_free(&sb); string_free(&_tmpl_res_$g.fn_decl.name);')
} else {
// return $tmpl string
fn_name := g.fn_decl.name.replace('.', '__')
g.writeln('return _tmpl_res_$fn_name;')
g.write(cur_line)
if g.inside_return {
g.write('return ')
}
g.write('_tmpl_res_$fn_name')
}
return
}

View File

@ -67,7 +67,7 @@ pub fn (mut p Parser) compile_template_file(template_file string, fn_name string
source.writeln('
import strings
// === vweb html template ===
fn vweb_tmpl_${fn_name}() {
fn vweb_tmpl_${fn_name}() string {
mut sb := strings.new_builder($lstartlength)\n
')
@ -237,6 +237,7 @@ mut sb := strings.new_builder($lstartlength)\n
}
source.writeln(parser.tmpl_str_end)
source.writeln('_tmpl_res_$fn_name := sb.str() ')
source.writeln('return _tmpl_res_$fn_name')
source.writeln('}')
source.writeln('// === end of vweb html template ===')
result := source.str()

View File

@ -10,8 +10,21 @@ fn one() string {
return $tmpl('tmpl/base.txt')
}
fn outside_return() string {
name := 'Peter'
age := 25
numbers := [1, 2, 3]
downloads := {
'vlang/ui': '3201'
'vlang/vtl': '123'
}
ignored := true
result := $tmpl('tmpl/base.txt')
return result
}
fn test_tmpl() {
assert one().trim_space() == "name: Peter
expected := "name: Peter
age: 25
numbers: [1, 2, 3]
@ -41,6 +54,9 @@ this is not ignored
so, it's basically true"
assert one().trim_space() == expected
assert outside_return().trim_space() == expected
}
fn test_tmpl_in_anon_fn() {