checker: -warn-about-allocs; nil interface allocation fix; parser: tmpl @else [cond]

This commit is contained in:
Alexander Medvednikov 2024-05-29 11:48:26 +03:00
parent 09eaae5f7a
commit 2d5c457901
9 changed files with 104 additions and 4 deletions

View File

@ -3449,6 +3449,10 @@ fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type {
c.error('cannot cast `string` to `enum`', node.pos)
}
}
if c.pref.warn_about_allocs && to_sym.info is ast.Interface {
c.warn_alloc('cast to interface', node.pos)
}
node.typname = c.table.sym(node.typ).name
return node.typ
}

View File

@ -32,6 +32,12 @@ fn (mut c Checker) warn(s string, pos token.Pos) {
c.warn_or_error(s, pos, allow_warnings)
}
fn (mut c Checker) warn_alloc(s string, pos token.Pos) {
if !c.is_builtin_mod && c.mod !in ['strings', 'math', 'math.bits', 'builtin'] {
c.warn('allocation (${s})', pos)
}
}
fn (mut c Checker) error(message string, pos token.Pos) {
if (c.pref.translated || c.file.is_translated) && message.starts_with('mismatched types') {
// TODO: move this
@ -178,6 +184,8 @@ fn (mut c Checker) trace[T](fbase string, x &T) {
}
fn (mut c Checker) deprecate(kind string, name string, attrs []ast.Attr, pos token.Pos) {
// println('deprecate kind=${kind} name=${name} attrs=$attrs')
// print_backtrace()
mut deprecation_message := ''
now := time.now()
mut after_time := now
@ -205,6 +213,8 @@ fn (mut c Checker) deprecate(kind string, name string, attrs []ast.Attr, pos tok
} else if after_time == now {
c.warn(semicolonize('${start_message} has been deprecated', deprecation_message),
pos)
// c.warn(semicolonize('${start_message} has been deprecated!11 m=${deprecation_message}',
// deprecation_message), pos)
} else {
c.note(semicolonize('${start_message} will be deprecated after ${after_time.ymmdd()}, and will become an error after ${error_time.ymmdd()}',
deprecation_message), pos)

View File

@ -850,6 +850,9 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
}
}
}
if node.op == .plus && c.pref.warn_about_allocs {
c.warn_alloc('string concatenation', node.pos)
}
/*
if (node.left is ast.InfixExpr && node.left.op == .inc) ||
(node.right is ast.InfixExpr && node.right.op == .inc) {

View File

@ -2564,6 +2564,13 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ
if exp_sym.info.is_generic {
fname = g.generic_fn_name(exp_sym.info.concrete_types, fname)
}
// Do not allocate for `Interface(unsafe{nil})` casts
is_nil_cast := expr is ast.UnsafeExpr && expr.expr is ast.Nil
if is_nil_cast {
g.write('/*nili*/')
g.write('((void*)0)')
return
}
g.call_cfn_for_casting_expr(fname, expr, expected_is_ptr, exp_styp, got_is_ptr,
false, got_styp)
}

View File

@ -245,7 +245,9 @@ fn vweb_tmpl_${fn_name}() string {
// Remove new line byte
source.go_back(1)
source.writeln(parser.tmpl_str_end)
source.writeln(' } else { ')
pos := line.index('@else') or { continue }
source.writeln('}' + line[pos + 1..] + '{')
// source.writeln(' } else { ')
source.writeln(tmpl_str_start)
continue
}
@ -332,7 +334,7 @@ fn vweb_tmpl_${fn_name}() string {
}
if pos := line.index('%') {
// %translation_key => ${tr('translation_key')}
// %translation_key => ${tr('translation_key')}
mut line_ := line
if pos + 1 < line.len && line[pos + 1].is_letter() { //|| line[pos + 1] == '_' {
mut end := pos + 1

View File

@ -232,8 +232,9 @@ pub mut:
checker_match_exhaustive_cutoff_limit int = 12
thread_stack_size int = 8388608 // Change with `-thread-stack-size 4194304`. Note: on macos it was 524288, which is too small for more complex programs with many nested callexprs.
// wasm settings:
wasm_stack_top int = 1024 + (16 * 1024) // stack size for webassembly backend
wasm_validate bool // validate webassembly code, by calling `wasm-validate`
wasm_stack_top int = 1024 + (16 * 1024) // stack size for webassembly backend
wasm_validate bool // validate webassembly code, by calling `wasm-validate`
warn_about_allocs bool // -warn-about-allocs warngs about every single allocation, e.g. 'hi $name'. Mostly for low level development where manual memory management is used.
// temp
// use_64_int bool
}
@ -504,6 +505,9 @@ pub fn parse_args_and_show_errors(known_external_commands []string, args []strin
'-sourcemap' {
res.sourcemap = true
}
'-warn-about-allocs' {
res.warn_about_allocs = true
}
'-sourcemap-src-included' {
res.sourcemap_src_included = true
}

View File

@ -0,0 +1,6 @@
interface Resource {}
fn main() {
mut resource := &Resource(unsafe { nil })
_ = resource
}

63
vlib/veb/oauth/oauth.v Normal file
View File

@ -0,0 +1,63 @@
module oauth
import json
import net.http
pub enum TokenPostType {
form
json
}
pub struct Context {
token_url string
client_id string
client_secret string
token_post_type TokenPostType = .form
redirect_uri string
}
pub struct Request {
pub:
client_id string
client_secret string
code string
state string
}
pub fn (ctx &Context) get_token(code string) string {
oauth_request := Request{
client_id: ctx.client_id
client_secret: ctx.client_secret
code: code
// state: csrf
}
js := json.encode(oauth_request)
if ctx.token_post_type == .json {
resp := http.post_json(ctx.token_url, js) or {
// app.info(err.msg())
// return app.redirect_to_index()
return ''
}
println('OAUTH RESPONSE ${resp}')
return resp.body
} else {
resp := http.post_form(ctx.token_url, {
'client_id': ctx.client_id
'client_secret': ctx.client_secret
'code': code
'grant_type': 'authorization_code'
//'scope': bot
'redirect_uri': ctx.redirect_uri
}) or {
// app.info(err.msg())
// return app.redirect_to_index()
return ''
}
println('OAUTH RESPONSE ${resp}')
return resp.body
}
return ''
}

View File

@ -1,3 +1,4 @@
//@[deprecated: '`x.vweb` is now `veb`. The module is no longer experimental.']
module vweb
import io