diff options
Diffstat (limited to 'src/server/requests.odin')
| -rw-r--r-- | src/server/requests.odin | 230 |
1 files changed, 165 insertions, 65 deletions
diff --git a/src/server/requests.odin b/src/server/requests.odin index 82d0ae2..3aec455 100644 --- a/src/server/requests.odin +++ b/src/server/requests.odin @@ -7,9 +7,6 @@ import "base:runtime" import "core:encoding/json" import "core:fmt" import "core:log" -import "core:mem" -import "core:odin/ast" -import "core:odin/parser" import "core:os" import "core:path/filepath" import path "core:path/slashpath" @@ -17,7 +14,6 @@ import "core:slice" import "core:strconv" import "core:strings" import "core:sync" -import "core:thread" import "core:time" import "src:common" @@ -218,7 +214,12 @@ read_and_parse_body :: proc(reader: ^Reader, header: Header) -> (json.Value, boo return value, true } -call_map: map[string]proc(_: json.Value, _: RequestId, _: ^common.Config, _: ^Writer) -> common.Error = { +call_map: map[string]proc( + _: json.Value, + _: RequestId, + _: ^common.Config, + _: ^Writer, +) -> common.Error = { "initialize" = request_initialize, "initialized" = request_initialized, "shutdown" = request_shutdown, @@ -278,6 +279,7 @@ consume_requests :: proc(config: ^common.Config, writer: ^Writer) -> bool { ordered_remove(&requests, delete_index) } } + clear(&deletings) for request in requests { append(&temp_requests, request) @@ -329,7 +331,10 @@ call :: proc(value: json.Value, id: RequestId, writer: ^Writer, config: ^common. if !ok { log.errorf("Failed to find method: %#v", root) - response := make_response_message_error(id = id, error = ResponseError{code = .MethodNotFound, message = ""}) + response := make_response_message_error( + id = id, + error = ResponseError{code = .MethodNotFound, message = ""}, + ) send_error(response, writer) return } @@ -347,7 +352,10 @@ call :: proc(value: json.Value, id: RequestId, writer: ^Writer, config: ^common. } else { err := fn(root["params"], id, config, writer) if err != .None { - response := make_response_message_error(id = id, error = ResponseError{code = err, message = ""}) + response := make_response_message_error( + id = id, + error = ResponseError{code = err, message = ""}, + ) send_error(response, writer) } } @@ -356,29 +364,44 @@ call :: proc(value: json.Value, id: RequestId, writer: ^Writer, config: ^common. //log.errorf("time duration %v for %v", time.duration_milliseconds(diff), method) } -read_ols_initialize_options :: proc(config: ^common.Config, ols_config: OlsConfig, uri: common.Uri) { - config.disable_parser_errors = ols_config.disable_parser_errors.(bool) or_else config.disable_parser_errors +read_ols_initialize_options :: proc( + config: ^common.Config, + ols_config: OlsConfig, + uri: common.Uri, +) { + config.disable_parser_errors = + ols_config.disable_parser_errors.(bool) or_else config.disable_parser_errors config.thread_count = ols_config.thread_pool_count.(int) or_else config.thread_count - config.enable_document_symbols = ols_config.enable_document_symbols.(bool) or_else config.enable_document_symbols + config.enable_document_symbols = + ols_config.enable_document_symbols.(bool) or_else config.enable_document_symbols config.enable_format = ols_config.enable_format.(bool) or_else config.enable_format config.enable_hover = ols_config.enable_hover.(bool) or_else config.enable_hover - config.enable_semantic_tokens = ols_config.enable_semantic_tokens.(bool) or_else config.enable_semantic_tokens - config.enable_unused_imports_reporting = ols_config.enable_unused_imports_reporting.(bool) or_else config.enable_unused_imports_reporting + config.enable_semantic_tokens = + ols_config.enable_semantic_tokens.(bool) or_else config.enable_semantic_tokens + config.enable_unused_imports_reporting = + ols_config.enable_unused_imports_reporting.(bool) or_else config.enable_unused_imports_reporting config.enable_procedure_context = ols_config.enable_procedure_context.(bool) or_else config.enable_procedure_context config.enable_snippets = ols_config.enable_snippets.(bool) or_else config.enable_snippets config.enable_references = ols_config.enable_references.(bool) or_else config.enable_references - config.enable_document_highlights = ols_config.enable_document_highlights.(bool) or_else config.enable_document_highlights + config.enable_document_highlights = + ols_config.enable_document_highlights.(bool) or_else config.enable_document_highlights 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_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.enable_comp_lit_signature_help_use_docs = + ols_config.enable_comp_lit_signature_help_use_docs.(bool) or_else config.enable_comp_lit_signature_help_use_docs config.verbose = ols_config.verbose.(bool) or_else config.verbose config.file_log = ols_config.file_log.(bool) or_else config.file_log config.enable_procedure_snippet = ols_config.enable_procedure_snippet.(bool) or_else config.enable_procedure_snippet - config.enable_auto_import = ols_config.enable_auto_import.(bool) or_else config.enable_auto_import + config.enable_auto_import = + ols_config.enable_auto_import.(bool) or_else config.enable_auto_import config.enable_checker_only_saved = ols_config.enable_checker_only_saved.(bool) or_else config.enable_checker_only_saved @@ -394,7 +417,10 @@ read_ols_initialize_options :: proc(config: ^common.Config, ols_config: OlsConfi } if ols_config.odin_root_override != "" { - config.odin_root_override = strings.clone(ols_config.odin_root_override, context.temp_allocator) + config.odin_root_override = strings.clone( + ols_config.odin_root_override, + context.temp_allocator, + ) allocated: bool config.odin_root_override, allocated = common.resolve_home_dir(config.odin_root_override) @@ -420,6 +446,11 @@ read_ols_initialize_options :: proc(config: ^common.Config, ols_config: OlsConfi } config.profile.os = strings.clone(profile.os) + config.profile.arch = strings.clone(profile.arch) + + for key, value in profile.defines { + config.profile.defines[strings.clone(key)] = strings.clone(value) + } break } @@ -442,7 +473,10 @@ read_ols_initialize_options :: proc(config: ^common.Config, ols_config: OlsConfi 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 + config.enable_fake_method = + ols_config.enable_fake_methods.(bool) or_else config.enable_fake_method + config.enable_overload_resolution = + ols_config.enable_overload_resolution.(bool) or_else config.enable_overload_resolution // Delete overriding collections. for it in ols_config.collections { @@ -462,7 +496,7 @@ read_ols_initialize_options :: proc(config: ^common.Config, ols_config: OlsConfi // Apply custom collections. for it in ols_config.collections { - forward_path, _ := filepath.to_slash(it.path, context.temp_allocator) + forward_path, _ := filepath.replace_path_separators(it.path, '/', context.temp_allocator) forward_path = common.resolve_home_dir(forward_path, context.temp_allocator) @@ -470,16 +504,21 @@ read_ols_initialize_options :: proc(config: ^common.Config, ols_config: OlsConfi when ODIN_OS == .Windows { if filepath.is_abs(it.path) { - final_path, _ = filepath.to_slash( + final_path, _ = filepath.replace_path_separators( common.get_case_sensitive_path(forward_path, context.temp_allocator), + '/', context.temp_allocator, ) } else { - final_path, _ = filepath.to_slash( + final_path, _ = filepath.replace_path_separators( common.get_case_sensitive_path( - path.join(elems = {uri.path, forward_path}, allocator = context.temp_allocator), + path.join( + elems = {uri.path, forward_path}, + allocator = context.temp_allocator, + ), context.temp_allocator, ), + '/', context.temp_allocator, ) } @@ -493,13 +532,18 @@ read_ols_initialize_options :: proc(config: ^common.Config, ols_config: OlsConfi } } - if abs_final_path, ok := filepath.abs(final_path); ok { - slashed_path, _ := filepath.to_slash(abs_final_path, context.temp_allocator) + abs_final_path, err := filepath.abs(final_path, context.temp_allocator) + if err != nil { + log.errorf("Failed to find absolute address of collection: %v", final_path, err) + config.collections[strings.clone(it.name)] = strings.clone(final_path) + } else { + slashed_path, _ := filepath.replace_path_separators( + abs_final_path, + '/', + context.temp_allocator, + ) config.collections[strings.clone(it.name)] = strings.clone(slashed_path) - } else { - log.errorf("Failed to find absolute address of collection: %v", final_path) - config.collections[strings.clone(it.name)] = strings.clone(final_path) } } @@ -543,7 +587,8 @@ read_ols_initialize_options :: proc(config: ^common.Config, ols_config: OlsConfi } if odin_core_env != "" { - if abs_core_env, ok := filepath.abs(odin_core_env, context.temp_allocator); ok { + if abs_core_env, err := filepath.abs(odin_core_env, context.temp_allocator); + err == nil { odin_core_env = abs_core_env } } @@ -554,7 +599,11 @@ read_ols_initialize_options :: proc(config: ^common.Config, ols_config: OlsConfi // Insert the default collections if they are not specified in the config. if odin_core_env != "" { - forward_path, _ := filepath.to_slash(odin_core_env, context.temp_allocator) + forward_path, _ := filepath.replace_path_separators( + odin_core_env, + '/', + context.temp_allocator, + ) // base if "base" not_in config.collections { @@ -582,7 +631,10 @@ read_ols_initialize_options :: proc(config: ^common.Config, ols_config: OlsConfi // shared if "shared" not_in config.collections { - shared_path := path.join(elems = {forward_path, "shared"}, allocator = context.allocator) + shared_path := path.join( + elems = {forward_path, "shared"}, + allocator = context.allocator, + ) if os.exists(shared_path) { config.collections[strings.clone("shared")] = shared_path } else { @@ -641,6 +693,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 = "" @@ -651,21 +704,18 @@ request_initialize :: proc( config.enable_auto_import = true read_ols_config :: proc(file: string, config: ^common.Config, uri: common.Uri) { - if data, ok := os.read_entire_file(file, context.temp_allocator); ok { - if value, err := json.parse(data = data, allocator = context.temp_allocator, parse_integers = true); - err == .None { - ols_config: OlsConfig - - if unmarshal(value, ols_config, context.temp_allocator) == nil { - read_ols_initialize_options(config, ols_config, uri) - } else { - log.warnf("Failed to unmarshal %v", file) - } - } else { - log.warnf("Failed to parse json %v", file) - } + data, err := os.read_entire_file(file, context.temp_allocator) + if err != nil { + log.warnf("Failed to read/find %v: %v", file, err) + return + } + ols_config: OlsConfig + + json_err := json.unmarshal(data, &ols_config, allocator = context.temp_allocator) + if json_err == nil { + read_ols_initialize_options(config, ols_config, uri) } else { - log.warnf("Failed to read/find %v", file) + log.errorf("Failed to unmarshal %v: %v", file, json_err) } } @@ -689,7 +739,10 @@ request_initialize :: proc( read_ols_initialize_options(config, initialize_params.initializationOptions, uri) // Apply ols.json config. - ols_config_path := path.join(elems = {uri.path, "ols.json"}, allocator = context.temp_allocator) + ols_config_path := path.join( + elems = {uri.path, "ols.json"}, + allocator = context.temp_allocator, + ) read_ols_config(ols_config_path, config, uri) } else { read_ols_initialize_options(config, initialize_params.initializationOptions, {}) @@ -710,7 +763,8 @@ request_initialize :: proc( config.enable_label_details = initialize_params.capabilities.textDocument.completion.completionItem.labelDetailsSupport - config.enable_snippets &= initialize_params.capabilities.textDocument.completion.completionItem.snippetSupport + config.enable_snippets &= + initialize_params.capabilities.textDocument.completion.completionItem.snippetSupport config.signature_offset_support = initialize_params.capabilities.textDocument.signatureHelp.signatureInformation.parameterInformation.labelOffsetSupport @@ -719,12 +773,17 @@ request_initialize :: proc( signatureTriggerCharacters := []string{"(", ","} signatureRetriggerCharacters := []string{","} - semantic_range_support := initialize_params.capabilities.textDocument.semanticTokens.requests.range + semantic_range_support := + initialize_params.capabilities.textDocument.semanticTokens.requests.range response := make_response_message( params = ResponseInitializeParams { capabilities = ServerCapabilities { - textDocumentSync = TextDocumentSyncOptions{openClose = true, change = 2, save = {includeText = true}}, + textDocumentSync = TextDocumentSyncOptions { + openClose = true, + change = 2, + save = {includeText = true}, + }, renameProvider = RenameOptions{prepareProvider = true}, workspaceSymbolProvider = true, referencesProvider = config.enable_references, @@ -742,22 +801,23 @@ request_initialize :: proc( }, semanticTokensProvider = SemanticTokensOptions { range = config.enable_semantic_tokens && semantic_range_support, - full = config.enable_semantic_tokens && !semantic_range_support, + full = config.enable_semantic_tokens, legend = SemanticTokensLegend { tokenTypes = semantic_token_type_names, 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), documentSymbolProvider = config.enable_document_symbols, hoverProvider = config.enable_hover, documentFormattingProvider = config.enable_format, documentLinkProvider = {resolveProvider = false}, - codeActionProvider = {resolveProvider = false, codeActionKinds = {"refactor.rewrite"}}, + codeActionProvider = { + resolveProvider = false, + codeActionKinds = {"refactor.rewrite"}, + }, }, }, id = id, @@ -823,7 +883,12 @@ request_initialized :: proc( return .None } -request_shutdown :: proc(params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error { +request_shutdown :: proc( + params: json.Value, + id: RequestId, + config: ^common.Config, + writer: ^Writer, +) -> common.Error { response := make_response_message(params = nil, id = id) send_response(response, writer) @@ -855,7 +920,7 @@ request_definition :: proc( return .InternalError } - locations, ok2 := get_definition_location(document, definition_params.position) + locations, ok2 := get_definition_location(document, definition_params.position, config) if !ok2 { log.warn("Failed to get definition location") @@ -938,7 +1003,12 @@ request_completion :: proc( } list: CompletionList - list, ok = get_completion_list(document, completition_params.position, completition_params.context_, config) + list, ok = get_completion_list( + document, + completition_params.position, + completition_params.context_, + config, + ) if !ok { return .InternalError @@ -976,7 +1046,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 @@ -1032,7 +1102,12 @@ request_format_document :: proc( return .None } -notification_exit :: proc(params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error { +notification_exit :: proc( + params: json.Value, + id: RequestId, + config: ^common.Config, + writer: ^Writer, +) -> common.Error { config.running = false return .None } @@ -1059,7 +1134,12 @@ notification_did_open :: proc( defer delete(open_params.textDocument.uri) - if n := document_open(open_params.textDocument.uri, open_params.textDocument.text, config, writer); n != .None { + if n := document_open( + open_params.textDocument.uri, + open_params.textDocument.text, + config, + writer, + ); n != .None { return .InternalError } @@ -1158,7 +1238,7 @@ notification_did_save :: proc( when ODIN_OS == .Windows { correct := common.get_case_sensitive_path(fullpath, context.temp_allocator) - fullpath, _ = filepath.to_slash(correct, context.temp_allocator) + fullpath, _ = filepath.replace_path_separators(correct, '/', context.temp_allocator) } corrected_uri := common.create_uri(fullpath, context.temp_allocator) @@ -1295,7 +1375,12 @@ request_document_symbols :: proc( return .None } -request_hover :: proc(params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error { +request_hover :: proc( + params: json.Value, + id: RequestId, + config: ^common.Config, + writer: ^Writer, +) -> common.Error { params_object, ok := params.(json.Object) if !ok { @@ -1443,7 +1528,12 @@ request_prepare_rename :: proc( return .None } -request_rename :: proc(params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error { +request_rename :: proc( + params: json.Value, + id: RequestId, + config: ^common.Config, + writer: ^Writer, +) -> common.Error { params_object, ok := params.(json.Object) if !ok { @@ -1557,7 +1647,12 @@ request_highlights :: proc( return .None } -request_code_action :: proc(params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error { +request_code_action :: proc( + params: json.Value, + id: RequestId, + config: ^common.Config, + writer: ^Writer, +) -> common.Error { params_object, ok := params.(json.Object) if !ok { @@ -1615,7 +1710,7 @@ notification_did_change_watched_files :: proc( find_all_package_aliases() } else { if uri, ok := common.parse_uri(change.uri, context.temp_allocator); ok { - if data, ok := os.read_entire_file(uri.path, context.temp_allocator); ok { + if data, err := os.read_entire_file(uri.path, context.temp_allocator); err == nil { index_file(uri, cast(string)data) } } @@ -1688,6 +1783,11 @@ request_workspace_symbols :: proc( return .None } -request_noop :: proc(params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error { +request_noop :: proc( + params: json.Value, + id: RequestId, + config: ^common.Config, + writer: ^Writer, +) -> common.Error { return .None } |