Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
206 changes: 113 additions & 93 deletions src/server/completion.odin
Original file line number Diff line number Diff line change
Expand Up @@ -772,99 +772,7 @@ get_selector_completion :: proc(
case SymbolFixedArrayValue:
is_incomplete = true
append_magic_array_like_completion(position_context, selector, results)

containsColor := 1
containsCoord := 1

expr_len := 0

if v.len != nil {
if basic, ok := v.len.derived.(^ast.Basic_Lit); ok {
if expr_len, ok = strconv.parse_int(basic.tok.text); !ok {
expr_len = 0
}
}
}

if field != "" {
for i := 0; i < len(field); i += 1 {
c := field[i]
if _, ok := swizzle_color_map[c]; ok {
containsColor += 1
} else if _, ok := swizzle_coord_map[c]; ok {
containsCoord += 1
} else {
return is_incomplete
}
}
}

if containsColor == 1 && containsCoord == 1 {
save := expr_len
for k in swizzle_color_components {
if expr_len <= 0 {
break
}

expr_len -= 1

item := CompletionItem {
label = fmt.tprintf("%v%v", field, k),
kind = .Property,
detail = fmt.tprintf("%v%v: %v", field, k, node_to_string(v.expr)),
}
append(results, CompletionResult{completion_item = item})
}

expr_len = save

for k in swizzle_coord_components {
if expr_len <= 0 {
break
}

expr_len -= 1

item := CompletionItem {
label = fmt.tprintf("%v%v", field, k),
kind = .Property,
detail = fmt.tprintf("%v%v: %v", field, k, node_to_string(v.expr)),
}
append(results, CompletionResult{completion_item = item})
}
}

if containsColor > 1 {
for k in swizzle_color_components {
if expr_len <= 0 {
break
}

expr_len -= 1

item := CompletionItem {
label = fmt.tprintf("%v%v", field, k),
kind = .Property,
detail = fmt.tprintf("%v%v: [%v]%v", field, k, containsColor, node_to_string(v.expr)),
}
append(results, CompletionResult{completion_item = item})
}
} else if containsCoord > 1 {
for k in swizzle_coord_components {
if expr_len <= 0 {
break
}

expr_len -= 1

item := CompletionItem {
label = fmt.tprintf("%v%v", field, k),
kind = .Property,
detail = fmt.tprintf("%v%v: [%v]%v", field, k, containsCoord, node_to_string(v.expr)),
}
append(results, CompletionResult{completion_item = item})
}
}
add_fixed_array_selector_completions(v, field, results)
add_soa_field_completion(ast_context, selector, v.expr, v.len, results, selector.name)
case SymbolUnionValue:
is_incomplete = false
Expand Down Expand Up @@ -971,6 +879,13 @@ get_selector_completion :: proc(
is_incomplete = false
for name, i in v.names {
if name == "_" {
if is_struct_field_using(v, i) {
if symbol, ok := resolve_type_expression(ast_context, v.types[i]); ok {
if value, ok := symbol.value.(SymbolFixedArrayValue); ok {
add_fixed_array_selector_completions(value, field, results)
}
}
}
continue
}

Expand All @@ -991,6 +906,12 @@ get_selector_completion :: proc(

construct_struct_field_symbol(&symbol, selector.name, v, i)
append(results, CompletionResult{symbol = symbol})

if is_struct_field_using(v, i) {
if value, ok := symbol.value.(SymbolFixedArrayValue); ok {
add_fixed_array_selector_completions(value, field, results)
}
}
} else {
//just give some generic symbol with name.
item := CompletionItem {
Expand Down Expand Up @@ -1084,6 +1005,105 @@ get_selector_completion :: proc(
return is_incomplete
}

add_fixed_array_selector_completions :: proc(
v: SymbolFixedArrayValue,
field: string,
results: ^[dynamic]CompletionResult,
) {
containsColor := 1
containsCoord := 1

expr_len := 0

if v.len != nil {
if basic, ok := v.len.derived.(^ast.Basic_Lit); ok {
if expr_len, ok = strconv.parse_int(basic.tok.text); !ok {
expr_len = 0
}
}
}

if field != "" {
for i := 0; i < len(field); i += 1 {
c := field[i]
if _, ok := swizzle_color_map[c]; ok {
containsColor += 1
} else if _, ok := swizzle_coord_map[c]; ok {
containsCoord += 1
} else {
return
}
}
}

if containsColor == 1 && containsCoord == 1 {
save := expr_len
for k in swizzle_color_components {
if expr_len <= 0 {
break
}

expr_len -= 1

item := CompletionItem {
label = fmt.tprintf("%v%v", field, k),
kind = .Property,
detail = fmt.tprintf("%v%v: %v", field, k, node_to_string(v.expr)),
}
append(results, CompletionResult{completion_item = item})
}

expr_len = save

for k in swizzle_coord_components {
if expr_len <= 0 {
break
}

expr_len -= 1

item := CompletionItem {
label = fmt.tprintf("%v%v", field, k),
kind = .Property,
detail = fmt.tprintf("%v%v: %v", field, k, node_to_string(v.expr)),
}
append(results, CompletionResult{completion_item = item})
}
}

if containsColor > 1 {
for k in swizzle_color_components {
if expr_len <= 0 {
break
}

expr_len -= 1

item := CompletionItem {
label = fmt.tprintf("%v%v", field, k),
kind = .Property,
detail = fmt.tprintf("%v%v: [%v]%v", field, k, containsColor, node_to_string(v.expr)),
}
append(results, CompletionResult{completion_item = item})
}
} else if containsCoord > 1 {
for k in swizzle_coord_components {
if expr_len <= 0 {
break
}

expr_len -= 1

item := CompletionItem {
label = fmt.tprintf("%v%v", field, k),
kind = .Property,
detail = fmt.tprintf("%v%v: [%v]%v", field, k, containsCoord, node_to_string(v.expr)),
}
append(results, CompletionResult{completion_item = item})
}
}
}

get_implicit_completion :: proc(
ast_context: ^AstContext,
position_context: ^DocumentPositionContext,
Expand Down
13 changes: 10 additions & 3 deletions src/server/symbol.odin
Original file line number Diff line number Diff line change
Expand Up @@ -412,10 +412,8 @@ write_struct_type :: proc(
}
}
}
s := Symbol{

}

s: Symbol
if _, ok := get_attribute_objc_class_name(attributes); ok {
b.symbol.flags |= {.ObjC}
if get_attribute_objc_is_class_method(attributes) {
Expand Down Expand Up @@ -629,6 +627,15 @@ expand_objc :: proc(ast_context: ^AstContext, b: ^SymbolStructValueBuilder) {
}
}

is_struct_field_using :: proc(v: SymbolStructValue, index: int) -> bool {
for i in v.usings {
if i == index {
return true
}
}
return false
}

get_proc_arg_count :: proc(v: SymbolProcedureValue) -> int {
total := 0
for proc_arg in v.arg_types {
Expand Down
36 changes: 36 additions & 0 deletions tests/completions_test.odin
Original file line number Diff line number Diff line change
Expand Up @@ -5238,3 +5238,39 @@ ast_completion_proc_arg_default_enum_alias :: proc(t: ^testing.T) {
}
test.expect_completion_docs(t, &source, "", {"A", "B"})
}

@(test)
ast_completion_struct_using_anonymous_vector_types :: proc(t: ^testing.T) {
source := test.Source {
main = `package test
Foo :: struct {
using _: [3]f32,
}

main :: proc() {
foo: Foo
foo.{*}
}

`,
}
test.expect_completion_docs(t, &source, "", {"r: f32", "x: f32"})
}

@(test)
ast_completion_struct_using_named_vector_types :: proc(t: ^testing.T) {
source := test.Source {
main = `package test
Foo :: struct {
using bar: [3]f32,
}

main :: proc() {
foo: Foo
foo.{*}
}

`,
}
test.expect_completion_docs(t, &source, "", {"Foo.bar: [3]f32", "r: f32", "x: f32"})
}