aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorDaniel Gavin <danielgavin5@hotmail.com>2021-12-25 13:43:58 +0100
committerDaniel Gavin <danielgavin5@hotmail.com>2021-12-25 13:43:58 +0100
commitbb1379a911f43134b8dc5ed9ec2eebb889b800fb (patch)
tree8eb5090124d0bb4c18d353e1daf1d09d50531f8d /src/server
parent74d5978d86d8da1e2f74727965d7d3d3b16c71f1 (diff)
add temp work
Diffstat (limited to 'src/server')
-rw-r--r--src/server/inlay_hints.odin82
-rw-r--r--src/server/requests.odin44
-rw-r--r--src/server/types.odin8
3 files changed, 130 insertions, 4 deletions
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