aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-07-03 18:37:02 -0400
committerBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-07-03 19:48:16 -0400
commit85d65fcfb761b49df6c03e1ed8e0523556c0bb62 (patch)
treef138f5d18a755502debfa44535d307f15fa3e23b
parent2edc388c40b4431cdfdc3d915fe9a139768aa783 (diff)
Add enum base type and values to the enum symbol and update hover to include that information
-rw-r--r--src/server/analysis.odin20
-rw-r--r--src/server/collector.odin19
-rw-r--r--src/server/documentation.odin18
-rw-r--r--src/server/symbol.odin11
-rw-r--r--tests/hover_test.odin14
5 files changed, 62 insertions, 20 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index 0a2fe1d..597c2cd 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -2757,33 +2757,37 @@ make_symbol_enum_from_ast :: proc(
names := make([dynamic]string, ast_context.allocator)
ranges := make([dynamic]common.Range, ast_context.allocator)
+ values := make([dynamic]^ast.Expr, ast_context.allocator)
for n in v.fields {
- name, range := get_enum_field_name_and_range(n, ast_context.file.src)
+ name, range, value := get_enum_field_name_range_value(n, ast_context.file.src)
append(&names, name)
append(&ranges, range)
+ append(&values, value)
}
symbol.value = SymbolEnumValue {
- names = names[:],
- ranges = ranges[:],
+ names = names[:],
+ ranges = ranges[:],
+ base_type = v.base_type,
+ values = values[:],
}
return symbol
}
-get_enum_field_name_and_range :: proc(n: ^ast.Expr, document_text: string) -> (string, common.Range) {
+get_enum_field_name_range_value :: proc(n: ^ast.Expr, document_text: string) -> (string, common.Range, ^ast.Expr) {
if ident, ok := n.derived.(^ast.Ident); ok {
- return ident.name, common.get_token_range(ident, document_text)
+ return ident.name, common.get_token_range(ident, document_text), nil
}
if field, ok := n.derived.(^ast.Field_Value); ok {
if ident, ok := field.field.derived.(^ast.Ident); ok {
- return ident.name, common.get_token_range(ident, document_text)
+ return ident.name, common.get_token_range(ident, document_text), field.value
} else if binary, ok := field.field.derived.(^ast.Binary_Expr); ok {
- return binary.left.derived.(^ast.Ident).name, common.get_token_range(binary, document_text)
+ return binary.left.derived.(^ast.Ident).name, common.get_token_range(binary, document_text), binary.right
}
}
- return "", {}
+ return "", {}, nil
}
make_symbol_bitset_from_ast :: proc(
diff --git a/src/server/collector.odin b/src/server/collector.odin
index b2c2d66..22aba08 100644
--- a/src/server/collector.odin
+++ b/src/server/collector.odin
@@ -151,7 +151,7 @@ collect_struct_fields :: proc(
}
value := to_symbol_struct_value(b)
- value.poly = cast(^ast.Field_List)clone_type(struct_type.poly_params, collection.allocator, &collection.unique_strings)
+ value.poly = cast(^ast.Field_List)clone_type(struct_type.poly_params, collection.allocator, &collection.unique_strings)
return value
}
@@ -189,23 +189,26 @@ collect_bit_field_fields :: proc(
collect_enum_fields :: proc(
collection: ^SymbolCollection,
- fields: []^ast.Expr,
+ enum_type: ast.Enum_Type,
package_map: map[string]string,
file: ast.File,
) -> SymbolEnumValue {
names := make([dynamic]string, 0, collection.allocator)
ranges := make([dynamic]common.Range, 0, collection.allocator)
+ values := make([dynamic]^ast.Expr, 0, collection.allocator)
- //ERROR no hover on n in the for, but elsewhere is fine
- for n in fields {
- name, range := get_enum_field_name_and_range(n, file.src)
+ for n in enum_type.fields {
+ name, range, value := get_enum_field_name_range_value(n, file.src)
append(&names, strings.clone(name, collection.allocator))
append(&ranges, range)
+ append(&values, clone_type(value, collection.allocator, &collection.unique_strings))
}
value := SymbolEnumValue {
- names = names[:],
- ranges = ranges[:],
+ names = names[:],
+ ranges = ranges[:],
+ values = values[:],
+ base_type = clone_type(enum_type.base_type, collection.allocator, &collection.unique_strings),
}
return value
@@ -529,7 +532,7 @@ collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: stri
case ^ast.Enum_Type:
token = v^
token_type = .Enum
- symbol.value = collect_enum_fields(collection, v.fields, package_map, file)
+ symbol.value = collect_enum_fields(collection, v^, package_map, file)
symbol.signature = "enum"
case ^ast.Union_Type:
token = v^
diff --git a/src/server/documentation.odin b/src/server/documentation.odin
index c0853d7..26dd9cf 100644
--- a/src/server/documentation.odin
+++ b/src/server/documentation.odin
@@ -19,10 +19,26 @@ get_signature :: proc(ast_context: ^AstContext, symbol: Symbol) -> string {
append_variable_full_name(&sb, ast_context, symbol, pointer_prefix)
strings.write_string(&sb, " :: ")
}
- strings.write_string(&sb, "enum {\n")
+
+ longestNameLen := 0
+ for name in v.names {
+ if len(name) > longestNameLen {
+ longestNameLen = len(name)
+ }
+ }
+ strings.write_string(&sb, "enum ")
+ if v.base_type != nil {
+ build_string_node(v.base_type, &sb, false)
+ strings.write_string(&sb, " ")
+ }
+ strings.write_string(&sb, "{\n")
for i in 0 ..< len(v.names) {
strings.write_string(&sb, "\t")
strings.write_string(&sb, v.names[i])
+ if v.values[i] != nil {
+ fmt.sbprintf(&sb, "%*s= ", longestNameLen - len(v.names[i]) + 1, "")
+ build_string_node(v.values[i], &sb, false)
+ }
strings.write_string(&sb, ",\n")
}
strings.write_string(&sb, "}")
diff --git a/src/server/symbol.odin b/src/server/symbol.odin
index 2d99d22..fddc775 100644
--- a/src/server/symbol.odin
+++ b/src/server/symbol.odin
@@ -67,8 +67,10 @@ SymbolAggregateValue :: struct {
}
SymbolEnumValue :: struct {
- names: []string,
- ranges: []common.Range,
+ names: []string,
+ values: []^ast.Expr,
+ base_type: ^ast.Expr,
+ ranges: []common.Range,
}
SymbolUnionValue :: struct {
@@ -345,7 +347,10 @@ write_struct_type :: proc(
}
write_symbol_struct_value :: proc(
- ast_context: ^AstContext, b: ^SymbolStructValueBuilder, v: SymbolStructValue, base_using_index: int
+ ast_context: ^AstContext,
+ b: ^SymbolStructValueBuilder,
+ v: SymbolStructValue,
+ base_using_index: int,
) {
base_index := len(b.names)
for name in v.names {
diff --git a/tests/hover_test.odin b/tests/hover_test.odin
index 5e6a66f..194fbea 100644
--- a/tests/hover_test.odin
+++ b/tests/hover_test.odin
@@ -1978,6 +1978,20 @@ ast_hover_enum_map_key :: proc(t: ^testing.T) {
}
test.expect_hover(t, &source, "test.Foo: .A")
}
+
+@(test)
+ast_hover_enum_defintion_with_base_type :: proc(t: ^testing.T) {
+ source :=test.Source {
+ main = `package test
+ F{*}oo :: enum u8 {
+ A = 1,
+ Bar = 2,
+ C = 3,
+ }
+ `
+ }
+ test.expect_hover(t, &source, "test.Foo: enum u8 {\n\tA = 1,\n\tBar = 2,\n\tC = 3,\n}")
+}
/*
Waiting for odin fix