Completion for index label in for loops and fix for function snippets
This commit is contained in:
parent
858f3cb282
commit
3ac6c82b9a
@ -104,7 +104,12 @@ pub fn getFunctionSignature(tree: ast.Tree, func: ast.full.FnProto) []const u8 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a function snippet insert text
|
/// Gets a function snippet insert text
|
||||||
pub fn getFunctionSnippet(allocator: *std.mem.Allocator, tree: ast.Tree, func: ast.full.FnProto, skip_self_param: bool) ![]const u8 {
|
pub fn getFunctionSnippet(
|
||||||
|
allocator: *std.mem.Allocator,
|
||||||
|
tree: ast.Tree,
|
||||||
|
func: ast.full.FnProto,
|
||||||
|
skip_self_param: bool,
|
||||||
|
) ![]const u8 {
|
||||||
const name_index = func.name_token orelse unreachable;
|
const name_index = func.name_token orelse unreachable;
|
||||||
|
|
||||||
var buffer = std.ArrayList(u8).init(allocator);
|
var buffer = std.ArrayList(u8).init(allocator);
|
||||||
@ -118,11 +123,15 @@ pub fn getFunctionSnippet(allocator: *std.mem.Allocator, tree: ast.Tree, func: a
|
|||||||
const token_tags = tree.tokens.items(.tag);
|
const token_tags = tree.tokens.items(.tag);
|
||||||
|
|
||||||
var it = func.iterate(tree);
|
var it = func.iterate(tree);
|
||||||
while (it.next()) |param| {
|
var i: usize = 0;
|
||||||
if (skip_self_param and it.param_i - 1 == 0) continue;
|
while (it.next()) |param| : (i += 1) {
|
||||||
if (it.param_i - 1 != @boolToInt(skip_self_param)) try buffer.appendSlice(", ${") else try buffer.appendSlice("${");
|
if (skip_self_param and i == 0) continue;
|
||||||
|
if (i != @boolToInt(skip_self_param))
|
||||||
|
try buffer.appendSlice(", ${")
|
||||||
|
else
|
||||||
|
try buffer.appendSlice("${");
|
||||||
|
|
||||||
try buf_stream.print("{d}:", .{it.param_i});
|
try buf_stream.print("{d}:", .{i + 1});
|
||||||
|
|
||||||
if (param.comptime_noalias) |token_index| {
|
if (param.comptime_noalias) |token_index| {
|
||||||
if (token_tags[token_index] == .keyword_comptime)
|
if (token_tags[token_index] == .keyword_comptime)
|
||||||
@ -141,7 +150,7 @@ pub fn getFunctionSnippet(allocator: *std.mem.Allocator, tree: ast.Tree, func: a
|
|||||||
try buffer.appendSlice("anytype")
|
try buffer.appendSlice("anytype")
|
||||||
else
|
else
|
||||||
try buffer.appendSlice("...");
|
try buffer.appendSlice("...");
|
||||||
} else {
|
} else if (param.type_expr != 0) {
|
||||||
var curr_token = tree.firstToken(param.type_expr);
|
var curr_token = tree.firstToken(param.type_expr);
|
||||||
var end_token = tree.lastToken(param.type_expr);
|
var end_token = tree.lastToken(param.type_expr);
|
||||||
while (curr_token <= end_token) : (curr_token += 1) {
|
while (curr_token <= end_token) : (curr_token += 1) {
|
||||||
@ -152,7 +161,8 @@ pub fn getFunctionSnippet(allocator: *std.mem.Allocator, tree: ast.Tree, func: a
|
|||||||
try buffer.appendSlice(tree.tokenSlice(curr_token));
|
try buffer.appendSlice(tree.tokenSlice(curr_token));
|
||||||
if (is_comma or tag == .keyword_const) try buffer.append(' ');
|
if (is_comma or tag == .keyword_const) try buffer.append(' ');
|
||||||
}
|
}
|
||||||
}
|
} else unreachable;
|
||||||
|
|
||||||
try buffer.append('}');
|
try buffer.append('}');
|
||||||
}
|
}
|
||||||
try buffer.append(')');
|
try buffer.append(')');
|
||||||
@ -780,13 +790,14 @@ pub fn resolveTypeOfNodeInternal(
|
|||||||
|
|
||||||
// Bind type params to the expressions passed in txhe calls.
|
// Bind type params to the expressions passed in txhe calls.
|
||||||
const param_len = std.math.min(call.ast.params.len + @boolToInt(has_self_param), fn_decl.ast.params.len);
|
const param_len = std.math.min(call.ast.params.len + @boolToInt(has_self_param), fn_decl.ast.params.len);
|
||||||
while (it.next()) |decl_param| {
|
var i: usize = 0;
|
||||||
if (it.param_i - 1 == 0 and has_self_param) continue;
|
while (it.next()) |decl_param| : (i += 1) {
|
||||||
if (it.param_i - 1 >= param_len) break;
|
if (i == 0 and has_self_param) continue;
|
||||||
|
if (i >= param_len) break;
|
||||||
if (!typeIsType(decl.handle.tree, decl_param.type_expr)) continue;
|
if (!typeIsType(decl.handle.tree, decl_param.type_expr)) continue;
|
||||||
|
|
||||||
const call_param_type = (try resolveTypeOfNodeInternal(store, arena, .{
|
const call_param_type = (try resolveTypeOfNodeInternal(store, arena, .{
|
||||||
.node = call.ast.params[it.param_i - 1 - @boolToInt(has_self_param)],
|
.node = call.ast.params[i - @boolToInt(has_self_param)],
|
||||||
.handle = handle,
|
.handle = handle,
|
||||||
}, bound_type_params)) orelse continue;
|
}, bound_type_params)) orelse continue;
|
||||||
if (!call_param_type.type.is_type_val) continue;
|
if (!call_param_type.type.is_type_val) continue;
|
||||||
@ -1921,6 +1932,7 @@ pub const Declaration = union(enum) {
|
|||||||
identifier: ast.TokenIndex,
|
identifier: ast.TokenIndex,
|
||||||
array_expr: ast.Node.Index,
|
array_expr: ast.Node.Index,
|
||||||
},
|
},
|
||||||
|
array_index: ast.TokenIndex,
|
||||||
switch_payload: struct {
|
switch_payload: struct {
|
||||||
node: ast.TokenIndex,
|
node: ast.TokenIndex,
|
||||||
switch_expr: ast.Node.Index,
|
switch_expr: ast.Node.Index,
|
||||||
@ -1941,6 +1953,7 @@ pub const DeclWithHandle = struct {
|
|||||||
.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,
|
.array_payload => |ap| ap.identifier,
|
||||||
|
.array_index => |ai| ai,
|
||||||
.switch_payload => |sp| sp.node,
|
.switch_payload => |sp| sp.node,
|
||||||
.label_decl => |ld| ld,
|
.label_decl => |ld| ld,
|
||||||
};
|
};
|
||||||
@ -2008,6 +2021,10 @@ pub const DeclWithHandle = struct {
|
|||||||
.Single,
|
.Single,
|
||||||
bound_type_params,
|
bound_type_params,
|
||||||
),
|
),
|
||||||
|
.array_index => TypeWithHandle{
|
||||||
|
.type = .{ .data = .primitive, .is_type_val = true },
|
||||||
|
.handle = self.handle,
|
||||||
|
},
|
||||||
.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;
|
||||||
@ -2024,7 +2041,7 @@ pub const DeclWithHandle = struct {
|
|||||||
if (scope.decls.getEntry(tree.tokenSlice(main_tokens[pay.items[0]]))) |candidate| {
|
if (scope.decls.getEntry(tree.tokenSlice(main_tokens[pay.items[0]]))) |candidate| {
|
||||||
switch (candidate.value) {
|
switch (candidate.value) {
|
||||||
.ast_node => |node| {
|
.ast_node => |node| {
|
||||||
if (containerField(tree, node)) |container_field| {
|
if (containerField(switch_expr_type.handle.tree, node)) |container_field| {
|
||||||
if (container_field.ast.type_expr != 0) {
|
if (container_field.ast.type_expr != 0) {
|
||||||
return ((try resolveTypeOfNodeInternal(
|
return ((try resolveTypeOfNodeInternal(
|
||||||
store,
|
store,
|
||||||
@ -2919,7 +2936,7 @@ fn makeScopeInternal(
|
|||||||
if (token_tags[name_token + 1] == .comma) {
|
if (token_tags[name_token + 1] == .comma) {
|
||||||
const index_token = name_token + 2;
|
const index_token = name_token + 2;
|
||||||
std.debug.assert(token_tags[index_token] == .identifier);
|
std.debug.assert(token_tags[index_token] == .identifier);
|
||||||
if (try scope.decls.fetchPut(tree.tokenSlice(index_token), .{ .label_decl = index_token })) |existing| {
|
if (try scope.decls.fetchPut(tree.tokenSlice(index_token), .{ .array_index = index_token })) |existing| {
|
||||||
// TODO Record a redefinition error
|
// TODO Record a redefinition error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2955,7 +2972,7 @@ fn makeScopeInternal(
|
|||||||
const extra = tree.extraData(data[node_idx].rhs, ast.Node.SubRange);
|
const extra = tree.extraData(data[node_idx].rhs, ast.Node.SubRange);
|
||||||
const cases = tree.extra_data[extra.start..extra.end];
|
const cases = tree.extra_data[extra.start..extra.end];
|
||||||
|
|
||||||
for(cases)|case| {
|
for (cases) |case| {
|
||||||
const switch_case: ast.full.SwitchCase = switch (tags[case]) {
|
const switch_case: ast.full.SwitchCase = switch (tags[case]) {
|
||||||
.switch_case => tree.switchCase(case),
|
.switch_case => tree.switchCase(case),
|
||||||
.switch_case_one => tree.switchCaseOne(case),
|
.switch_case_one => tree.switchCaseOne(case),
|
||||||
|
12
src/main.zig
12
src/main.zig
@ -391,6 +391,8 @@ fn nodeToCompletion(
|
|||||||
var it = func.iterate(tree);
|
var it = func.iterate(tree);
|
||||||
const param = it.next().?;
|
const param = it.next().?;
|
||||||
|
|
||||||
|
if (param.type_expr == 0) break :param_check false;
|
||||||
|
|
||||||
if (try analysis.resolveTypeOfNode(&document_store, arena, .{
|
if (try analysis.resolveTypeOfNode(&document_store, arena, .{
|
||||||
.node = param.type_expr,
|
.node = param.type_expr,
|
||||||
.handle = handle,
|
.handle = handle,
|
||||||
@ -641,6 +643,10 @@ fn hoverSymbol(
|
|||||||
try std.fmt.allocPrint(&arena.allocator, "```zig\n{s}\n```", .{handle.tree.tokenSlice(payload.identifier)})
|
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)}),
|
try std.fmt.allocPrint(&arena.allocator, "{s}", .{handle.tree.tokenSlice(payload.identifier)}),
|
||||||
|
.array_index => |payload| if (hover_kind == .Markdown)
|
||||||
|
try std.fmt.allocPrint(&arena.allocator, "```zig\n{s}\n```", .{handle.tree.tokenSlice(payload)})
|
||||||
|
else
|
||||||
|
try std.fmt.allocPrint(&arena.allocator, "{s}", .{handle.tree.tokenSlice(payload)}),
|
||||||
.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
|
||||||
@ -957,6 +963,12 @@ fn declToCompletion(context: DeclToCompletionContext, decl_handle: analysis.Decl
|
|||||||
.kind = .Variable,
|
.kind = .Variable,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
.array_index => |payload| {
|
||||||
|
try context.completions.append(.{
|
||||||
|
.label = tree.tokenSlice(payload),
|
||||||
|
.kind = .Variable,
|
||||||
|
});
|
||||||
|
},
|
||||||
.switch_payload => |payload| {
|
.switch_payload => |payload| {
|
||||||
try context.completions.append(.{
|
try context.completions.append(.{
|
||||||
.label = tree.tokenSlice(payload.node),
|
.label = tree.tokenSlice(payload.node),
|
||||||
|
@ -585,7 +585,7 @@ pub fn symbolReferences(
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
.pointer_payload, .switch_payload, .array_payload => {
|
.pointer_payload, .switch_payload, .array_payload, .array_index => {
|
||||||
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