aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2025-09-27 22:10:14 +0200
committerDanielGavin <danielgavin5@hotmail.com>2025-09-27 22:10:14 +0200
commitfe88eb50b8d695a8f05e07846408751e56b054ee (patch)
tree67a07356fc0d6e053bdf7f3ace9397d1137b05b9 /src
parentfadba86f623fd0c0e0399b88b79804c5e466ef95 (diff)
parent4a2a71e12d61be1cd8ca486d96de8dd47dd49df2 (diff)
Merge branch 'master' into remove-unused-imports
Diffstat (limited to 'src')
-rw-r--r--src/common/config.odin1
-rw-r--r--src/server/inlay_hints.odin105
-rw-r--r--src/server/requests.odin40
-rw-r--r--src/server/types.odin2
4 files changed, 115 insertions, 33 deletions
diff --git a/src/common/config.odin b/src/common/config.odin
index ae5597f..30f18c9 100644
--- a/src/common/config.odin
+++ b/src/common/config.odin
@@ -25,6 +25,7 @@ Config :: struct {
enable_inlay_hints: bool,
enable_inlay_hints_params: bool,
enable_inlay_hints_default_params: bool,
+ enable_inlay_hints_implicit_return: bool,
enable_procedure_context: bool,
enable_snippets: bool,
enable_references: bool,
diff --git a/src/server/inlay_hints.odin b/src/server/inlay_hints.odin
index c87ce3a..a91cd7a 100644
--- a/src/server/inlay_hints.odin
+++ b/src/server/inlay_hints.odin
@@ -16,30 +16,45 @@ get_inlay_hints :: proc(
bool,
) {
Visitor_Data :: struct {
- hints: [dynamic]InlayHint,
document: ^Document,
symbols: map[uintptr]SymbolAndNode,
config: ^common.Config,
+ hints: [dynamic]InlayHint,
+ depth: int,
+ procs: [dynamic]Proc_Data,
+ }
+
+ Proc_Data :: struct {
+ depth: int,
+ results: []^ast.Field,
}
data := Visitor_Data{
- hints = make([dynamic]InlayHint, context.temp_allocator),
document = document,
symbols = symbols,
config = config,
+ procs = make([dynamic]Proc_Data, context.temp_allocator),
+ hints = make([dynamic]InlayHint, context.temp_allocator),
}
visitor := ast.Visitor{
data = &data,
visit = proc(visitor: ^ast.Visitor, node: ^ast.Node) -> ^ast.Visitor {
- if node == nil || visitor == nil {
+
+ data := (^Visitor_Data)(visitor.data)
+
+ if node == nil {
+ if len(data.procs) > 0 && data.depth == data.procs[len(data.procs)-1].depth {
+ pop(&data.procs)
+ }
+ data.depth -= 1
return nil
}
- if call, is_call := node.derived.(^ast.Call_Expr); is_call {
- data := (^Visitor_Data)(visitor.data)
- visit_call(call, data)
- }
+ data.depth += 1
+
+ add_param_hints(node, data)
+ add_return_hints(node, data)
return visitor
},
@@ -57,11 +72,21 @@ get_inlay_hints :: proc(
}
}
- visit_call :: proc (
- call: ^ast.Call_Expr,
+ /*
+ Adds inlay hints for parameter names and default arguments in call expressions.
+ */
+ add_param_hints :: proc (
+ node: ^ast.Node,
data: ^Visitor_Data,
) -> (ok: bool) {
+ if !data.config.enable_inlay_hints_params &&
+ !data.config.enable_inlay_hints_default_params {
+ return
+ }
+
+ call := node.derived.(^ast.Call_Expr) or_return
+
src := string(data.document.text)
end_pos := common.token_pos_to_position(call.close, src)
@@ -242,5 +267,67 @@ get_inlay_hints :: proc(
return true
}
+ /*
+ Adds inlay hints for implicit returned values in naked returns.
+ */
+ add_return_hints :: proc (
+ node: ^ast.Node,
+ data: ^Visitor_Data,
+ ) -> (ok: bool) {
+
+ if !data.config.enable_inlay_hints_implicit_return do return
+
+ return_node: ^ast.Node
+ is_or_return: bool
+
+ #partial switch v in node.derived {
+ case ^ast.Proc_Lit:
+ if v.type != nil && v.type.results != nil && len(v.type.results.list) > 0 {
+ // check if all return values are named
+ for res in v.type.results.list {
+ if len(res.names) == 0 do return
+ }
+ append(&data.procs, Proc_Data{data.depth, v.type.results.list})
+ }
+ return
+
+ case ^ast.Return_Stmt:
+ if len(v.results) > 0 do return // explicit return, skip
+ return_node = &v.stmt_base
+
+ case ^ast.Or_Return_Expr:
+ return_node = &v.expr_base
+ is_or_return = true
+
+ case: return
+ }
+
+ if len(data.procs) == 0 do return // not inside a proc
+
+ proc_data := &data.procs[len(data.procs)-1]
+
+ sb := strings.builder_make(context.temp_allocator)
+ strings.write_string(&sb, " ")
+
+ for res, i in proc_data.results {
+ for name, j in res.names {
+ str := expr_name(name) or_continue
+ if i > 0 || j > 0 {
+ strings.write_string(&sb, ", ")
+ }
+ if is_or_return && i == len(proc_data.results)-1 && j == len(res.names)-1 {
+ strings.write_string(&sb, "_")
+ } else {
+ strings.write_string(&sb, str)
+ }
+ }
+ }
+
+ range := common.get_token_range(return_node^, string(data.document.text))
+ append(&data.hints, InlayHint{range.end, .Parameter, strings.to_string(sb)})
+
+ return true
+ }
+
return data.hints[:], true
}
diff --git a/src/server/requests.odin b/src/server/requests.odin
index c013ffc..e153503 100644
--- a/src/server/requests.odin
+++ b/src/server/requests.odin
@@ -433,11 +433,12 @@ read_ols_initialize_options :: proc(config: ^common.Config, ols_config: OlsConfi
config.checker_targets = slice.clone(ols_config.checker_targets, context.allocator)
- config.enable_inlay_hints = ols_config.enable_inlay_hints.(bool) or_else config.enable_inlay_hints
config.enable_inlay_hints_params =
ols_config.enable_inlay_hints_params.(bool) or_else config.enable_inlay_hints_params
config.enable_inlay_hints_default_params =
ols_config.enable_inlay_hints_default_params.(bool) or_else config.enable_inlay_hints_default_params
+ config.enable_inlay_hints_implicit_return =
+ ols_config.enable_inlay_hints_implicit_return.(bool) or_else config.enable_inlay_hints_implicit_return
config.enable_fake_method = ols_config.enable_fake_methods.(bool) or_else config.enable_fake_method
@@ -605,9 +606,9 @@ request_initialize :: proc(
config.enable_hover = true
config.enable_format = true
- config.enable_inlay_hints = false
- config.enable_inlay_hints_params = true
- config.enable_inlay_hints_default_params = true
+ config.enable_inlay_hints_params = false
+ config.enable_inlay_hints_default_params = false
+ config.enable_inlay_hints_implicit_return = false
config.disable_parser_errors = false
config.thread_count = 2
@@ -727,7 +728,11 @@ request_initialize :: proc(
tokenModifiers = semantic_token_modifier_names,
},
},
- inlayHintProvider = config.enable_inlay_hints,
+ inlayHintProvider = (
+ config.enable_inlay_hints_params ||
+ config.enable_inlay_hints_default_params ||
+ config.enable_inlay_hints_implicit_return
+ ),
documentSymbolProvider = config.enable_document_symbols,
hoverProvider = config.enable_hover,
documentFormattingProvider = config.enable_format,
@@ -1299,38 +1304,27 @@ request_inlay_hint :: proc(
config: ^common.Config,
writer: ^Writer,
) -> common.Error {
- params_object, ok := params.(json.Object)
- if !ok {
- return .ParseError
- }
+ _, is_params_object := params.(json.Object)
+ if !is_params_object do return .ParseError
inlay_params: InlayParams
-
if unmarshal(params, inlay_params, context.temp_allocator) != nil {
return .ParseError
}
document := document_get(inlay_params.textDocument.uri)
-
- if document == nil {
- return .InternalError
- }
-
- hints: []InlayHint
+ if document == nil do return .InternalError
resolve_entire_file_cached(document)
- if file, ok := file_resolve_cache.files[document.uri.uri]; ok {
- hints, ok = get_inlay_hints(document, file.symbols, config)
- }
+ file, file_ok := file_resolve_cache.files[document.uri.uri]
+ if !file_ok do return .InternalError
- if !ok {
- return .InternalError
- }
+ hints, hints_ok := get_inlay_hints(document, file.symbols, config)
+ if !hints_ok do return .InternalError
response := make_response_message(params = hints, id = id)
-
send_response(response, writer)
return .None
diff --git a/src/server/types.odin b/src/server/types.odin
index 6487d1f..e0a2667 100644
--- a/src/server/types.odin
+++ b/src/server/types.odin
@@ -420,9 +420,9 @@ OlsConfig :: struct {
enable_references: Maybe(bool),
enable_document_links: Maybe(bool),
enable_completion_matching: Maybe(bool),
- enable_inlay_hints: Maybe(bool),
enable_inlay_hints_params: Maybe(bool),
enable_inlay_hints_default_params: Maybe(bool),
+ enable_inlay_hints_implicit_return: Maybe(bool),
enable_semantic_tokens: Maybe(bool),
enable_unused_imports_reporting: Maybe(bool),
enable_procedure_context: Maybe(bool),