parser, cgen: fix multiple comptime tmpl in one function (#12757)
parent
2fbf7fea75
commit
e433badcb8
|
@ -62,12 +62,12 @@ fn (mut g Gen) comptime_call(mut node ast.ComptimeCall) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn_name := g.fn_decl.name.replace('.', '__') + node.pos.pos.str()
|
||||||
if is_html {
|
if is_html {
|
||||||
// return vweb html template
|
// 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);')
|
g.writeln('vweb__Context_html(&app->Context, _tmpl_res_$fn_name); strings__Builder_free(&sb_$fn_name); string_free(&_tmpl_res_$fn_name);')
|
||||||
} else {
|
} else {
|
||||||
// return $tmpl string
|
// return $tmpl string
|
||||||
fn_name := g.fn_decl.name.replace('.', '__')
|
|
||||||
g.write(cur_line)
|
g.write(cur_line)
|
||||||
if g.inside_return {
|
if g.inside_return {
|
||||||
g.write('return ')
|
g.write('return ')
|
||||||
|
|
|
@ -192,7 +192,7 @@ fn (mut p Parser) comptime_call() ast.ComptimeCall {
|
||||||
}
|
}
|
||||||
// println('path is now "$path"')
|
// println('path is now "$path"')
|
||||||
}
|
}
|
||||||
tmp_fn_name := p.cur_fn_name.replace('.', '__')
|
tmp_fn_name := p.cur_fn_name.replace('.', '__') + start_pos.pos.str()
|
||||||
$if trace_comptime ? {
|
$if trace_comptime ? {
|
||||||
println('>>> compiling comptime template file "$path" for $tmp_fn_name')
|
println('>>> compiling comptime template file "$path" for $tmp_fn_name')
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,10 +8,6 @@ import v.errors
|
||||||
import os
|
import os
|
||||||
import strings
|
import strings
|
||||||
|
|
||||||
const tmpl_str_start = "sb.write_string('"
|
|
||||||
|
|
||||||
const tmpl_str_end = "')\n"
|
|
||||||
|
|
||||||
enum State {
|
enum State {
|
||||||
html
|
html
|
||||||
css // <style>
|
css // <style>
|
||||||
|
@ -63,15 +59,17 @@ pub fn (mut p Parser) compile_template_file(template_file string, fn_name string
|
||||||
}
|
}
|
||||||
basepath := os.dir(template_file)
|
basepath := os.dir(template_file)
|
||||||
lstartlength := lines.len * 30
|
lstartlength := lines.len * 30
|
||||||
|
tmpl_str_start := "sb_${fn_name}.write_string('"
|
||||||
|
tmpl_str_end := "')\n"
|
||||||
mut source := strings.new_builder(1000)
|
mut source := strings.new_builder(1000)
|
||||||
source.writeln('
|
source.writeln('
|
||||||
import strings
|
import strings
|
||||||
// === vweb html template ===
|
// === vweb html template ===
|
||||||
fn vweb_tmpl_${fn_name}() string {
|
fn vweb_tmpl_${fn_name}() string {
|
||||||
mut sb := strings.new_builder($lstartlength)\n
|
mut sb_$fn_name := strings.new_builder($lstartlength)\n
|
||||||
|
|
||||||
')
|
')
|
||||||
source.write_string(parser.tmpl_str_start)
|
source.write_string(tmpl_str_start)
|
||||||
mut state := State.html
|
mut state := State.html
|
||||||
mut in_span := false
|
mut in_span := false
|
||||||
mut end_of_line_pos := 0
|
mut end_of_line_pos := 0
|
||||||
|
@ -172,27 +170,27 @@ mut sb := strings.new_builder($lstartlength)\n
|
||||||
source.write_string(line[pos + 6..line.len - 1])
|
source.write_string(line[pos + 6..line.len - 1])
|
||||||
source.writeln('" rel="stylesheet" type="text/css">')
|
source.writeln('" rel="stylesheet" type="text/css">')
|
||||||
} else if line.contains('@if ') {
|
} else if line.contains('@if ') {
|
||||||
source.writeln(parser.tmpl_str_end)
|
source.writeln(tmpl_str_end)
|
||||||
pos := line.index('@if') or { continue }
|
pos := line.index('@if') or { continue }
|
||||||
source.writeln('if ' + line[pos + 4..] + '{')
|
source.writeln('if ' + line[pos + 4..] + '{')
|
||||||
source.writeln(parser.tmpl_str_start)
|
source.writeln(tmpl_str_start)
|
||||||
} else if line.contains('@end') {
|
} else if line.contains('@end') {
|
||||||
// Remove new line byte
|
// Remove new line byte
|
||||||
source.go_back(1)
|
source.go_back(1)
|
||||||
source.writeln(parser.tmpl_str_end)
|
source.writeln(tmpl_str_end)
|
||||||
source.writeln('}')
|
source.writeln('}')
|
||||||
source.writeln(parser.tmpl_str_start)
|
source.writeln(tmpl_str_start)
|
||||||
} else if line.contains('@else') {
|
} else if line.contains('@else') {
|
||||||
// Remove new line byte
|
// Remove new line byte
|
||||||
source.go_back(1)
|
source.go_back(1)
|
||||||
source.writeln(parser.tmpl_str_end)
|
source.writeln(tmpl_str_end)
|
||||||
source.writeln(' } else { ')
|
source.writeln(' } else { ')
|
||||||
source.writeln(parser.tmpl_str_start)
|
source.writeln(tmpl_str_start)
|
||||||
} else if line.contains('@for') {
|
} else if line.contains('@for') {
|
||||||
source.writeln(parser.tmpl_str_end)
|
source.writeln(tmpl_str_end)
|
||||||
pos := line.index('@for') or { continue }
|
pos := line.index('@for') or { continue }
|
||||||
source.writeln('for ' + line[pos + 4..] + '{')
|
source.writeln('for ' + line[pos + 4..] + '{')
|
||||||
source.writeln(parser.tmpl_str_start)
|
source.writeln(tmpl_str_start)
|
||||||
} else if state == .html && line.starts_with('span.') && line.ends_with('{') {
|
} else if state == .html && line.starts_with('span.') && line.ends_with('{') {
|
||||||
// `span.header {` => `<span class='header'>`
|
// `span.header {` => `<span class='header'>`
|
||||||
class := line.find_between('span.', '{').trim_space()
|
class := line.find_between('span.', '{').trim_space()
|
||||||
|
@ -228,7 +226,7 @@ mut sb := strings.new_builder($lstartlength)\n
|
||||||
} else {
|
} else {
|
||||||
// HTML, may include `@var`
|
// HTML, may include `@var`
|
||||||
// escaped by cgen, unless it's a `vweb.RawHtml` string
|
// escaped by cgen, unless it's a `vweb.RawHtml` string
|
||||||
trailing_bs := parser.tmpl_str_end + 'sb.write_b(92)\n' + parser.tmpl_str_start
|
trailing_bs := tmpl_str_end + 'sb_${fn_name}.write_b(92)\n' + tmpl_str_start
|
||||||
round1 := ['\\', '\\\\', r"'", "\\'", r'@', r'$']
|
round1 := ['\\', '\\\\', r"'", "\\'", r'@', r'$']
|
||||||
round2 := [r'$$', r'\@', r'.$', r'.@']
|
round2 := [r'$$', r'\@', r'.$', r'.@']
|
||||||
rline := line.replace_each(round1).replace_each(round2)
|
rline := line.replace_each(round1).replace_each(round2)
|
||||||
|
@ -239,8 +237,8 @@ mut sb := strings.new_builder($lstartlength)\n
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
source.writeln(parser.tmpl_str_end)
|
source.writeln(tmpl_str_end)
|
||||||
source.writeln('_tmpl_res_$fn_name := sb.str() ')
|
source.writeln('_tmpl_res_$fn_name := sb_${fn_name}.str() ')
|
||||||
source.writeln('return _tmpl_res_$fn_name')
|
source.writeln('return _tmpl_res_$fn_name')
|
||||||
source.writeln('}')
|
source.writeln('}')
|
||||||
source.writeln('// === end of vweb html template ===')
|
source.writeln('// === end of vweb html template ===')
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
fn test_multi_comptime_tmpl_in_one_fn() {
|
||||||
|
a := 'A'
|
||||||
|
at := $tmpl('tmpl/a.txt')
|
||||||
|
println(at)
|
||||||
|
assert at.contains('A')
|
||||||
|
|
||||||
|
b := 'B'
|
||||||
|
bt := $tmpl('tmpl/b.txt')
|
||||||
|
println(bt)
|
||||||
|
assert bt.contains('B')
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
@a
|
|
@ -0,0 +1 @@
|
||||||
|
@b
|
Loading…
Reference in New Issue