summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-12-11 07:25:13 -0500
committerBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-12-11 07:25:13 -0500
commita13716d68e7cde284a762c7ccbbcc9b864db3ada (patch)
tree2ed804fb1c8a52e86462a73670fe016758f93093 /src
parent465e4b4f1472ee4a2786321409d9f58eb79259e8 (diff)
Add optional feature for displaying signature help for comp literals
Diffstat (limited to 'src')
-rw-r--r--src/common/config.odin1
-rw-r--r--src/server/requests.odin5
-rw-r--r--src/server/signature.odin95
-rw-r--r--src/server/symbol.odin3
-rw-r--r--src/server/types.odin1
-rw-r--r--src/testing/testing.odin60
6 files changed, 108 insertions, 57 deletions
diff --git a/src/common/config.odin b/src/common/config.odin
index 4aaefac..6890685 100644
--- a/src/common/config.odin
+++ b/src/common/config.odin
@@ -38,6 +38,7 @@ Config :: struct {
enable_auto_import: bool,
enable_completion_matching: bool,
enable_document_links: bool,
+ enable_comp_lit_signature_help: bool,
disable_parser_errors: bool,
thread_count: int,
file_log: bool,
diff --git a/src/server/requests.odin b/src/server/requests.odin
index 9a7326a..8f9be06 100644
--- a/src/server/requests.odin
+++ b/src/server/requests.odin
@@ -374,6 +374,8 @@ read_ols_initialize_options :: proc(config: ^common.Config, ols_config: OlsConfi
config.enable_completion_matching =
ols_config.enable_completion_matching.(bool) or_else config.enable_completion_matching
config.enable_document_links = ols_config.enable_document_links.(bool) or_else config.enable_document_links
+ config.enable_comp_lit_signature_help =
+ ols_config.enable_comp_lit_signature_help.(bool) or_else config.enable_comp_lit_signature_help
config.verbose = ols_config.verbose.(bool) or_else config.verbose
config.file_log = ols_config.file_log.(bool) or_else config.file_log
@@ -648,6 +650,7 @@ request_initialize :: proc(
config.enable_document_highlights = true
config.enable_completion_matching = true
config.enable_document_links = true
+ config.enable_comp_lit_signature_help = false
config.verbose = false
config.file_log = false
config.odin_command = ""
@@ -977,7 +980,7 @@ request_signature_help :: proc(
}
help: SignatureHelp
- help, ok = get_signature_information(document, signature_params.position)
+ help, ok = get_signature_information(document, signature_params.position, config)
if !ok {
return .InternalError
diff --git a/src/server/signature.odin b/src/server/signature.odin
index 51f919d..c902d61 100644
--- a/src/server/signature.odin
+++ b/src/server/signature.odin
@@ -62,7 +62,14 @@ seperate_proc_field_arguments :: proc(procedure: ^Symbol) {
}
-get_signature_information :: proc(document: ^Document, position: common.Position) -> (SignatureHelp, bool) {
+get_signature_information :: proc(
+ document: ^Document,
+ position: common.Position,
+ config: ^common.Config,
+) -> (
+ SignatureHelp,
+ bool,
+) {
signature_help: SignatureHelp
ast_context := make_ast_context(
@@ -81,7 +88,7 @@ get_signature_information :: proc(document: ^Document, position: common.Position
ast_context.position_hint = position_context.hint
//TODO(should probably not be an ast.Expr, but ast.Call_Expr)
- if position_context.call == nil {
+ if position_context.call == nil && !config.enable_comp_lit_signature_help {
return signature_help, true
}
@@ -90,37 +97,73 @@ get_signature_information :: proc(document: ^Document, position: common.Position
if position_context.function != nil {
get_locals(document.ast, position_context.function, &ast_context, &position_context)
}
+ signature_information := make([dynamic]SignatureInformation, context.temp_allocator)
+
+ if config.enable_comp_lit_signature_help {
+ if symbol, ok := resolve_comp_literal(&ast_context, &position_context); ok {
+ build_documentation(&ast_context, &symbol, short_signature = false)
+ append(
+ &signature_information,
+ SignatureInformation {
+ label = get_signature(symbol),
+ documentation = construct_symbol_docs(symbol, markdown = false),
+ },
+ )
+ }
+ }
+
+ if position_context.call != nil {
+ signature_help.activeParameter = add_proc_signature(&ast_context, &position_context, &signature_information)
+ }
+
+ signature_help.signatures = signature_information[:]
+
+ return signature_help, true
+}
+
+@(private = "file")
+get_signature :: proc(symbol: Symbol) -> string {
+ sb := strings.builder_make()
+ write_symbol_name(&sb, symbol)
+ strings.write_string(&sb, " :: ")
+ strings.write_string(&sb, symbol.signature)
+ return strings.to_string(sb)
+}
+@(private = "file")
+add_proc_signature :: proc(
+ ast_context: ^AstContext,
+ position_context: ^DocumentPositionContext,
+ signature_information: ^[dynamic]SignatureInformation,
+) -> (
+ active_parameter: int,
+) {
for comma, i in position_context.call_commas {
if position_context.position > comma {
- signature_help.activeParameter = i + 1
+ active_parameter = i + 1
} else if position_context.position == comma {
- signature_help.activeParameter = i
+ active_parameter = i
}
}
if position_context.arrow {
- signature_help.activeParameter += 1
+ active_parameter = 1
}
- call: Symbol
- call, ok = resolve_type_expression(&ast_context, position_context.call)
-
+ call, ok := resolve_type_expression(ast_context, position_context.call)
if !ok {
- return signature_help, true
+ return active_parameter
}
seperate_proc_field_arguments(&call)
- signature_information := make([dynamic]SignatureInformation, context.temp_allocator)
-
if value, ok := call.value.(SymbolProcedureValue); ok {
parameters := make([]ParameterInformation, len(value.orig_arg_types), context.temp_allocator)
for arg, i in value.orig_arg_types {
if arg.type != nil {
if _, is_ellipsis := arg.type.derived.(^ast.Ellipsis); is_ellipsis {
- signature_help.activeParameter = min(i, signature_help.activeParameter)
+ active_parameter = min(i, active_parameter)
}
}
@@ -130,13 +173,13 @@ get_signature_information :: proc(document: ^Document, position: common.Position
sb := strings.builder_make(context.temp_allocator)
write_procedure_symbol_signature(&sb, value, detailed_signature = false)
call.signature = strings.to_string(sb)
-
+
info := SignatureInformation {
- label = get_signature(call),
+ label = get_signature(call),
documentation = construct_symbol_docs(call, markdown = false),
parameters = parameters,
}
- append(&signature_information, info)
+ append(signature_information, info)
} else if value, ok := call.value.(SymbolAggregateValue); ok {
//function overloaded procedures
for symbol in value.symbols {
@@ -148,7 +191,7 @@ get_signature_information :: proc(document: ^Document, position: common.Position
for arg, i in value.orig_arg_types {
if arg.type != nil {
if _, is_ellipsis := arg.type.derived.(^ast.Ellipsis); is_ellipsis {
- signature_help.activeParameter = min(i, signature_help.activeParameter)
+ active_parameter = min(i, active_parameter)
}
}
@@ -158,28 +201,16 @@ get_signature_information :: proc(document: ^Document, position: common.Position
sb := strings.builder_make(context.temp_allocator)
write_procedure_symbol_signature(&sb, value, detailed_signature = false)
symbol.signature = strings.to_string(sb)
-
+
info := SignatureInformation {
- label = get_signature(symbol),
+ label = get_signature(symbol),
documentation = construct_symbol_docs(symbol, markdown = false),
parameters = parameters,
}
- append(&signature_information, info)
+ append(signature_information, info)
}
}
}
-
- signature_help.signatures = signature_information[:]
-
- return signature_help, true
-}
-
-@(private="file")
-get_signature :: proc(symbol: Symbol) -> string {
- sb := strings.builder_make()
- write_symbol_name(&sb, symbol)
- strings.write_string(&sb, " :: ")
- strings.write_string(&sb, symbol.signature)
- return strings.to_string(sb)
+ return active_parameter
}
diff --git a/src/server/symbol.odin b/src/server/symbol.odin
index 2869e5c..d2f44ae 100644
--- a/src/server/symbol.odin
+++ b/src/server/symbol.odin
@@ -411,6 +411,9 @@ write_struct_type :: proc(
}
}
}
+ s := Symbol{
+
+ }
if _, ok := get_attribute_objc_class_name(attributes); ok {
b.symbol.flags |= {.ObjC}
diff --git a/src/server/types.odin b/src/server/types.odin
index 4b4c0bd..0377e62 100644
--- a/src/server/types.odin
+++ b/src/server/types.odin
@@ -422,6 +422,7 @@ OlsConfig :: struct {
enable_references: Maybe(bool),
enable_document_highlights: Maybe(bool),
enable_document_links: Maybe(bool),
+ enable_comp_lit_signature_help: Maybe(bool),
enable_completion_matching: Maybe(bool),
enable_inlay_hints_params: Maybe(bool),
enable_inlay_hints_default_params: Maybe(bool),
diff --git a/src/testing/testing.odin b/src/testing/testing.odin
index 4cb9484..6a6b80d 100644
--- a/src/testing/testing.odin
+++ b/src/testing/testing.odin
@@ -2,7 +2,6 @@ package ols_testing
import "core:fmt"
import "core:log"
-import "core:mem"
import "core:mem/virtual"
import "core:odin/ast"
import "core:odin/parser"
@@ -127,7 +126,7 @@ expect_signature_labels :: proc(t: ^testing.T, src: ^Source, expect_labels: []st
setup(src)
defer teardown(src)
- help, ok := server.get_signature_information(src.document, src.position)
+ help, ok := server.get_signature_information(src.document, src.position, &src.config)
if !ok {
log.error("Failed get_signature_information")
@@ -159,7 +158,7 @@ expect_signature_parameter_position :: proc(t: ^testing.T, src: ^Source, positio
setup(src)
defer teardown(src)
- help, ok := server.get_signature_information(src.document, src.position)
+ help, ok := server.get_signature_information(src.document, src.position, &src.config)
if help.activeParameter != position {
log.errorf("expected parameter position %v, but received %v", position, help.activeParameter)
@@ -463,7 +462,10 @@ expect_action :: proc(t: ^testing.T, src: ^Source, expect_action_names: []string
setup(src)
defer teardown(src)
- input_range := common.Range{start=src.position, end=src.position}
+ input_range := common.Range {
+ start = src.position,
+ end = src.position,
+ }
actions, ok := server.get_code_actions(src.document, input_range, &src.config)
if !ok {
log.error("Failed to find actions")
@@ -537,31 +539,30 @@ expect_inlay_hints :: proc(t: ^testing.T, src: ^Source) {
src_builder := strings.builder_make(context.temp_allocator)
expected_hints := make([dynamic]server.InlayHint, context.temp_allocator)
- HINT_OPEN :: "[["
+ HINT_OPEN :: "[["
HINT_CLOSE :: "]]"
{
last, line, col: int
saw_brackets: bool
- for i:= 0; i < len(src.main); i += 1 {
+ for i := 0; i < len(src.main); i += 1 {
if saw_brackets {
- if i+1 < len(src.main) && src.main[i:][:len(HINT_CLOSE)] == HINT_CLOSE {
+ if i + 1 < len(src.main) && src.main[i:][:len(HINT_CLOSE)] == HINT_CLOSE {
saw_brackets = false
hint_str := src.main[last:i]
- last = i+len(HINT_CLOSE)
- i = last-1
- append(&expected_hints, server.InlayHint{
- position = {line, col},
- label = hint_str,
- kind = .Parameter,
- })
+ last = i + len(HINT_CLOSE)
+ i = last - 1
+ append(
+ &expected_hints,
+ server.InlayHint{position = {line, col}, label = hint_str, kind = .Parameter},
+ )
}
} else {
- if i+1 < len(src.main) && src.main[i:][:len(HINT_OPEN)] == HINT_OPEN {
+ if i + 1 < len(src.main) && src.main[i:][:len(HINT_OPEN)] == HINT_OPEN {
strings.write_string(&src_builder, src.main[last:i])
saw_brackets = true
- last = i+len(HINT_OPEN)
- i = last-1
+ last = i + len(HINT_OPEN)
+ i = last - 1
} else if src.main[i] == '\n' {
line += 1
col = 0
@@ -584,7 +585,7 @@ expect_inlay_hints :: proc(t: ^testing.T, src: ^Source) {
setup(src)
defer teardown(src)
- symbols_and_nodes := server.resolve_entire_file(src.document, allocator=context.temp_allocator)
+ symbols_and_nodes := server.resolve_entire_file(src.document, allocator = context.temp_allocator)
range := common.Range {
end = {line = 9000000},
@@ -595,7 +596,8 @@ expect_inlay_hints :: proc(t: ^testing.T, src: ^Source) {
return
}
- testing.expectf(t,
+ testing.expectf(
+ t,
len(expected_hints) == len(hints),
"Expected %d inlay hints, but received %d",
len(expected_hints),
@@ -620,20 +622,30 @@ expect_inlay_hints :: proc(t: ^testing.T, src: ^Source) {
for i in 0 ..< max(len(expected_hints), len(hints)) {
expected_text := "---"
- actual_text := "---"
+ actual_text := "---"
if i < len(expected_hints) {
expected := expected_hints[i]
expected_line := get_source_line_with_hint(lines, expected)
- expected_text = fmt.tprintf("\"%s\" at (%d, %d): \"%s\"",
- expected.label, expected.position.line, expected.position.character, expected_line)
+ expected_text = fmt.tprintf(
+ "\"%s\" at (%d, %d): \"%s\"",
+ expected.label,
+ expected.position.line,
+ expected.position.character,
+ expected_line,
+ )
}
if i < len(hints) {
actual := hints[i]
actual_line := get_source_line_with_hint(lines, actual)
- actual_text = fmt.tprintf("\"%s\" at (%d, %d): \"%s\"",
- actual.label, actual.position.line, actual.position.character, actual_line)
+ actual_text = fmt.tprintf(
+ "\"%s\" at (%d, %d): \"%s\"",
+ actual.label,
+ actual.position.line,
+ actual.position.character,
+ actual_line,
+ )
}
if i >= len(expected_hints) {