aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2025-08-07 15:15:27 +0200
committerGitHub <noreply@github.com>2025-08-07 15:15:27 +0200
commitf9c23d7ec2841d8580fb55acd4fb26aaae8d605b (patch)
treea78ece63bffafed2694ff6e453ff285df8c8f6ab
parent0167f6c8f58bba8a014d53e3015f741b0b150fe9 (diff)
parent23219e126f8fc31dafb8dc6b5d9f7212483d803d (diff)
Merge pull request #824 from BradLewis/feat/resolve-poly-types
Resolve poly type variables
-rw-r--r--src/server/analysis.odin16
-rw-r--r--src/server/documentation.odin5
-rw-r--r--src/server/semantic_tokens.odin3
-rw-r--r--src/server/symbol.odin7
-rw-r--r--tests/completions_test.odin14
-rw-r--r--tests/hover_test.odin18
-rw-r--r--tests/references_test.odin19
7 files changed, 81 insertions, 1 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index ab2efd7..47722e8 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -1168,6 +1168,8 @@ internal_resolve_type_expression :: proc(ast_context: ^AstContext, node: ^ast.Ex
if v.specialization != nil {
return internal_resolve_type_expression(ast_context, v.specialization, out)
}
+ out^ = make_symbol_poly_type_from_ast(ast_context, v.type)
+ return true
case:
log.warnf("default node kind, internal_resolve_type_expression: %v", v)
@@ -3096,6 +3098,20 @@ make_symbol_basic_type_from_ast :: proc(ast_context: ^AstContext, n: ^ast.Ident)
return symbol
}
+make_symbol_poly_type_from_ast :: proc(ast_context: ^AstContext, n: ^ast.Ident) -> Symbol {
+ symbol := Symbol {
+ range = common.get_token_range(n^, ast_context.file.src),
+ type = .Variable,
+ pkg = get_package_from_node(n^),
+ }
+
+ symbol.value = SymbolPolyTypeValue {
+ ident = n,
+ }
+
+ return symbol
+}
+
make_symbol_union_from_ast :: proc(
ast_context: ^AstContext,
v: ast.Union_Type,
diff --git a/src/server/documentation.odin b/src/server/documentation.odin
index c22bbb4..d7c3295 100644
--- a/src/server/documentation.odin
+++ b/src/server/documentation.odin
@@ -312,6 +312,11 @@ get_short_signature :: proc(ast_context: ^AstContext, symbol: Symbol) -> string
build_string_node(v.ident, &sb, false)
}
return strings.to_string(sb)
+ case SymbolPolyTypeValue:
+ sb := strings.builder_make(ast_context.allocator)
+ fmt.sbprintf(&sb, "%s$", pointer_prefix)
+ build_string_node(v.ident, &sb, false)
+ return strings.to_string(sb)
case SymbolBitSetValue:
sb := strings.builder_make(ast_context.allocator)
fmt.sbprintf(&sb, "%sbit_set[", pointer_prefix)
diff --git a/src/server/semantic_tokens.odin b/src/server/semantic_tokens.odin
index 1a5fcb6..7210ccf 100644
--- a/src/server/semantic_tokens.odin
+++ b/src/server/semantic_tokens.odin
@@ -611,7 +611,8 @@ visit_ident :: proc(
SymbolSliceValue,
SymbolMapValue,
SymbolMultiPointerValue,
- SymbolBasicValue:
+ SymbolBasicValue,
+ SymbolPolyTypeValue:
write_semantic_node(builder, ident, .Type, modifiers)
case SymbolUntypedValue:
// handled by static syntax highlighting
diff --git a/src/server/symbol.odin b/src/server/symbol.odin
index 7352425..a41a310 100644
--- a/src/server/symbol.odin
+++ b/src/server/symbol.odin
@@ -135,6 +135,10 @@ SymbolMatrixValue :: struct {
expr: ^ast.Expr,
}
+SymbolPolyTypeValue :: struct {
+ ident: ^ast.Ident,
+}
+
/*
Generic symbol that is used by the indexer for any variable type(constants, defined global variables, etc),
*/
@@ -161,6 +165,7 @@ SymbolValue :: union {
SymbolUntypedValue,
SymbolMatrixValue,
SymbolBitFieldValue,
+ SymbolPolyTypeValue,
}
SymbolFlag :: enum {
@@ -641,6 +646,8 @@ free_symbol :: proc(symbol: Symbol, allocator: mem.Allocator) {
free_ast(v.expr, allocator)
case SymbolBasicValue:
free_ast(v.ident, allocator)
+ case SymbolPolyTypeValue:
+ free_ast(v.ident, allocator)
case SymbolAggregateValue:
for symbol in v.symbols {
free_symbol(symbol, allocator)
diff --git a/tests/completions_test.odin b/tests/completions_test.odin
index 148252d..b2e1503 100644
--- a/tests/completions_test.odin
+++ b/tests/completions_test.odin
@@ -4259,3 +4259,17 @@ ast_completion_nested_struct_with_enum_fields_unnamed :: proc(t: ^testing.T) {
}
test.expect_completion_docs( t, &source, "", {"C", "D"}, {"A", "B"})
}
+
+@(test)
+ast_completion_poly_type :: proc(t: ^testing.T) {
+ source := test.Source {
+ main = `package test
+ foo :: proc(array: $A/[]$T) {
+ for elem, i in array {
+ el{*}
+ }
+ }
+ `,
+ }
+ test.expect_completion_docs( t, &source, "", {"test.elem: $T"})
+}
diff --git a/tests/hover_test.odin b/tests/hover_test.odin
index 923095b..edba279 100644
--- a/tests/hover_test.odin
+++ b/tests/hover_test.odin
@@ -3572,6 +3572,24 @@ ast_hover_union_field_documentation_same_line :: proc(t: ^testing.T) {
"test.Foo: union {\n\t// Doc for int and string\n\t// Mulitple lines!\n\tint, // comment for int and string\n\t// Doc for int and string\n\t// Mulitple lines!\n\tstring, // comment for int and string\n}"
)
}
+
+@(test)
+ast_hover_parapoly_proc_dynamic_array_elems :: proc(t: ^testing.T) {
+ source := test.Source {
+ main = `package test
+ foo :: proc(array: $A/[dynamic]^$T) {
+ for e{*}lem, i in array {
+
+ }
+ }
+ `,
+ }
+ test.expect_hover(
+ t,
+ &source,
+ "test.elem: ^$T"
+ )
+}
/*
Waiting for odin fix
diff --git a/tests/references_test.odin b/tests/references_test.odin
index c7b69aa..fb409e6 100644
--- a/tests/references_test.odin
+++ b/tests/references_test.odin
@@ -1129,3 +1129,22 @@ ast_references_enum_struct_field_without_name :: proc(t: ^testing.T) {
test.expect_reference_locations(t, &source, locations[:])
}
+
+@(test)
+ast_references_poly_type :: proc(t: ^testing.T) {
+ source := test.Source {
+ main = `package test
+ foo :: proc(array: $A/[dynamic]^$T) {
+ for e{*}lem, i in array {
+ elem
+ }
+ }
+ `,
+ }
+ locations := []common.Location {
+ {range = {start = {line = 2, character = 7}, end = {line = 2, character = 11}}},
+ {range = {start = {line = 3, character = 4}, end = {line = 3, character = 8}}},
+ }
+
+ test.expect_reference_locations(t, &source, locations[:])
+}