vfmt: strip `current_module.` in fn args more robustly

pull/5806/head
Delyan Angelov 2020-07-11 16:09:12 +03:00
parent b55f84c0a8
commit 26768e8514
7 changed files with 48 additions and 36 deletions

View File

@ -99,7 +99,7 @@ fn (app App) gen_api_for_module_in_os(mod_name, os_name string) string {
for s in f.stmts { for s in f.stmts {
if s is ast.FnDecl { if s is ast.FnDecl {
if s.is_pub { if s.is_pub {
fn_signature := s.stringify(b.table) fn_signature := s.stringify(b.table, mod_name)
fn_mod := s.modname() fn_mod := s.modname()
if fn_mod == mod_name { if fn_mod == mod_name {
fline := '${fn_mod}: $fn_signature' fline := '${fn_mod}: $fn_signature'

View File

@ -24,18 +24,19 @@ pub fn (node &FnDecl) modname() string {
// These methods are used only by vfmt, vdoc, and for debugging. // These methods are used only by vfmt, vdoc, and for debugging.
pub fn (node &FnDecl) stringify(t &table.Table) string { pub fn (node &FnDecl) stringify(t &table.Table, cur_mod string) string {
mut f := strings.new_builder(30) mut f := strings.new_builder(30)
if node.is_pub { if node.is_pub {
f.write('pub ') f.write('pub ')
} }
mut receiver := '' mut receiver := ''
if node.is_method { if node.is_method {
mut styp := t.type_to_str(node.receiver.typ) mut styp := util.no_cur_mod(t.type_to_str(node.receiver.typ), cur_mod)
mut m := if node.rec_mut { node.receiver.typ.share().str() + ' ' } else { '' } mut m := if node.rec_mut { node.receiver.typ.share().str() + ' ' } else { '' }
if node.rec_mut { if node.rec_mut {
styp = styp[1..] // remove & styp = styp[1..] // remove &
} }
styp = util.no_cur_mod(styp, cur_mod)
receiver = '($m$node.receiver.name $styp) ' receiver = '($m$node.receiver.name $styp) '
/* /*
sym := t.get_type_symbol(node.receiver.typ) sym := t.get_type_symbol(node.receiver.typ)
@ -82,6 +83,7 @@ pub fn (node &FnDecl) stringify(t &table.Table) string {
s = s[1..] s = s[1..]
} }
} }
s = util.no_cur_mod(s, cur_mod)
if should_add_type { if should_add_type {
if node.is_variadic && is_last_arg { if node.is_variadic && is_last_arg {
f.write(' ...' + s) f.write(' ...' + s)
@ -97,7 +99,7 @@ pub fn (node &FnDecl) stringify(t &table.Table) string {
if node.return_type != table.void_type { if node.return_type != table.void_type {
// typ := t.type_to_str(node.typ) // typ := t.type_to_str(node.typ)
// if typ.starts_with(' // if typ.starts_with('
f.write(' ' + t.type_to_str(node.return_type)) f.write(' ' + util.no_cur_mod(t.type_to_str(node.return_type), cur_mod))
} }
return f.str() return f.str()
} }

View File

@ -118,7 +118,7 @@ pub fn (mut d Doc) get_signature(stmt ast.Stmt, file &ast.File) string {
return 'module $stmt.name' return 'module $stmt.name'
} }
ast.FnDecl { ast.FnDecl {
return stmt.stringify(d.table).replace(d.fmt.cur_mod + '.', '') return stmt.stringify(d.table, d.fmt.cur_mod)
} }
else { else {
d.fmt.out = strings.new_builder(1000) d.fmt.out = strings.new_builder(1000)
@ -307,7 +307,7 @@ fn (mut d Doc) generate() ?Doc {
} }
stmts := file_ast.stmts stmts := file_ast.stmts
d.fmt.file = file_ast d.fmt.file = file_ast
d.fmt.cur_mod = orig_mod_name d.fmt.set_current_module_name(orig_mod_name)
d.fmt.process_file_imports(file_ast) d.fmt.process_file_imports(file_ast)
mut last_import_stmt_idx := 0 mut last_import_stmt_idx := 0
for sidx, stmt in stmts { for sidx, stmt in stmts {

View File

@ -23,9 +23,8 @@ enum CommentsLevel {
} }
pub struct Fmt { pub struct Fmt {
pub:
table &table.Table
pub mut: pub mut:
table &table.Table
out_imports strings.Builder out_imports strings.Builder
out strings.Builder out strings.Builder
out_save strings.Builder out_save strings.Builder
@ -64,7 +63,7 @@ pub fn fmt(file ast.File, table &table.Table, is_debug bool) string {
is_debug: is_debug is_debug: is_debug
} }
f.process_file_imports(file) f.process_file_imports(file)
f.cur_mod = 'main' f.set_current_module_name('main')
for stmt in file.stmts { for stmt in file.stmts {
if stmt is ast.Import { if stmt is ast.Import {
// Just remember the position of the imports for now // Just remember the position of the imports for now
@ -191,8 +190,13 @@ fn (mut f Fmt) adjust_complete_line() {
} }
} }
pub fn (mut f Fmt) set_current_module_name(cmodname string){
f.cur_mod = cmodname
f.table.cmod_prefix = cmodname + '.'
}
pub fn (mut f Fmt) mod(mod ast.Module) { pub fn (mut f Fmt) mod(mod ast.Module) {
f.cur_mod = mod.name f.set_current_module_name(mod.name)
if mod.is_skipped { if mod.is_skipped {
return return
} }
@ -427,7 +431,7 @@ pub fn (mut f Fmt) stmt(node ast.Stmt) {
f.writeln('interface $it.name {') f.writeln('interface $it.name {')
for method in it.methods { for method in it.methods {
f.write('\t') f.write('\t')
f.writeln(method.stringify(f.table).after('fn ')) f.writeln(method.stringify(f.table, f.cur_mod).after('fn '))
} }
f.writeln('}\n') f.writeln('}\n')
} }
@ -512,7 +516,7 @@ pub fn (mut f Fmt) type_decl(node ast.TypeDecl) {
typ_sym := f.table.get_type_symbol(node.typ) typ_sym := f.table.get_type_symbol(node.typ)
fn_typ_info := typ_sym.info as table.FnType fn_typ_info := typ_sym.info as table.FnType
fn_info := fn_typ_info.func fn_info := fn_typ_info.func
fn_name := f.no_cur_mod_anywhere(node.name) fn_name := f.no_cur_mod(node.name)
f.write('type $fn_name = fn (') f.write('type $fn_name = fn (')
for i, arg in fn_info.args { for i, arg in fn_info.args {
f.write(arg.name) f.write(arg.name)
@ -1150,8 +1154,7 @@ pub fn (mut f Fmt) comments(some_comments []ast.Comment, remove_last_new_line bo
pub fn (mut f Fmt) fn_decl(node ast.FnDecl) { pub fn (mut f Fmt) fn_decl(node ast.FnDecl) {
// println('$it.name find_comment($it.pos.line_nr)') // println('$it.name find_comment($it.pos.line_nr)')
// f.find_comment(it.pos.line_nr) // f.find_comment(it.pos.line_nr)
s := node.stringify(f.table) f.write(node.stringify(f.table, f.cur_mod)) // `Expr` instead of `ast.Expr` in mod ast
f.write(f.no_cur_mod_anywhere(s)) // `Expr` instead of `ast.Expr` in mod ast
if node.language == .v { if node.language == .v {
f.writeln(' {') f.writeln(' {')
f.stmts(node.stmts) f.stmts(node.stmts)
@ -1169,28 +1172,8 @@ pub fn (mut f Fmt) fn_decl(node ast.FnDecl) {
f.mark_types_module_as_used(node.return_type) f.mark_types_module_as_used(node.return_type)
} }
pub fn (mut f Fmt) no_cur_mod_anywhere(typename string) string {
return typename.replace(f.cur_mod + '.', '')
}
pub fn (mut f Fmt) no_cur_mod(typename string) string { pub fn (mut f Fmt) no_cur_mod(typename string) string {
mut res := typename return util.no_cur_mod(typename, f.cur_mod)
map_prefix := 'map[string]'
cur_mod := f.cur_mod + '.'
has_map_prefix := res.starts_with(map_prefix)
if has_map_prefix {
res = res.replace(map_prefix, '')
}
no_symbols := res.trim_left('&[]')
should_shorten := no_symbols.starts_with(cur_mod)
// eprintln('> no_cur_mod typename: $typename | cur_mod: $cur_mod | no_symbols: $no_symbols | should_shorten: $should_shorten | res: |$res|')
if should_shorten {
res = res.replace_once(cur_mod, '')
}
if has_map_prefix {
res = map_prefix + res
}
return res
} }
// foo.bar.fn() => bar.fn() // foo.bar.fn() => bar.fn()

View File

@ -45,7 +45,7 @@ pub enum TypeFlag {
atomic_f atomic_f
} }
/* /*
To save precious TypeFlag bits the 4 possible ShareTypes are coded in the two 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).
*/ */
@ -770,6 +770,9 @@ pub fn (table &Table) type_to_str(t Type) string {
if vals.len > 2 { if vals.len > 2 {
res = vals[vals.len - 2] + '.' + vals[vals.len - 1] res = vals[vals.len - 2] + '.' + vals[vals.len - 1]
} }
if res.starts_with(table.cmod_prefix) {
res = res.replace_once(table.cmod_prefix, '')
}
if sym.kind == .array && !res.starts_with('[]') { if sym.kind == .array && !res.starts_with('[]') {
res = '[]' + res res = '[]' + res
} }

View File

@ -17,6 +17,7 @@ pub mut:
cflags []cflag.CFlag cflags []cflag.CFlag
redefined_fns []string redefined_fns []string
fn_gen_types map[string][]Type // for generic functions fn_gen_types map[string][]Type // for generic functions
cmod_prefix string // needed for table.type_to_str(Type) while vfmt; contains `os.`
} }
pub struct Fn { pub struct Fn {

View File

@ -343,3 +343,26 @@ pub fn strip_main_name(name string) string {
pub fn no_dots(s string) string { pub fn no_dots(s string) string {
return s.replace('.', '__') return s.replace('.', '__')
} }
// no_cur_mod - removes cur_mod. prefix from typename,
// but *only* when it is at the start, i.e.:
// no_cur_mod('vproto.Abdcdef', 'proto') == 'vproto.Abdcdef'
// even though proto. is a substring
pub fn no_cur_mod(typename, cur_mod string) string {
mut res := typename
map_prefix := 'map[string]'
mod_prefix := cur_mod + '.'
has_map_prefix := res.starts_with(map_prefix)
if has_map_prefix {
res = res.replace(map_prefix, '')
}
no_symbols := res.trim_left('&[]')
should_shorten := no_symbols.starts_with(mod_prefix)
if should_shorten {
res = res.replace_once(mod_prefix, '')
}
if has_map_prefix {
res = map_prefix + res
}
return res
}