all: support `[markused]` tags for fns/consts/globals
parent
1a6899e85e
commit
df7f2aa8a3
|
@ -444,9 +444,9 @@ fn (t Tree) stmt(node ast.Stmt) &Node {
|
|||
fn (t Tree) import_module(node ast.Import) &Node {
|
||||
mut obj := new_object()
|
||||
obj.add_terse('ast_type', t.string_node('Import'))
|
||||
obj.add('mod', t.string_node(node.mod))
|
||||
obj.add('alias', t.string_node(node.alias))
|
||||
obj.add('syms', t.array_node_import_symbol(node.syms))
|
||||
obj.add_terse('mod', t.string_node(node.mod))
|
||||
obj.add_terse('alias', t.string_node(node.alias))
|
||||
obj.add_terse('syms', t.array_node_import_symbol(node.syms))
|
||||
obj.add('comments', t.array_node_comment(node.comments))
|
||||
obj.add('next_comments', t.array_node_comment(node.next_comments))
|
||||
obj.add('pos', t.position(node.pos))
|
||||
|
@ -458,7 +458,7 @@ fn (t Tree) import_module(node ast.Import) &Node {
|
|||
|
||||
fn (t Tree) import_symbol(node ast.ImportSymbol) &Node {
|
||||
mut obj := new_object()
|
||||
obj.add('name', t.string_node(node.name))
|
||||
obj.add_terse('name', t.string_node(node.name))
|
||||
obj.add('pos', t.position(node.pos))
|
||||
return obj
|
||||
}
|
||||
|
@ -485,9 +485,10 @@ fn (t Tree) comment(node ast.Comment) &Node {
|
|||
fn (t Tree) const_decl(node ast.ConstDecl) &Node {
|
||||
mut obj := new_object()
|
||||
obj.add_terse('ast_type', t.string_node('ConstDecl'))
|
||||
obj.add('is_pub', t.bool_node(node.is_pub))
|
||||
obj.add('is_block', t.bool_node(node.is_block))
|
||||
obj.add('fields', t.array_node_const_field(node.fields))
|
||||
obj.add_terse('is_pub', t.bool_node(node.is_pub))
|
||||
obj.add_terse('is_block', t.bool_node(node.is_block))
|
||||
obj.add_terse('fields', t.array_node_const_field(node.fields))
|
||||
obj.add_terse('attrs', t.array_node_attr(node.attrs))
|
||||
obj.add('end_comments', t.array_node_comment(node.end_comments))
|
||||
obj.add('pos', t.position(node.pos))
|
||||
return obj
|
||||
|
@ -496,11 +497,12 @@ fn (t Tree) const_decl(node ast.ConstDecl) &Node {
|
|||
fn (t Tree) const_field(node ast.ConstField) &Node {
|
||||
mut obj := new_object()
|
||||
obj.add_terse('ast_type', t.string_node('ConstField'))
|
||||
obj.add('mod', t.string_node(node.mod))
|
||||
obj.add('name', t.string_node(node.name))
|
||||
obj.add('expr', t.expr(node.expr))
|
||||
obj.add('is_pub', t.bool_node(node.is_pub))
|
||||
obj.add('typ', t.type_node(node.typ))
|
||||
obj.add_terse('mod', t.string_node(node.mod))
|
||||
obj.add_terse('name', t.string_node(node.name))
|
||||
obj.add_terse('expr', t.expr(node.expr))
|
||||
obj.add_terse('is_pub', t.bool_node(node.is_pub))
|
||||
obj.add_terse('is_markused', t.bool_node(node.is_markused))
|
||||
obj.add_terse('typ', t.type_node(node.typ))
|
||||
obj.add('comments', t.array_node_comment(node.comments))
|
||||
obj.add('comptime_expr_value', t.comptime_expr_value(node.comptime_expr_value))
|
||||
obj.add('pos', t.position(node.pos))
|
||||
|
@ -527,18 +529,18 @@ fn (t Tree) fn_decl(node ast.FnDecl) &Node {
|
|||
obj.add_terse('ast_type', t.string_node('FnDecl'))
|
||||
obj.add_terse('name', t.string_node(node.name))
|
||||
obj.add_terse('mod', t.string_node(node.mod))
|
||||
obj.add('is_deprecated', t.bool_node(node.is_deprecated))
|
||||
obj.add('is_pub', t.bool_node(node.is_pub))
|
||||
obj.add('is_variadic', t.bool_node(node.is_variadic))
|
||||
obj.add_terse('is_deprecated', t.bool_node(node.is_deprecated))
|
||||
obj.add_terse('is_pub', t.bool_node(node.is_pub))
|
||||
obj.add_terse('is_variadic', t.bool_node(node.is_variadic))
|
||||
obj.add('is_anon', t.bool_node(node.is_anon))
|
||||
obj.add('is_noreturn', t.bool_node(node.is_noreturn))
|
||||
obj.add('is_manualfree', t.bool_node(node.is_manualfree))
|
||||
obj.add_terse('is_noreturn', t.bool_node(node.is_noreturn))
|
||||
obj.add_terse('is_manualfree', t.bool_node(node.is_manualfree))
|
||||
obj.add('is_main', t.bool_node(node.is_main))
|
||||
obj.add('is_test', t.bool_node(node.is_test))
|
||||
obj.add('is_conditional', t.bool_node(node.is_conditional))
|
||||
obj.add('is_exported', t.bool_node(node.is_exported))
|
||||
obj.add_terse('is_exported', t.bool_node(node.is_exported))
|
||||
obj.add('is_keep_alive', t.bool_node(node.is_keep_alive))
|
||||
obj.add('is_unsafe', t.bool_node(node.is_unsafe))
|
||||
obj.add_terse('is_unsafe', t.bool_node(node.is_unsafe))
|
||||
obj.add_terse('receiver', t.struct_field(node.receiver))
|
||||
obj.add('receiver_pos', t.position(node.receiver_pos))
|
||||
obj.add_terse('is_method', t.bool_node(node.is_method))
|
||||
|
@ -597,8 +599,8 @@ fn (t Tree) struct_decl(node ast.StructDecl) &Node {
|
|||
obj.add_terse('is_union', t.bool_node(node.is_union))
|
||||
obj.add('pos', t.position(node.pos))
|
||||
obj.add_terse('fields', t.array_node_struct_field(node.fields))
|
||||
obj.add('generic_types', t.array_node_type(node.generic_types))
|
||||
obj.add('attrs', t.array_node_attr(node.attrs))
|
||||
obj.add_terse('generic_types', t.array_node_type(node.generic_types))
|
||||
obj.add_terse('attrs', t.array_node_attr(node.attrs))
|
||||
obj.add('end_comments', t.array_node_comment(node.end_comments))
|
||||
obj.add_terse('embeds', t.array_node_embed(node.embeds))
|
||||
return obj
|
||||
|
@ -746,6 +748,7 @@ fn (t Tree) global_field(node ast.GlobalField) &Node {
|
|||
obj.add_terse('expr', t.expr(node.expr))
|
||||
obj.add_terse('typ', t.type_node(node.typ))
|
||||
obj.add_terse('has_expr', t.bool_node(node.has_expr))
|
||||
obj.add_terse('is_markused', t.bool_node(node.is_markused))
|
||||
obj.add('comments', t.array_node_comment(node.comments))
|
||||
obj.add('pos', t.position(node.pos))
|
||||
obj.add('typ_pos', t.position(node.typ_pos))
|
||||
|
|
|
@ -128,7 +128,7 @@ pub:
|
|||
kind AttributeKind
|
||||
}
|
||||
|
||||
[used]
|
||||
[markused]
|
||||
fn v_segmentation_fault_handler(signal int) {
|
||||
eprintln('signal 11: segmentation fault')
|
||||
print_backtrace()
|
||||
|
|
|
@ -292,6 +292,7 @@ pub:
|
|||
name string
|
||||
expr Expr // the value expr of field; everything after `=`
|
||||
is_pub bool
|
||||
is_markused bool // an explict `[markused]` tag; the const will NOT be removed by `-skip-unused`, no matter what
|
||||
pos token.Position
|
||||
pub mut:
|
||||
typ Type // the type of the const field, it can be any type in V
|
||||
|
@ -306,6 +307,7 @@ pub struct ConstDecl {
|
|||
pub:
|
||||
is_pub bool
|
||||
pos token.Position
|
||||
attrs []Attr // tags like `[markused]`, valid for all the consts in the list
|
||||
pub mut:
|
||||
fields []ConstField // all the const fields in the `const (...)` block
|
||||
end_comments []Comment // comments that after last const field
|
||||
|
@ -460,6 +462,7 @@ pub:
|
|||
is_exported bool // true for `[export: 'exact_C_name']`
|
||||
is_keep_alive bool // passed memory must not be freed (by GC) before function returns
|
||||
is_unsafe bool // true, when [unsafe] is used on a fn
|
||||
is_markused bool // true, when an explict `[markused]` tag was put on a fn; `-skip-unused` will not remove that fn
|
||||
receiver StructField // TODO this is not a struct field
|
||||
receiver_pos token.Position // `(u User)` in `fn (u User) name()` position
|
||||
is_method bool
|
||||
|
@ -484,7 +487,7 @@ pub mut:
|
|||
return_type Type
|
||||
return_type_pos token.Position // `string` in `fn (u User) name() string` position
|
||||
has_return bool
|
||||
should_be_skipped bool
|
||||
should_be_skipped bool // true, when -skip-unused could not find any usages of that function, starting from main + other known used functions
|
||||
has_await bool // 'true' if this function uses JS.await
|
||||
//
|
||||
comments []Comment // comments *after* the header, but *before* `{`; used for InterfaceDecl
|
||||
|
@ -525,7 +528,7 @@ pub mut:
|
|||
left_type Type // type of `user`
|
||||
receiver_type Type // User
|
||||
return_type Type
|
||||
should_be_skipped bool
|
||||
should_be_skipped bool // true for calls to `[if someflag?]` functions, when there is no `-d someflag`
|
||||
concrete_types []Type // concrete types, e.g. <int, string>
|
||||
concrete_list_pos token.Position
|
||||
free_receiver bool // true if the receiver expression needs to be freed
|
||||
|
@ -596,7 +599,7 @@ pub mut:
|
|||
// [11, 12, 13] <- cast order (smartcasts)
|
||||
// 12 <- the current casted type (typ)
|
||||
pos token.Position
|
||||
is_used bool
|
||||
is_used bool // whether the local variable was used in other expressions
|
||||
is_changed bool // to detect mutable vars that are never changed
|
||||
//
|
||||
// (for setting the position after the or block for autofree)
|
||||
|
@ -628,6 +631,7 @@ pub:
|
|||
has_expr bool
|
||||
pos token.Position
|
||||
typ_pos token.Position
|
||||
is_markused bool // an explict `[markused]` tag; the global will NOT be removed by `-skip-unused`
|
||||
pub mut:
|
||||
expr Expr
|
||||
typ Type
|
||||
|
@ -639,7 +643,7 @@ pub:
|
|||
mod string
|
||||
pos token.Position
|
||||
is_block bool // __global() block
|
||||
attrs []Attr
|
||||
attrs []Attr // tags like `[markused]`, valid for all the globals in the list
|
||||
pub mut:
|
||||
fields []GlobalField
|
||||
end_comments []Comment
|
||||
|
|
|
@ -776,6 +776,7 @@ mut:
|
|||
}
|
||||
|
||||
pub fn (mut f Fmt) const_decl(node ast.ConstDecl) {
|
||||
f.attrs(node.attrs)
|
||||
if node.is_pub {
|
||||
f.write('pub ')
|
||||
}
|
||||
|
|
|
@ -336,6 +336,9 @@ pub fn mark_used(mut table ast.Table, pref &pref.Preferences, ast_files []&ast.F
|
|||
pref: pref
|
||||
}
|
||||
// println( all_fns.keys() )
|
||||
walker.mark_markused_fns() // tagged with `[markused]`
|
||||
walker.mark_markused_consts() // tagged with `[markused]`
|
||||
walker.mark_markused_globals() // tagged with `[markused]`
|
||||
walker.mark_exported_fns()
|
||||
walker.mark_root_fns(all_fn_root_names)
|
||||
|
||||
|
|
|
@ -72,6 +72,30 @@ pub fn (mut w Walker) mark_exported_fns() {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn (mut w Walker) mark_markused_fns() {
|
||||
for _, mut func in w.all_fns {
|
||||
if func.is_markused {
|
||||
w.fn_decl(mut func)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut w Walker) mark_markused_consts() {
|
||||
for ckey, mut constfield in w.all_consts {
|
||||
if constfield.is_markused {
|
||||
w.mark_const_as_used(ckey)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut w Walker) mark_markused_globals() {
|
||||
for gkey, mut globalfield in w.all_globals {
|
||||
if globalfield.is_markused {
|
||||
w.mark_global_as_used(gkey)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut w Walker) stmt(node ast.Stmt) {
|
||||
match mut node {
|
||||
ast.EmptyStmt {}
|
||||
|
|
|
@ -180,6 +180,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
|||
mut is_noreturn := false
|
||||
mut is_ctor_new := false
|
||||
mut is_c2v_variadic := false
|
||||
mut is_markused := false
|
||||
for fna in p.attrs {
|
||||
match fna.name {
|
||||
'noreturn' { is_noreturn = true }
|
||||
|
@ -193,6 +194,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
|||
'trusted' { is_trusted = true }
|
||||
'c2v_variadic' { is_c2v_variadic = true }
|
||||
'use_new' { is_ctor_new = true }
|
||||
'markused' { is_markused = true }
|
||||
else {}
|
||||
}
|
||||
}
|
||||
|
@ -496,6 +498,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
|||
is_test: is_test
|
||||
is_keep_alive: is_keep_alive
|
||||
is_unsafe: is_unsafe
|
||||
is_markused: is_markused
|
||||
//
|
||||
attrs: p.attrs
|
||||
is_conditional: conditional_ctdefine_idx != -1
|
||||
|
|
|
@ -13,9 +13,7 @@ import v.errors
|
|||
import os
|
||||
import hash.fnv1a
|
||||
|
||||
pub const (
|
||||
builtin_functions = ['print', 'println', 'eprint', 'eprintln', 'isnil', 'panic', 'exit']
|
||||
)
|
||||
pub const builtin_functions = ['print', 'println', 'eprint', 'eprintln', 'isnil', 'panic', 'exit']
|
||||
|
||||
pub struct Parser {
|
||||
pref &pref.Preferences
|
||||
|
@ -3009,6 +3007,18 @@ fn (mut p Parser) import_syms(mut parent ast.Import) {
|
|||
|
||||
fn (mut p Parser) const_decl() ast.ConstDecl {
|
||||
p.top_level_statement_start()
|
||||
mut attrs := []ast.Attr{}
|
||||
if p.attrs.len > 0 {
|
||||
attrs = p.attrs
|
||||
p.attrs = []
|
||||
}
|
||||
mut is_markused := false
|
||||
for ga in attrs {
|
||||
match ga.name {
|
||||
'markused' { is_markused = true }
|
||||
else {}
|
||||
}
|
||||
}
|
||||
start_pos := p.tok.position()
|
||||
is_pub := p.tok.kind == .key_pub
|
||||
if is_pub {
|
||||
|
@ -3055,6 +3065,7 @@ fn (mut p Parser) const_decl() ast.ConstDecl {
|
|||
expr: expr
|
||||
pos: pos.extend(expr.position())
|
||||
comments: comments
|
||||
is_markused: is_markused
|
||||
}
|
||||
fields << field
|
||||
p.table.global_scope.register(field)
|
||||
|
@ -3073,6 +3084,7 @@ fn (mut p Parser) const_decl() ast.ConstDecl {
|
|||
is_pub: is_pub
|
||||
end_comments: comments
|
||||
is_block: is_block
|
||||
attrs: attrs
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3105,6 +3117,15 @@ fn (mut p Parser) global_decl() ast.GlobalDecl {
|
|||
attrs = p.attrs
|
||||
p.attrs = []
|
||||
}
|
||||
|
||||
mut is_markused := false
|
||||
for ga in attrs {
|
||||
match ga.name {
|
||||
'markused' { is_markused = true }
|
||||
else {}
|
||||
}
|
||||
}
|
||||
|
||||
if !p.has_globals && !p.pref.enable_globals && !p.pref.is_fmt && !p.pref.translated
|
||||
&& !p.pref.is_livemain && !p.pref.building_v && !p.builtin_mod {
|
||||
p.error('use `v -enable-globals ...` to enable globals')
|
||||
|
@ -3180,6 +3201,7 @@ fn (mut p Parser) global_decl() ast.GlobalDecl {
|
|||
typ_pos: typ_pos
|
||||
typ: typ
|
||||
comments: comments
|
||||
is_markused: is_markused
|
||||
}
|
||||
fields << field
|
||||
p.table.global_scope.register(field)
|
||||
|
|
Loading…
Reference in New Issue