aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-06-10 21:53:15 -0400
committerBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-06-10 22:20:36 -0400
commit2a284808585aa062932e5bf162e4facfd5b8cee2 (patch)
treec7bcd770f31d0c95da94b52a2c7587a5524ece98
parent3f089f4d757e2a705056eb331c74442ab48862aa (diff)
Add struct field type to hover information
-rw-r--r--src/server/analysis.odin16
-rw-r--r--src/server/completion.odin4
-rw-r--r--src/server/hover.odin14
-rw-r--r--src/server/symbol.odin2
-rw-r--r--tests/hover_test.odin44
5 files changed, 70 insertions, 10 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index f25250b..5659839 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -2328,7 +2328,6 @@ get_using_packages :: proc(ast_context: ^AstContext) -> []string {
}
get_symbol_pkg_name :: proc(ast_context: ^AstContext, symbol: Symbol) -> string {
-
name := path.base(symbol.pkg, false, context.temp_allocator)
for imp in ast_context.imports {
@@ -3822,7 +3821,6 @@ append_variable_full_name :: proc(
get_signature :: proc(
ast_context: ^AstContext,
- ident: ast.Any_Node,
symbol: Symbol,
was_variable := false,
short_signature := false,
@@ -3889,6 +3887,16 @@ get_signature :: proc(
builder := strings.builder_make(ast_context.allocator)
if is_variable {
append_variable_full_name(&builder, ast_context, symbol, pointer_prefix)
+ } else if symbol.type_name != "" {
+ if symbol.type_pkg == "" {
+ fmt.sbprintf(&builder, "%s%s :: ", pointer_prefix, symbol.type_name)
+ } else {
+ // TODO: make this function just take a string
+ symbol := symbol
+ symbol.pkg = symbol.type_pkg
+ pkg_name := get_symbol_pkg_name(ast_context, symbol)
+ fmt.sbprintf(&builder, "%s%s.%s :: ", pointer_prefix, pkg_name, symbol.type_name)
+ }
}
longestNameLen := 0
for name in v.names {
@@ -3896,6 +3904,10 @@ get_signature :: proc(
longestNameLen = len(name)
}
}
+ if len(v.names) == 0 {
+ strings.write_string(&builder, "struct {}")
+ return strings.to_string(builder)
+ }
strings.write_string(&builder, "struct {\n")
for i in 0 ..< len(v.names) {
strings.write_string(&builder, "\t")
diff --git a/src/server/completion.odin b/src/server/completion.odin
index b76a2c5..30e7ac6 100644
--- a/src/server/completion.odin
+++ b/src/server/completion.odin
@@ -1290,7 +1290,7 @@ get_identifier_completion :: proc(
ident.name = k
if symbol, ok := resolve_type_identifier(ast_context, ident^); ok {
- symbol.signature = get_signature(ast_context, ident, symbol, short_signature=true)
+ symbol.signature = get_signature(ast_context, symbol, short_signature=true)
build_procedure_symbol_signature(&symbol)
@@ -1331,7 +1331,7 @@ get_identifier_completion :: proc(
ident.name = k
if symbol, ok := resolve_type_identifier(ast_context, ident^); ok {
- symbol.signature = get_signature(ast_context, ident, symbol, short_signature=true)
+ symbol.signature = get_signature(ast_context, symbol, short_signature=true)
build_procedure_symbol_signature(&symbol)
diff --git a/src/server/hover.odin b/src/server/hover.odin
index 3c602c1..89b75eb 100644
--- a/src/server/hover.odin
+++ b/src/server/hover.odin
@@ -125,9 +125,11 @@ get_hover_information :: proc(document: ^Document, position: common.Position) ->
&ast_context,
position_context.value_decl.names[0],
); ok {
+ symbol.type_name = symbol.name
+ symbol.type_pkg = symbol.pkg
symbol.pkg = struct_symbol.name
symbol.name = identifier.name
- symbol.signature = get_signature(&ast_context, field.type.derived, symbol)
+ symbol.signature = get_signature(&ast_context, symbol)
hover.contents = write_hover_content(&ast_context, symbol)
return hover, true, true
}
@@ -188,7 +190,7 @@ get_hover_information :: proc(document: ^Document, position: common.Position) ->
if position_in_node(base, position_context.position) {
if resolved, ok := resolve_type_identifier(&ast_context, ident); ok {
- resolved.signature = get_signature(&ast_context, &ident, resolved)
+ resolved.signature = get_signature(&ast_context, resolved)
resolved.name = ident.name
if resolved.type == .Variable {
@@ -237,9 +239,11 @@ get_hover_information :: proc(document: ^Document, position: common.Position) ->
for name, i in v.names {
if name == field {
if symbol, ok := resolve_type_expression(&ast_context, v.types[i]); ok {
+ symbol.type_name = symbol.name
+ symbol.type_pkg = symbol.pkg
symbol.name = name
symbol.pkg = selector.name
- symbol.signature = get_signature(&ast_context, v.types[i].derived, symbol)
+ symbol.signature = get_signature(&ast_context, symbol)
hover.contents = write_hover_content(&ast_context, symbol)
return hover, true, true
}
@@ -269,7 +273,7 @@ get_hover_information :: proc(document: ^Document, position: common.Position) ->
}
}
if resolved, ok := resolve_type_identifier(&ast_context, ident^); ok {
- resolved.signature = get_signature(&ast_context, ident, resolved)
+ resolved.signature = get_signature(&ast_context, resolved)
resolved.name = ident.name
if resolved.type == .Variable {
@@ -331,7 +335,7 @@ get_hover_information :: proc(document: ^Document, position: common.Position) ->
}
if resolved, ok := resolve_type_identifier(&ast_context, ident); ok {
- resolved.signature = get_signature(&ast_context, &ident, resolved)
+ resolved.signature = get_signature(&ast_context, resolved)
resolved.name = ident.name
if resolved.type == .Variable {
diff --git a/src/server/symbol.odin b/src/server/symbol.odin
index 8a3f4ab..7286028 100644
--- a/src/server/symbol.odin
+++ b/src/server/symbol.odin
@@ -162,6 +162,8 @@ Symbol :: struct {
doc: string,
signature: string, //type signature
type: SymbolType,
+ type_pkg: string,
+ type_name: string,
value: SymbolValue,
pointers: int, //how many `^` are applied to the symbol
flags: SymbolFlags,
diff --git a/tests/hover_test.odin b/tests/hover_test.odin
index cbb7ba9..9cc1d5b 100644
--- a/tests/hover_test.odin
+++ b/tests/hover_test.odin
@@ -491,7 +491,7 @@ ast_hover_foreign_package_name_collision :: proc(t: ^testing.T) {
packages = packages[:],
}
- test.expect_hover(t, &source, "node.bar: struct {\n}")
+ test.expect_hover(t, &source, "node.bar: ^my_package.bar :: struct {}")
}
@(test)
ast_hover_struct :: proc(t: ^testing.T) {
@@ -638,6 +638,26 @@ ast_hover_struct_field_definition :: proc(t: ^testing.T) {
}
@(test)
+ast_hover_struct_field_complex_definition :: proc(t: ^testing.T) {
+ source := test.Source {
+ main = `package test
+ Bar :: struct {}
+
+ Foo :: struct {
+ b{*}ar: ^Bar,
+ f: proc(a: int) -> int,
+ }
+
+ foo := Foo{
+ bar = 1
+ }
+ `,
+ }
+
+ test.expect_hover(t, &source, "Foo.bar: ^test.Bar :: struct {}")
+}
+
+@(test)
ast_hover_within_struct_declaration :: proc(t: ^testing.T) {
source := test.Source {
main = `package test
@@ -853,6 +873,28 @@ ast_hover_sub_string_slices :: proc(t: ^testing.T) {
test.expect_hover(t, &source, "test.sub_str: string")
}
+
+@(test)
+ast_hover_struct_field_use :: proc(t: ^testing.T) {
+ source := test.Source {
+ main = `package test
+ Foo :: struct {
+ value: int,
+ }
+
+ Bar :: struct {
+ foo: Foo,
+ }
+
+ main :: proc() {
+ bar := Bar{}
+ bar.fo{*}o.value += 1
+ }
+ `,
+ }
+
+ test.expect_hover(t, &source, "Bar.foo: test.Foo :: struct {\n\tvalue: int,\n}")
+}
/*
Waiting for odin fix