1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

checker,ast: clean up deprecation code (#14980)

This commit is contained in:
zakuro 2022-07-07 21:45:45 +09:00 committed by GitHub
parent de77114593
commit 972bba66d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 52 additions and 98 deletions

View File

@ -310,10 +310,7 @@ pub:
is_mut bool
is_global bool
is_volatile bool
//
is_deprecated bool
deprecation_msg string
deprecated_after string
pub mut:
default_expr Expr
default_expr_typ Type

View File

@ -4,7 +4,6 @@
[has_globals]
module ast
import time
import v.cflag
import v.token
import v.util
@ -41,8 +40,8 @@ pub mut:
gostmts int // how many `go` statements there were in the parsed files.
// When table.gostmts > 0, __VTHREADS__ is defined, which can be checked with `$if threads {`
enum_decls map[string]EnumDecl
mdeprecated_msg map[string]string // module deprecation message
mdeprecated_after map[string]time.Time // module deprecation date
module_deprecated map[string]bool
module_attrs map[string][]Attr // module attributes
builtin_pub_fns map[string]bool
pointer_size int
// cache for type_to_str_using_aliases
@ -319,15 +318,6 @@ pub fn (t &Table) known_fn(name string) bool {
return true
}
pub fn (mut t Table) mark_module_as_deprecated(mname string, message string) {
t.mdeprecated_msg[mname] = message
t.mdeprecated_after[mname] = time.now()
}
pub fn (mut t Table) mark_module_as_deprecated_after(mname string, after_date string) {
t.mdeprecated_after[mname] = time.parse_iso8601(after_date) or { time.now() }
}
pub fn (mut t Table) register_fn(new_fn Fn) {
t.fns[new_fn.name] = new_fn
if new_fn.is_pub && new_fn.mod == 'builtin' {

View File

@ -109,7 +109,7 @@ pub enum TypeFlag {
/*
To save precious TypeFlag bits the 4 possible ShareTypes are coded in the two
bits `shared` and `atomic_or_rw` (see sharetype_from_flags() below).
bits `shared` and `atomic_or_rw` (see sharetype_from_flags() below).
*/
pub enum ShareType {
mut_t

View File

@ -1234,15 +1234,7 @@ pub fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
}
field_sym := c.table.sym(field.typ)
if field.is_deprecated && is_used_outside {
now := time.now()
mut after_time := now
if field.deprecated_after != '' {
after_time = time.parse_iso8601(field.deprecated_after) or {
c.error('invalid time format', field.pos)
now
}
}
c.deprecate('field', field_name, field.deprecation_msg, now, after_time, node.pos)
c.deprecate('field', field_name, field.attrs, node.pos)
}
if field_sym.kind in [.sum_type, .interface_] {
if !prevent_sum_type_unwrapping_once {
@ -1943,10 +1935,8 @@ fn (mut c Checker) import_stmt(node ast.Import) {
}
c.error('module `$node.mod` has no constant or function `$sym.name`', sym.pos)
}
if after_time := c.table.mdeprecated_after[node.mod] {
now := time.now()
deprecation_message := c.table.mdeprecated_msg[node.mod]
c.deprecate('module', node.mod, deprecation_message, now, after_time, node.pos)
if c.table.module_deprecated[node.mod] {
c.deprecate('module', node.mod, c.table.module_attrs[node.mod], node.pos)
}
}
@ -3866,3 +3856,42 @@ pub fn (mut c Checker) fail_if_unreadable(expr ast.Expr, typ ast.Type, what stri
pos)
}
}
fn (mut c Checker) deprecate(kind string, name string, attrs []ast.Attr, pos token.Pos) {
mut deprecation_message := ''
now := time.now()
mut after_time := now
for attr in attrs {
if attr.name == 'deprecated' && attr.arg != '' {
deprecation_message = attr.arg
}
if attr.name == 'deprecated_after' && attr.arg != '' {
after_time = time.parse_iso8601(attr.arg) or {
c.error('invalid time format', attr.pos)
now
}
}
}
start_message := '$kind `$name`'
error_time := after_time.add_days(180)
if error_time < now {
c.error(semicolonize('$start_message has been deprecated since $after_time.ymmdd()',
deprecation_message), pos)
} else if after_time < now {
c.warn(semicolonize('$start_message has been deprecated since $after_time.ymmdd(), it will be an error after $error_time.ymmdd()',
deprecation_message), pos)
} else if after_time == now {
c.warn(semicolonize('$start_message has been deprecated', 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)
}
}
fn semicolonize(main string, details string) string {
if details == '' {
return main
}
return '$main; $details'
}

View File

@ -2,7 +2,6 @@ module checker
import v.ast
import v.pref
import time
import v.util
import v.token
@ -725,7 +724,7 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool)
c.error('function `$func.name` is private', node.pos)
}
if !isnil(c.table.cur_fn) && !c.table.cur_fn.is_deprecated && func.is_deprecated {
c.deprecate_fnmethod('function', func.name, func, node)
c.deprecate('function', func.name, func.attrs, node.pos)
}
if func.is_unsafe && !c.inside_unsafe
&& (func.language != .c || (func.name[2] in [`m`, `s`] && func.mod == 'builtin')) {
@ -1479,7 +1478,7 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
node.pos)
}
if !isnil(c.table.cur_fn) && !c.table.cur_fn.is_deprecated && method.is_deprecated {
c.deprecate_fnmethod('method', '${left_sym.name}.$method.name', method, node)
c.deprecate('method', '${left_sym.name}.$method.name', method.attrs, node.pos)
}
c.set_node_expected_arg_types(mut node, method)
if is_method_from_embed {
@ -1628,49 +1627,6 @@ fn (mut c Checker) set_node_expected_arg_types(mut node ast.CallExpr, func &ast.
}
}
fn (mut c Checker) deprecate_fnmethod(kind string, name string, the_fn ast.Fn, node ast.CallExpr) {
mut deprecation_message := ''
now := time.now()
mut after_time := now
for attr in the_fn.attrs {
if attr.name == 'deprecated' && attr.arg != '' {
deprecation_message = attr.arg
}
if attr.name == 'deprecated_after' && attr.arg != '' {
after_time = time.parse_iso8601(attr.arg) or {
c.error('invalid time format', attr.pos)
now
}
}
}
c.deprecate(kind, name, deprecation_message, now, after_time, node.pos)
}
fn (mut c Checker) deprecate(kind string, name string, deprecation_message string, now time.Time, after_time time.Time, pos token.Pos) {
start_message := '$kind `$name`'
error_time := after_time.add_days(180)
if error_time < now {
c.error(semicolonize('$start_message has been deprecated since $after_time.ymmdd()',
deprecation_message), pos)
} else if after_time < now {
c.warn(semicolonize('$start_message has been deprecated since $after_time.ymmdd(), it will be an error after $error_time.ymmdd()',
deprecation_message), pos)
} else if after_time == now {
c.warn(semicolonize('$start_message has been deprecated', 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)
}
}
fn semicolonize(main string, details string) string {
if details == '' {
return main
}
return '$main; $details'
}
fn (mut c Checker) post_process_generic_fns() {
// Loop thru each generic function concrete type.
// Check each specific fn instantiation.

View File

@ -3145,15 +3145,11 @@ fn (mut p Parser) module_decl() ast.Module {
name_pos: name_pos
}
if !is_skipped {
p.table.module_attrs[p.mod] = module_attrs
for ma in module_attrs {
match ma.name {
'deprecated' {
// [deprecated: 'use a replacement']
p.table.mark_module_as_deprecated(p.mod, ma.arg)
}
'deprecated_after' {
// [deprecated_after: '2027-12-30']
p.table.mark_module_as_deprecated_after(p.mod, ma.arg)
'deprecated', 'deprecated_after' {
p.table.module_deprecated[p.mod] = true
}
'manualfree' {
p.is_manualfree = true

View File

@ -186,8 +186,6 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl {
field_start_pos := p.tok.pos()
mut is_field_volatile := false
mut is_field_deprecated := false
mut field_deprecation_msg := ''
mut field_deprecated_after := ''
if p.tok.kind == .key_volatile {
p.next()
is_field_volatile = true
@ -254,16 +252,8 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl {
// attrs are stored in `p.attrs`
p.attributes()
for fa in p.attrs {
match fa.name {
'deprecated' {
// [deprecated: 'use a replacement']
is_field_deprecated = true
field_deprecation_msg = fa.arg
}
'deprecated_after' {
field_deprecated_after = fa.arg
}
else {}
if fa.name == 'deprecated' {
is_field_deprecated = true
}
}
}
@ -297,8 +287,6 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl {
is_global: is_field_global
is_volatile: is_field_volatile
is_deprecated: is_field_deprecated
deprecation_msg: field_deprecation_msg
deprecated_after: field_deprecated_after
}
}
// save embeds as table fields too, it will be used in generation phase
@ -317,8 +305,6 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl {
is_global: is_field_global
is_volatile: is_field_volatile
is_deprecated: is_field_deprecated
deprecation_msg: field_deprecation_msg
deprecated_after: field_deprecated_after
}
p.attrs = []
i++