aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2025-06-10 20:22:27 +0200
committerGitHub <noreply@github.com>2025-06-10 20:22:27 +0200
commite4ba6606fb75e964e360bf22fdfd0641f169497a (patch)
treee1327c7bd089edab3c843b1578b1b2a679eb97d9 /src/server
parenta42400e0c9f1471ec27454476f6fe6c19dc95242 (diff)
parentcea7502466e9a413d1b8980b6447c9316f03a93a (diff)
Merge pull request #650 from BradLewis/feat/hover-struct-definitions
Enrich hover information
Diffstat (limited to 'src/server')
-rw-r--r--src/server/analysis.odin94
-rw-r--r--src/server/completion.odin4
-rw-r--r--src/server/hover.odin29
3 files changed, 112 insertions, 15 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index 668260b..e67b31e 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -3765,7 +3765,28 @@ unwrap_bitset :: proc(ast_context: ^AstContext, bitset_symbol: Symbol) -> (Symbo
return {}, false
}
-get_signature :: proc(ast_context: ^AstContext, ident: ast.Ident, symbol: Symbol, was_variable := false) -> string {
+append_variable_full_name :: proc(
+ sb: ^strings.Builder,
+ ast_context: ^AstContext,
+ symbol: Symbol,
+ pointer_prefix: string,
+) {
+ pkg_name := get_symbol_pkg_name(ast_context, symbol)
+ if pkg_name == "" {
+ fmt.sbprintf(sb, "%s%s :: ", pointer_prefix, symbol.name)
+ return
+ }
+ fmt.sbprintf(sb, "%s%s.%s :: ", pointer_prefix, pkg_name, symbol.name)
+ return
+}
+
+get_signature :: proc(
+ ast_context: ^AstContext,
+ ident: ast.Any_Node,
+ symbol: Symbol,
+ was_variable := false,
+ short_signature := false,
+) -> string {
if symbol.type == .Function {
return symbol.signature
}
@@ -3789,11 +3810,26 @@ get_signature :: proc(ast_context: ^AstContext, ident: ast.Ident, symbol: Symbol
allocator = ast_context.allocator,
)
case SymbolEnumValue:
+ if short_signature {
+ builder := strings.builder_make(ast_context.allocator)
+ if is_variable {
+ append_variable_full_name(&builder, ast_context, symbol, pointer_prefix)
+ }
+ strings.write_string(&builder, "enum")
+ return strings.to_string(builder)
+ }
+ builder := strings.builder_make(ast_context.allocator)
if is_variable {
- return symbol.name
- } else {
- return "enum"
+ append_variable_full_name(&builder, ast_context, symbol, pointer_prefix)
+ }
+ strings.write_string(&builder, "enum {\n")
+ for i in 0 ..< len(v.names) {
+ strings.write_string(&builder, "\t")
+ strings.write_string(&builder, v.names[i])
+ strings.write_string(&builder, ",\n")
}
+ strings.write_string(&builder, "}")
+ return strings.to_string(builder)
case SymbolMapValue:
return strings.concatenate(
a = {pointer_prefix, "map[", common.node_to_string(v.key), "]", common.node_to_string(v.value)},
@@ -3802,17 +3838,55 @@ get_signature :: proc(ast_context: ^AstContext, ident: ast.Ident, symbol: Symbol
case SymbolProcedureValue:
return "proc"
case SymbolStructValue:
+ if short_signature {
+ builder := strings.builder_make(ast_context.allocator)
+ if is_variable {
+ append_variable_full_name(&builder, ast_context, symbol, pointer_prefix)
+ }
+ strings.write_string(&builder, "struct")
+ return strings.to_string(builder)
+ }
+ builder := strings.builder_make(ast_context.allocator)
if is_variable {
- return strings.concatenate({pointer_prefix, symbol.name}, ast_context.allocator)
- } else {
- return "struct"
+ append_variable_full_name(&builder, ast_context, symbol, pointer_prefix)
+ }
+ longestNameLen := 0
+ for name in v.names {
+ if len(name) > longestNameLen {
+ longestNameLen = len(name)
+ }
+ }
+ strings.write_string(&builder, "struct {\n")
+ for i in 0 ..< len(v.names) {
+ strings.write_string(&builder, "\t")
+ strings.write_string(&builder, v.names[i])
+ fmt.sbprintf(&builder, ":%*s", longestNameLen - len(v.names[i]) + 1, "")
+ common.build_string_node(v.types[i], &builder, false)
+ strings.write_string(&builder, ",\n")
}
+ strings.write_string(&builder, "}")
+ return strings.to_string(builder)
case SymbolUnionValue:
+ if short_signature {
+ builder := strings.builder_make(ast_context.allocator)
+ if is_variable {
+ append_variable_full_name(&builder, ast_context, symbol, pointer_prefix)
+ }
+ strings.write_string(&builder, "union")
+ return strings.to_string(builder)
+ }
+ builder := strings.builder_make(ast_context.allocator)
if is_variable {
- return strings.concatenate({pointer_prefix, symbol.name}, ast_context.allocator)
- } else {
- return "union"
+ append_variable_full_name(&builder, ast_context, symbol, pointer_prefix)
+ }
+ strings.write_string(&builder, "union {\n")
+ for i in 0 ..< len(v.types) {
+ strings.write_string(&builder, "\t")
+ common.build_string_node(v.types[i], &builder, false)
+ strings.write_string(&builder, ",\n")
}
+ strings.write_string(&builder, "}")
+ return strings.to_string(builder)
case SymbolBitFieldValue:
if is_variable {
return strings.concatenate({pointer_prefix, symbol.name}, ast_context.allocator)
diff --git a/src/server/completion.odin b/src/server/completion.odin
index 8d61e3e..57d289d 100644
--- a/src/server/completion.odin
+++ b/src/server/completion.odin
@@ -1289,7 +1289,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)
+ symbol.signature = get_signature(ast_context, ident, symbol, short_signature=true)
build_procedure_symbol_signature(&symbol)
@@ -1330,7 +1330,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)
+ symbol.signature = get_signature(ast_context, ident, symbol, short_signature=true)
build_procedure_symbol_signature(&symbol)
diff --git a/src/server/hover.odin b/src/server/hover.odin
index cc3c5b2..b69385a 100644
--- a/src/server/hover.odin
+++ b/src/server/hover.odin
@@ -108,6 +108,28 @@ get_hover_information :: proc(document: ^Document, position: common.Position) ->
}
}
+ if position_context.struct_type != nil {
+ for field in position_context.struct_type.fields.list {
+ for name in field.names {
+ if position_in_node(name, position_context.position) {
+ if identifier, ok := name.derived.(^ast.Ident); ok && field.type != nil {
+ if position_context.value_decl != nil && len(position_context.value_decl.names) != 0 {
+ if symbol, ok := resolve_type_expression(&ast_context, field.type); ok {
+ if struct_symbol, ok := resolve_type_expression(&ast_context, position_context.value_decl.names[0]); ok {
+ symbol.pkg = struct_symbol.name
+ symbol.name = identifier.name
+ symbol.signature = get_signature(&ast_context, field.type.derived, symbol)
+ hover.contents = write_hover_content(&ast_context, symbol)
+ return hover, true, true
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
if position_context.field_value != nil && position_context.comp_lit != nil {
if comp_symbol, ok := resolve_comp_literal(&ast_context, &position_context); ok {
if field, ok := position_context.field_value.field.derived.(^ast.Ident); ok {
@@ -155,7 +177,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, &ident, resolved)
resolved.name = ident.name
if resolved.type == .Variable {
@@ -206,7 +228,7 @@ get_hover_information :: proc(document: ^Document, position: common.Position) ->
if symbol, ok := resolve_type_expression(&ast_context, v.types[i]); ok {
symbol.name = name
symbol.pkg = selector.name
- symbol.signature = common.node_to_string(v.types[i])
+ symbol.signature = get_signature(&ast_context, v.types[i].derived, symbol)
hover.contents = write_hover_content(&ast_context, symbol)
return hover, true, true
}
@@ -228,6 +250,7 @@ get_hover_information :: proc(document: ^Document, position: common.Position) ->
if position_context.field != nil {
if ident, ok := position_context.field.derived.(^ast.Ident); ok {
if symbol, ok := resolve_type_identifier(&ast_context, ident^); ok {
+ symbol.signature = get_signature(&ast_context, ident, symbol)
hover.contents = write_hover_content(&ast_context, symbol)
return hover, true, true
}
@@ -282,7 +305,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, &ident, resolved)
resolved.name = ident.name
if resolved.type == .Variable {