diff options
| author | Brad Lewis <22850972+BradLewis@users.noreply.github.com> | 2025-08-22 21:54:44 -0400 |
|---|---|---|
| committer | Brad Lewis <22850972+BradLewis@users.noreply.github.com> | 2025-08-22 22:29:31 -0400 |
| commit | 302698f2b878cf68302fee5a46a49086e17a83cc (patch) | |
| tree | 1e0702d8a52781e928aebc3947660a977c9fe26f /src | |
| parent | 52839df5fa441be5cf1cd0fb0e6b43cb5c6560c6 (diff) | |
Always collect private symbols and filter them when resolving
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/analysis.odin | 22 | ||||
| -rw-r--r-- | src/server/ast.odin | 23 | ||||
| -rw-r--r-- | src/server/builtins.odin | 23 | ||||
| -rw-r--r-- | src/server/collector.odin | 2 | ||||
| -rw-r--r-- | src/server/completion.odin | 4 | ||||
| -rw-r--r-- | src/server/documentation.odin | 2 | ||||
| -rw-r--r-- | src/server/indexer.odin | 28 | ||||
| -rw-r--r-- | src/server/memory_index.odin | 13 | ||||
| -rw-r--r-- | src/server/methods.odin | 11 | ||||
| -rw-r--r-- | src/server/workspace_symbols.odin | 2 |
10 files changed, 83 insertions, 47 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin index 44245e1..076a7e7 100644 --- a/src/server/analysis.odin +++ b/src/server/analysis.odin @@ -1449,7 +1449,7 @@ resolve_selector_expression :: proc(ast_context: ^AstContext, node: ^ast.Selecto try_build_package(ast_context.current_package) if node.field != nil { - return resolve_symbol_return(ast_context, lookup(node.field.name, selector.pkg)) + return resolve_symbol_return(ast_context, lookup(node.field.name, selector.pkg, node.pos.file)) } else { return Symbol{}, false } @@ -1580,7 +1580,7 @@ internal_resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ide switch node.name { case "context": for built in indexer.builtin_packages { - if symbol, ok := lookup("Context", built); ok { + if symbol, ok := lookup("Context", built, ""); ok { symbol.type = .Variable return symbol, ok } @@ -1604,24 +1604,24 @@ internal_resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ide is_runtime := strings.contains(ast_context.current_package, "base/runtime") if is_runtime { - if symbol, ok := lookup(node.name, "$builtin"); ok { + if symbol, ok := lookup(node.name, "$builtin", node.pos.file); ok { return resolve_symbol_return(ast_context, symbol) } } //last option is to check the index - if symbol, ok := lookup(node.name, ast_context.current_package); ok { + if symbol, ok := lookup(node.name, ast_context.current_package, node.pos.file); ok { return resolve_symbol_return(ast_context, symbol) } if !is_runtime { - if symbol, ok := lookup(node.name, "$builtin"); ok { + if symbol, ok := lookup(node.name, "$builtin", node.pos.file); ok { return resolve_symbol_return(ast_context, symbol) } } for built in indexer.builtin_packages { - if symbol, ok := lookup(node.name, built); ok { + if symbol, ok := lookup(node.name, built, node.pos.file); ok { return resolve_symbol_return(ast_context, symbol) } } @@ -1629,7 +1629,7 @@ internal_resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ide for u in ast_context.usings { for imp in ast_context.imports { if strings.compare(imp.name, u.pkg_name) == 0 { - if symbol, ok := lookup(node.name, imp.name); ok { + if symbol, ok := lookup(node.name, imp.name, node.pos.file); ok { return resolve_symbol_return(ast_context, symbol) } } @@ -2446,19 +2446,19 @@ resolve_location_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) - return symbol, true } - if symbol, ok := lookup(node.name, ast_context.document_package); ok { + if symbol, ok := lookup(node.name, ast_context.document_package, node.pos.file); ok { return symbol, ok } usings := get_using_packages(ast_context) for pkg in usings { - if symbol, ok := lookup(node.name, pkg); ok { + if symbol, ok := lookup(node.name, pkg, node.pos.file); ok { return symbol, ok } } - if symbol, ok := lookup(node.name, "$builtin"); ok { + if symbol, ok := lookup(node.name, "$builtin", node.pos.file); ok { return resolve_symbol_return(ast_context, symbol) } @@ -2676,7 +2676,7 @@ resolve_symbol_selector :: proc( } } case SymbolPackageValue: - if pkg, ok := lookup(field, symbol.pkg); ok { + if pkg, ok := lookup(field, symbol.pkg, symbol.uri); ok { symbol.range = pkg.range symbol.uri = pkg.uri } else { diff --git a/src/server/ast.odin b/src/server/ast.odin index ceb0183..57cd704 100644 --- a/src/server/ast.odin +++ b/src/server/ast.odin @@ -358,7 +358,6 @@ collect_value_decl :: proc( file: ast.File, file_tags: parser.File_Tags, stmt: ^ast.Node, - skip_private: bool, foreign_attrs: []^ast.Attribute, ) { value_decl, is_value_decl := stmt.derived.(^ast.Value_Decl) @@ -411,10 +410,6 @@ collect_value_decl :: proc( global_expr.private = .File } - if skip_private && global_expr.private == .File { - return - } - for name, i in value_decl.names { global_expr.name = get_ast_node_string(name, file.src) global_expr.name_expr = name @@ -434,7 +429,6 @@ collect_when_stmt :: proc( file: ast.File, file_tags: parser.File_Tags, when_decl: ^ast.When_Stmt, - skip_private: bool, ) { if when_decl.cond == nil { return @@ -448,7 +442,6 @@ collect_when_stmt :: proc( if block, ok := when_decl.body.derived.(^ast.Block_Stmt); ok { for stmt in block.stmts { if when_stmt, ok := stmt.derived.(^ast.When_Stmt); ok { - collect_when_stmt(exprs, file, file_tags, when_stmt, skip_private) } else if foreign_decl, ok := stmt.derived.(^ast.Foreign_Block_Decl); ok { if foreign_decl.body == nil { continue @@ -461,13 +454,12 @@ collect_when_stmt :: proc( file, file_tags, foreign_stmt, - skip_private, foreign_decl.attributes[:], ) } } } else { - collect_value_decl(exprs, file, file_tags, stmt, skip_private, {}) + collect_value_decl(exprs, file, file_tags, stmt, {}) } } } @@ -480,7 +472,7 @@ collect_when_stmt :: proc( if block, ok := else_when.body.derived.(^ast.Block_Stmt); ok { for stmt in block.stmts { if when_stmt, ok := stmt.derived.(^ast.When_Stmt); ok { - collect_when_stmt(exprs, file, file_tags, when_stmt, skip_private) + collect_when_stmt(exprs, file, file_tags, when_stmt) } else if foreign_decl, ok := stmt.derived.(^ast.Foreign_Block_Decl); ok { if foreign_decl.body != nil { if foreign_block, ok := foreign_decl.body.derived.(^ast.Block_Stmt); ok { @@ -490,14 +482,13 @@ collect_when_stmt :: proc( file, file_tags, foreign_stmt, - skip_private, foreign_decl.attributes[:], ) } } } } else { - collect_value_decl(exprs, file, file_tags, stmt, skip_private, {}) + collect_value_decl(exprs, file, file_tags, stmt, {}) } } } @@ -513,7 +504,7 @@ collect_when_stmt :: proc( } -collect_globals :: proc(file: ast.File, skip_private := false) -> []GlobalExpr { +collect_globals :: proc(file: ast.File) -> []GlobalExpr { exprs := make([dynamic]GlobalExpr, context.temp_allocator) defer shrink(&exprs) @@ -521,9 +512,9 @@ collect_globals :: proc(file: ast.File, skip_private := false) -> []GlobalExpr { for decl in file.decls { if value_decl, ok := decl.derived.(^ast.Value_Decl); ok { - collect_value_decl(&exprs, file, file_tags, decl, skip_private, {}) + collect_value_decl(&exprs, file, file_tags, decl, {}) } else if when_decl, ok := decl.derived.(^ast.When_Stmt); ok { - collect_when_stmt(&exprs, file, file_tags, when_decl, skip_private) + collect_when_stmt(&exprs, file, file_tags, when_decl) } else if foreign_decl, ok := decl.derived.(^ast.Foreign_Block_Decl); ok { if foreign_decl.body == nil { continue @@ -531,7 +522,7 @@ collect_globals :: proc(file: ast.File, skip_private := false) -> []GlobalExpr { if block, ok := foreign_decl.body.derived.(^ast.Block_Stmt); ok { for stmt in block.stmts { - collect_value_decl(&exprs, file, file_tags, stmt, skip_private, foreign_decl.attributes[:]) + collect_value_decl(&exprs, file, file_tags, stmt, foreign_decl.attributes[:]) } } } diff --git a/src/server/builtins.odin b/src/server/builtins.odin index 9b47182..7c5ce8e 100644 --- a/src/server/builtins.odin +++ b/src/server/builtins.odin @@ -20,7 +20,10 @@ check_builtin_proc_return_type :: proc( symbol: Symbol, call: ^ast.Call_Expr, is_mutable: bool, -) -> (^ast.Expr, bool) { +) -> ( + ^ast.Expr, + bool, +) { if symbol.pkg == "$builtin" { switch symbol.name { case "max", "min": @@ -133,9 +136,9 @@ check_builtin_proc_return_type :: proc( return nil, false } -@(private="file") +@(private = "file") get_return_expr :: proc(ast_context: ^AstContext, expr: ^ast.Expr, is_mutable: bool) -> ^ast.Expr { - if v, ok := expr.derived.(^ast.Field_Value); ok { +if v, ok := expr.derived.(^ast.Field_Value); ok { return get_return_expr(ast_context, v.value, is_mutable) } if ident, ok := expr.derived.(^ast.Ident); ok { @@ -153,7 +156,7 @@ get_return_expr :: proc(ast_context: ^AstContext, expr: ^ast.Expr, is_mutable: b return expr } -@(private="file") +@(private = "file") convert_candidate :: proc(candidate: ^ast.Basic_Lit, is_mutable: bool) -> ^ast.Expr { if is_mutable { ident := ast.new(ast.Ident, candidate.pos, candidate.end) @@ -168,7 +171,7 @@ convert_candidate :: proc(candidate: ^ast.Basic_Lit, is_mutable: bool) -> ^ast.E return candidate } -@(private="file") +@(private = "file") get_complex_return_expr :: proc(ast_context: ^AstContext, expr: ^ast.Expr) -> ^ast.Expr { if v, ok := expr.derived.(^ast.Field_Value); ok { return get_complex_return_expr(ast_context, v.value) @@ -189,7 +192,7 @@ get_complex_return_expr :: proc(ast_context: ^AstContext, expr: ^ast.Expr) -> ^a return expr } -@(private="file") +@(private = "file") convert_complex_candidate :: proc(candidate: ^ast.Basic_Lit, is_mutable: bool) -> ^ast.Expr { if is_mutable { ident := ast.new(ast.Ident, candidate.pos, candidate.end) @@ -200,7 +203,7 @@ convert_complex_candidate :: proc(candidate: ^ast.Basic_Lit, is_mutable: bool) - return candidate } -@(private="file") +@(private = "file") get_quaternion_return_expr :: proc(ast_context: ^AstContext, expr: ^ast.Expr) -> ^ast.Expr { if v, ok := expr.derived.(^ast.Field_Value); ok { return get_quaternion_return_expr(ast_context, v.value) @@ -221,7 +224,7 @@ get_quaternion_return_expr :: proc(ast_context: ^AstContext, expr: ^ast.Expr) -> return expr } -@(private="file") +@(private = "file") convert_quaternion_candidate :: proc(candidate: ^ast.Basic_Lit, is_mutable: bool) -> ^ast.Expr { if is_mutable { ident := ast.new(ast.Ident, candidate.pos, candidate.end) @@ -232,7 +235,7 @@ convert_quaternion_candidate :: proc(candidate: ^ast.Basic_Lit, is_mutable: bool return candidate } -@(private="file") +@(private = "file") get_basic_lit_value :: proc(n: ^ast.Expr) -> (^ast.Basic_Lit, f64, bool) { n := n if v, ok := n.derived.(^ast.Field_Value); ok { @@ -261,7 +264,7 @@ get_basic_lit_value :: proc(n: ^ast.Expr) -> (^ast.Basic_Lit, f64, bool) { return nil, 0, false } -@(private="file") +@(private = "file") compare_basic_lit_value :: proc(a, b: f64, name: string) -> bool { if name == "max" { return a > b diff --git a/src/server/collector.odin b/src/server/collector.odin index 541522d..6e0ffff 100644 --- a/src/server/collector.odin +++ b/src/server/collector.odin @@ -502,7 +502,7 @@ collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: stri forward, _ := filepath.to_slash(file.fullpath, context.temp_allocator) directory := path.dir(forward, context.temp_allocator) package_map := get_package_mapping(file, collection.config, directory) - exprs := collect_globals(file, true) + exprs := collect_globals(file) for expr in exprs { symbol: Symbol diff --git a/src/server/completion.odin b/src/server/completion.odin index 01218cf..617ffca 100644 --- a/src/server/completion.odin +++ b/src/server/completion.odin @@ -885,7 +885,7 @@ get_selector_completion :: proc( pkg := selector.pkg - if searched, ok := fuzzy_search(field, {pkg}); ok { + if searched, ok := fuzzy_search(field, {pkg}, ast_context.fullpath); ok { for search in searched { symbol := search.symbol @@ -1409,7 +1409,7 @@ get_identifier_completion :: proc( append(&pkgs, ast_context.document_package) append(&pkgs, "$builtin") - if fuzzy_results, ok := fuzzy_search(lookup_name, pkgs[:]); ok { + if fuzzy_results, ok := fuzzy_search(lookup_name, pkgs[:], ast_context.fullpath); ok { for r in fuzzy_results { r := r resolve_unresolved_symbol(ast_context, &r.symbol) diff --git a/src/server/documentation.odin b/src/server/documentation.odin index 1cc804d..ac1227f 100644 --- a/src/server/documentation.odin +++ b/src/server/documentation.odin @@ -335,7 +335,7 @@ write_short_signature :: proc(sb: ^strings.Builder, ast_context: ^AstContext, sy case SymbolProcedureValue: write_procedure_symbol_signature(sb, v, detailed_signature = true) return - case SymbolAggregateValue: + case SymbolAggregateValue, SymbolProcedureGroupValue: strings.write_string(sb, "proc (..)") return case SymbolStructValue: diff --git a/src/server/indexer.odin b/src/server/indexer.odin index 0a161aa..3a9a3fe 100644 --- a/src/server/indexer.odin +++ b/src/server/indexer.odin @@ -3,6 +3,7 @@ package server import "core:fmt" import "core:log" import "core:odin/ast" +import "core:path/filepath" import "core:slice" import "core:strings" @@ -25,20 +26,41 @@ clear_index_cache :: proc() { memory_index_clear_cache(&indexer.index) } -lookup :: proc(name: string, pkg: string, loc := #caller_location) -> (Symbol, bool) { +should_skip_private_symbol :: proc(symbol: Symbol, current_file: string) -> bool { + if .PrivateFile not_in symbol.flags && .PrivatePackage not_in symbol.flags { + return false + } + + symbol_file := strings.trim_prefix(symbol.uri, "file://") + current_file := strings.trim_prefix(current_file, "file://") + if .PrivateFile in symbol.flags && symbol_file != current_file { + return true + } + + current_pkg := filepath.dir(current_file, context.temp_allocator) + if .PrivatePackage in symbol.flags && current_pkg != symbol.pkg { + return true + } + return false +} + +lookup :: proc(name: string, pkg: string, current_file: string, loc := #caller_location) -> (Symbol, bool) { if name == "" { return {}, false } if symbol, ok := memory_index_lookup(&indexer.index, name, pkg); ok { + if should_skip_private_symbol(symbol, current_file) { + return {}, false + } return symbol, true } return {}, false } -fuzzy_search :: proc(name: string, pkgs: []string) -> ([]FuzzyResult, bool) { - results, ok := memory_index_fuzzy_search(&indexer.index, name, pkgs) +fuzzy_search :: proc(name: string, pkgs: []string, current_file: string) -> ([]FuzzyResult, bool) { + results, ok := memory_index_fuzzy_search(&indexer.index, name, pkgs, current_file) result := make([dynamic]FuzzyResult, context.temp_allocator) if !ok { diff --git a/src/server/memory_index.odin b/src/server/memory_index.odin index 0e660de..da55f44 100644 --- a/src/server/memory_index.odin +++ b/src/server/memory_index.odin @@ -40,7 +40,15 @@ memory_index_lookup :: proc(index: ^MemoryIndex, name: string, pkg: string) -> ( return {}, false } -memory_index_fuzzy_search :: proc(index: ^MemoryIndex, name: string, pkgs: []string) -> ([]FuzzyResult, bool) { +memory_index_fuzzy_search :: proc( + index: ^MemoryIndex, + name: string, + pkgs: []string, + current_file: string, +) -> ( + []FuzzyResult, + bool, +) { symbols := make([dynamic]FuzzyResult, 0, context.temp_allocator) fuzzy_matcher := common.make_fuzzy_matcher(name) @@ -50,6 +58,9 @@ memory_index_fuzzy_search :: proc(index: ^MemoryIndex, name: string, pkgs: []str for pkg in pkgs { if pkg, ok := index.collection.packages[pkg]; ok { for _, symbol in pkg.symbols { + if should_skip_private_symbol(symbol, current_file) { + continue + } if score, ok := common.fuzzy_match(fuzzy_matcher, symbol.name); ok == 1 { result := FuzzyResult { symbol = symbol, diff --git a/src/server/methods.odin b/src/server/methods.odin index 8b05840..e05fded 100644 --- a/src/server/methods.odin +++ b/src/server/methods.odin @@ -19,7 +19,13 @@ import "src:common" @(private) -create_remove_edit :: proc(position_context: ^DocumentPositionContext, strip_leading_period := false) -> ([]TextEdit, bool) { +create_remove_edit :: proc( + position_context: ^DocumentPositionContext, + strip_leading_period := false, +) -> ( + []TextEdit, + bool, +) { range, ok := get_range_from_selection_start_to_dot(position_context) if !ok { @@ -110,6 +116,9 @@ collect_methods :: proc( for k, v in indexer.index.collection.packages { if symbols, ok := &v.methods[method]; ok { for &symbol in symbols { + if should_skip_private_symbol(symbol, ast_context.fullpath) { + continue + } resolve_unresolved_symbol(ast_context, &symbol) range, ok := get_range_from_selection_start_to_dot(position_context) diff --git a/src/server/workspace_symbols.odin b/src/server/workspace_symbols.odin index 2d0f2f1..ac4e9dd 100644 --- a/src/server/workspace_symbols.odin +++ b/src/server/workspace_symbols.odin @@ -67,7 +67,7 @@ get_workspace_symbols :: proc(query: string) -> (workspace_symbols: []WorkspaceS try_build_package(pkg) - if results, ok := fuzzy_search(query, {pkg}); ok { + if results, ok := fuzzy_search(query, {pkg}, ""); ok { for result in results { symbol := WorkspaceSymbol { name = result.symbol.name, |