diff options
| author | DanielGavin <danielgavin5@hotmail.com> | 2025-06-10 20:30:38 +0200 |
|---|---|---|
| committer | DanielGavin <danielgavin5@hotmail.com> | 2025-06-10 20:30:38 +0200 |
| commit | 33a69987c62e75c6c83757b08bc56654384e8cd5 (patch) | |
| tree | 707e13d6763e25ceab78a32e07f2db6e27ef147e /src/server | |
| parent | 14cedf5f30b96cccd9d3b977c6e39fe3e1c0e009 (diff) | |
| parent | 53b3b0872c51f69e8cde898992318c0b9615be00 (diff) | |
Merge branch 'master' of https://github.com/DanielGavin/ols
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/definition.odin | 27 | ||||
| -rw-r--r-- | src/server/file_resolve.odin | 4 | ||||
| -rw-r--r-- | src/server/hover.odin | 29 | ||||
| -rw-r--r-- | src/server/references.odin | 10 |
6 files changed, 129 insertions, 39 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/definition.odin b/src/server/definition.odin index 0a216cc..00a62fc 100644 --- a/src/server/definition.odin +++ b/src/server/definition.odin @@ -76,25 +76,22 @@ get_definition_location :: proc(document: ^Document, position: common.Position) } } else if position_context.selector_expr != nil { //if the base selector is the client wants to go to. - if base, ok := position_context.selector.derived.(^ast.Ident); ok && position_context.identifier != nil { + if position_in_node(position_context.selector, position_context.position) && position_context.identifier != nil { ident := position_context.identifier.derived.(^ast.Ident) + if resolved, ok := resolve_location_identifier(&ast_context, ident^); ok { + location.range = resolved.range - if position_in_node(base, position_context.position) { - if resolved, ok := resolve_location_identifier(&ast_context, ident^); ok { - location.range = resolved.range - - if resolved.uri == "" { - location.uri = document.uri.uri - } else { - location.uri = resolved.uri - } - - append(&locations, location) - - return locations[:], true + if resolved.uri == "" { + location.uri = document.uri.uri } else { - return {}, false + location.uri = resolved.uri } + + append(&locations, location) + + return locations[:], true + } else { + return {}, false } } diff --git a/src/server/file_resolve.odin b/src/server/file_resolve.odin index dd2eabb..d3e93fe 100644 --- a/src/server/file_resolve.odin +++ b/src/server/file_resolve.odin @@ -196,7 +196,9 @@ resolve_node :: proc(node: ^ast.Node, data: ^FileResolveData) { } } - if _, ok := n.expr.derived.(^ast.Selector_Expr); ok { + #partial switch v in n.expr.derived { + // TODO: Should there be more here? + case ^ast.Selector_Expr, ^ast.Index_Expr, ^ast.Ident: resolve_node(n.expr, data) } } else { diff --git a/src/server/hover.odin b/src/server/hover.odin index d1e861a..f9f2613 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 { @@ -157,7 +179,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 { @@ -208,7 +230,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 } @@ -230,6 +252,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 } @@ -284,7 +307,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 { diff --git a/src/server/references.odin b/src/server/references.odin index 944a337..b62efee 100644 --- a/src/server/references.odin +++ b/src/server/references.odin @@ -136,13 +136,7 @@ prepare_references :: proc( resolve_flag = .Field } else if position_context.selector_expr != nil { - resolve_flag = .Field - - base: ^ast.Ident - base, ok = position_context.selector.derived.(^ast.Ident) - - if position_in_node(base, position_context.position) && position_context.identifier != nil && ok { - + if position_in_node(position_context.selector, position_context.position) && position_context.identifier != nil { ident := position_context.identifier.derived.(^ast.Ident) symbol, ok = resolve_location_identifier(ast_context, ident^) @@ -151,7 +145,7 @@ prepare_references :: proc( return } - resolve_flag = .Base + resolve_flag = .Identifier } else { symbol, ok = resolve_location_selector(ast_context, position_context.selector_expr) |