aboutsummaryrefslogtreecommitdiff
path: root/src/server/analysis.odin
diff options
context:
space:
mode:
authorBradley Lewis <22850972+BradLewis@users.noreply.github.com>2025-10-04 07:50:19 -0400
committerGitHub <noreply@github.com>2025-10-04 07:50:19 -0400
commitb85caeb82b86af897113eff551d37616d4e8e440 (patch)
treefc4a8df6b3bee1d84105f35b3df5eddae677505a /src/server/analysis.odin
parent0f166cc7e740b1f7175246942d9e04ef3a070d17 (diff)
parentccda4509f972ceb683d7d6c1fd6e55497bde1634 (diff)
Merge pull request #1076 from BradLewis/fix/call-after-proc-overload
Correctly provide completions when calling a proc immediately after a proc overload call
Diffstat (limited to 'src/server/analysis.odin')
-rw-r--r--src/server/analysis.odin80
1 files changed, 48 insertions, 32 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index 2278e00..abddab6 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -25,27 +25,32 @@ UsingStatement :: struct {
}
AstContext :: struct {
- locals: [dynamic]LocalGroup, //locals all the way to the document position
- globals: map[string]GlobalExpr,
- recursion_map: map[rawptr]struct{},
- usings: [dynamic]UsingStatement,
- file: ast.File,
- allocator: mem.Allocator,
- imports: []Package, //imports for the current document
- current_package: string,
- document_package: string,
- deferred_package: [DeferredDepth]string, //When a package change happens when resolving
- deferred_count: int,
- use_locals: bool,
- call: ^ast.Call_Expr, //used to determine the types for generics and the correct function for overloaded functions
- value_decl: ^ast.Value_Decl,
- field_name: ast.Ident,
- uri: string,
- fullpath: string,
- non_mutable_only: bool, //Only store local value declarations that are non mutable.
- overloading: bool,
- position_hint: DocumentPositionContextHint,
- resolving_locals: bool,
+ locals: [dynamic]LocalGroup, //locals all the way to the document position
+ globals: map[string]GlobalExpr,
+ recursion_map: map[rawptr]struct{},
+ usings: [dynamic]UsingStatement,
+ file: ast.File,
+ allocator: mem.Allocator,
+ imports: []Package, //imports for the current document
+ current_package: string,
+ document_package: string,
+ deferred_package: [DeferredDepth]string, //When a package change happens when resolving
+ deferred_count: int,
+ use_locals: bool,
+ call: ^ast.Call_Expr, //used to determine the types for generics and the correct function for overloaded functions
+ value_decl: ^ast.Value_Decl,
+ field_name: ast.Ident,
+ uri: string,
+ fullpath: string,
+ non_mutable_only: bool, //Only store local value declarations that are non mutable.
+ overloading: bool,
+ position_hint: DocumentPositionContextHint,
+ resolving_locals: bool,
+ // Explicitly set whether to only resolve the correct overload, rather than have it be inferred by
+ // whether we're resolving locals and the position hint
+ //
+ // We should probably rework how this is handled in the future
+ resolve_specific_overload: bool,
}
make_ast_context :: proc(
@@ -669,6 +674,20 @@ get_top_candiate :: proc(candidates: []Candidate) -> (Candidate, bool) {
return top, true
}
+
+should_resolve_all_proc_overload_possibilities :: proc(ast_context: ^AstContext, call_expr: ^ast.Call_Expr) -> bool {
+ // TODO: We need a better way to handle this
+ if ast_context.resolve_specific_overload {
+ return false
+ }
+
+ if ast_context.resolving_locals {
+ return false
+ }
+
+ return ast_context.position_hint == .Completion || ast_context.position_hint == .SignatureHelp || call_expr == nil
+}
+
/*
Figure out which function the call expression is using out of the list from proc group
*/
@@ -686,15 +705,7 @@ resolve_function_overload :: proc(ast_context: ^AstContext, group: ast.Proc_Grou
ast_context.overloading = false
}
- resolve_all_possibilities: bool
- if ast_context.resolving_locals {
- resolve_all_possibilities = false
- } else {
- resolve_all_possibilities =
- ast_context.position_hint == .Completion || ast_context.position_hint == .SignatureHelp || call_expr == nil
- }
-
-
+ resolve_all_possibilities := should_resolve_all_proc_overload_possibilities(ast_context, call_expr)
call_unnamed_arg_count := 0
if call_expr != nil {
call_unnamed_arg_count = get_unnamed_arg_count(call_expr.args)
@@ -1230,6 +1241,8 @@ internal_resolve_type_expression :: proc(ast_context: ^AstContext, node: ^ast.Ex
resolve_call_expr :: proc(ast_context: ^AstContext, v: ^ast.Call_Expr) -> (Symbol, bool) {
symbol := Symbol{}
+ // The function being called may be a local variable
+ ast_context.use_locals = true
if ident, ok := v.expr.derived.(^ast.Ident); ok && len(v.args) >= 1 {
switch ident.name {
case "type_of":
@@ -1239,6 +1252,9 @@ resolve_call_expr :: proc(ast_context: ^AstContext, v: ^ast.Call_Expr) -> (Symbo
}
} else if call, ok := v.expr.derived.(^ast.Call_Expr); ok {
// handle the case where we immediately call a proc returned by another proc
+ // in this case we don't want to resolve all possibilities for a proc overload
+ ast_context.resolve_specific_overload = true
+ defer ast_context.resolve_specific_overload = false
if ok := internal_resolve_type_expression(ast_context, v.expr, &symbol); ok {
if value, ok := symbol.value.(SymbolProcedureValue); ok {
if len(value.return_types) == 1 {
@@ -1298,9 +1314,9 @@ resolve_index_expr :: proc(ast_context: ^AstContext, v: ^ast.Index_Expr) -> (Sym
}
return {}, false
case SymbolMatrixValue:
- value := SymbolFixedArrayValue{
+ value := SymbolFixedArrayValue {
expr = v2.expr,
- len = v2.x,
+ len = v2.x,
}
indexed.value = value
return indexed, true