Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ Options:

- `enable_inlay_hints_implicit_return`: Turn on inlay hints for implicit return values.

- `enable_inlay_hints_optional_result`: Adds inlay hints for unhandled optional result value. (#optional_ok and #optional_allocator_error)

- `enable_semantic_tokens`: Turns on syntax highlighting.

- `enable_snippets`: Turns on builtin snippets
Expand Down
5 changes: 5 additions & 0 deletions misc/ols.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@
"description": "Turn on inlay hints for implicit return values.",
"default": false
},
"enable_inlay_hints_optional_result": {
"type": "boolean",
"description": "Adds inlay hints for unhandled optional result value. (#optional_ok and #optional_allocator_error)",
"default": false
},
"enable_procedure_snippet": {
"type": "boolean",
"description": "Use snippets when completing procedures—adds parenthesis after the name.",
Expand Down
1 change: 1 addition & 0 deletions src/common/config.odin
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Config :: struct {
enable_inlay_hints_params: bool,
enable_inlay_hints_default_params: bool,
enable_inlay_hints_implicit_return: bool,
enable_inlay_hints_optional_result: bool,
enable_procedure_context: bool,
enable_snippets: bool,
enable_references: bool,
Expand Down
49 changes: 48 additions & 1 deletion src/server/inlay_hints.odin
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package server

import "core:strings"
import "core:fmt"
import "core:log"
import "core:odin/ast"

import "src:common"
Expand Down Expand Up @@ -64,6 +63,7 @@ get_inlay_hints :: proc(

add_param_hints(node, data)
add_return_hints(node, data)
add_result_hints(node, data)

return visitor
},
Expand Down Expand Up @@ -338,5 +338,52 @@ get_inlay_hints :: proc(
return true
}

/*
Adds inlay hints for unhandled optional result value.
#optional_ok and #optional_allocator_error
*/
add_result_hints :: proc (
node: ^ast.Node,
data: ^Visitor_Data,
) -> (ok: bool) {

if !data.config.enable_inlay_hints_optional_result do return

// a = foo() | a := foo()
lhs, rhs: []^ast.Expr
#partial switch v in node.derived {
case ^ast.Assign_Stmt: lhs, rhs = v.lhs, v.rhs
case ^ast.Value_Decl: lhs, rhs = v.names, v.values
case: return
}

// optional result can only be handled when there is a single rhs expr
if len(rhs) != 1 do return

call := rhs[0].derived.(^ast.Call_Expr) or_return

symbol_and_node := data.symbols[uintptr(call.expr)] or_return // could not resolve symbol
proc_symbol := symbol_and_node.symbol.value.(SymbolProcedureValue) or_return // not a procedure call, e.g. type cast

if .Optional_Ok not_in proc_symbol.tags &&
.Optional_Allocator_Error not_in proc_symbol.tags {
return
}

// check if all results are handled
results_len: int
for field in proc_symbol.return_types {
results_len += len(field.names)
}
if len(lhs) >= results_len do return

// a, b[[, _]] := foo()
last := lhs[len(lhs)-1]
range := common.get_token_range(last^, string(data.document.text))
append(&data.hints, InlayHint{range.end, .Parameter, ", _"})

return true
}

return data.hints[:], true
}
9 changes: 7 additions & 2 deletions src/server/requests.odin
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,8 @@ read_ols_initialize_options :: proc(config: ^common.Config, ols_config: OlsConfi
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_inlay_hints_optional_result =
ols_config.enable_inlay_hints_optional_result.(bool) or_else config.enable_inlay_hints_optional_result

config.enable_fake_method = ols_config.enable_fake_methods.(bool) or_else config.enable_fake_method
config.enable_overload_resolution =
Expand Down Expand Up @@ -801,9 +803,12 @@ request_initialize :: proc(
tokenModifiers = semantic_token_modifier_names,
},
},
inlayHintProvider = (config.enable_inlay_hints_params ||
inlayHintProvider = (
config.enable_inlay_hints_params ||
config.enable_inlay_hints_default_params ||
config.enable_inlay_hints_implicit_return),
config.enable_inlay_hints_implicit_return ||
config.enable_inlay_hints_optional_result
),
documentSymbolProvider = config.enable_document_symbols,
hoverProvider = config.enable_hover,
documentFormattingProvider = config.enable_format,
Expand Down
1 change: 1 addition & 0 deletions src/server/types.odin
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,7 @@ OlsConfig :: struct {
enable_inlay_hints_params: Maybe(bool),
enable_inlay_hints_default_params: Maybe(bool),
enable_inlay_hints_implicit_return: Maybe(bool),
enable_inlay_hints_optional_result: Maybe(bool),
enable_semantic_tokens: Maybe(bool),
enable_unused_imports_reporting: Maybe(bool),
enable_procedure_context: Maybe(bool),
Expand Down
30 changes: 28 additions & 2 deletions tests/inlay_hints_test.odin
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package tests

import "core:fmt"
import "core:testing"

import test "src:testing"
Expand Down Expand Up @@ -227,4 +226,31 @@ ast_inlay_hints_implicit_return_values :: proc(t: ^testing.T) {
}

test.expect_inlay_hints(t, &source)
}
}

@(test)
ast_inlay_hints_optional_result :: proc(t: ^testing.T) {
source := test.Source {
main = `package test

foo :: proc () -> (res: int, ok: bool) #optional_ok {
return
}
bar :: proc () -> (a, b: int, ok: bool) #optional_ok {
return
}
main :: proc () {
res[[, _]] := foo()
res[[, _]] = foo()
a, b[[, _]] := bar()
}
`,
packages = {},
config = {
enable_inlay_hints_optional_result = true,
},
}

test.expect_inlay_hints(t, &source)
}

Loading