vdoc: move local scope-based doc generation to its own function (#6565)

pull/6568/head
Ned Palacios 2020-10-05 13:59:17 +08:00 committed by GitHub
parent 7a29240b00
commit 2b1a5d7a56
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 91 additions and 76 deletions

View File

@ -30,6 +30,7 @@ pub mut:
fmt fmt.Fmt fmt fmt.Fmt
time_generated time.Time time_generated time.Time
with_pos bool with_pos bool
with_head bool = true
filename string filename string
pos int pos int
is_vlib bool is_vlib bool
@ -295,8 +296,9 @@ fn get_parent_mod(dir string) ?string {
return file_ast.mod.name return file_ast.mod.name
} }
fn (mut d Doc) generate_from_ast(file_ast ast.File, orig_mod_name string) { pub fn (mut d Doc) generate_from_ast(file_ast ast.File, orig_mod_name string) []DocNode {
mut const_idx := -1 mut const_idx := -1
mut contents := []DocNode{}
stmts := file_ast.stmts stmts := file_ast.stmts
d.fmt.file = file_ast d.fmt.file = file_ast
d.fmt.set_current_module_name(orig_mod_name) d.fmt.set_current_module_name(orig_mod_name)
@ -319,6 +321,9 @@ fn (mut d Doc) generate_from_ast(file_ast ast.File, orig_mod_name string) {
} }
// TODO: Fetch head comment once // TODO: Fetch head comment once
if stmt is ast.Module { if stmt is ast.Module {
if !d.with_head {
continue
}
// the previous comments were probably a copyright/license one // the previous comments were probably a copyright/license one
module_comment := get_comment_block_right_before(prev_comments) module_comment := get_comment_block_right_before(prev_comments)
prev_comments = [] prev_comments = []
@ -336,46 +341,58 @@ fn (mut d Doc) generate_from_ast(file_ast ast.File, orig_mod_name string) {
if last_import_stmt_idx > 0 && sidx == last_import_stmt_idx { if last_import_stmt_idx > 0 && sidx == last_import_stmt_idx {
// the accumulated comments were interspersed before/between the imports; // the accumulated comments were interspersed before/between the imports;
// just add them all to the module comment: // just add them all to the module comment:
if d.with_head {
import_comments := merge_comments(prev_comments) import_comments := merge_comments(prev_comments)
if d.head.comment != '' { if d.head.comment != '' {
d.head.comment += '\n' d.head.comment += '\n'
} }
d.head.comment += import_comments d.head.comment += import_comments
}
prev_comments = [] prev_comments = []
imports_section = false imports_section = false
} }
if stmt is ast.Import { if stmt is ast.Import {
continue continue
} }
signature := d.get_signature(stmt, file_ast) mut node := DocNode{
pos := d.get_pos(stmt) name: d.get_name(stmt)
mut name := d.get_name(stmt) content: d.get_signature(stmt, file_ast)
if (!signature.starts_with('pub') && d.pub_only) || stmt is ast.GlobalDecl { comment: ''
pos: convert_pos(file_ast.path, d.get_pos(stmt))
file_path: file_ast.path
}
if (!node.content.starts_with('pub') && d.pub_only) || stmt is ast.GlobalDecl {
prev_comments = [] prev_comments = []
continue continue
} }
if name.starts_with(orig_mod_name + '.') { if node.name.starts_with(orig_mod_name + '.') {
name = name.all_after(orig_mod_name + '.') node.name = node.name.all_after(orig_mod_name + '.')
}
mut node := DocNode{
name: name
content: signature
comment: ''
pos: convert_pos(file_ast.path, pos)
file_path: file_ast.path
} }
if node.name.len == 0 && node.comment.len == 0 && node.content.len == 0 { if node.name.len == 0 && node.comment.len == 0 && node.content.len == 0 {
continue continue
} }
if stmt is ast.FnDecl { match stmt {
ast.ConstDecl {
if const_idx == -1 {
const_idx = sidx
} else {
node.attrs['parent'] = 'Constants'
}
node.attrs['category'] = 'Constants'
}
ast.EnumDecl { node.attrs['category'] = 'Enums' }
ast.InterfaceDecl { node.attrs['category'] = 'Interfaces' }
ast.StructDecl { node.attrs['category'] = 'Structs' }
ast.TypeDecl { node.attrs['category'] = 'Typedefs' }
ast.FnDecl {
if stmt.is_deprecated { if stmt.is_deprecated {
continue continue
} }
if stmt.receiver.typ != 0 { if stmt.receiver.typ != 0 {
node.attrs['parent'] = d.fmt.type_to_str(stmt.receiver.typ).trim_left('&') node.attrs['parent'] = d.fmt.type_to_str(stmt.receiver.typ).trim_left('&')
p_idx := d.contents.index_by_name(node.attrs['parent']) p_idx := contents.index_by_name(node.attrs['parent'])
if p_idx == -1 && node.attrs['parent'] != 'void' { if p_idx == -1 && node.attrs['parent'] != 'void' {
d.contents << DocNode{ contents << DocNode{
name: node.attrs['parent'] name: node.attrs['parent']
content: '' content: ''
comment: '' comment: ''
@ -385,32 +402,48 @@ fn (mut d Doc) generate_from_ast(file_ast ast.File, orig_mod_name string) {
} }
} }
} }
node.attrs['category'] = if node.attrs['parent'] in ['void', ''] ||
!node.attrs.exists('parent') { 'Functions' } else { 'Methods' }
} }
if stmt is ast.ConstDecl {
if const_idx == -1 {
const_idx = sidx
} else {
node.attrs['parent'] = 'Constants'
}
}
match stmt {
ast.ConstDecl { node.attrs['category'] = 'Constants' }
ast.EnumDecl { node.attrs['category'] = 'Enums' }
ast.InterfaceDecl { node.attrs['category'] = 'Interfaces' }
ast.StructDecl { node.attrs['category'] = 'Structs' }
ast.TypeDecl { node.attrs['category'] = 'Typedefs' }
ast.FnDecl { node.attrs['category'] = if node.attrs['parent'] in ['void', ''] ||
!node.attrs.exists('parent') { 'Functions' } else { 'Methods' } }
else {} else {}
} }
d.contents << node contents << node
if d.with_comments && (prev_comments.len > 0) { if d.with_comments && (prev_comments.len > 0) {
last_comment := d.contents[d.contents.len - 1].comment last_comment := contents[contents.len - 1].comment
cmt := last_comment + '\n' + get_comment_block_right_before(prev_comments) cmt := last_comment + '\n' + get_comment_block_right_before(prev_comments)
d.contents[d.contents.len - 1].comment = cmt contents[contents.len - 1].comment = cmt
} }
prev_comments = [] prev_comments = []
} }
return contents
}
pub fn (mut d Doc) generate_from_ast_with_pos(file_ast ast.File, pos int) []DocNode {
lscope := file_ast.scope.innermost(pos)
mut contents := []DocNode{}
for name, val in lscope.objects {
if val !is ast.Var {
continue
}
vr_data := val as ast.Var
vr_expr := vr_data.expr
l_node := DocNode{
name: name
content: ''
comment: ''
pos: convert_pos(file_ast.path, vr_data.pos)
file_path: file_ast.path
attrs: {
'category': 'Variable'
'return_type': d.expr_typ_to_string(vr_expr)
'local': 'true'
}
}
contents << l_node
}
return contents
} }
fn (mut d Doc) expr_typ_to_string(ex ast.Expr) string { fn (mut d Doc) expr_typ_to_string(ex ast.Expr) string {
@ -458,37 +491,19 @@ fn (mut d Doc) generate() ?Doc {
if module_name != 'main' && parent_mod_name.len > 0 { if module_name != 'main' && parent_mod_name.len > 0 {
module_name = parent_mod_name + '.' + module_name module_name = parent_mod_name + '.' + module_name
} }
if d.with_head {
d.head = DocNode{ d.head = DocNode{
name: module_name name: module_name
content: 'module $module_name' content: 'module $module_name'
comment: '' comment: ''
} }
}
} else if file_ast.mod.name != orig_mod_name { } else if file_ast.mod.name != orig_mod_name {
continue continue
} }
d.generate_from_ast(file_ast, orig_mod_name) d.contents << d.generate_from_ast(file_ast, orig_mod_name)
if file_ast.path == d.filename { if file_ast.path == d.filename {
lscope := file_ast.scope.innermost(d.pos) d.contents << d.generate_from_ast_with_pos(file_ast, d.pos)
for name, val in lscope.objects {
if val !is ast.Var {
continue
}
vr_data := val as ast.Var
vr_expr := vr_data.expr
l_node := DocNode{
name: name
content: ''
comment: ''
pos: convert_pos(file_ast.path, vr_data.pos)
file_path: file_ast.path
attrs: {
'category': 'Variable'
'return_type': d.expr_typ_to_string(vr_expr)
'local': 'true'
}
}
d.contents << l_node
}
} }
d.fmt.mod2alias = map[string]string{} d.fmt.mod2alias = map[string]string{}
} }