aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2025-06-10 20:30:38 +0200
committerDanielGavin <danielgavin5@hotmail.com>2025-06-10 20:30:38 +0200
commit33a69987c62e75c6c83757b08bc56654384e8cd5 (patch)
tree707e13d6763e25ceab78a32e07f2db6e27ef147e /src/server
parent14cedf5f30b96cccd9d3b977c6e39fe3e1c0e009 (diff)
parent53b3b0872c51f69e8cde898992318c0b9615be00 (diff)
Merge branch 'master' of https://github.com/DanielGavin/ols
Diffstat (limited to 'src/server')
-rw-r--r--src/server/analysis.odin94
-rw-r--r--src/server/completion.odin4
-rw-r--r--src/server/definition.odin27
-rw-r--r--src/server/file_resolve.odin4
-rw-r--r--src/server/hover.odin29
-rw-r--r--src/server/references.odin10
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)