diff --git a/cmd/tools/vdoc/html.v b/cmd/tools/vdoc/html.v index bd516afeca..7931c7eefd 100644 --- a/cmd/tools/vdoc/html.v +++ b/cmd/tools/vdoc/html.v @@ -438,9 +438,12 @@ fn doc_node_html(dn doc.DocNode, link string, head bool, include_examples bool, html_tag_escape(comments) } md_content := markdown.to_html(escaped_html) - hlighted_code := html_highlight(dn.content, tb) + highlighted_code := html_highlight(dn.content, tb) node_class := if dn.kind == .const_group { ' const' } else { '' } sym_name := get_sym_name(dn) + mut tags := dn.tags + tags.sort() + tags_str := ' ' + tags.map('[$it]').join('') mut node_id := get_node_id(dn) mut hash_link := if !head { ' #' } else { '' } if head && is_module_readme(dn) { @@ -450,9 +453,9 @@ fn doc_node_html(dn doc.DocNode, link string, head bool, include_examples bool, dnw.writeln('${tabs[1]}
') if dn.name.len > 0 { if dn.kind == .const_group { - dnw.write_string('${tabs[2]}
<$head_tag>$sym_name$hash_link') + dnw.write_string('${tabs[2]}
<$head_tag>$sym_name$tags_str$hash_link') } else { - dnw.write_string('${tabs[2]}
<$head_tag>$dn.kind $sym_name$hash_link') + dnw.write_string('${tabs[2]}
<$head_tag>$dn.kind $sym_name$tags_str<$hash_link/$head_tag>') } if link.len != 0 { dnw.write_string('$link_svg') @@ -460,7 +463,7 @@ fn doc_node_html(dn doc.DocNode, link string, head bool, include_examples bool, dnw.write_string('
') } if !head && dn.content.len > 0 { - dnw.writeln('
$hlighted_code
') + dnw.writeln('
$highlighted_code
') } // do not mess with md_content further, its formatting is important, just output it 1:1 ! dnw.writeln('$md_content\n') diff --git a/cmd/tools/vdoc/resources/doc.css b/cmd/tools/vdoc/resources/doc.css index 24d685b59b..db0c59a431 100644 --- a/cmd/tools/vdoc/resources/doc.css +++ b/cmd/tools/vdoc/resources/doc.css @@ -578,6 +578,11 @@ pre { color: var(--code-function-text-color); } +/* Attribute tag colors */ +.attribute-tag { + color: red !important; +} + /* Medium screen and up */ @media (min-width: 768px) { *::-webkit-scrollbar { diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index a07cacdf49..cd6e5896af 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -370,6 +370,7 @@ pub: is_conditional bool // true for `[if abc] fn abc(){}` is_exported bool // true for `[export: 'exact_C_name']` is_keep_alive bool // passed memory must not be freed (by GC) before function returns + is_unsafe bool // true, when [unsafe] is used on a fn receiver StructField // TODO this is not a struct field receiver_pos token.Position // `(u User)` in `fn (u User) name()` position is_method bool diff --git a/vlib/v/doc/doc.v b/vlib/v/doc/doc.v index 6e7ccc9114..34c1fc47b1 100644 --- a/vlib/v/doc/doc.v +++ b/vlib/v/doc/doc.v @@ -127,7 +127,7 @@ pub mut: pos token.Position file_path string kind SymbolKind - deprecated bool + tags []string parent_name string return_type string children []DocNode @@ -257,7 +257,15 @@ pub fn (mut d Doc) stmt(stmt ast.Stmt, filename string) ?DocNode { node.kind = .typedef } ast.FnDecl { - node.deprecated = stmt.is_deprecated + if stmt.is_deprecated { + node.tags << 'deprecated' + } + if stmt.is_unsafe { + node.tags << 'unsafe' + } + if node.tags.len > 0 { + eprintln(node.tags) + } node.kind = .function node.return_type = d.type_to_str(stmt.return_type) if stmt.receiver.typ !in [0, 1] { diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index 8da2637b1f..4085d91ed5 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -467,6 +467,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl { is_main: is_main is_test: is_test is_keep_alive: is_keep_alive + is_unsafe: is_unsafe // attrs: p.attrs is_conditional: conditional_ctdefine_idx != -1