vdoc: support -os and show docs according to the platform (#9474)

pull/9483/head
Swastik Baranwal 2021-03-27 14:20:06 +05:30 committed by GitHub
parent 762036963c
commit 0e254e0329
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 98 additions and 7 deletions

View File

@ -57,6 +57,7 @@ mut:
output_type OutputType = .unset output_type OutputType = .unset
input_path string input_path string
symbol_name string symbol_name string
platform doc.Platform
} }
// //
@ -292,7 +293,7 @@ fn (mut vd VDoc) generate_docs_from_file() {
} }
for dirpath in dirs { for dirpath in dirs {
vd.vprintln('Generating $out.typ docs for "$dirpath"') vd.vprintln('Generating $out.typ docs for "$dirpath"')
mut dcs := doc.generate(dirpath, cfg.pub_only, true, cfg.symbol_name) or { mut dcs := doc.generate(dirpath, cfg.pub_only, true, cfg.platform, cfg.symbol_name) or {
vd.emit_generate_err(err) vd.emit_generate_err(err)
exit(1) exit(1)
} }
@ -419,6 +420,19 @@ fn parse_arguments(args []string) Config {
cfg.output_path = if opath == 'stdout' { opath } else { os.real_path(opath) } cfg.output_path = if opath == 'stdout' { opath } else { os.real_path(opath) }
i++ i++
} }
'-os' {
platform_str := cmdline.option(current_args, '-os', '')
if platform_str == 'cross' {
eprintln('`v doc -os cross` is not supported yet.')
exit(1)
}
selected_platform := doc.platform_from_string(platform_str) or {
eprintln(err.msg)
exit(1)
}
cfg.platform = selected_platform
i++
}
'-no-timestamp' { '-no-timestamp' {
cfg.no_timestamp = true cfg.no_timestamp = true
} }

View File

@ -28,6 +28,54 @@ pub enum SymbolKind {
struct_field struct_field
} }
pub enum Platform {
auto
ios
macos
linux
windows
freebsd
openbsd
netbsd
dragonfly
js // for interoperability in prefs.OS
android
solaris
haiku
cross // TODO: add functionality for v doc -os cross whenever possible
}
// copy of pref.os_from_string
pub fn platform_from_string(platform_str string) ?Platform {
match platform_str {
'all', 'cross' { return .cross }
'linux' { return .linux }
'windows' { return .windows }
'ios' { return .ios }
'macos' { return .macos }
'freebsd' { return .freebsd }
'openbsd' { return .openbsd }
'netbsd' { return .netbsd }
'dragonfly' { return .dragonfly }
'js' { return .js }
'solaris' { return .solaris }
'android' { return .android }
'haiku' { return .haiku }
'linux_or_macos', 'nix' { return .linux }
'' { return .auto }
else { return error('vdoc: invalid platform `$platform_str`') }
}
}
pub fn platform_from_filename(filename string) Platform {
suffix := filename.all_after_last('_').all_before('.c.v')
mut platform := platform_from_string(suffix) or { Platform.cross }
if platform == .auto {
platform = .cross
}
return platform
}
pub fn (sk SymbolKind) str() string { pub fn (sk SymbolKind) str() string {
return match sk { return match sk {
.const_group { 'Constants' } .const_group { 'Constants' }
@ -41,8 +89,8 @@ pub fn (sk SymbolKind) str() string {
} }
pub struct Doc { pub struct Doc {
prefs &pref.Preferences = new_vdoc_preferences()
pub mut: pub mut:
prefs &pref.Preferences = new_vdoc_preferences()
base_path string base_path string
table &table.Table = &table.Table{} table &table.Table = &table.Table{}
checker checker.Checker = checker.Checker{ checker checker.Checker = checker.Checker{
@ -66,6 +114,8 @@ pub mut:
orig_mod_name string orig_mod_name string
extract_vars bool extract_vars bool
filter_symbol_names []string filter_symbol_names []string
common_symbols []string
platform Platform
} }
pub struct DocNode { pub struct DocNode {
@ -83,16 +133,19 @@ pub mut:
attrs map[string]string [json: attributes] attrs map[string]string [json: attributes]
from_scope bool from_scope bool
is_pub bool [json: public] is_pub bool [json: public]
platform Platform
} }
// new_vdoc_preferences creates a new instance of pref.Preferences tailored for v.doc. // new_vdoc_preferences creates a new instance of pref.Preferences tailored for v.doc.
pub fn new_vdoc_preferences() &pref.Preferences { pub fn new_vdoc_preferences() &pref.Preferences {
// vdoc should be able to parse as much user code as possible // vdoc should be able to parse as much user code as possible
// so its preferences should be permissive: // so its preferences should be permissive:
return &pref.Preferences{ mut pref := &pref.Preferences{
enable_globals: true enable_globals: true
is_fmt: true is_fmt: true
} }
pref.fill_with_defaults()
return pref
} }
// new creates a new instance of a `Doc` struct. // new creates a new instance of a `Doc` struct.
@ -118,12 +171,20 @@ pub fn new(input_path string) Doc {
// An option error is thrown if the symbol is not exposed to the public // An option error is thrown if the symbol is not exposed to the public
// (when `pub_only` is enabled) or the content's of the AST node is empty. // (when `pub_only` is enabled) or the content's of the AST node is empty.
pub fn (mut d Doc) stmt(stmt ast.Stmt, filename string) ?DocNode { pub fn (mut d Doc) stmt(stmt ast.Stmt, filename string) ?DocNode {
mut name := d.stmt_name(stmt)
if name in d.common_symbols {
return error('already documented')
}
if name.starts_with(d.orig_mod_name + '.') {
name = name.all_after(d.orig_mod_name + '.')
}
mut node := DocNode{ mut node := DocNode{
name: d.stmt_name(stmt) name: name
content: d.stmt_signature(stmt) content: d.stmt_signature(stmt)
pos: stmt.pos pos: stmt.pos
file_path: os.join_path(d.base_path, filename) file_path: os.join_path(d.base_path, filename)
is_pub: d.stmt_pub(stmt) is_pub: d.stmt_pub(stmt)
platform: platform_from_filename(filename)
} }
if (!node.is_pub && d.pub_only) || stmt is ast.GlobalDecl { if (!node.is_pub && d.pub_only) || stmt is ast.GlobalDecl {
return error('symbol $node.name not public') return error('symbol $node.name not public')
@ -222,6 +283,13 @@ pub fn (mut d Doc) stmt(stmt ast.Stmt, filename string) ?DocNode {
return error('invalid stmt type to document') return error('invalid stmt type to document')
} }
} }
included := node.name in d.filter_symbol_names || node.parent_name in d.filter_symbol_names
if d.filter_symbol_names.len != 0 && !included {
return error('not included in the list of symbol names')
}
if d.prefs.os == .all {
d.common_symbols << node.name
}
return node return node
} }
@ -425,11 +493,15 @@ pub fn (mut d Doc) file_asts(file_asts []ast.File) ? {
// generate documents a certain file directory and returns an // generate documents a certain file directory and returns an
// instance of `Doc` if it is successful. Otherwise, it will throw an error. // instance of `Doc` if it is successful. Otherwise, it will throw an error.
pub fn generate(input_path string, pub_only bool, with_comments bool, filter_symbol_names ...string) ?Doc { pub fn generate(input_path string, pub_only bool, with_comments bool, platform Platform, filter_symbol_names ...string) ?Doc {
if platform == .js {
return error('vdoc: Platform `$platform` is not supported.')
}
mut doc := new(input_path) mut doc := new(input_path)
doc.pub_only = pub_only doc.pub_only = pub_only
doc.with_comments = with_comments doc.with_comments = with_comments
doc.filter_symbol_names = filter_symbol_names.filter(it.len != 0) doc.filter_symbol_names = filter_symbol_names.filter(it.len != 0)
doc.prefs.os = if platform == .auto { pref.get_host_os() } else { pref.OS(int(platform)) }
doc.generate() ? doc.generate() ?
return doc return doc
} }

View File

@ -87,5 +87,5 @@ pub fn lookup_module(mod string) ?string {
// generate_from_mod generates a documentation from a specific module. // generate_from_mod generates a documentation from a specific module.
pub fn generate_from_mod(module_name string, pub_only bool, with_comments bool) ?Doc { pub fn generate_from_mod(module_name string, pub_only bool, with_comments bool) ?Doc {
mod_path := lookup_module(module_name) ? mod_path := lookup_module(module_name) ?
return generate(mod_path, pub_only, with_comments) return generate(mod_path, pub_only, with_comments, .auto)
} }

View File

@ -17,6 +17,7 @@ pub enum OS {
android android
solaris solaris
haiku haiku
all
} }
// Helper function to convert string names to OS enum // Helper function to convert string names to OS enum
@ -34,7 +35,7 @@ pub fn os_from_string(os_str string) ?OS {
'solaris' { return .solaris } 'solaris' { return .solaris }
'android' { return .android } 'android' { return .android }
'haiku' { return .haiku } 'haiku' { return .haiku }
'linux_or_macos' { return .linux } 'linux_or_macos', 'nix' { return .linux }
'' { return ._auto } '' { return ._auto }
else { return error('bad OS $os_str') } else { return error('bad OS $os_str') }
} }
@ -55,6 +56,7 @@ pub fn (o OS) str() string {
.android { return 'Android' } .android { return 'Android' }
.solaris { return 'Solaris' } .solaris { return 'Solaris' }
.haiku { return 'Haiku' } .haiku { return 'Haiku' }
.all { return 'all' }
} }
} }

View File

@ -120,6 +120,9 @@ pub fn (prefs &Preferences) should_compile_c(file string) bool {
// Probably something like `a.js.v`. // Probably something like `a.js.v`.
return false return false
} }
if prefs.os == .all {
return true
}
if (file.ends_with('_windows.c.v') || file.ends_with('_windows.v')) && prefs.os != .windows { if (file.ends_with('_windows.c.v') || file.ends_with('_windows.v')) && prefs.os != .windows {
return false return false
} }