summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBradley Lewis <22850972+BradLewis@users.noreply.github.com>2025-10-30 00:14:15 -0400
committerGitHub <noreply@github.com>2025-10-30 00:14:15 -0400
commit7ee9a6fc9647adf493d7e95ac675c0094f11ee4d (patch)
tree838d91c485947fd587d8d7894c41c88fb3fb51de
parent9854c3ec2786498c94a341183c6b901af375826a (diff)
parent2e0f171e43d44b61c60296bab45fb86846f671f0 (diff)
Merge pull request #1132 from BradLewis/fix/generic-proc-packages
Fix/generic proc packages
-rw-r--r--src/server/analysis.odin106
-rw-r--r--src/server/caches.odin2
-rw-r--r--src/server/generics.odin39
-rw-r--r--tests/hover_test.odin21
4 files changed, 75 insertions, 93 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index 83aef98..fdc1956 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -1811,37 +1811,7 @@ resolve_local_identifier :: proc(ast_context: ^AstContext, node: ast.Ident, loca
return_symbol, ok = make_symbol_bit_field_from_ast(ast_context, v, node.name), true
return_symbol.name = node.name
case ^ast.Proc_Lit:
- if is_procedure_generic(v.type) {
- return_symbol, ok = resolve_generic_function(ast_context, v^)
-
- if !ok && !ast_context.overloading {
- return_symbol, ok =
- make_symbol_procedure_from_ast(
- ast_context,
- local.rhs,
- v.type^,
- node.name,
- {},
- false,
- v.inlining,
- v.where_clauses,
- ),
- true
- }
- } else {
- return_symbol, ok =
- make_symbol_procedure_from_ast(
- ast_context,
- local.rhs,
- v.type^,
- node.name,
- {},
- false,
- v.inlining,
- v.where_clauses,
- ),
- true
- }
+ return_symbol, ok = resolve_proc_lit(ast_context, local.rhs, v, node.name, {}, false)
case ^ast.Proc_Group:
return_symbol, ok = resolve_function_overload(ast_context, v^)
case ^ast.Array_Type:
@@ -1935,38 +1905,7 @@ resolve_global_identifier :: proc(ast_context: ^AstContext, node: ast.Ident, glo
return_symbol, ok = make_symbol_bit_field_from_ast(ast_context, v, node.name), true
return_symbol.name = node.name
case ^ast.Proc_Lit:
- if is_procedure_generic(v.type) {
- return_symbol, ok = resolve_generic_function(ast_context, v^)
-
- //If we are not overloading just show the unresolved generic function
- if !ok && !ast_context.overloading {
- return_symbol, ok =
- make_symbol_procedure_from_ast(
- ast_context,
- global.expr,
- v.type^,
- node.name,
- global.attributes,
- false,
- v.inlining,
- v.where_clauses,
- ),
- true
- }
- } else {
- return_symbol, ok =
- make_symbol_procedure_from_ast(
- ast_context,
- global.expr,
- v.type^,
- node.name,
- global.attributes,
- false,
- v.inlining,
- v.where_clauses,
- ),
- true
- }
+ return_symbol, ok = resolve_proc_lit(ast_context, global.expr, v, node.name, global.attributes, false)
case ^ast.Proc_Group:
return_symbol, ok = resolve_function_overload(ast_context, v^)
case ^ast.Array_Type:
@@ -2013,6 +1952,38 @@ resolve_global_identifier :: proc(ast_context: ^AstContext, node: ast.Ident, glo
return return_symbol, ok
}
+resolve_proc_lit :: proc(
+ ast_context: ^AstContext,
+ node: ^ast.Node,
+ proc_lit: ^ast.Proc_Lit,
+ name: string,
+ attributes: []^ast.Attribute,
+ type: bool,
+) -> (
+ Symbol,
+ bool,
+) {
+ symbol := make_symbol_procedure_from_ast(
+ ast_context,
+ node,
+ proc_lit.type^,
+ name,
+ attributes,
+ type,
+ proc_lit.inlining,
+ proc_lit.where_clauses,
+ )
+
+ if is_procedure_generic(proc_lit.type) {
+ if generic_symbol, ok := resolve_generic_function(ast_context, proc_lit^, symbol); ok {
+ return generic_symbol, ok
+ } else if ast_context.overloading {
+ return {}, false
+ }
+ }
+ return symbol, true
+}
+
struct_type_from_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -> (^ast.Struct_Type, bool) {
if check_node_recursion(ast_context, node.derived.(^ast.Ident)) {
return {}, false
@@ -2528,8 +2499,13 @@ resolve_symbol_return :: proc(ast_context: ^AstContext, symbol: Symbol, ok := tr
}
case SymbolProcedureValue:
if v.generic {
- if resolved_symbol, ok := resolve_generic_function(ast_context, v.arg_types, v.return_types, v.inlining);
- ok {
+ if resolved_symbol, ok := resolve_generic_function(
+ ast_context,
+ v.arg_types,
+ v.return_types,
+ v.inlining,
+ symbol,
+ ); ok {
return resolved_symbol, ok
} else {
return symbol, true
diff --git a/src/server/caches.odin b/src/server/caches.odin
index 423e568..ff7a422 100644
--- a/src/server/caches.odin
+++ b/src/server/caches.odin
@@ -2,8 +2,6 @@ package server
import "src:common"
-import "core:fmt"
-import "core:log"
import "core:mem/virtual"
import "core:os"
import "core:path/filepath"
diff --git a/src/server/generics.odin b/src/server/generics.odin
index d57f4d5..37546a2 100644
--- a/src/server/generics.odin
+++ b/src/server/generics.odin
@@ -1,19 +1,9 @@
package server
-import "core:fmt"
-import "core:log"
-import "core:mem"
import "core:odin/ast"
-import "core:odin/parser"
import "core:odin/tokenizer"
-import "core:path/filepath"
-import path "core:path/slashpath"
import "core:reflect"
-import "core:slice"
-import "core:sort"
-import "core:strconv"
import "core:strings"
-import "core:unicode/utf8"
import "src:common"
@@ -487,7 +477,14 @@ resolve_generic_function :: proc {
resolve_generic_function_symbol,
}
-resolve_generic_function_ast :: proc(ast_context: ^AstContext, proc_lit: ast.Proc_Lit) -> (Symbol, bool) {
+resolve_generic_function_ast :: proc(
+ ast_context: ^AstContext,
+ proc_lit: ast.Proc_Lit,
+ proc_symbol: Symbol,
+) -> (
+ Symbol,
+ bool,
+) {
if ast_context.call == nil {
return Symbol{}, false
}
@@ -502,7 +499,9 @@ resolve_generic_function_ast :: proc(ast_context: ^AstContext, proc_lit: ast.Pro
results = proc_lit.type.results.list
}
- return resolve_generic_function_symbol(ast_context, params, results, proc_lit.inlining)
+ range := common.get_token_range(proc_lit, ast_context.file.src)
+ uri := common.create_uri(proc_lit.pos.file, ast_context.allocator).uri
+ return resolve_generic_function_symbol(ast_context, params, results, proc_lit.inlining, proc_symbol)
}
@@ -511,6 +510,7 @@ resolve_generic_function_symbol :: proc(
params: []^ast.Field,
results: []^ast.Field,
inlining: ast.Proc_Inlining,
+ proc_symbol: Symbol,
) -> (
Symbol,
bool,
@@ -606,29 +606,15 @@ resolve_generic_function_symbol :: proc(
}
function_name := ""
- function_range: common.Range
- function_uri := ""
if ident, ok := call_expr.expr.derived.(^ast.Ident); ok {
function_name = ident.name
- function_range = common.get_token_range(ident, ast_context.file.src)
- function_uri = common.create_uri(ident.pos.file, ast_context.allocator).uri
} else if selector, ok := call_expr.expr.derived.(^ast.Selector_Expr); ok {
function_name = selector.field.name
- function_range = common.get_token_range(selector, ast_context.file.src)
- function_uri = common.create_uri(selector.field.pos.file, ast_context.allocator).uri
} else {
return {}, false
}
- symbol := Symbol {
- range = function_range,
- type = .Function,
- name = function_name,
- pkg = ast_context.current_package,
- uri = function_uri,
- }
-
return_types := make([dynamic]^ast.Field, ast_context.allocator)
argument_types := make([dynamic]^ast.Field, ast_context.allocator)
@@ -682,6 +668,7 @@ resolve_generic_function_symbol :: proc(
}
+ symbol := proc_symbol
symbol.value = SymbolProcedureValue {
return_types = return_types[:],
arg_types = argument_types[:],
diff --git a/tests/hover_test.odin b/tests/hover_test.odin
index 391ff60..4a99d19 100644
--- a/tests/hover_test.odin
+++ b/tests/hover_test.odin
@@ -5347,6 +5347,27 @@ ast_hover_quaternion_literal :: proc(t: ^testing.T) {
}
test.expect_hover(t, &source, "test.foo: quaternion256")
}
+
+@(test)
+ast_hover_parapoly_other_package :: proc(t: ^testing.T) {
+ packages := make([dynamic]test.Package, context.temp_allocator)
+
+ append(&packages, test.Package{pkg = "my_package", source = `package my_package
+ // Docs!
+ bar :: proc(_: $T) {} // Comment!
+ `})
+ source := test.Source {
+ main = `package test
+ import "my_package"
+
+ main :: proc() {
+ my_package.ba{*}r("test")
+ }
+ `,
+ packages = packages[:],
+ }
+ test.expect_hover(t, &source, "my_package.bar :: proc(_: $T)\n Docs!\n\n// Comment!")
+}
/*
Waiting for odin fix