From bb1379a911f43134b8dc5ed9ec2eebb889b800fb Mon Sep 17 00:00:00 2001 From: Daniel Gavin Date: Sat, 25 Dec 2021 13:43:58 +0100 Subject: add temp work --- src/server/inlay_hints.odin | 82 +++++++++++++++++++++++++++++++++++++++++++++ src/server/requests.odin | 44 +++++++++++++++++++++--- src/server/types.odin | 8 +++++ 3 files changed, 130 insertions(+), 4 deletions(-) create mode 100644 src/server/inlay_hints.odin (limited to 'src/server') diff --git a/src/server/inlay_hints.odin b/src/server/inlay_hints.odin new file mode 100644 index 0000000..7d96c84 --- /dev/null +++ b/src/server/inlay_hints.odin @@ -0,0 +1,82 @@ +package server + +import "core:odin/ast" +import "core:fmt" + +import "shared:common" +import "shared:analysis" +import "shared:index" + +//document +get_inlay_hints :: proc(document: ^common.Document) -> ([]InlayHint, bool) { + + using analysis; + + hints := make([dynamic]InlayHint, context.temp_allocator); + + ast_context := make_ast_context(document.ast, document.imports, document.package_name, document.uri.uri); + + Visit_Data :: struct { + calls: [dynamic]ast.Call_Expr, + } + + data := Visit_Data { + calls = make([dynamic]ast.Call_Expr, context.temp_allocator), + }; + + visit :: proc(visitor: ^ast.Visitor, node: ^ast.Node) -> ^ast.Visitor { + if node == nil || visitor == nil { + return nil; + } + + data := cast(^Visit_Data)visitor.data; + + if call, ok := node.derived.(ast.Call_Expr); ok { + append(&data.calls, call); + } + + return visitor; + } + + visitor := ast.Visitor { + data = &data, + visit = visit, + } + + for decl in document.ast.decls { + ast.walk(&visitor, decl); + } + + loop: for call in &data.calls { + symbol_arg_count := 0 + for arg in call.args { + if _, ok := arg.derived.(ast.Field); ok { + continue loop; + } + } + + if symbol, ok := resolve_type_expression(&ast_context, &call); ok { + if symbol_call, ok := symbol.value.(index.SymbolProcedureValue); ok { + for arg in symbol_call.arg_types { + for name in arg.names { + if symbol_arg_count >= len(call.args) { + continue loop; + } + + if ident, ok := name.derived.(ast.Ident); ok { + hint := InlayHint { + kind = "parameter", + label = fmt.tprintf("%v:", ident.name), + range = common.get_token_range(call.args[symbol_arg_count], string(document.text)), + } + append(&hints, hint); + } + symbol_arg_count += 1; + } + } + } + } + } + + return hints[:], true; +} \ No newline at end of file diff --git a/src/server/requests.odin b/src/server/requests.odin index f4dc267..8fc0fa1 100644 --- a/src/server/requests.odin +++ b/src/server/requests.odin @@ -43,6 +43,7 @@ RequestType :: enum { FormatDocument, Hover, CancelRequest, + InlayHint, } RequestInfo :: struct { @@ -186,6 +187,7 @@ request_map: map[string]RequestType = { "textDocument/hover" = .Hover, "$/cancelRequest" = .CancelRequest, "textDocument/formatting" = .FormatDocument, + "odin/inlayHints" = .InlayHint, }; handle_error :: proc (err: common.Error, id: RequestId, writer: ^Writer) { @@ -282,6 +284,8 @@ handle_request :: proc (request: json.Value, config: ^common.Config, writer: ^Wr case .CancelRequest: case .FormatDocument: task_proc = request_format_document; + case .InlayHint: + task_proc = request_inlay_hint; } task := common.Task { @@ -298,9 +302,9 @@ handle_request :: proc (request: json.Value, config: ^common.Config, writer: ^Wr break; } } - case .Initialize,.Initialized: + case .Initialize, .Initialized: task_proc(&task); - case .Completion,.Definition,.Hover,.FormatDocument: + case .Completion, .Definition, .Hover, .FormatDocument: uri := root["params"].(json.Object)["textDocument"].(json.Object)["uri"].(json.String); @@ -315,7 +319,7 @@ handle_request :: proc (request: json.Value, config: ^common.Config, writer: ^Wr task_proc(&task); - case .DidClose,.DidChange,.DidOpen,.DidSave: + case .DidClose, .DidChange, .DidOpen, .DidSave: uri := root["params"].(json.Object)["textDocument"].(json.Object)["uri"].(json.String); @@ -335,7 +339,7 @@ handle_request :: proc (request: json.Value, config: ^common.Config, writer: ^Wr document_release(document); case .Shutdown,.Exit: task_proc(&task); - case .SignatureHelp,.SemanticTokensFull,.SemanticTokensRange,.DocumentSymbol: + case .SignatureHelp, .SemanticTokensFull, .SemanticTokensRange, .DocumentSymbol, .InlayHint: uri := root["params"].(json.Object)["textDocument"].(json.Object)["uri"].(json.String); @@ -541,6 +545,7 @@ request_initialize :: proc (task: ^common.Task) { tokenModifiers = token_modifiers, }, }, + inlayHintsProvider = true, documentSymbolProvider = config.enable_document_symbols, hoverProvider = config.enable_hover, documentFormattingProvider = config.enable_format, @@ -1108,3 +1113,34 @@ request_hover :: proc (task: ^common.Task) { send_response(response, writer); } + +request_inlay_hint :: proc (task: ^common.Task) { + info := get_request_info(task); + + using info; + + defer { + document_release(document); + json.destroy_value(root); + free(info); + } + + params_object, ok := params.(json.Object); + + if !ok { + handle_error(.ParseError, id, writer); + return; + } + + hints: []InlayHint; + hints, ok = get_inlay_hints(document); + + if !ok { + handle_error(.InternalError, id, writer); + return; + } + + response := make_response_message(params = hints, id = id); + + send_response(response, writer); +} \ No newline at end of file diff --git a/src/server/types.odin b/src/server/types.odin index 9f3c866..d369b33 100644 --- a/src/server/types.odin +++ b/src/server/types.odin @@ -26,6 +26,7 @@ ResponseParams :: union { SemanticTokens, Hover, []TextEdit, + []InlayHint, } ResponseMessage :: struct { @@ -91,6 +92,7 @@ ServerCapabilities :: struct { documentSymbolProvider: bool, hoverProvider: bool, documentFormattingProvider: bool, + inlayHintsProvider: bool, } CompletionOptions :: struct { @@ -357,4 +359,10 @@ Command :: struct { title: string, command: string, arguments: []string, +} + +InlayHint :: struct { + range: common.Range, + kind: string, + label: string, } \ No newline at end of file -- cgit v1.2.3