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)
|
||||||
.pointer_payload = .{
|
.{
|
||||||
.name = name_token,
|
.array_payload = .{
|
||||||
.condition = while_node.ast.cond_expr,
|
.identifier = name_token,
|
||||||
},
|
.array_expr = while_node.ast.cond_expr,
|
||||||
});
|
},
|
||||||
|
}
|
||||||
|
else
|
||||||
|
.{
|
||||||
|
.pointer_payload = .{
|
||||||
|
.name = name_token,
|
||||||
|
.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