Work on completion for unwrapped slices/optionals in loops/ifs
This commit is contained in:
		
							parent
							
								
									fd6b94bcc9
								
							
						
					
					
						commit
						43ebfc7300
					
				@ -595,6 +595,7 @@ fn resolveBracketAccessType(
 | 
				
			|||||||
    const tags = tree.nodes.items(.tag);
 | 
					    const tags = tree.nodes.items(.tag);
 | 
				
			||||||
    const tag = tags[lhs_node];
 | 
					    const tag = tags[lhs_node];
 | 
				
			||||||
    const data = tree.nodes.items(.data)[lhs_node];
 | 
					    const data = tree.nodes.items(.data)[lhs_node];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (tag == .array_type or tag == .array_type_sentinel) {
 | 
					    if (tag == .array_type or tag == .array_type_sentinel) {
 | 
				
			||||||
        if (rhs == .Single)
 | 
					        if (rhs == .Single)
 | 
				
			||||||
            return ((try resolveTypeOfNodeInternal(store, arena, .{
 | 
					            return ((try resolveTypeOfNodeInternal(store, arena, .{
 | 
				
			||||||
@ -605,11 +606,11 @@ fn resolveBracketAccessType(
 | 
				
			|||||||
            .type = .{ .data = .{ .slice = data.rhs }, .is_type_val = false },
 | 
					            .type = .{ .data = .{ .slice = data.rhs }, .is_type_val = false },
 | 
				
			||||||
            .handle = lhs.handle,
 | 
					            .handle = lhs.handle,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
    } else if (isPtrType(tree, lhs_node)) {
 | 
					    } else if (ptrType(tree, lhs_node)) |ptr_type| {
 | 
				
			||||||
        if (tags[data.rhs] == .array_type or tags[data.rhs] == .array_type_sentinel) {
 | 
					        if (ptr_type.size == .Slice) {
 | 
				
			||||||
            if (rhs == .Single) {
 | 
					            if (rhs == .Single) {
 | 
				
			||||||
                return ((try resolveTypeOfNodeInternal(store, arena, .{
 | 
					                return ((try resolveTypeOfNodeInternal(store, arena, .{
 | 
				
			||||||
                    .node = tree.nodes.items(.data)[data.rhs].rhs,
 | 
					                    .node = ptr_type.ast.child_type,
 | 
				
			||||||
                    .handle = lhs.handle,
 | 
					                    .handle = lhs.handle,
 | 
				
			||||||
                }, bound_type_params)) orelse return null).instanceTypeVal();
 | 
					                }, bound_type_params)) orelse return null).instanceTypeVal();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -1321,10 +1322,15 @@ pub fn getFieldAccessType(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                // Can't call a function type, we need a function type instance.
 | 
					                // Can't call a function type, we need a function type instance.
 | 
				
			||||||
                if (current_type.type.is_type_val) return null;
 | 
					                if (current_type.type.is_type_val) return null;
 | 
				
			||||||
 | 
					                const cur_tree = current_type.handle.tree;
 | 
				
			||||||
                var buf: [1]ast.Node.Index = undefined;
 | 
					                var buf: [1]ast.Node.Index = undefined;
 | 
				
			||||||
                if (fnProto(tree, current_type_node, &buf)) |func| {
 | 
					                if (fnProto(cur_tree, current_type_node, &buf)) |func| {
 | 
				
			||||||
                    const has_body = tree.nodes.items(.tag)[current_type_node] == .fn_decl;
 | 
					                    // Check if the function has a body and if so, pass it
 | 
				
			||||||
                    const body = tree.nodes.items(.data)[current_type_node].rhs;
 | 
					                    // so the type can be resolved if it's a generic function returning
 | 
				
			||||||
 | 
					                    // an anonymous struct
 | 
				
			||||||
 | 
					                    const has_body = cur_tree.nodes.items(.tag)[current_type_node] == .fn_decl;
 | 
				
			||||||
 | 
					                    const body = cur_tree.nodes.items(.data)[current_type_node].rhs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if (try resolveReturnType(store, arena, func, current_type.handle, &bound_type_params, if (has_body) body else null)) |ret| {
 | 
					                    if (try resolveReturnType(store, arena, func, current_type.handle, &bound_type_params, if (has_body) body else null)) |ret| {
 | 
				
			||||||
                        current_type = ret;
 | 
					                        current_type = ret;
 | 
				
			||||||
                        // Skip to the right paren
 | 
					                        // Skip to the right paren
 | 
				
			||||||
@ -1911,16 +1917,16 @@ pub const Declaration = union(enum) {
 | 
				
			|||||||
        name: ast.TokenIndex,
 | 
					        name: ast.TokenIndex,
 | 
				
			||||||
        condition: ast.Node.Index,
 | 
					        condition: ast.Node.Index,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    // array_payload: struct {
 | 
					    array_payload: struct {
 | 
				
			||||||
    //     identifier: *ast.Node,
 | 
					        identifier: ast.TokenIndex,
 | 
				
			||||||
    //     array_expr: ast.full.ArrayType,
 | 
					        array_expr: ast.Node.Index,
 | 
				
			||||||
    // },
 | 
					    },
 | 
				
			||||||
    switch_payload: struct {
 | 
					    switch_payload: struct {
 | 
				
			||||||
        node: ast.TokenIndex,
 | 
					        node: ast.TokenIndex,
 | 
				
			||||||
        switch_expr: ast.Node.Index,
 | 
					        switch_expr: ast.Node.Index,
 | 
				
			||||||
        items: []const ast.Node.Index,
 | 
					        items: []const ast.Node.Index,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    label_decl: ast.TokenIndex, // .id is While, For or Block (firstToken will be the label)
 | 
					    label_decl: ast.TokenIndex,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub const DeclWithHandle = struct {
 | 
					pub const DeclWithHandle = struct {
 | 
				
			||||||
@ -1934,7 +1940,7 @@ pub const DeclWithHandle = struct {
 | 
				
			|||||||
            .ast_node => |n| getDeclNameToken(tree, n).?,
 | 
					            .ast_node => |n| getDeclNameToken(tree, n).?,
 | 
				
			||||||
            .param_decl => |p| p.name_token.?,
 | 
					            .param_decl => |p| p.name_token.?,
 | 
				
			||||||
            .pointer_payload => |pp| pp.name,
 | 
					            .pointer_payload => |pp| pp.name,
 | 
				
			||||||
            // .array_payload => |ap| ap.identifier.firstToken(),
 | 
					            .array_payload => |ap| ap.identifier,
 | 
				
			||||||
            .switch_payload => |sp| sp.node + @boolToInt(token_tags[sp.node] == .asterisk),
 | 
					            .switch_payload => |sp| sp.node + @boolToInt(token_tags[sp.node] == .asterisk),
 | 
				
			||||||
            .label_decl => |ld| ld,
 | 
					            .label_decl => |ld| ld,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
@ -1956,9 +1962,13 @@ pub const DeclWithHandle = struct {
 | 
				
			|||||||
        const tree = self.handle.tree;
 | 
					        const tree = self.handle.tree;
 | 
				
			||||||
        const node_tags = tree.nodes.items(.tag);
 | 
					        const node_tags = tree.nodes.items(.tag);
 | 
				
			||||||
        const main_tokens = tree.nodes.items(.main_token);
 | 
					        const main_tokens = tree.nodes.items(.main_token);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        return switch (self.decl.*) {
 | 
					        return switch (self.decl.*) {
 | 
				
			||||||
            .ast_node => |node| try resolveTypeOfNodeInternal(store, arena, .{ .node = node, .handle = self.handle }, bound_type_params),
 | 
					            .ast_node => |node| try resolveTypeOfNodeInternal(
 | 
				
			||||||
 | 
					                store,
 | 
				
			||||||
 | 
					                arena,
 | 
				
			||||||
 | 
					                .{ .node = node, .handle = self.handle },
 | 
				
			||||||
 | 
					                bound_type_params,
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
            .param_decl => |param_decl| {
 | 
					            .param_decl => |param_decl| {
 | 
				
			||||||
                if (typeIsType(self.handle.tree, param_decl.type_expr)) {
 | 
					                if (typeIsType(self.handle.tree, param_decl.type_expr)) {
 | 
				
			||||||
                    var bound_param_it = bound_type_params.iterator();
 | 
					                    var bound_param_it = bound_type_params.iterator();
 | 
				
			||||||
@ -1988,6 +1998,16 @@ pub const DeclWithHandle = struct {
 | 
				
			|||||||
                }, bound_type_params)) orelse return null,
 | 
					                }, bound_type_params)) orelse return null,
 | 
				
			||||||
                bound_type_params,
 | 
					                bound_type_params,
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
 | 
					            .array_payload => |pay| try resolveBracketAccessType(
 | 
				
			||||||
 | 
					                store,
 | 
				
			||||||
 | 
					                arena,
 | 
				
			||||||
 | 
					                (try resolveTypeOfNodeInternal(store, arena, .{
 | 
				
			||||||
 | 
					                    .node = pay.array_expr,
 | 
				
			||||||
 | 
					                    .handle = self.handle,
 | 
				
			||||||
 | 
					                }, bound_type_params)) orelse return null,
 | 
				
			||||||
 | 
					                .Single,
 | 
				
			||||||
 | 
					                bound_type_params,
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
            .label_decl => return null,
 | 
					            .label_decl => return null,
 | 
				
			||||||
            .switch_payload => |pay| {
 | 
					            .switch_payload => |pay| {
 | 
				
			||||||
                if (pay.items.len == 0) return null;
 | 
					                if (pay.items.len == 0) return null;
 | 
				
			||||||
@ -2832,7 +2852,7 @@ fn makeScopeInternal(
 | 
				
			|||||||
        .while_cont,
 | 
					        .while_cont,
 | 
				
			||||||
        .@"for",
 | 
					        .@"for",
 | 
				
			||||||
        .for_simple,
 | 
					        .for_simple,
 | 
				
			||||||
        => {
 | 
					        => |tag| {
 | 
				
			||||||
            const while_node: ast.full.While = switch (node) {
 | 
					            const while_node: ast.full.While = switch (node) {
 | 
				
			||||||
                .@"while" => tree.whileFull(node_idx),
 | 
					                .@"while" => tree.whileFull(node_idx),
 | 
				
			||||||
                .while_simple => tree.whileSimple(node_idx),
 | 
					                .while_simple => tree.whileSimple(node_idx),
 | 
				
			||||||
@ -2841,6 +2861,9 @@ fn makeScopeInternal(
 | 
				
			|||||||
                .for_simple => tree.forSimple(node_idx),
 | 
					                .for_simple => tree.forSimple(node_idx),
 | 
				
			||||||
                else => unreachable,
 | 
					                else => unreachable,
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            const is_for = tag == .@"for" or tag == .for_simple;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (while_node.label_token) |label| {
 | 
					            if (while_node.label_token) |label| {
 | 
				
			||||||
                std.debug.assert(token_tags[label] == .identifier);
 | 
					                std.debug.assert(token_tags[label] == .identifier);
 | 
				
			||||||
                var scope = try scopes.addOne(allocator);
 | 
					                var scope = try scopes.addOne(allocator);
 | 
				
			||||||
@ -2877,12 +2900,29 @@ fn makeScopeInternal(
 | 
				
			|||||||
                std.debug.assert(token_tags[name_token] == .identifier);
 | 
					                std.debug.assert(token_tags[name_token] == .identifier);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                const name = tree.tokenSlice(name_token);
 | 
					                const name = tree.tokenSlice(name_token);
 | 
				
			||||||
                try scope.decls.putNoClobber(name, .{
 | 
					                try scope.decls.putNoClobber(name, if (is_for)
 | 
				
			||||||
 | 
					                    .{
 | 
				
			||||||
 | 
					                        .array_payload = .{
 | 
				
			||||||
 | 
					                            .identifier = name_token,
 | 
				
			||||||
 | 
					                            .array_expr = while_node.ast.cond_expr,
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                    .{
 | 
				
			||||||
                        .pointer_payload = .{
 | 
					                        .pointer_payload = .{
 | 
				
			||||||
                            .name = name_token,
 | 
					                            .name = name_token,
 | 
				
			||||||
                            .condition = while_node.ast.cond_expr,
 | 
					                            .condition = while_node.ast.cond_expr,
 | 
				
			||||||
                        },
 | 
					                        },
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // for loop with index as well
 | 
				
			||||||
 | 
					                if (token_tags[name_token + 1] == .comma) {
 | 
				
			||||||
 | 
					                    const index_token = name_token + 2;
 | 
				
			||||||
 | 
					                    std.debug.assert(token_tags[index_token] == .identifier);
 | 
				
			||||||
 | 
					                    if (try scope.decls.fetchPut(tree.tokenSlice(index_token), .{ .label_decl = index_token })) |existing| {
 | 
				
			||||||
 | 
					                        // TODO Record a redefinition error
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            try makeScopeInternal(allocator, scopes, error_completions, enum_completions, tree, while_node.ast.then_expr);
 | 
					            try makeScopeInternal(allocator, scopes, error_completions, enum_completions, tree, while_node.ast.then_expr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										23
									
								
								src/main.zig
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								src/main.zig
									
									
									
									
									
								
							@ -637,10 +637,10 @@ fn hoverSymbol(
 | 
				
			|||||||
            try std.fmt.allocPrint(&arena.allocator, "```zig\n{s}\n```", .{tree.tokenSlice(payload.name)})
 | 
					            try std.fmt.allocPrint(&arena.allocator, "```zig\n{s}\n```", .{tree.tokenSlice(payload.name)})
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
            try std.fmt.allocPrint(&arena.allocator, "{s}", .{tree.tokenSlice(payload.name)}),
 | 
					            try std.fmt.allocPrint(&arena.allocator, "{s}", .{tree.tokenSlice(payload.name)}),
 | 
				
			||||||
        // .array_payload => |payload| if (hover_kind == .Markdown)
 | 
					        .array_payload => |payload| if (hover_kind == .Markdown)
 | 
				
			||||||
        //     try std.fmt.allocPrint(&arena.allocator, "```zig\n{s}\n```", .{handle.tree.tokenSlice(payload.identifier.firstToken())})
 | 
					            try std.fmt.allocPrint(&arena.allocator, "```zig\n{s}\n```", .{handle.tree.tokenSlice(payload.identifier)})
 | 
				
			||||||
        // else
 | 
					        else
 | 
				
			||||||
        //     try std.fmt.allocPrint(&arena.allocator, "{s}", .{handle.tree.tokenSlice(payload.identifier.firstToken())}),
 | 
					            try std.fmt.allocPrint(&arena.allocator, "{s}", .{handle.tree.tokenSlice(payload.identifier)}),
 | 
				
			||||||
        .switch_payload => |payload| if (hover_kind == .Markdown)
 | 
					        .switch_payload => |payload| if (hover_kind == .Markdown)
 | 
				
			||||||
            try std.fmt.allocPrint(&arena.allocator, "```zig\n{s}\n```", .{tree.tokenSlice(payload.node)})
 | 
					            try std.fmt.allocPrint(&arena.allocator, "```zig\n{s}\n```", .{tree.tokenSlice(payload.node)})
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
@ -935,9 +935,8 @@ fn declToCompletion(context: DeclToCompletionContext, decl_handle: analysis.Decl
 | 
				
			|||||||
            const first_token = param.first_doc_comment orelse
 | 
					            const first_token = param.first_doc_comment orelse
 | 
				
			||||||
                param.comptime_noalias orelse
 | 
					                param.comptime_noalias orelse
 | 
				
			||||||
                param.name_token orelse
 | 
					                param.name_token orelse
 | 
				
			||||||
                param.anytype_ellipsis3 orelse
 | 
					 | 
				
			||||||
                tree.firstToken(param.type_expr);
 | 
					                tree.firstToken(param.type_expr);
 | 
				
			||||||
            const last_token = tree.lastToken(param.type_expr);
 | 
					            const last_token = param.anytype_ellipsis3 orelse tree.lastToken(param.type_expr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            try context.completions.append(.{
 | 
					            try context.completions.append(.{
 | 
				
			||||||
                .label = tree.tokenSlice(param.name_token.?),
 | 
					                .label = tree.tokenSlice(param.name_token.?),
 | 
				
			||||||
@ -952,12 +951,12 @@ fn declToCompletion(context: DeclToCompletionContext, decl_handle: analysis.Decl
 | 
				
			|||||||
                .kind = .Variable,
 | 
					                .kind = .Variable,
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        // .array_payload => |payload| {
 | 
					        .array_payload => |payload| {
 | 
				
			||||||
        //     try context.completions.append(.{
 | 
					            try context.completions.append(.{
 | 
				
			||||||
        //         .label = tree.tokenSlice(payload.identifier.firstToken()),
 | 
					                .label = tree.tokenSlice(payload.identifier),
 | 
				
			||||||
        //         .kind = .Variable,
 | 
					                .kind = .Variable,
 | 
				
			||||||
        //     });
 | 
					            });
 | 
				
			||||||
        // },
 | 
					        },
 | 
				
			||||||
        .switch_payload => |payload| {
 | 
					        .switch_payload => |payload| {
 | 
				
			||||||
            try context.completions.append(.{
 | 
					            try context.completions.append(.{
 | 
				
			||||||
                .label = tree.tokenSlice(tree.firstToken(payload.node)),
 | 
					                .label = tree.tokenSlice(tree.firstToken(payload.node)),
 | 
				
			||||||
 | 
				
			|||||||
@ -585,7 +585,7 @@ pub fn symbolReferences(
 | 
				
			|||||||
                return;
 | 
					                return;
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        .pointer_payload, .switch_payload => {
 | 
					        .pointer_payload, .switch_payload, .array_payload => {
 | 
				
			||||||
            if (include_decl) {
 | 
					            if (include_decl) {
 | 
				
			||||||
                try tokenReference(curr_handle, decl_handle.nameToken(), encoding, context, handler);
 | 
					                try tokenReference(curr_handle, decl_handle.nameToken(), encoding, context, handler);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user