aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2024-06-17 20:04:29 +0200
committerDanielGavin <danielgavin5@hotmail.com>2024-06-17 20:04:29 +0200
commitc388704714dc5797ffa71d0b0119899df006497a (patch)
tree74acd241a491917e52b3a1b6b6416d5c94945553
parentc99b080e2dd14e951975206ed5d89d4e4689053e (diff)
Start adding support for enumerated arrays for completion.
-rw-r--r--src/server/analysis.odin4
-rw-r--r--src/server/completion.odin36
-rw-r--r--src/server/file_resolve.odin2
-rw-r--r--tests/completions_test.odin32
4 files changed, 74 insertions, 0 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index c482206..d6592ae 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -35,6 +35,8 @@ DocumentPositionContext :: struct {
identifier: ^ast.Node,
label: ^ast.Ident,
implicit_context: ^ast.Implicit,
+ index: ^ast.Index_Expr,
+ previous_index: ^ast.Index_Expr,
tag: ^ast.Node,
field: ^ast.Expr, //used for completion
call: ^ast.Expr, //used for signature help
@@ -4957,6 +4959,8 @@ get_document_position_node :: proc(
get_document_position(n.field, position_context)
}
case ^Index_Expr:
+ position_context.previous_index = position_context.index
+ position_context.index = n
get_document_position(n.expr, position_context)
get_document_position(n.index, position_context)
case ^Deref_Expr:
diff --git a/src/server/completion.odin b/src/server/completion.odin
index 2e5689f..a863d5c 100644
--- a/src/server/completion.odin
+++ b/src/server/completion.odin
@@ -1283,6 +1283,42 @@ get_implicit_completion :: proc(
}
}
}
+
+ if position_context.index != nil {
+ symbol: Symbol
+ ok := false
+ if position_context.previous_index != nil {
+ symbol, ok = resolve_type_expression(
+ ast_context,
+ position_context.previous_index,
+ )
+ if !ok {
+ return
+ }
+ } else {
+ symbol, ok = resolve_type_expression(
+ ast_context,
+ position_context.index.expr,
+ )
+ }
+
+ if array, ok := symbol.value.(SymbolFixedArrayValue); ok {
+ if enum_value, ok := unwrap_enum(ast_context, array.len); ok {
+ for name in enum_value.names {
+ item := CompletionItem {
+ label = name,
+ kind = .EnumMember,
+ detail = name,
+ }
+
+ append(&items, item)
+ }
+
+ list.items = items[:]
+ return
+ }
+ }
+ }
}
get_identifier_completion :: proc(
diff --git a/src/server/file_resolve.odin b/src/server/file_resolve.odin
index 64bdd56..39186de 100644
--- a/src/server/file_resolve.odin
+++ b/src/server/file_resolve.odin
@@ -32,6 +32,8 @@ reset_position_context :: proc(position_context: ^DocumentPositionContext) {
position_context.call = nil
position_context.binary = nil
position_context.parent_binary = nil
+ position_context.previous_index = nil
+ position_context.index = nil
}
resolve_entire_file :: proc(
diff --git a/tests/completions_test.odin b/tests/completions_test.odin
index ea7a8ab..60e7070 100644
--- a/tests/completions_test.odin
+++ b/tests/completions_test.odin
@@ -2846,3 +2846,35 @@ ast_generics_function_with_comp_lit_struct :: proc(t: ^testing.T) {
},
)
}
+
+@(test)
+ast_enumerated_array_index_completion :: proc(t: ^testing.T) {
+ source := test.Source {
+ main = `package main
+ Direction :: enum {
+ North,
+ East,
+ South,
+ West,
+ }
+
+ Direction_Vectors :: [Direction][2]int {
+ .North = {0, -1},
+ .East = {+1, 0},
+ .South = {0, +1},
+ .West = {-1, 0},
+ }
+
+ main :: proc() {
+ Direction_Vectors[.{*}]
+ }
+ `,
+ }
+
+ test.expect_completion_labels(
+ t,
+ &source,
+ ".",
+ {"North", "East", "South", "West"},
+ )
+}