From 123783da820cfa5cd2b230dd910e07005f30ebca Mon Sep 17 00:00:00 2001 From: Daniel Gavin Date: Mon, 14 Mar 2022 21:41:04 +0100 Subject: Fix union completion with pointers. --- src/common/ast.odin | 13 +++++++------ src/server/completion.odin | 23 ++++++++++------------- tests/completions_test.odin | 31 ++++++++++++++++++++++++++++--- 3 files changed, 45 insertions(+), 22 deletions(-) diff --git a/src/common/ast.odin b/src/common/ast.odin index 05c651f..34cbd4b 100644 --- a/src/common/ast.odin +++ b/src/common/ast.odin @@ -495,7 +495,6 @@ free_ast_node :: proc(node: ^ast.Node, allocator: mem.Allocator) { } free_ast_file :: proc(file: ast.File, allocator := context.allocator) { - for decl in file.decls { free_ast(decl, allocator) } @@ -518,7 +517,6 @@ node_equal :: proc{ } node_equal_array :: proc(a, b: $A/[]^$T) -> bool { - ret := true if len(a) != len(b) { @@ -533,7 +531,6 @@ node_equal_array :: proc(a, b: $A/[]^$T) -> bool { } node_equal_dynamic_array :: proc(a, b: $A/[dynamic]^$T) -> bool { - ret := true if len(a) != len(b) { @@ -707,7 +704,6 @@ node_equal_node :: proc(a, b: ^ast.Node) -> bool { Returns the string representation of a type. This allows us to print the signature without storing it in the indexer as a string(saving memory). */ node_to_string :: proc(node: ^ast.Node) -> string { - builder := strings.make_builder(context.temp_allocator) build_string(node, &builder) @@ -722,14 +718,12 @@ build_string :: proc{ } build_string_dynamic_array :: proc(array: $A/[]^$T, builder: ^strings.Builder) { - for elem, i in array { build_string(elem, builder) } } build_string_ast_array :: proc(array: $A/[dynamic]^$T, builder: ^strings.Builder) { - for elem, i in array { build_string(elem, builder) } @@ -908,3 +902,10 @@ build_string_node :: proc(node: ^ast.Node, builder: ^strings.Builder) { build_string(n.value, builder) } } + +repeat :: proc(value: string, count: int, allocator := context.allocator) -> string { + if count == 0 { + return "" + } + return strings.repeat(value, count, allocator) +} diff --git a/src/server/completion.odin b/src/server/completion.odin index 8d6d93a..6e67e35 100644 --- a/src/server/completion.odin +++ b/src/server/completion.odin @@ -363,9 +363,9 @@ get_selector_completion :: proc(ast_context: ^analysis.AstContext, position_cont } if symbol.pkg == ast_context.document_package || base == "runtime" { - item.label = fmt.aprintf("(%v)", common.node_to_string(type)) + item.label = fmt.aprintf("(%v%v)", common.repeat("^", symbol.pointers, context.temp_allocator), symbol.name) } else { - item.label = fmt.aprintf("(%v.%v)", path.base(symbol.pkg, false, context.temp_allocator), common.node_to_string(type)) + item.label = fmt.aprintf("(%v%v.%v)", common.repeat("^", symbol.pointers, context.temp_allocator), path.base(symbol.pkg, false, context.temp_allocator), symbol.name) } append(&items, item) @@ -1168,23 +1168,20 @@ get_type_switch_completion :: proc(ast_context: ^analysis.AstContext, position_c if assign, ok := position_context.switch_type_stmt.tag.derived.(^ast.Assign_Stmt); ok && assign.rhs != nil && len(assign.rhs) == 1 { if union_value, ok := unwrap_union(ast_context, assign.rhs[0]); ok { for type, i in union_value.types { - name := common.node_to_string(type) - - if name in used_unions { - continue - } - if symbol, ok := resolve_type_expression(ast_context, union_value.types[i]); ok { + name := symbol.name + if name in used_unions { + continue + } + item := CompletionItem { kind = .EnumMember, } - + if symbol.pkg == ast_context.document_package { - item.label = fmt.aprintf("%v", common.node_to_string(union_value.types[i])) - item.detail = item.label + item.label = fmt.aprintf("%v%v", common.repeat("^", symbol.pointers, context.temp_allocator), name) } else { - item.label = fmt.aprintf("%v.%v", path.base(symbol.pkg, false, context.temp_allocator), name) - item.detail = item.label + item.label = fmt.aprintf("%v%v.%v", common.repeat("^", symbol.pointers, context.temp_allocator), path.base(symbol.pkg, false, context.temp_allocator), name) } append(&items, item) diff --git a/tests/completions_test.odin b/tests/completions_test.odin index 3655b42..70fc965 100644 --- a/tests/completions_test.odin +++ b/tests/completions_test.odin @@ -1063,11 +1063,36 @@ ast_implicit_mixed_named_and_unnamed_comp_lit_bitset :: proc(t: ^testing.T) { } } `, - }; + } test.expect_completion_details(t, &source, ".", {"A", "B", "C"}); } +@(test) +ast_comp_lit_in_complit_completion :: proc(t: ^testing.T) { + source := test.Source { + main = `package main + My_Struct_2 :: struct { + aaa: int, + aab: int, + } + My_Struct :: struct { + foo: My_Struct_2, + } + + main :: proc() { + inst := My_Struct { + foo = { + a* + } + } + } + `, + } + + test.expect_completion_details(t, &source, "", {"My_Struct_2.aab: int", "My_Struct_2.aaa: int"}) +} + @(test) ast_inlined_struct :: proc(t: ^testing.T) { source := test.Source { @@ -1084,9 +1109,9 @@ ast_inlined_struct :: proc(t: ^testing.T) { inst.foo.* } `, - }; + } - test.expect_completion_details(t, &source, ".", {"struct.a: int", "struct.b: int"}); + test.expect_completion_details(t, &source, ".", {"struct.a: int", "struct.b: int"}) } @(test) -- cgit v1.2.3