aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Lewis <22850972+BradLewis@users.noreply.github.com>2026-01-24 09:27:19 +1100
committerBrad Lewis <22850972+BradLewis@users.noreply.github.com>2026-01-24 09:27:19 +1100
commit00955b4ddf08c2a87a53af72b25c0108f862d95e (patch)
tree9f80c07e33cf7beba915511c47c6b2c1cefece02
parente21db4a48e04e558e0aa3a46e0bd7668168714e1 (diff)
Correctly resolve hover info for poly types in where clauses for procs
-rw-r--r--src/server/analysis.odin3
-rw-r--r--src/server/ast.odin2
-rw-r--r--src/server/documentation.odin3
-rw-r--r--src/server/file_resolve.odin3
-rw-r--r--src/server/imports.odin2
-rw-r--r--src/server/locals.odin10
-rw-r--r--src/server/position_context.odin7
-rw-r--r--src/server/symbol.odin1
-rw-r--r--tests/hover_test.odin20
9 files changed, 45 insertions, 6 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index cec34e3..8e27d1e 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -1977,6 +1977,9 @@ resolve_local_identifier :: proc(ast_context: ^AstContext, node: ast.Ident, loca
if .Variable in local.flags {
return_symbol.flags |= {.Variable}
}
+ if .PolyType in local.flags {
+ return_symbol.flags |= {.PolyType}
+ }
return_symbol.flags |= {.Local}
return_symbol.value_expr = local.value_expr
diff --git a/src/server/ast.odin b/src/server/ast.odin
index 0547b83..42c0ba6 100644
--- a/src/server/ast.odin
+++ b/src/server/ast.odin
@@ -561,7 +561,7 @@ collect_globals :: proc(file: ast.File) -> []GlobalExpr {
}
get_ast_node_string :: proc(node: ^ast.Node, src: string) -> string {
- return string(src[node.pos.offset:node.end.offset])
+ return strings.trim_prefix(string(src[node.pos.offset:node.end.offset]), "$")
}
COMMENT_DELIMITER_LENGTH :: len("//")
diff --git a/src/server/documentation.odin b/src/server/documentation.odin
index 25e4140..7c26a37 100644
--- a/src/server/documentation.odin
+++ b/src/server/documentation.odin
@@ -848,6 +848,9 @@ write_symbol_name :: proc(sb: ^strings.Builder, symbol: Symbol) {
} else if pkg != "" && pkg != "$builtin" {
fmt.sbprintf(sb, "%v.", pkg)
}
+ if .PolyType in symbol.flags {
+ strings.write_string(sb, "$")
+ }
strings.write_string(sb, symbol.name)
}
diff --git a/src/server/file_resolve.odin b/src/server/file_resolve.odin
index c526030..8c7de51 100644
--- a/src/server/file_resolve.odin
+++ b/src/server/file_resolve.odin
@@ -512,6 +512,9 @@ resolve_node :: proc(node: ^ast.Node, data: ^FileResolveData) {
data.position_context.struct_type = n
resolve_node(n.poly_params, data)
resolve_node(n.align, data)
+ for clause in n.where_clauses {
+ resolve_node(clause, data)
+ }
resolve_node(n.fields, data)
if data.flag != .None {
diff --git a/src/server/imports.odin b/src/server/imports.odin
index 256295b..16deec5 100644
--- a/src/server/imports.odin
+++ b/src/server/imports.odin
@@ -1,8 +1,6 @@
package server
-import "core:log"
import "core:mem"
-import "core:odin/ast"
import "base:runtime"
diff --git a/src/server/locals.odin b/src/server/locals.odin
index b02a841..3e3d126 100644
--- a/src/server/locals.odin
+++ b/src/server/locals.odin
@@ -6,6 +6,7 @@ import "core:odin/ast"
LocalFlag :: enum {
Mutable, // or constant
Variable, // or type
+ PolyType,
}
DocumentLocal :: struct {
@@ -1066,6 +1067,11 @@ get_locals_proc_param_and_results :: proc(
if proc_lit.type != nil && proc_lit.type.params != nil {
for arg in proc_lit.type.params.list {
for name in arg.names {
+ flags: bit_set[LocalFlag] = {.Mutable}
+ if _, ok := name.derived.(^ast.Poly_Type); ok {
+ flags |= {.PolyType}
+ }
+
if arg.type != nil {
str := get_ast_node_string(name, file.src)
store_local(
@@ -1076,7 +1082,7 @@ get_locals_proc_param_and_results :: proc(
str,
ast_context.non_mutable_only,
false,
- {.Mutable},
+ flags,
"",
true,
)
@@ -1097,7 +1103,7 @@ get_locals_proc_param_and_results :: proc(
str,
ast_context.non_mutable_only,
false,
- {.Mutable},
+ flags,
"",
true,
)
diff --git a/src/server/position_context.odin b/src/server/position_context.odin
index 602d9a1..7670e79 100644
--- a/src/server/position_context.odin
+++ b/src/server/position_context.odin
@@ -61,7 +61,7 @@ DocumentPositionContext :: struct {
import_stmt: ^ast.Import_Decl,
type_cast: ^ast.Type_Cast,
call_commas: []int,
- directive: ^ast.Basic_Directive,
+ directive: ^ast.Basic_Directive,
}
@@ -845,6 +845,11 @@ get_document_position_node :: proc(node: ^ast.Node, position_context: ^DocumentP
position_context.struct_type = n
get_document_position(n.poly_params, position_context)
get_document_position(n.align, position_context)
+ for clause in n.where_clauses {
+ if position_in_node(clause, position_context.position) {
+ get_document_position(clause, position_context)
+ }
+ }
get_document_position(n.fields, position_context)
case ^Union_Type:
position_context.union_type = n
diff --git a/src/server/symbol.odin b/src/server/symbol.odin
index 96c83ed..14e231c 100644
--- a/src/server/symbol.odin
+++ b/src/server/symbol.odin
@@ -212,6 +212,7 @@ SymbolFlag :: enum {
SoaPointer,
Simd,
Parameter, //If the symbol is a procedure argument
+ PolyType,
}
SymbolFlags :: bit_set[SymbolFlag]
diff --git a/tests/hover_test.odin b/tests/hover_test.odin
index 9929ee3..630f4d7 100644
--- a/tests/hover_test.odin
+++ b/tests/hover_test.odin
@@ -6004,6 +6004,26 @@ ast_hover_soa_struct_field_indexed :: proc(t: ^testing.T) {
}
test.expect_hover(t, &source, "test.foo: #soa^#soa[dynamic]Foo")
}
+
+@(test)
+ast_hover_proc_poly_params :: proc(t: ^testing.T) {
+ source := test.Source {
+ main = `package test
+ foo :: proc($T{*}: int) {}
+ `,
+ }
+ test.expect_hover(t, &source, "test.$T: int")
+}
+
+@(test)
+ast_hover_proc_poly_params_where_clause :: proc(t: ^testing.T) {
+ source := test.Source {
+ main = `package test
+ foo :: proc($T: int) where T{*} >= 0 {}
+ `,
+ }
+ test.expect_hover(t, &source, "test.$T: int")
+}
/*
Waiting for odin fix