aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2025-08-09 17:30:54 +0200
committerGitHub <noreply@github.com>2025-08-09 17:30:54 +0200
commiteda157808c74ae676c0d6e680b0138d6707a9643 (patch)
tree2ed36ca88dd09100cc389228386ca98b1702b766 /src
parentf88c3de16dfdb0eb6d27406d901a29d25f7cb2b4 (diff)
parent5b4b6564584ccf544f5fe7e0ce9bafd2e77cdd09 (diff)
Merge pull request #837 from BradLewis/fix/resolve-poly-procs-return-type-locals
Implement method to resolve poly return types based on the types of local variables
Diffstat (limited to 'src')
-rw-r--r--src/server/analysis.odin88
-rw-r--r--src/server/generics.odin5
-rw-r--r--src/server/symbol.odin4
3 files changed, 53 insertions, 44 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index fc5df05..dbe9d48 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -1586,62 +1586,62 @@ internal_resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ide
if global, ok := ast_context.globals[node.name];
ast_context.current_package == ast_context.document_package && ok {
return resolve_global_identifier(ast_context, node, &global)
- } else {
- switch node.name {
- case "context":
- for built in indexer.builtin_packages {
- if symbol, ok := lookup("Context", built); ok {
- symbol.type = .Variable
- return symbol, ok
- }
- }
- }
-
+ }
- //right now we replace the package ident with the absolute directory name, so it should have '/' which is not a valid ident character
- if strings.contains(node.name, "/") {
- symbol := Symbol {
- type = .Package,
- pkg = node.name,
- value = SymbolPackageValue{},
+ switch node.name {
+ case "context":
+ for built in indexer.builtin_packages {
+ if symbol, ok := lookup("Context", built); ok {
+ symbol.type = .Variable
+ return symbol, ok
}
+ }
+ }
- try_build_package(symbol.pkg)
- return symbol, true
+ //right now we replace the package ident with the absolute directory name, so it should have '/' which is not a valid ident character
+ if strings.contains(node.name, "/") {
+ symbol := Symbol {
+ type = .Package,
+ pkg = node.name,
+ value = SymbolPackageValue{},
}
- is_runtime := strings.contains(ast_context.current_package, "base/runtime")
+ try_build_package(symbol.pkg)
- if is_runtime {
- if symbol, ok := lookup(node.name, "$builtin"); ok {
- return resolve_symbol_return(ast_context, symbol)
- }
- }
+ return symbol, true
+ }
+
+ is_runtime := strings.contains(ast_context.current_package, "base/runtime")
- //last option is to check the index
- if symbol, ok := lookup(node.name, ast_context.current_package); ok {
+ if is_runtime {
+ if symbol, ok := lookup(node.name, "$builtin"); ok {
return resolve_symbol_return(ast_context, symbol)
}
+ }
- if !is_runtime {
- if symbol, ok := lookup(node.name, "$builtin"); 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 {
+ return resolve_symbol_return(ast_context, symbol)
+ }
+
+ if !is_runtime {
+ if symbol, ok := lookup(node.name, "$builtin"); ok {
+ return resolve_symbol_return(ast_context, symbol)
}
+ }
- for built in indexer.builtin_packages {
- if symbol, ok := lookup(node.name, built); ok {
- return resolve_symbol_return(ast_context, symbol)
- }
+ for built in indexer.builtin_packages {
+ if symbol, ok := lookup(node.name, built); ok {
+ return resolve_symbol_return(ast_context, symbol)
}
+ }
- 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 {
- return resolve_symbol_return(ast_context, symbol)
- }
+ 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 {
+ return resolve_symbol_return(ast_context, symbol)
}
}
}
@@ -1720,6 +1720,8 @@ resolve_local_identifier :: proc(ast_context: ^AstContext, node: ast.Ident, loca
return_symbol, ok = resolve_function_overload(ast_context, v^)
case ^ast.Array_Type:
return_symbol, ok = make_symbol_array_from_ast(ast_context, v^, node), true
+ case ^ast.Multi_Pointer_Type:
+ return_symbol, ok = make_symbol_multi_pointer_from_ast(ast_context, v^, node), true
case ^ast.Dynamic_Array_Type:
return_symbol, ok = make_symbol_dynamic_array_from_ast(ast_context, v^, node), true
case ^ast.Matrix_Type:
@@ -3549,8 +3551,6 @@ get_locals_value_decl :: proc(file: ast.File, value_decl: ast.Value_Decl, ast_co
result_i := min(len(results) - 1, i)
str := get_ast_node_string(name, file.src)
- call := false
-
store_local(
ast_context,
name,
@@ -3558,7 +3558,7 @@ get_locals_value_decl :: proc(file: ast.File, value_decl: ast.Value_Decl, ast_co
value_decl.end.offset,
str,
ast_context.non_mutable_only,
- calls[result_i] or_else false,
+ false, // calls[result_i] or_else false, // TODO: find a good way to handle this
value_decl.is_mutable,
get_package_from_node(results[result_i]^),
false,
diff --git a/src/server/generics.odin b/src/server/generics.odin
index 1802efb..a629d3e 100644
--- a/src/server/generics.odin
+++ b/src/server/generics.odin
@@ -494,6 +494,7 @@ resolve_generic_function_symbol :: proc(
if symbol, ok := resolve_type_expression(ast_context, call_expr.args[i]); ok {
file := strings.trim_prefix(symbol.uri, "file://")
+
if file == "" {
file = call_expr.args[i].pos.file
}
@@ -522,6 +523,10 @@ resolve_generic_function_symbol :: proc(
}
}
+ // We set the offset so we can find it as a local if it's based on the type of a local var
+ symbol_expr.pos.offset = call_expr.pos.offset
+ symbol_expr.end.offset = call_expr.end.offset
+
symbol_expr = clone_expr(symbol_expr, ast_context.allocator, nil)
param_type := clone_expr(param.type, ast_context.allocator, nil)
diff --git a/src/server/symbol.odin b/src/server/symbol.odin
index 147626b..ff88099 100644
--- a/src/server/symbol.odin
+++ b/src/server/symbol.odin
@@ -773,6 +773,10 @@ symbol_to_expr :: proc(symbol: Symbol, file: string, allocator := context.temp_a
case SymbolBitFieldValue:
type := new_type(ast.Bit_Field_Type, pos, end, allocator)
return type
+ case SymbolMultiPointerValue:
+ type := new_type(ast.Multi_Pointer_Type, pos, end, allocator)
+ type.elem = v.expr
+ return type
case:
return nil
}