diff options
| author | Brad Lewis <22850972+BradLewis@users.noreply.github.com> | 2026-02-10 21:09:00 +1100 |
|---|---|---|
| committer | Brad Lewis <22850972+BradLewis@users.noreply.github.com> | 2026-02-10 21:09:00 +1100 |
| commit | 1efe81498d2fbb91ecac80b57b6009a6399f2ba3 (patch) | |
| tree | d06c4b84ad1869f3563dc1efbaa604029b8229cf /src/server | |
| parent | bdb8de855fe54090a388a25c03ef19f279b13b19 (diff) | |
Add documentation to package hover info
Diffstat (limited to 'src/server')
| -rw-r--r-- | src/server/analysis.odin | 19 | ||||
| -rw-r--r-- | src/server/check.odin | 5 | ||||
| -rw-r--r-- | src/server/collector.odin | 93 |
3 files changed, 72 insertions, 45 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin index 6d0cf09..67d7ef3 100644 --- a/src/server/analysis.odin +++ b/src/server/analysis.odin @@ -1812,7 +1812,7 @@ internal_resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ide try_build_package(symbol.pkg) - return symbol, true + return resolve_symbol_return(ast_context, symbol) } } @@ -1823,8 +1823,9 @@ internal_resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ide pkg = indexer.runtime_package, value = SymbolPackageValue{}, } + try_build_package(symbol.pkg) - return symbol, true + return resolve_symbol_return(ast_context, symbol) } if global, ok := ast_context.globals[node.name]; @@ -1853,7 +1854,7 @@ internal_resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ide try_build_package(symbol.pkg) - return symbol, true + return resolve_symbol_return(ast_context, symbol) } is_runtime := strings.contains(ast_context.current_package, "base/runtime") @@ -1896,7 +1897,7 @@ resolve_local_identifier :: proc(ast_context: ^AstContext, node: ast.Ident, loca value = SymbolPackageValue{}, } - return symbol, true + return resolve_symbol_return(ast_context, symbol) } } } @@ -2639,6 +2640,16 @@ resolve_symbol_return :: proc(ast_context: ^AstContext, symbol: Symbol, ok := tr } #partial switch &v in symbol.value { + case SymbolPackageValue: + if pkg, ok := indexer.index.collection.packages[symbol.pkg]; ok { + if symbol.doc == "" { + symbol.doc = strings.to_string(pkg.doc) + } + if symbol.comment == "" { + symbol.comment = strings.to_string(pkg.comment) + } + } + return symbol, true case SymbolProcedureGroupValue: if s, ok := resolve_function_overload(ast_context, v.group.derived.(^ast.Proc_Group)); ok { if s.doc == "" { diff --git a/src/server/check.odin b/src/server/check.odin index e8400d3..78eb25f 100644 --- a/src/server/check.odin +++ b/src/server/check.odin @@ -1,6 +1,5 @@ package server -import "base:intrinsics" import "base:runtime" import "core:encoding/json" @@ -11,11 +10,7 @@ import "core:os" import "core:path/filepath" import path "core:path/slashpath" import "core:slice" -import "core:strconv" import "core:strings" -import "core:sync" -import "core:text/scanner" -import "core:thread" import "src:common" diff --git a/src/server/collector.odin b/src/server/collector.odin index 708c96b..24fd0fa 100644 --- a/src/server/collector.odin +++ b/src/server/collector.odin @@ -1,6 +1,7 @@ #+feature using-stmt package server +import "core:fmt" import "core:mem" import "core:odin/ast" import "core:path/filepath" @@ -38,6 +39,8 @@ SymbolPackage :: struct { methods: map[Method][dynamic]Symbol, imports: [dynamic]string, //Used for references to figure whether the package is even able to reference the symbol proc_group_members: map[string]bool, // Tracks procedure names that are part of proc groups (used by fake methods) + doc: strings.Builder, + comment: strings.Builder, } get_index_unique_string :: proc { @@ -477,6 +480,8 @@ get_or_create_package :: proc(collection: ^SymbolCollection, pkg_name: string) - pkg.methods = make(map[Method][dynamic]Symbol, 100, collection.allocator) pkg.objc_structs = make(map[string]ObjcStruct, 5, collection.allocator) pkg.proc_group_members = make(map[string]bool, 10, collection.allocator) + pkg.doc = strings.builder_make(collection.allocator) + pkg.comment = strings.builder_make(collection.allocator) } return pkg } @@ -662,6 +667,49 @@ collect_imports :: proc(collection: ^SymbolCollection, file: ast.File, directory } +@(private = "file") +get_symbol_package_name :: proc( + collection: ^SymbolCollection, + directory: string, + uri: string, + treat_as_builtin := false, +) -> string { + if treat_as_builtin || strings.contains(uri, "builtin.odin") { + return "$builtin" + } + + if strings.contains(uri, "intrinsics.odin") { + intrinsics_path := filepath.join( + elems = {common.config.collections["base"], "/intrinsics"}, + allocator = context.temp_allocator, + ) + intrinsics_path, _ = filepath.to_slash(intrinsics_path, context.temp_allocator) + return get_index_unique_string(collection, intrinsics_path) + } + + return get_index_unique_string(collection, directory) +} + +@(private = "file") +get_package_decl_doc_comment :: proc(file: ast.File, allocator := context.temp_allocator) -> (string, string) { + if file.pkg_decl != nil { + docs := get_comment(file.pkg_decl.docs, allocator = allocator) + comment := get_comment(file.pkg_decl.comment, allocator = allocator) + return docs, comment + } + return "", "" +} + +@(private = "file") +write_doc_string :: proc(sb: ^strings.Builder, doc: string) { + if doc != "" { + if strings.builder_len(sb^) > 0 { + fmt.sbprintf(sb, "\n%s", doc) + } else { + strings.write_string(sb, doc) + } + } +} collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: string) -> common.Error { forward, _ := filepath.to_slash(file.fullpath, context.temp_allocator) @@ -669,6 +717,12 @@ collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: stri package_map := get_package_mapping(file, collection.config, directory) exprs := collect_globals(file) + file_pkg_name := get_symbol_package_name(collection, directory, uri) + file_pkg := get_or_create_package(collection, file_pkg_name) + doc, comment := get_package_decl_doc_comment(file, collection.allocator) + write_doc_string(&file_pkg.doc, doc) + write_doc_string(&file_pkg.comment, comment) + for expr in exprs { symbol: Symbol @@ -694,18 +748,7 @@ collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: stri } // Compute pkg early so it's available inside the switch - if expr.builtin || strings.contains(uri, "builtin.odin") { - symbol.pkg = "$builtin" - } else if strings.contains(uri, "intrinsics.odin") { - intrinsics_path := filepath.join( - elems = {common.config.collections["base"], "/intrinsics"}, - allocator = context.temp_allocator, - ) - intrinsics_path, _ = filepath.to_slash(intrinsics_path, context.temp_allocator) - symbol.pkg = get_index_unique_string(collection, intrinsics_path) - } else { - symbol.pkg = get_index_unique_string(collection, directory) - } + symbol.pkg = get_symbol_package_name(collection, directory, uri, expr.builtin) #partial switch v in col_expr.derived { case ^ast.Matrix_Type: @@ -899,17 +942,7 @@ collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: stri symbol.flags |= {.Mutable} } - pkg: ^SymbolPackage - ok: bool - - if pkg, ok = &collection.packages[symbol.pkg]; !ok { - collection.packages[symbol.pkg] = {} - pkg = &collection.packages[symbol.pkg] - pkg.symbols = make(map[string]Symbol, 100, collection.allocator) - pkg.methods = make(map[Method][dynamic]Symbol, 100, collection.allocator) - pkg.objc_structs = make(map[string]ObjcStruct, 5, collection.allocator) - pkg.proc_group_members = make(map[string]bool, 10, collection.allocator) - } + pkg := get_or_create_package(collection, symbol.pkg) if .ObjC in symbol.flags { collect_objc(collection, expr.attributes, symbol) @@ -942,19 +975,7 @@ collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: stri collect_fake_methods :: proc(collection: ^SymbolCollection, exprs: []GlobalExpr, directory: string, uri: string) { for expr in exprs { // Determine the package name (same logic as in collect_symbols) - pkg_name: string - if expr.builtin || strings.contains(uri, "builtin.odin") { - pkg_name = "$builtin" - } else if strings.contains(uri, "intrinsics.odin") { - intrinsics_path := filepath.join( - elems = {common.config.collections["base"], "/intrinsics"}, - allocator = context.temp_allocator, - ) - intrinsics_path, _ = filepath.to_slash(intrinsics_path, context.temp_allocator) - pkg_name = get_index_unique_string(collection, intrinsics_path) - } else { - pkg_name = get_index_unique_string(collection, directory) - } + pkg_name := get_symbol_package_name(collection, directory, uri, expr.builtin) pkg, ok := &collection.packages[pkg_name] if !ok { |