diff options
| author | Brad Lewis <22850972+BradLewis@users.noreply.github.com> | 2025-06-10 21:53:15 -0400 |
|---|---|---|
| committer | Brad Lewis <22850972+BradLewis@users.noreply.github.com> | 2025-06-10 22:20:36 -0400 |
| commit | 2a284808585aa062932e5bf162e4facfd5b8cee2 (patch) | |
| tree | c7bcd770f31d0c95da94b52a2c7587a5524ece98 | |
| parent | 3f089f4d757e2a705056eb331c74442ab48862aa (diff) | |
Add struct field type to hover information
| -rw-r--r-- | src/server/analysis.odin | 16 | ||||
| -rw-r--r-- | src/server/completion.odin | 4 | ||||
| -rw-r--r-- | src/server/hover.odin | 14 | ||||
| -rw-r--r-- | src/server/symbol.odin | 2 | ||||
| -rw-r--r-- | tests/hover_test.odin | 44 |
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 |