Merge pull request #1116 from nullptrdevs/nested-struct-init
Nested struct init fields completion
This commit is contained in:
		
						commit
						7978485aaf
					
				@ -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)
 | 
					        // 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;
 | 
					            if (tokens_start[upper_index] > source_index) continue;
 | 
				
			||||||
            upper_index -= 1;
 | 
					            upper_index -= 1;
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
@ -829,26 +829,38 @@ fn completeDot(server: *Server, handle: *const DocumentStore.Handle, source_inde
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        const token_tags = tree.tokens.items(.tag);
 | 
					        const token_tags = tree.tokens.items(.tag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // look for an .l_brace (but don't extend past a .semicolon or .r_brace)
 | 
					        if (token_tags[upper_index] == .number_literal) break :struct_init; // `var s = MyStruct{.float_field = 1.`
 | 
				
			||||||
        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;
 | 
					        // 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;
 | 
					            upper_index -= 1;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // the .l_brace should be preceded by an .identifier
 | 
					        if (upper_index == 0) break :struct_init;
 | 
				
			||||||
        if (upper_index == 0 or token_tags[upper_index - 1] != .identifier) {
 | 
					 | 
				
			||||||
            break :struct_init;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        upper_index -= 1; // identifier's index
 | 
					 | 
				
			||||||
        var identifier_loc = offsets.tokenIndexToLoc(tree.source, tokens_start[upper_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`
 | 
					        // if this is done as a field access collect all the identifiers, eg `path.to.MyStruct`
 | 
				
			||||||
        var identifier_original_start = identifier_loc.start;
 | 
					        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];
 | 
					            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){};
 | 
					        var completions = std.ArrayListUnmanaged(types.CompletionItem){};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (identifier_loc.start != identifier_original_start) { // path.to.MyStruct{.<cursor> => use field access resolution
 | 
					        if (identifier_loc.start != identifier_original_start) { // path.to.MyStruct{.<cursor> => use field access resolution
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user