diff options
| author | DanielGavin <danielgavin5@hotmail.com> | 2025-06-10 20:22:27 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-10 20:22:27 +0200 |
| commit | e4ba6606fb75e964e360bf22fdfd0641f169497a (patch) | |
| tree | e1327c7bd089edab3c843b1578b1b2a679eb97d9 /src/server | |
| parent | a42400e0c9f1471ec27454476f6fe6c19dc95242 (diff) | |
| parent | cea7502466e9a413d1b8980b6447c9316f03a93a (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.odin | 94 | ||||
| -rw-r--r-- | src/server/completion.odin | 4 | ||||
| -rw-r--r-- | src/server/hover.odin | 29 |
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 { |