aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-08-22 21:54:44 -0400
committerBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-08-22 22:29:31 -0400
commit302698f2b878cf68302fee5a46a49086e17a83cc (patch)
tree1e0702d8a52781e928aebc3947660a977c9fe26f /src
parent52839df5fa441be5cf1cd0fb0e6b43cb5c6560c6 (diff)
Always collect private symbols and filter them when resolving
Diffstat (limited to 'src')
-rw-r--r--src/server/analysis.odin22
-rw-r--r--src/server/ast.odin23
-rw-r--r--src/server/builtins.odin23
-rw-r--r--src/server/collector.odin2
-rw-r--r--src/server/completion.odin4
-rw-r--r--src/server/documentation.odin2
-rw-r--r--src/server/indexer.odin28
-rw-r--r--src/server/memory_index.odin13
-rw-r--r--src/server/methods.odin11
-rw-r--r--src/server/workspace_symbols.odin2
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,