aboutsummaryrefslogtreecommitdiff
path: root/src/server/requests.odin
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/requests.odin')
-rw-r--r--src/server/requests.odin230
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
}