aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/analysis.odin41
-rw-r--r--src/server/completion.odin74
-rw-r--r--tests/completions_test.odin25
-rw-r--r--tests/definition_test.odin30
4 files changed, 123 insertions, 47 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index 2e3839c..e3857c1 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -1690,10 +1690,43 @@ resolve_comp_literal :: proc(
symbol: Symbol,
ok: bool,
) {
- symbol = resolve_type_expression(
- ast_context,
- position_context.parent_comp_lit.type,
- ) or_return
+ if position_context.parent_comp_lit.type != nil {
+ symbol = resolve_type_expression(
+ ast_context,
+ position_context.parent_comp_lit.type,
+ ) or_return
+ } else if position_context.call != nil {
+ if call_expr, ok := position_context.call.derived.(^ast.Call_Expr);
+ ok {
+ arg_index := 0
+ for arg, i in call_expr.args {
+ if position_in_node(arg, position_context.position) {
+ arg_index = i
+ break
+ }
+ }
+
+ symbol = resolve_type_expression(
+ ast_context,
+ position_context.call,
+ ) or_return
+
+ value := symbol.value.(SymbolProcedureValue) or_return
+
+ if len(value.arg_types) <= arg_index {
+ return {}, false
+ }
+
+ if value.arg_types[arg_index].type == nil {
+ return {}, false
+ }
+
+ symbol = resolve_type_expression(
+ ast_context,
+ value.arg_types[arg_index].type,
+ ) or_return
+ }
+ }
symbol, _ = resolve_type_comp_literal(
ast_context,
diff --git a/src/server/completion.odin b/src/server/completion.odin
index 2f5c1ce..eb83432 100644
--- a/src/server/completion.odin
+++ b/src/server/completion.odin
@@ -222,57 +222,45 @@ get_comp_lit_completion :: proc(
) {
items := make([dynamic]CompletionItem, context.temp_allocator)
- if position_context.parent_comp_lit.type == nil {
- return
- }
- if symbol, ok := resolve_type_expression(
- ast_context,
- position_context.parent_comp_lit.type,
- ); ok {
- if comp_symbol, _, ok := resolve_type_comp_literal(
- ast_context,
- position_context,
- symbol,
- position_context.parent_comp_lit,
- ); ok {
- ast_context.current_package = comp_symbol.pkg
- #partial switch v in comp_symbol.value {
- case SymbolStructValue:
- for name, i in v.names {
- if name == "_" {
+ if symbol, ok := resolve_comp_literal(ast_context, position_context); ok {
+ //ast_context.current_package = comp_symbol.pkg
+ #partial switch v in symbol.value {
+ case SymbolStructValue:
+ for name, i in v.names {
+ if name == "_" {
+ continue
+ }
+
+ ast_context.current_package = symbol.pkg
+
+ if resolved, ok := resolve_type_expression(
+ ast_context,
+ v.types[i],
+ ); ok {
+ if field_exists_in_comp_lit(
+ position_context.comp_lit,
+ name,
+ ) {
continue
}
- ast_context.current_package = comp_symbol.pkg
-
- if resolved, ok := resolve_type_expression(
- ast_context,
- v.types[i],
- ); ok {
- if field_exists_in_comp_lit(
- position_context.comp_lit,
+ item := CompletionItem {
+ label = name,
+ kind = .Field,
+ detail = fmt.tprintf(
+ "%v.%v: %v",
+ symbol.name,
name,
- ) {
- continue
- }
-
- item := CompletionItem {
- label = name,
- kind = .Field,
- detail = fmt.tprintf(
- "%v.%v: %v",
- comp_symbol.name,
- name,
- common.node_to_string(v.types[i]),
- ),
- documentation = resolved.doc,
- }
-
- append(&items, item)
+ common.node_to_string(v.types[i]),
+ ),
+ documentation = resolved.doc,
}
+
+ append(&items, item)
}
}
+
}
}
diff --git a/tests/completions_test.odin b/tests/completions_test.odin
index 0330137..962e944 100644
--- a/tests/completions_test.odin
+++ b/tests/completions_test.odin
@@ -2607,3 +2607,28 @@ ast_poly_proc_matrix_whole :: proc(t: ^testing.T) {
)
}
+
+
+ast_completion_comp_lit_in_proc :: proc(t: ^testing.T) {
+ packages := make([dynamic]test.Package)
+
+ source := test.Source {
+ main = `package test
+ My_Struct :: struct {
+ one: int,
+ two: int,
+ }
+
+ my_function :: proc(my_struct: My_Struct) {
+
+ }
+
+ main :: proc() {
+ my_function({on{*}})
+ }
+ `,
+ packages = {},
+ }
+
+ test.expect_completion_details(t, &source, "", {"My_Struct.one: int"})
+}
diff --git a/tests/definition_test.odin b/tests/definition_test.odin
index 6f4b982..bf9fcd7 100644
--- a/tests/definition_test.odin
+++ b/tests/definition_test.odin
@@ -59,3 +59,33 @@ ast_goto_comp_lit_field_indexed :: proc(t: ^testing.T) {
test.expect_definition_locations(t, &source, {location})
}
+
+@(test)
+ast_goto_untyped_comp_lit_in_proc :: proc(t: ^testing.T) {
+ source := test.Source {
+ main = `package test
+ My_Struct :: struct {
+ one: int,
+ two: int,
+ }
+
+ my_function :: proc(my_struct: My_Struct) {
+
+ }
+
+ main :: proc() {
+ my_function({on{*}e = 2, two = 3})
+ }
+ `,
+ packages = {},
+ }
+
+ location := common.Location {
+ range = {
+ start = {line = 2, character = 4},
+ end = {line = 2, character = 7},
+ },
+ }
+
+ test.expect_definition_locations(t, &source, {location})
+}