parser: check for using comptime $veb.html()/$vweb.html(), without importing veb or vweb (#21957)

This commit is contained in:
yuyi 2024-07-29 21:55:29 +08:00 committed by GitHub
parent 5e435a7111
commit c9c38d5c11
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 43 additions and 4 deletions

View file

@ -46,11 +46,11 @@ pub fn (mut app App) index(mut ctx Context) veb.Result {
show := true show := true
hello := 'Hello world from veb, request number: ${c}' hello := 'Hello world from veb, request number: ${c}'
numbers := [1, 2, 3] numbers := [1, 2, 3]
return $vweb.html() return $veb.html()
} }
pub fn (mut app App) custom_template(mut ctx Context) veb.Result { pub fn (mut app App) custom_template(mut ctx Context) veb.Result {
return $vweb.html('custom.html') return $veb.html('custom.html')
} }
pub fn (mut app App) show_text(mut ctx Context) veb.Result { pub fn (mut app App) show_text(mut ctx Context) veb.Result {

View file

@ -1938,6 +1938,7 @@ pub:
method_pos token.Pos method_pos token.Pos
scope &Scope = unsafe { nil } scope &Scope = unsafe { nil }
is_vweb bool is_vweb bool
is_veb bool
is_embed bool // $embed_file(...) is_embed bool // $embed_file(...)
is_env bool // $env(...) // TODO: deprecate after $d() is stable is_env bool // $env(...) // TODO: deprecate after $d() is stable
is_compile_value bool // $d(...) is_compile_value bool // $d(...)

View file

@ -2153,12 +2153,20 @@ pub fn (mut f Fmt) comptime_call(node ast.ComptimeCall) {
if node.is_vweb { if node.is_vweb {
if node.method_name == 'html' { if node.method_name == 'html' {
if node.args.len == 1 && node.args[0].expr is ast.StringLiteral { if node.args.len == 1 && node.args[0].expr is ast.StringLiteral {
if node.is_veb {
f.write('\$veb.html(')
} else {
f.write('\$vweb.html(') f.write('\$vweb.html(')
}
f.expr(node.args[0].expr) f.expr(node.args[0].expr)
f.write(')') f.write(')')
} else {
if node.is_veb {
f.write('\$veb.html()')
} else { } else {
f.write('\$vweb.html()') f.write('\$vweb.html()')
} }
}
} else { } else {
f.write('\$tmpl(') f.write('\$tmpl(')
f.expr(node.args[0].expr) f.expr(node.args[0].expr)

View file

@ -106,6 +106,7 @@ fn (mut p Parser) comptime_call() ast.ComptimeCall {
} }
start_pos := p.tok.pos() start_pos := p.tok.pos()
p.check(.dollar) p.check(.dollar)
mut is_veb := false
error_msg := 'only `\$tmpl()`, `\$env()`, `\$embed_file()`, `\$pkgconfig()`, `\$vweb.html()`, `\$compile_error()`, `\$compile_warn()`, `\$d()` and `\$res()` comptime functions are supported right now' error_msg := 'only `\$tmpl()`, `\$env()`, `\$embed_file()`, `\$pkgconfig()`, `\$vweb.html()`, `\$compile_error()`, `\$compile_warn()`, `\$d()` and `\$res()` comptime functions are supported right now'
if p.peek_tok.kind == .dot { if p.peek_tok.kind == .dot {
name := p.check_name() // skip `vweb.html()` TODO name := p.check_name() // skip `vweb.html()` TODO
@ -113,6 +114,17 @@ fn (mut p Parser) comptime_call() ast.ComptimeCall {
p.error(error_msg) p.error(error_msg)
return err_node return err_node
} }
import_mods := p.ast_imports.map(it.mod)
if name == 'vweb' && 'vweb' !in import_mods && 'x.vweb' !in import_mods {
p.error_with_pos('`\$vweb` cannot be used without importing vweb', start_pos.extend(p.prev_tok.pos()))
return err_node
} else if name == 'veb' {
if 'veb' !in import_mods {
p.error_with_pos('`\$veb` cannot be used without importing veb', start_pos.extend(p.prev_tok.pos()))
return err_node
}
is_veb = true
}
p.check(.dot) p.check(.dot)
} }
method_name := p.check_name() method_name := p.check_name()
@ -265,6 +277,7 @@ fn (mut p Parser) comptime_call() ast.ComptimeCall {
return ast.ComptimeCall{ return ast.ComptimeCall{
scope: unsafe { nil } scope: unsafe { nil }
is_vweb: true is_vweb: true
is_veb: is_veb
method_name: method_name method_name: method_name
args_var: literal_string_param args_var: literal_string_param
args: [arg] args: [arg]
@ -306,6 +319,7 @@ fn (mut p Parser) comptime_call() ast.ComptimeCall {
return ast.ComptimeCall{ return ast.ComptimeCall{
scope: unsafe { nil } scope: unsafe { nil }
is_vweb: true is_vweb: true
is_veb: is_veb
vweb_tmpl: file vweb_tmpl: file
method_name: method_name method_name: method_name
args_var: literal_string_param args_var: literal_string_param

View file

@ -0,0 +1,5 @@
vlib/v/parser/tests/comptime_veb_without_import_veb_err.vv:2:2: error: `$veb` cannot be used without importing veb
1 | fn main() {
2 | $veb.html('index.html')
| ~~~~
3 | }

View file

@ -0,0 +1,3 @@
fn main() {
$veb.html('index.html')
}

View file

@ -0,0 +1,5 @@
vlib/v/parser/tests/comptime_vweb_without_import_vweb_err.vv:2:2: error: `$vweb` cannot be used without importing vweb
1 | fn main() {
2 | $vweb.html('index.html')
| ~~~~~
3 | }

View file

@ -0,0 +1,3 @@
fn main() {
$vweb.html('index.html')
}