mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
parser,fmt: implement [manualfree] module abc
for opting out *all* fns in a given .v from autofree
This commit is contained in:
parent
083dc23db8
commit
46a5c487c1
@ -7,7 +7,7 @@
|
||||
- `byte.str()` has been fixed and works like with all other numbers. `byte.ascii_str()` has been added.
|
||||
- Smart cast in for loops: `for mut x is string {}`.
|
||||
- `[noinit]` struct attribute to disallow direct struct initialization with `Foo{}`.
|
||||
- `[manualfree]` attribute for functions, that want to do their own memory management.
|
||||
- support `[manualfree] fn f1(){}` and `[manualfree] module m1`, for functions doing their own memory management.
|
||||
|
||||
## V 0.2.1
|
||||
*30 Dec 2020*
|
||||
|
@ -131,6 +131,7 @@ pub fn (e &SelectorExpr) root_ident() Ident {
|
||||
pub struct Module {
|
||||
pub:
|
||||
name string
|
||||
attrs []table.Attr
|
||||
pos token.Position
|
||||
is_skipped bool // module main can be skipped in single file programs
|
||||
}
|
||||
|
@ -193,6 +193,7 @@ pub fn (mut f Fmt) mod(mod ast.Module) {
|
||||
if mod.is_skipped {
|
||||
return
|
||||
}
|
||||
f.attrs(mod.attrs)
|
||||
f.writeln('module $mod.name\n')
|
||||
}
|
||||
|
||||
|
18
vlib/v/fmt/tests/manualfree_keep.v
Normal file
18
vlib/v/fmt/tests/manualfree_keep.v
Normal file
@ -0,0 +1,18 @@
|
||||
[manualfree]
|
||||
module main
|
||||
|
||||
fn abc() {
|
||||
x := 'abc should be autofreed'
|
||||
println(x)
|
||||
}
|
||||
|
||||
[manualfree]
|
||||
fn xyz() {
|
||||
x := 'xyz should do its own memory management'
|
||||
println(x)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
abc()
|
||||
xyz()
|
||||
}
|
@ -156,7 +156,7 @@ pub fn (mut p Parser) call_args() []ast.CallArg {
|
||||
fn (mut p Parser) fn_decl() ast.FnDecl {
|
||||
p.top_level_statement_start()
|
||||
start_pos := p.tok.position()
|
||||
is_manualfree := p.attrs.contains('manualfree')
|
||||
is_manualfree := p.is_manualfree || p.attrs.contains('manualfree')
|
||||
is_deprecated := p.attrs.contains('deprecated')
|
||||
is_direct_arr := p.attrs.contains('direct_array_access')
|
||||
mut is_unsafe := p.attrs.contains('unsafe')
|
||||
|
@ -45,6 +45,7 @@ mut:
|
||||
or_is_handled bool // ignore `or` in this expression
|
||||
builtin_mod bool // are we in the `builtin` module?
|
||||
mod string // current module name
|
||||
is_manualfree bool // true when `[manualfree] module abc`, makes *all* fns in the current .v file, opt out of autofree
|
||||
attrs []table.Attr // attributes before next decl stmt
|
||||
expr_mod string // for constructing full type names in parse_type()
|
||||
scope &ast.Scope
|
||||
@ -817,10 +818,12 @@ fn (mut p Parser) attributes() {
|
||||
}
|
||||
|
||||
fn (mut p Parser) parse_attr() table.Attr {
|
||||
apos := p.prev_tok.position()
|
||||
if p.tok.kind == .key_unsafe {
|
||||
p.next()
|
||||
return table.Attr{
|
||||
name: 'unsafe'
|
||||
pos: apos.extend(p.tok.position())
|
||||
}
|
||||
}
|
||||
mut is_ctdefine := false
|
||||
@ -862,6 +865,7 @@ fn (mut p Parser) parse_attr() table.Attr {
|
||||
is_ctdefine: is_ctdefine
|
||||
arg: arg
|
||||
is_string_arg: is_string_arg
|
||||
pos: apos.extend(p.tok.position())
|
||||
}
|
||||
}
|
||||
|
||||
@ -1670,10 +1674,16 @@ fn (mut p Parser) parse_number_literal() ast.Expr {
|
||||
}
|
||||
|
||||
fn (mut p Parser) module_decl() ast.Module {
|
||||
mut module_attrs := []table.Attr{}
|
||||
if p.tok.kind == .lsbr {
|
||||
p.attributes()
|
||||
module_attrs = p.attrs
|
||||
}
|
||||
mut name := 'main'
|
||||
is_skipped := p.tok.kind != .key_module
|
||||
mut module_pos := token.Position{}
|
||||
if !is_skipped {
|
||||
p.attrs = []
|
||||
module_pos = p.tok.position()
|
||||
p.next()
|
||||
mut pos := p.tok.position()
|
||||
@ -1710,8 +1720,22 @@ fn (mut p Parser) module_decl() ast.Module {
|
||||
}
|
||||
p.mod = full_mod
|
||||
p.builtin_mod = p.mod == 'builtin'
|
||||
if !is_skipped {
|
||||
for ma in module_attrs {
|
||||
match ma.name {
|
||||
'manualfree' {
|
||||
p.is_manualfree = true
|
||||
}
|
||||
else {
|
||||
p.error_with_pos('unknown module attribute `[$ma.name]`', ma.pos)
|
||||
return ast.Module{}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ast.Module{
|
||||
name: full_mod
|
||||
attrs: module_attrs
|
||||
is_skipped: is_skipped
|
||||
pos: module_pos
|
||||
}
|
||||
|
@ -3,6 +3,8 @@
|
||||
// that can be found in the LICENSE file.
|
||||
module table
|
||||
|
||||
import v.token
|
||||
|
||||
// e.g. `[unsafe]`
|
||||
pub struct Attr {
|
||||
pub:
|
||||
@ -11,6 +13,7 @@ pub:
|
||||
is_ctdefine bool // [if name]
|
||||
arg string // [name: arg]
|
||||
is_string_arg bool // [name: 'arg']
|
||||
pos token.Position
|
||||
}
|
||||
|
||||
// no square brackets
|
||||
|
Loading…
Reference in New Issue
Block a user