Nested struct init fields completion
This commit is contained in:
parent
55b1aeb6f7
commit
735f884394
@ -821,7 +821,7 @@ fn completeDot(server: *Server, handle: *const DocumentStore.Handle, source_inde
|
||||
}
|
||||
|
||||
// iterate until we find current token loc (should be a .period)
|
||||
while (upper_index > 1) : (upper_index -= 1) {
|
||||
while (upper_index > 0) : (upper_index -= 1) {
|
||||
if (tokens_start[upper_index] > source_index) continue;
|
||||
upper_index -= 1;
|
||||
break;
|
||||
@ -829,26 +829,38 @@ fn completeDot(server: *Server, handle: *const DocumentStore.Handle, source_inde
|
||||
|
||||
const token_tags = tree.tokens.items(.tag);
|
||||
|
||||
// look for an .l_brace (but don't extend past a .semicolon or .r_brace)
|
||||
while (upper_index != 0 and token_tags[upper_index] != .l_brace) {
|
||||
if (token_tags[upper_index] == .semicolon or token_tags[upper_index] == .r_brace) break :struct_init;
|
||||
if (token_tags[upper_index] == .number_literal) break :struct_init; // `var s = MyStruct{.float_field = 1.`
|
||||
|
||||
// look for .identifier followed by .l_brace, skipping matches at depth 0+
|
||||
var depth: i32 = 0; // Should end up being negative, ie even the first/single .l_brace would put it at -1; 0+ => nested
|
||||
while (upper_index > 0) {
|
||||
if (token_tags[upper_index] != .identifier) {
|
||||
switch (token_tags[upper_index]) {
|
||||
.r_brace => depth += 1,
|
||||
.l_brace => depth -= 1,
|
||||
.period => if (depth < 0 and token_tags[upper_index + 1] == .l_brace) break :struct_init, // anon struct init `.{.`
|
||||
.semicolon => break :struct_init, // generic exit; maybe also .keyword_(var/const)
|
||||
else => {},
|
||||
}
|
||||
} else if (token_tags[upper_index + 1] == .l_brace and depth < 0) break;
|
||||
upper_index -= 1;
|
||||
}
|
||||
|
||||
// the .l_brace should be preceded by an .identifier
|
||||
if (upper_index == 0 or token_tags[upper_index - 1] != .identifier) {
|
||||
break :struct_init;
|
||||
}
|
||||
if (upper_index == 0) break :struct_init;
|
||||
|
||||
upper_index -= 1; // identifier's index
|
||||
var identifier_loc = offsets.tokenIndexToLoc(tree.source, tokens_start[upper_index]);
|
||||
|
||||
// if this is done as a field access collect all the identifiers, eg `path.to.MyStruct`
|
||||
var identifier_original_start = identifier_loc.start;
|
||||
while ((token_tags[upper_index] == .period or token_tags[upper_index] == .identifier) and upper_index != 0) : (upper_index -= 1) {
|
||||
while ((token_tags[upper_index] == .period or token_tags[upper_index] == .identifier) and upper_index > 0) : (upper_index -= 1) {
|
||||
identifier_loc.start = tokens_start[upper_index];
|
||||
}
|
||||
|
||||
// token_tags[upper_index + 1] should be .identifier, else => there are potentially more tokens, eg
|
||||
// the `@import("my_file.zig")` in `var s = @import("my_file.zig").MyStruct{.`, which getSymbolFieldAccesses can(?) handle
|
||||
// but it could be some other combo of tokens.. potential TODO
|
||||
if (token_tags[upper_index + 1] != .identifier) break :struct_init;
|
||||
|
||||
var completions = std.ArrayListUnmanaged(types.CompletionItem){};
|
||||
|
||||
if (identifier_loc.start != identifier_original_start) { // path.to.MyStruct{.<cursor> => use field access resolution
|
||||
|
Loading…
Reference in New Issue
Block a user