aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-08-23 12:22:36 -0400
committerBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-08-24 08:55:23 -0400
commit118db4f7667c91b24fcc21353df7c3cd7a5830b3 (patch)
tree0f098b492a06712f79782d493797604eec4e844b /src/server
parent39b2e758cacb40ba1a062b8af87af9edf8958375 (diff)
Add special case for handling `append` for dynamic arrays
Diffstat (limited to 'src/server')
-rw-r--r--src/server/completion.odin57
1 files changed, 44 insertions, 13 deletions
diff --git a/src/server/completion.odin b/src/server/completion.odin
index 61e528b..51a9911 100644
--- a/src/server/completion.odin
+++ b/src/server/completion.odin
@@ -11,6 +11,7 @@ import "core:odin/tokenizer"
import "core:os"
import "core:path/filepath"
import path "core:path/slashpath"
+import "core:reflect"
import "core:slice"
import "core:sort"
import "core:strconv"
@@ -186,9 +187,16 @@ get_completion_list :: proc(
get_target_symbol :: proc(ast_context: ^AstContext, position_context: ^DocumentPositionContext) -> Maybe(Symbol) {
if position_context.call != nil {
if call, ok := position_context.call.derived.(^ast.Call_Expr); ok {
- if call_symbol, ok := resolve_type_expression(ast_context, call.expr); ok {
- if value, ok := call_symbol.value.(SymbolProcedureValue); ok {
- if param_index, ok := find_position_in_call_param(position_context, call^); ok {
+ if param_index, ok := find_position_in_call_param(position_context, call^); ok {
+ // Manually check this so we handle the pointer case of the first argument
+ if ident, ok := call.expr.derived.(^ast.Ident); ok && param_index == 0 {
+ switch ident.name {
+ case "append", "non_zero_append":
+ return Symbol{value = SymbolDynamicArrayValue{}, pointers = 1}
+ }
+ }
+ if call_symbol, ok := resolve_type_expression(ast_context, call.expr); ok {
+ if value, ok := call_symbol.value.(SymbolProcedureValue); ok {
if arg_type, arg_type_ok := get_proc_arg_type_from_index(value, param_index); ok {
if position_context.field_value != nil {
// we are using a named param so we want to ensure we use that type and not the
@@ -350,7 +358,6 @@ convert_completion_results :: proc(
}
item.kind = symbol_type_to_completion_kind(result.symbol.type)
-
if result.symbol.type == .Function && common.config.enable_snippets && common.config.enable_procedure_snippet {
item.insertText = fmt.tprintf("%v($0)", item.label)
item.insertTextFormat = .Snippet
@@ -379,19 +386,43 @@ handle_pointers :: proc(
item: ^CompletionItem,
completion_type: Completion_Type,
) {
- if v, ok := arg_symbol.value.(SymbolBasicValue); ok {
- if v.ident.name == "any" {
- return
+ should_skip :: proc(arg_symbol, result_symbol: Symbol) -> bool {
+ if v, ok := arg_symbol.value.(SymbolBasicValue); ok {
+ if v.ident.name == "any" {
+ return true
+ }
}
- }
- if _, ok := result_symbol.value.(SymbolUntypedValue); ok && arg_symbol.type == .Keyword {
- if _, ok := are_symbol_untyped_basic_same_typed(arg_symbol, result_symbol); !ok {
- if _, ok := are_symbol_untyped_basic_same_typed(result_symbol, arg_symbol); !ok {
- return
+ if _, ok := result_symbol.value.(SymbolUntypedValue); ok && arg_symbol.type == .Keyword {
+ if _, ok := are_symbol_untyped_basic_same_typed(arg_symbol, result_symbol); !ok {
+ if _, ok := are_symbol_untyped_basic_same_typed(result_symbol, arg_symbol); !ok {
+ return true
+ }
+ return false
}
+ return false
}
- } else if result_symbol.uri != arg_symbol.uri || result_symbol.range != arg_symbol.range {
+
+ a_id := reflect.union_variant_typeid(arg_symbol.value)
+ b_id := reflect.union_variant_typeid(result_symbol.value)
+
+ if a_id != b_id {
+ return true
+ }
+
+ #partial switch v in arg_symbol.value {
+ case SymbolMapValue, SymbolDynamicArrayValue, SymbolSliceValue, SymbolMultiPointerValue, SymbolFixedArrayValue:
+ return false
+ }
+
+ if result_symbol.uri != arg_symbol.uri || result_symbol.range != arg_symbol.range {
+ return true
+ }
+
+ return false
+ }
+
+ if should_skip(arg_symbol, result_symbol) {
return
}