Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

vlib, tools: make minor improvements #19950

Merged
merged 8 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
33 changes: 16 additions & 17 deletions cmd/tools/vdoc/html.v
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,17 @@ import v.pref
import v.util { tabs }

const (
css_js_assets = ['doc.css', 'normalize.css', 'doc.js', 'dark-mode.js']
default_theme = os.resource_abs_path('theme')
link_svg = '<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"/></svg>'
css_js_assets = ['doc.css', 'normalize.css', 'doc.js', 'dark-mode.js']
default_theme = os.resource_abs_path('theme')
link_svg = '<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"/></svg>'

single_quote = "'"
double_quote = '"'
no_quotes_replacement = [single_quote, '', double_quote, '']
single_quote = "'"
double_quote = '"'
no_quotes_replacement = [single_quote, '', double_quote, '']

html_tag_escape_replacement = ['<', '&lt;', '>', '&gt;']
html_tag_escape_re = regex.regex_opt(r'`.+[(&lt;)(&gt;)].+`') or { panic(err) }
html_tag_escape_re = regex.regex_opt(r'`.+[(&lt;)(&gt;)].+`') or { panic(err) }
html_tag_escape_seq = ['<', '&lt;', '>', '&gt;']
md_script_escape_seq = ['<script>', '`', '</script>', '`']
)

enum HighlightTokenTyp {
Expand Down Expand Up @@ -213,14 +214,13 @@ fn (vd VDoc) gen_html(d doc.Doc) string {
}
// write nav1
if cfg.is_multi || vd.docs.len > 1 {
mut used_submod_prefix := []string{}
for i, dc in vd.docs {
names := dc.head.name.split('.')
submod_prefix := if names.len > 1 { names[0] } else { dc.head.name }
if i - 1 >= 0 && submod_prefix in used_submod_prefix {
mut used_submod_prefixes := map[string]bool{}
for dc in vd.docs {
submod_prefix := dc.head.name.all_before('.')
if used_submod_prefixes[submod_prefix] {
ttytm marked this conversation as resolved.
Show resolved Hide resolved
continue
}
used_submod_prefix << submod_prefix
used_submod_prefixes[submod_prefix] = true
mut href_name := './${dc.head.name}.html'
if (cfg.is_vlib && dc.head.name == 'builtin' && !cfg.include_readme)
|| dc.head.name == 'README' {
Expand Down Expand Up @@ -424,8 +424,7 @@ fn doc_node_html(dn doc.DocNode, link string, head bool, include_examples bool,
// Allow README.md to go through unescaped except for script tags
escaped_html := if head && is_module_readme(dn) {
// Strip markdown [TOC] directives, since we generate our own.
stripped := comments.replace('[TOC]', '')
markdown_escape_script_tags(stripped)
comments.replace('[TOC]', '').replace_each(md_script_escape_seq)
} else {
html_tag_escape(comments)
}
Expand Down Expand Up @@ -494,7 +493,7 @@ fn doc_node_html(dn doc.DocNode, link string, head bool, include_examples bool,
}

fn html_tag_escape(str string) string {
escaped_string := str.replace_each(html_tag_escape_replacement)
escaped_string := str.replace_each(html_tag_escape_seq)
mut re := html_tag_escape_re
if re.find_all_str(escaped_string).len > 0 {
return str
Expand Down
4 changes: 0 additions & 4 deletions cmd/tools/vdoc/markdown.v
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@ module main
import strings
import v.doc

fn markdown_escape_script_tags(str string) string {
return str.replace_each(['<script>', '`', '</script>', '`'])
}

fn (vd VDoc) gen_markdown(d doc.Doc, with_toc bool) string {
mut hw := strings.new_builder(200)
mut cw := strings.new_builder(200)
Expand Down
7 changes: 5 additions & 2 deletions cmd/tools/vvet/vvet.v
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ struct Options {
doc_private_fns_too bool
}

const term_colors = term.can_show_color_on_stderr()
const (
term_colors = term.can_show_color_on_stderr()
clean_seq = ['[', '', ']', '', ' ', '']
)

fn main() {
vet_options := cmdline.options_after(os.args, ['vet'])
Expand Down Expand Up @@ -140,7 +143,7 @@ fn (mut vt Vet) vet_fn_documentation(lines []string, line string, lnumber int) {
if lnumber > 0 {
collect_tags := fn (line string) []string {
mut cleaned := line.all_before('/')
cleaned = cleaned.replace_each(['[', '', ']', '', ' ', ''])
cleaned = cleaned.replace_each(clean_seq)
return cleaned.split(',')
}
ident_fn_name := fn (line string) string {
Expand Down
18 changes: 6 additions & 12 deletions vlib/net/http/request.v
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,9 @@ fn (req &Request) method_and_url_to_response(method Method, url urllib.URL) !Res
// println('fetch $method, $scheme, $host_name, $nport, $path ')
if scheme == 'https' && req.proxy == unsafe { nil } {
// println('ssl_do( $nport, $method, $host_name, $path )')
mut retries := 0
for {
for i in 0 .. req.max_retries {
res := req.ssl_do(nport, method, host_name, path) or {
retries++
if is_no_need_retry_error(err.code()) || retries >= req.max_retries {
if i == req.max_retries - 1 || is_no_need_retry_error(err.code()) {
return err
}
continue
Expand All @@ -154,23 +152,19 @@ fn (req &Request) method_and_url_to_response(method Method, url urllib.URL) !Res
}
} else if scheme == 'http' && req.proxy == unsafe { nil } {
// println('http_do( $nport, $method, $host_name, $path )')
mut retries := 0
for {
for i in 0 .. req.max_retries {
res := req.http_do('${host_name}:${nport}', method, path) or {
retries++
if is_no_need_retry_error(err.code()) || retries >= req.max_retries {
if i == req.max_retries - 1 || is_no_need_retry_error(err.code()) {
return err
}
continue
}
return res
}
} else if req.proxy != unsafe { nil } {
mut retries := 0
for {
for i in 0 .. req.max_retries {
res := req.proxy.http_do(url, method, path, req) or {
retries++
if is_no_need_retry_error(err.code()) || retries >= req.max_retries {
if i == req.max_retries - 1 || is_no_need_retry_error(err.code()) {
return err
}
continue
Expand Down
8 changes: 4 additions & 4 deletions vlib/v/checker/checker.v
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ pub fn (mut c Checker) check_files(ast_files []&ast.File) {
}
}
// After the main checker run, run the line info check, print line info, and exit (if it's present)
if c.pref.line_info != '' && !c.pref.linfo.is_running { //'' && c.pref.linfo.line_nr == 0 {
if !c.pref.linfo.is_running && c.pref.line_info != '' { //'' && c.pref.linfo.line_nr == 0 {
// c.do_line_info(c.pref.line_info, ast_files)
println('setting is_running=true, pref.path=${c.pref.linfo.path} curdir' + os.getwd())
c.pref.linfo.is_running = true
Expand Down Expand Up @@ -963,7 +963,7 @@ fn (mut c Checker) type_implements(typ ast.Type, interface_type ast.Type, pos to
styp := c.table.type_to_str(utyp)
typ_sym := c.table.sym(utyp)
mut inter_sym := c.table.sym(interface_type)
if inter_sym.mod !in [typ_sym.mod, c.mod] && !inter_sym.is_pub && typ_sym.mod != 'builtin' {
if !inter_sym.is_pub && inter_sym.mod !in [typ_sym.mod, c.mod] && typ_sym.mod != 'builtin' {
c.error('`${styp}` cannot implement private interface `${inter_sym.name}` of other module',
pos)
return false
Expand Down Expand Up @@ -2321,7 +2321,7 @@ fn (mut c Checker) hash_stmt(mut node ast.HashStmt) {
c.error('hash statements are only allowed in backend specific files such "x.js.v" and "x.go.v"',
node.pos)
}
if c.mod == 'main' && c.pref.backend != .golang {
if c.pref.backend != .golang && c.mod == 'main' {
c.error('hash statements are not allowed in the main module. Place them in a separate module.',
node.pos)
}
Expand Down Expand Up @@ -4600,7 +4600,7 @@ fn (c &Checker) check_struct_signature(from ast.Struct, to ast.Struct) bool {
fn (mut c Checker) fetch_field_name(field ast.StructField) string {
mut name := field.name
for attr in field.attrs {
if attr.kind == .string && attr.name == 'sql' && attr.arg != '' {
if attr.kind == .string && attr.arg != '' && attr.name == 'sql' {
name = attr.arg
break
}
Expand Down
8 changes: 5 additions & 3 deletions vlib/v/checker/errors.v
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,12 @@ fn (mut c Checker) deprecate(kind string, name string, attrs []ast.Attr, pos tok
now := time.now()
mut after_time := now
for attr in attrs {
if attr.name == 'deprecated' && attr.arg != '' {
deprecation_message = attr.arg
if attr.arg == '' {
continue
}
if attr.name == 'deprecated_after' && attr.arg != '' {
if attr.name == 'deprecated' {
deprecation_message = attr.arg
} else if attr.name == 'deprecated_after' {
after_time = time.parse_iso8601(attr.arg) or {
c.error('invalid time format', attr.pos)
now
Expand Down
14 changes: 7 additions & 7 deletions vlib/v/checker/fn.v
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
node.params[1].typ) {
c.error('expected `${receiver_sym.name}` not `${param_sym.name}` - both operands must be the same type for operator overloading',
node.params[1].type_pos)
} else if node.name in ['<', '=='] && node.return_type != ast.bool_type {
} else if node.return_type != ast.bool_type && node.name in ['<', '=='] {
c.error('operator comparison methods should return `bool`', node.pos)
} else if parent_sym.is_primitive() {
// aliases of primitive types are explicitly allowed
Expand Down Expand Up @@ -728,7 +728,7 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast.
}
}
panic('unreachable')
} else if node.args.len > 0 && fn_name == 'json.encode' && node.args[0].typ.has_flag(.shared_f) {
} else if node.args.len > 0 && node.args[0].typ.has_flag(.shared_f) && fn_name == 'json.encode' {
c.error('json.encode cannot handle shared data', node.pos)
return ast.void_type
} else if node.args.len > 0 && fn_name == 'json.decode' {
Expand Down Expand Up @@ -801,7 +801,7 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast.
}
}
// try prefix with current module as it would have never gotten prefixed
if !found && !fn_name.contains('.') && node.mod != 'builtin' {
if !found && node.mod != 'builtin' && !fn_name.contains('.') {
name_prefixed := '${node.mod}.${fn_name}'
if f := c.table.find_fn(name_prefixed) {
node.name = name_prefixed
Expand Down Expand Up @@ -2572,10 +2572,10 @@ fn (mut c Checker) map_builtin_method_call(mut node ast.CallExpr, left_type ast.
c.table.find_or_register_array(info.value_type)
}
ret_type = ast.Type(typ)
if method_name == 'keys' && info.key_type.has_flag(.generic) {
if info.key_type.has_flag(.generic) && method_name == 'keys' {
ret_type = ret_type.set_flag(.generic)
}
if method_name == 'values' && info.value_type.has_flag(.generic) {
if info.value_type.has_flag(.generic) && method_name == 'values' {
ret_type = ret_type.set_flag(.generic)
}
}
Expand Down Expand Up @@ -2614,7 +2614,7 @@ fn (mut c Checker) ensure_same_array_return_type(mut node ast.CallExpr, left_typ
fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type ast.Type, left_sym ast.TypeSymbol) ast.Type {
method_name := node.name
mut elem_typ := ast.void_type
if method_name == 'slice' && !c.is_builtin_mod {
if !c.is_builtin_mod && method_name == 'slice' {
c.error('.slice() is a private method, use `x[start..end]` instead', node.pos)
return ast.void_type
}
Expand Down Expand Up @@ -2646,7 +2646,7 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as
// position of `it` doesn't matter
scope_register_it(mut node.scope, node.pos, elem_typ)
}
} else if method_name == 'sorted_with_compare' && node.args.len == 1 {
} else if node.args.len == 1 && method_name == 'sorted_with_compare' {
if node.args.len > 0 && mut node.args[0].expr is ast.LambdaExpr {
c.support_lambda_expr_in_sort(elem_typ.ref(), ast.int_type, mut node.args[0].expr)
}
Expand Down
4 changes: 2 additions & 2 deletions vlib/v/checker/struct.v
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ fn (mut c Checker) struct_decl(mut node ast.StructDecl) {
struct_sym.info.fields.sort_with_compare(minify_sort_fn)
}
for attr in node.attrs {
if attr.name == 'typedef' && node.language != .c {
if node.language != .c && attr.name == 'typedef' {
c.error('`typedef` attribute can only be used with C structs', node.pos)
}
}
Expand Down Expand Up @@ -827,7 +827,7 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.',
}
*/
// Check for `[required]` struct attr
if field.attrs.contains('required') && !node.no_keys && !node.has_update_expr {
if !node.no_keys && !node.has_update_expr && field.attrs.contains('required') {
mut found := false
for init_field in node.init_fields {
if field.name == init_field.name {
Expand Down
68 changes: 37 additions & 31 deletions vlib/v/parser/comptime.v
Original file line number Diff line number Diff line change
Expand Up @@ -303,37 +303,43 @@ fn (mut p Parser) comptime_for() ast.ComptimeFor {
for_val := p.check_name()
mut kind := ast.ComptimeForKind.methods
p.open_scope()
if for_val == 'methods' {
p.scope.register(ast.Var{
name: val_var
typ: p.table.find_type_idx('FunctionData')
pos: var_pos
})
} else if for_val == 'values' {
p.scope.register(ast.Var{
name: val_var
typ: p.table.find_type_idx('EnumData')
pos: var_pos
})
kind = .values
} else if for_val == 'fields' {
p.scope.register(ast.Var{
name: val_var
typ: p.table.find_type_idx('FieldData')
pos: var_pos
})
kind = .fields
} else if for_val == 'attributes' {
p.scope.register(ast.Var{
name: val_var
typ: p.table.find_type_idx('StructAttribute')
pos: var_pos
})
kind = .attributes
} else {
p.error_with_pos('unknown kind `${for_val}`, available are: `methods`, `fields`, `values`, or `attributes`',
p.prev_tok.pos())
return ast.ComptimeFor{}
match for_val {
'methods' {
p.scope.register(ast.Var{
name: val_var
typ: p.table.find_type_idx('FunctionData')
pos: var_pos
})
}
'values' {
p.scope.register(ast.Var{
name: val_var
typ: p.table.find_type_idx('EnumData')
pos: var_pos
})
kind = .values
}
'fields' {
p.scope.register(ast.Var{
name: val_var
typ: p.table.find_type_idx('FieldData')
pos: var_pos
})
kind = .fields
}
'attributes' {
p.scope.register(ast.Var{
name: val_var
typ: p.table.find_type_idx('StructAttribute')
pos: var_pos
})
kind = .attributes
}
else {
p.error_with_pos('unknown kind `${for_val}`, available are: `methods`, `fields`, `values`, or `attributes`',
p.prev_tok.pos())
return ast.ComptimeFor{}
}
}
spos := p.tok.pos()
stmts := p.parse_block()
Expand Down
6 changes: 3 additions & 3 deletions vlib/v/parser/expr.v
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ fn (mut p Parser) check_expr(precedence int) !ast.Expr {
p.is_stmt_ident = is_stmt_ident
}
.name, .question {
if p.tok.lit == 'sql' && p.peek_tok.kind == .name {
if p.peek_tok.kind == .name && p.tok.lit == 'sql' {
node = p.sql_expr()
} else if p.tok.lit == 'map' && p.peek_tok.kind == .lcbr && !(p.builtin_mod
} else if p.peek_tok.kind == .lcbr && p.tok.lit == 'map' && !(p.builtin_mod
&& p.file_base in ['map.v', 'map_d_gcboehm_opt.v']) {
p.error_with_pos("deprecated map syntax, use syntax like `{'age': 20}`",
p.tok.pos())
Expand Down Expand Up @@ -296,7 +296,7 @@ fn (mut p Parser) check_expr(precedence int) !ast.Expr {
|| p.tok.kind.is_start_of_type()
|| (p.tok.lit.len > 0 && p.tok.lit[0].is_capital())

if p.tok.lit in ['c', 'r'] && p.peek_tok.kind == .string {
if p.peek_tok.kind == .string && p.tok.lit in ['c', 'r'] {
is_known_var = false
is_type = false
}
Expand Down