refactor document scope creation with ast.iterateChildren
This commit is contained in:
parent
b958b258a3
commit
6f7f9dab9d
308
src/analysis.zig
308
src/analysis.zig
@ -2615,10 +2615,9 @@ pub fn makeDocumentScope(allocator: std.mem.Allocator, tree: Ast) !DocumentScope
|
|||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.scopes = &document_scope.scopes,
|
.scopes = &document_scope.scopes,
|
||||||
.current_scope = ¤t_scope,
|
.current_scope = ¤t_scope,
|
||||||
.tree = tree,
|
|
||||||
.errors = &document_scope.error_completions,
|
.errors = &document_scope.error_completions,
|
||||||
.enums = &document_scope.enum_completions,
|
.enums = &document_scope.enum_completions,
|
||||||
}, 0);
|
}, tree, 0);
|
||||||
|
|
||||||
return document_scope;
|
return document_scope;
|
||||||
}
|
}
|
||||||
@ -2627,7 +2626,6 @@ const ScopeContext = struct {
|
|||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
scopes: *std.MultiArrayList(Scope),
|
scopes: *std.MultiArrayList(Scope),
|
||||||
current_scope: *Scope.Index,
|
current_scope: *Scope.Index,
|
||||||
tree: Ast,
|
|
||||||
enums: *CompletionSet,
|
enums: *CompletionSet,
|
||||||
errors: *CompletionSet,
|
errors: *CompletionSet,
|
||||||
|
|
||||||
@ -2651,13 +2649,12 @@ const ScopeContext = struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fn makeInnerScope(context: ScopeContext, node_idx: Ast.Node.Index) error{OutOfMemory}!void {
|
fn makeInnerScope(context: ScopeContext, tree: Ast, node_idx: Ast.Node.Index) error{OutOfMemory}!void {
|
||||||
const tracy_zone = tracy.trace(@src());
|
const tracy_zone = tracy.trace(@src());
|
||||||
defer tracy_zone.end();
|
defer tracy_zone.end();
|
||||||
|
|
||||||
const allocator = context.allocator;
|
const allocator = context.allocator;
|
||||||
const scopes = context.scopes;
|
const scopes = context.scopes;
|
||||||
const tree = context.tree;
|
|
||||||
const tags = tree.nodes.items(.tag);
|
const tags = tree.nodes.items(.tag);
|
||||||
|
|
||||||
const scope_index = try context.pushScope(
|
const scope_index = try context.pushScope(
|
||||||
@ -2675,18 +2672,22 @@ fn makeInnerScope(context: ScopeContext, node_idx: Ast.Node.Index) error{OutOfMe
|
|||||||
errdefer uses.deinit(allocator);
|
errdefer uses.deinit(allocator);
|
||||||
|
|
||||||
for (container_decl.ast.members) |decl| {
|
for (container_decl.ast.members) |decl| {
|
||||||
if (tags[decl] == .@"usingnamespace") {
|
try makeScopeInternal(context, tree, decl);
|
||||||
try uses.append(allocator, decl);
|
|
||||||
continue;
|
switch (tags[decl]) {
|
||||||
|
.@"usingnamespace" => {
|
||||||
|
try uses.append(allocator, decl);
|
||||||
|
continue;
|
||||||
|
},
|
||||||
|
.test_decl => {
|
||||||
|
try tests.append(allocator, decl);
|
||||||
|
continue;
|
||||||
|
},
|
||||||
|
else => {},
|
||||||
}
|
}
|
||||||
|
|
||||||
try makeScopeInternal(context, decl);
|
|
||||||
const name = getDeclName(tree, decl) orelse continue;
|
const name = getDeclName(tree, decl) orelse continue;
|
||||||
|
|
||||||
if (tags[decl] == .test_decl) {
|
|
||||||
try tests.append(allocator, decl);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
try scopes.items(.decls)[scope_index].put(allocator, name, .{ .ast_node = decl });
|
try scopes.items(.decls)[scope_index].put(allocator, name, .{ .ast_node = decl });
|
||||||
|
|
||||||
if (container_decl.ast.enum_token != null) {
|
if (container_decl.ast.enum_token != null) {
|
||||||
@ -2713,13 +2714,13 @@ fn makeInnerScope(context: ScopeContext, node_idx: Ast.Node.Index) error{OutOfMe
|
|||||||
|
|
||||||
/// If `node_idx` is a block it's scope index will be returned
|
/// If `node_idx` is a block it's scope index will be returned
|
||||||
/// Otherwise, a new scope will be created that will enclose `node_idx`
|
/// Otherwise, a new scope will be created that will enclose `node_idx`
|
||||||
fn makeBlockScopeInternal(context: ScopeContext, node_idx: Ast.Node.Index) error{OutOfMemory}!?usize {
|
fn makeBlockScopeInternal(context: ScopeContext, tree: Ast, node_idx: Ast.Node.Index) error{OutOfMemory}!?usize {
|
||||||
if (node_idx == 0) return null;
|
if (node_idx == 0) return null;
|
||||||
const tags = context.tree.nodes.items(.tag);
|
const tags = tree.nodes.items(.tag);
|
||||||
|
|
||||||
// if node_idx is a block, the next scope will be a block so we store its index here
|
// if node_idx is a block, the next scope will be a block so we store its index here
|
||||||
const block_scope_index = context.scopes.len;
|
const block_scope_index = context.scopes.len;
|
||||||
try makeScopeInternal(context, node_idx);
|
try makeScopeInternal(context, tree, node_idx);
|
||||||
|
|
||||||
switch (tags[node_idx]) {
|
switch (tags[node_idx]) {
|
||||||
.block,
|
.block,
|
||||||
@ -2732,7 +2733,7 @@ fn makeBlockScopeInternal(context: ScopeContext, node_idx: Ast.Node.Index) error
|
|||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
const new_scope = try context.pushScope(
|
const new_scope = try context.pushScope(
|
||||||
offsets.nodeToLoc(context.tree, node_idx),
|
offsets.nodeToLoc(tree, node_idx),
|
||||||
.other,
|
.other,
|
||||||
);
|
);
|
||||||
context.popScope();
|
context.popScope();
|
||||||
@ -2741,16 +2742,17 @@ fn makeBlockScopeInternal(context: ScopeContext, node_idx: Ast.Node.Index) error
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn makeScopeInternal(context: ScopeContext, node_idx: Ast.Node.Index) error{OutOfMemory}!void {
|
fn makeScopeInternal(context: ScopeContext, tree: Ast, node_idx: Ast.Node.Index) error{OutOfMemory}!void {
|
||||||
if (node_idx == 0) return;
|
if (node_idx == 0) return;
|
||||||
|
|
||||||
const allocator = context.allocator;
|
const allocator = context.allocator;
|
||||||
const scopes = context.scopes;
|
const scopes = context.scopes;
|
||||||
const tree = context.tree;
|
|
||||||
const tags = tree.nodes.items(.tag);
|
const tags = tree.nodes.items(.tag);
|
||||||
const token_tags = tree.tokens.items(.tag);
|
const token_tags = tree.tokens.items(.tag);
|
||||||
const data = tree.nodes.items(.data);
|
const data = tree.nodes.items(.data);
|
||||||
const main_tokens = tree.nodes.items(.main_token);
|
const main_tokens = tree.nodes.items(.main_token);
|
||||||
|
|
||||||
const node_tag = tags[node_idx];
|
const node_tag = tags[node_idx];
|
||||||
|
|
||||||
switch (node_tag) {
|
switch (node_tag) {
|
||||||
@ -2767,9 +2769,7 @@ fn makeScopeInternal(context: ScopeContext, node_idx: Ast.Node.Index) error{OutO
|
|||||||
.tagged_union_two_trailing,
|
.tagged_union_two_trailing,
|
||||||
.tagged_union_enum_tag,
|
.tagged_union_enum_tag,
|
||||||
.tagged_union_enum_tag_trailing,
|
.tagged_union_enum_tag_trailing,
|
||||||
=> {
|
=> try makeInnerScope(context, tree, node_idx),
|
||||||
try makeInnerScope(context, node_idx);
|
|
||||||
},
|
|
||||||
.error_set_decl => {
|
.error_set_decl => {
|
||||||
const scope_index = try context.pushScope(
|
const scope_index = try context.pushScope(
|
||||||
offsets.nodeToLoc(tree, node_idx),
|
offsets.nodeToLoc(tree, node_idx),
|
||||||
@ -2832,7 +2832,7 @@ fn makeScopeInternal(context: ScopeContext, node_idx: Ast.Node.Index) error{OutO
|
|||||||
}
|
}
|
||||||
// Visit parameter types to pick up any error sets and enum
|
// Visit parameter types to pick up any error sets and enum
|
||||||
// completions
|
// completions
|
||||||
try makeScopeInternal(context, param.type_expr);
|
try makeScopeInternal(context, tree, param.type_expr);
|
||||||
param_index += 1;
|
param_index += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2841,11 +2841,11 @@ fn makeScopeInternal(context: ScopeContext, node_idx: Ast.Node.Index) error{OutO
|
|||||||
const return_type_node = data[data[node_idx].lhs].rhs;
|
const return_type_node = data[data[node_idx].lhs].rhs;
|
||||||
|
|
||||||
// Visit the return type
|
// Visit the return type
|
||||||
try makeScopeInternal(context, return_type_node);
|
try makeScopeInternal(context, tree, return_type_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Visit the function body
|
// Visit the function body
|
||||||
try makeScopeInternal(context, data[node_idx].rhs);
|
try makeScopeInternal(context, tree, data[node_idx].rhs);
|
||||||
},
|
},
|
||||||
.block,
|
.block,
|
||||||
.block_semicolon,
|
.block_semicolon,
|
||||||
@ -2884,7 +2884,7 @@ fn makeScopeInternal(context: ScopeContext, node_idx: Ast.Node.Index) error{OutO
|
|||||||
const statements = ast.blockStatements(tree, node_idx, &buffer).?;
|
const statements = ast.blockStatements(tree, node_idx, &buffer).?;
|
||||||
|
|
||||||
for (statements) |idx| {
|
for (statements) |idx| {
|
||||||
try makeScopeInternal(context, idx);
|
try makeScopeInternal(context, tree, idx);
|
||||||
if (tree.fullVarDecl(idx)) |var_decl| {
|
if (tree.fullVarDecl(idx)) |var_decl| {
|
||||||
const name = tree.tokenSlice(var_decl.ast.mut_token + 1);
|
const name = tree.tokenSlice(var_decl.ast.mut_token + 1);
|
||||||
try scopes.items(.decls)[scope_index].put(allocator, name, .{ .ast_node = idx });
|
try scopes.items(.decls)[scope_index].put(allocator, name, .{ .ast_node = idx });
|
||||||
@ -2896,7 +2896,7 @@ fn makeScopeInternal(context: ScopeContext, node_idx: Ast.Node.Index) error{OutO
|
|||||||
=> {
|
=> {
|
||||||
const if_node = ast.fullIf(tree, node_idx).?;
|
const if_node = ast.fullIf(tree, node_idx).?;
|
||||||
|
|
||||||
const then_scope = (try makeBlockScopeInternal(context, if_node.ast.then_expr)).?;
|
const then_scope = (try makeBlockScopeInternal(context, tree, if_node.ast.then_expr)).?;
|
||||||
|
|
||||||
if (if_node.payload_token) |payload| {
|
if (if_node.payload_token) |payload| {
|
||||||
const name_token = payload + @boolToInt(token_tags[payload] == .asterisk);
|
const name_token = payload + @boolToInt(token_tags[payload] == .asterisk);
|
||||||
@ -2911,7 +2911,7 @@ fn makeScopeInternal(context: ScopeContext, node_idx: Ast.Node.Index) error{OutO
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (if_node.ast.else_expr != 0) {
|
if (if_node.ast.else_expr != 0) {
|
||||||
const else_scope = (try makeBlockScopeInternal(context, if_node.ast.else_expr)).?;
|
const else_scope = (try makeBlockScopeInternal(context, tree, if_node.ast.else_expr)).?;
|
||||||
if (if_node.error_token) |err_token| {
|
if (if_node.error_token) |err_token| {
|
||||||
const name = tree.tokenSlice(err_token);
|
const name = tree.tokenSlice(err_token);
|
||||||
try scopes.items(.decls)[else_scope].put(allocator, name, .{ .ast_node = if_node.ast.else_expr });
|
try scopes.items(.decls)[else_scope].put(allocator, name, .{ .ast_node = if_node.ast.else_expr });
|
||||||
@ -2919,9 +2919,9 @@ fn makeScopeInternal(context: ScopeContext, node_idx: Ast.Node.Index) error{OutO
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
.@"catch" => {
|
.@"catch" => {
|
||||||
try makeScopeInternal(context, data[node_idx].lhs);
|
try makeScopeInternal(context, tree, data[node_idx].lhs);
|
||||||
|
|
||||||
const expr_scope = (try makeBlockScopeInternal(context, data[node_idx].rhs)).?;
|
const expr_scope = (try makeBlockScopeInternal(context, tree, data[node_idx].rhs)).?;
|
||||||
|
|
||||||
const catch_token = main_tokens[node_idx] + 2;
|
const catch_token = main_tokens[node_idx] + 2;
|
||||||
if (token_tags.len > catch_token and
|
if (token_tags.len > catch_token and
|
||||||
@ -2939,11 +2939,11 @@ fn makeScopeInternal(context: ScopeContext, node_idx: Ast.Node.Index) error{OutO
|
|||||||
// label_token: inline_token while (cond_expr) |payload_token| : (cont_expr) then_expr else else_expr
|
// label_token: inline_token while (cond_expr) |payload_token| : (cont_expr) then_expr else else_expr
|
||||||
const while_node = ast.fullWhile(tree, node_idx).?;
|
const while_node = ast.fullWhile(tree, node_idx).?;
|
||||||
|
|
||||||
try makeScopeInternal(context, while_node.ast.cond_expr);
|
try makeScopeInternal(context, tree, while_node.ast.cond_expr);
|
||||||
|
|
||||||
const cont_scope = try makeBlockScopeInternal(context, while_node.ast.cont_expr);
|
const cont_scope = try makeBlockScopeInternal(context, tree, while_node.ast.cont_expr);
|
||||||
const then_scope = (try makeBlockScopeInternal(context, while_node.ast.then_expr)).?;
|
const then_scope = (try makeBlockScopeInternal(context, tree, while_node.ast.then_expr)).?;
|
||||||
const else_scope = try makeBlockScopeInternal(context, while_node.ast.else_expr);
|
const else_scope = try makeBlockScopeInternal(context, tree, while_node.ast.else_expr);
|
||||||
|
|
||||||
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);
|
||||||
@ -2993,11 +2993,11 @@ fn makeScopeInternal(context: ScopeContext, node_idx: Ast.Node.Index) error{OutO
|
|||||||
const for_node = ast.fullFor(tree, node_idx).?;
|
const for_node = ast.fullFor(tree, node_idx).?;
|
||||||
|
|
||||||
for (for_node.ast.inputs) |input_node| {
|
for (for_node.ast.inputs) |input_node| {
|
||||||
try makeScopeInternal(context, input_node);
|
try makeScopeInternal(context, tree, input_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
const then_scope = (try makeBlockScopeInternal(context, for_node.ast.then_expr)).?;
|
const then_scope = (try makeBlockScopeInternal(context, tree, for_node.ast.then_expr)).?;
|
||||||
const else_scope = try makeBlockScopeInternal(context, for_node.ast.else_expr);
|
const else_scope = try makeBlockScopeInternal(context, tree, for_node.ast.else_expr);
|
||||||
|
|
||||||
var capture_token = for_node.payload_token;
|
var capture_token = for_node.payload_token;
|
||||||
for (for_node.ast.inputs) |input| {
|
for (for_node.ast.inputs) |input| {
|
||||||
@ -3042,7 +3042,7 @@ fn makeScopeInternal(context: ScopeContext, node_idx: Ast.Node.Index) error{OutO
|
|||||||
const switch_case: Ast.full.SwitchCase = tree.fullSwitchCase(case).?;
|
const switch_case: Ast.full.SwitchCase = tree.fullSwitchCase(case).?;
|
||||||
|
|
||||||
if (switch_case.payload_token) |payload| {
|
if (switch_case.payload_token) |payload| {
|
||||||
const expr_index = (try makeBlockScopeInternal(context, switch_case.ast.target_expr)).?;
|
const expr_index = (try makeBlockScopeInternal(context, tree, switch_case.ast.target_expr)).?;
|
||||||
// if payload is *name than get next token
|
// if payload is *name than get next token
|
||||||
const name_token = payload + @boolToInt(token_tags[payload] == .asterisk);
|
const name_token = payload + @boolToInt(token_tags[payload] == .asterisk);
|
||||||
const name = tree.tokenSlice(name_token);
|
const name = tree.tokenSlice(name_token);
|
||||||
@ -3055,132 +3055,14 @@ fn makeScopeInternal(context: ScopeContext, node_idx: Ast.Node.Index) error{OutO
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
try makeScopeInternal(context, switch_case.ast.target_expr);
|
try makeScopeInternal(context, tree, switch_case.ast.target_expr);
|
||||||
} else {
|
} else {
|
||||||
try makeScopeInternal(context, switch_case.ast.target_expr);
|
try makeScopeInternal(context, tree, switch_case.ast.target_expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.global_var_decl,
|
|
||||||
.local_var_decl,
|
|
||||||
.aligned_var_decl,
|
|
||||||
.simple_var_decl,
|
|
||||||
=> {
|
|
||||||
const var_decl = tree.fullVarDecl(node_idx).?;
|
|
||||||
if (var_decl.ast.type_node != 0) {
|
|
||||||
try makeScopeInternal(context, var_decl.ast.type_node);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (var_decl.ast.init_node != 0) {
|
|
||||||
try makeScopeInternal(context, var_decl.ast.init_node);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
.call,
|
|
||||||
.call_comma,
|
|
||||||
.call_one,
|
|
||||||
.call_one_comma,
|
|
||||||
.async_call,
|
|
||||||
.async_call_comma,
|
|
||||||
.async_call_one,
|
|
||||||
.async_call_one_comma,
|
|
||||||
=> {
|
|
||||||
var buf: [1]Ast.Node.Index = undefined;
|
|
||||||
const call = tree.fullCall(&buf, node_idx).?;
|
|
||||||
|
|
||||||
try makeScopeInternal(context, call.ast.fn_expr);
|
|
||||||
for (call.ast.params) |param|
|
|
||||||
try makeScopeInternal(context, param);
|
|
||||||
},
|
|
||||||
.struct_init,
|
|
||||||
.struct_init_comma,
|
|
||||||
.struct_init_dot,
|
|
||||||
.struct_init_dot_comma,
|
|
||||||
.struct_init_dot_two,
|
|
||||||
.struct_init_dot_two_comma,
|
|
||||||
.struct_init_one,
|
|
||||||
.struct_init_one_comma,
|
|
||||||
=> {
|
|
||||||
var buf: [2]Ast.Node.Index = undefined;
|
|
||||||
const struct_init: Ast.full.StructInit = tree.fullStructInit(&buf, node_idx).?;
|
|
||||||
|
|
||||||
if (struct_init.ast.type_expr != 0)
|
|
||||||
try makeScopeInternal(context, struct_init.ast.type_expr);
|
|
||||||
|
|
||||||
for (struct_init.ast.fields) |field| {
|
|
||||||
try makeScopeInternal(context, field);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
.array_init,
|
|
||||||
.array_init_comma,
|
|
||||||
.array_init_dot,
|
|
||||||
.array_init_dot_comma,
|
|
||||||
.array_init_dot_two,
|
|
||||||
.array_init_dot_two_comma,
|
|
||||||
.array_init_one,
|
|
||||||
.array_init_one_comma,
|
|
||||||
=> {
|
|
||||||
var buf: [2]Ast.Node.Index = undefined;
|
|
||||||
const array_init: Ast.full.ArrayInit = tree.fullArrayInit(&buf, node_idx).?;
|
|
||||||
|
|
||||||
if (array_init.ast.type_expr != 0)
|
|
||||||
try makeScopeInternal(context, array_init.ast.type_expr);
|
|
||||||
for (array_init.ast.elements) |elem| {
|
|
||||||
try makeScopeInternal(context, elem);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
.container_field,
|
|
||||||
.container_field_align,
|
|
||||||
.container_field_init,
|
|
||||||
=> {
|
|
||||||
const field = tree.fullContainerField(node_idx).?;
|
|
||||||
|
|
||||||
try makeScopeInternal(context, field.ast.type_expr);
|
|
||||||
try makeScopeInternal(context, field.ast.align_expr);
|
|
||||||
try makeScopeInternal(context, field.ast.value_expr);
|
|
||||||
},
|
|
||||||
.builtin_call,
|
|
||||||
.builtin_call_comma,
|
|
||||||
.builtin_call_two,
|
|
||||||
.builtin_call_two_comma,
|
|
||||||
=> {
|
|
||||||
var buffer: [2]Ast.Node.Index = undefined;
|
|
||||||
const params = ast.builtinCallParams(tree, node_idx, &buffer).?;
|
|
||||||
|
|
||||||
for (params) |param| {
|
|
||||||
try makeScopeInternal(context, param);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
.ptr_type,
|
|
||||||
.ptr_type_aligned,
|
|
||||||
.ptr_type_bit_range,
|
|
||||||
.ptr_type_sentinel,
|
|
||||||
=> {
|
|
||||||
const ptr_type: Ast.full.PtrType = ast.fullPtrType(tree, node_idx).?;
|
|
||||||
|
|
||||||
try makeScopeInternal(context, ptr_type.ast.sentinel);
|
|
||||||
try makeScopeInternal(context, ptr_type.ast.align_node);
|
|
||||||
try makeScopeInternal(context, ptr_type.ast.child_type);
|
|
||||||
},
|
|
||||||
.array_type_sentinel => {
|
|
||||||
const array_type: Ast.full.ArrayType = tree.fullArrayType(node_idx).?;
|
|
||||||
|
|
||||||
try makeScopeInternal(context, array_type.ast.elem_count);
|
|
||||||
try makeScopeInternal(context, array_type.ast.elem_type);
|
|
||||||
try makeScopeInternal(context, array_type.ast.sentinel);
|
|
||||||
},
|
|
||||||
.slice,
|
|
||||||
.slice_open,
|
|
||||||
.slice_sentinel,
|
|
||||||
=> {
|
|
||||||
const slice: Ast.full.Slice = tree.fullSlice(node_idx).?;
|
|
||||||
|
|
||||||
try makeScopeInternal(context, slice.ast.sliced);
|
|
||||||
try makeScopeInternal(context, slice.ast.start);
|
|
||||||
try makeScopeInternal(context, slice.ast.end);
|
|
||||||
try makeScopeInternal(context, slice.ast.sentinel);
|
|
||||||
},
|
|
||||||
.@"errdefer" => {
|
.@"errdefer" => {
|
||||||
const expr_scope = (try makeBlockScopeInternal(context, data[node_idx].rhs)).?;
|
const expr_scope = (try makeBlockScopeInternal(context, tree, data[node_idx].rhs)).?;
|
||||||
|
|
||||||
const payload_token = data[node_idx].lhs;
|
const payload_token = data[node_idx].lhs;
|
||||||
if (payload_token != 0) {
|
if (payload_token != 0) {
|
||||||
@ -3188,112 +3070,8 @@ fn makeScopeInternal(context: ScopeContext, node_idx: Ast.Node.Index) error{OutO
|
|||||||
try scopes.items(.decls)[expr_scope].putNoClobber(allocator, name, .{ .ast_node = data[node_idx].rhs });
|
try scopes.items(.decls)[expr_scope].putNoClobber(allocator, name, .{ .ast_node = data[node_idx].rhs });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
else => {
|
||||||
.switch_case,
|
try ast.iterateChildren(tree, node_idx, context, error{OutOfMemory}, makeScopeInternal);
|
||||||
.switch_case_inline,
|
|
||||||
.switch_case_one,
|
|
||||||
.switch_case_inline_one,
|
|
||||||
.@"asm",
|
|
||||||
.asm_simple,
|
|
||||||
.asm_output,
|
|
||||||
.asm_input,
|
|
||||||
.error_value,
|
|
||||||
.multiline_string_literal,
|
|
||||||
.string_literal,
|
|
||||||
.enum_literal,
|
|
||||||
.identifier,
|
|
||||||
.anyframe_literal,
|
|
||||||
.char_literal,
|
|
||||||
.number_literal,
|
|
||||||
.unreachable_literal,
|
|
||||||
.@"continue",
|
|
||||||
=> {},
|
|
||||||
|
|
||||||
.test_decl,
|
|
||||||
.@"break",
|
|
||||||
.@"defer",
|
|
||||||
.anyframe_type,
|
|
||||||
=> {
|
|
||||||
try makeScopeInternal(context, data[node_idx].rhs);
|
|
||||||
},
|
|
||||||
|
|
||||||
.@"return",
|
|
||||||
.@"resume",
|
|
||||||
.field_access,
|
|
||||||
.@"suspend",
|
|
||||||
.deref,
|
|
||||||
.@"try",
|
|
||||||
.@"await",
|
|
||||||
.optional_type,
|
|
||||||
.@"comptime",
|
|
||||||
.@"nosuspend",
|
|
||||||
.bool_not,
|
|
||||||
.negation,
|
|
||||||
.bit_not,
|
|
||||||
.negation_wrap,
|
|
||||||
.address_of,
|
|
||||||
.grouped_expression,
|
|
||||||
.unwrap_optional,
|
|
||||||
.@"usingnamespace",
|
|
||||||
=> {
|
|
||||||
try makeScopeInternal(context, data[node_idx].lhs);
|
|
||||||
},
|
|
||||||
|
|
||||||
.equal_equal,
|
|
||||||
.bang_equal,
|
|
||||||
.less_than,
|
|
||||||
.greater_than,
|
|
||||||
.less_or_equal,
|
|
||||||
.greater_or_equal,
|
|
||||||
.assign_mul,
|
|
||||||
.assign_div,
|
|
||||||
.assign_mod,
|
|
||||||
.assign_add,
|
|
||||||
.assign_sub,
|
|
||||||
.assign_shl,
|
|
||||||
.assign_shr,
|
|
||||||
.assign_bit_and,
|
|
||||||
.assign_bit_xor,
|
|
||||||
.assign_bit_or,
|
|
||||||
.assign_mul_wrap,
|
|
||||||
.assign_add_wrap,
|
|
||||||
.assign_sub_wrap,
|
|
||||||
.assign_mul_sat,
|
|
||||||
.assign_add_sat,
|
|
||||||
.assign_sub_sat,
|
|
||||||
.assign_shl_sat,
|
|
||||||
.assign,
|
|
||||||
.merge_error_sets,
|
|
||||||
.mul,
|
|
||||||
.div,
|
|
||||||
.mod,
|
|
||||||
.array_mult,
|
|
||||||
.mul_wrap,
|
|
||||||
.mul_sat,
|
|
||||||
.add,
|
|
||||||
.sub,
|
|
||||||
.array_cat,
|
|
||||||
.add_wrap,
|
|
||||||
.sub_wrap,
|
|
||||||
.add_sat,
|
|
||||||
.sub_sat,
|
|
||||||
.shl,
|
|
||||||
.shl_sat,
|
|
||||||
.shr,
|
|
||||||
.bit_and,
|
|
||||||
.bit_xor,
|
|
||||||
.bit_or,
|
|
||||||
.@"orelse",
|
|
||||||
.bool_and,
|
|
||||||
.bool_or,
|
|
||||||
.array_type,
|
|
||||||
.array_access,
|
|
||||||
.error_union,
|
|
||||||
.for_range,
|
|
||||||
.switch_range,
|
|
||||||
=> {
|
|
||||||
try makeScopeInternal(context, data[node_idx].lhs);
|
|
||||||
try makeScopeInternal(context, data[node_idx].rhs);
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -463,6 +463,16 @@ test "completion - usingnamespace" {
|
|||||||
// TODO private should not be visible
|
// TODO private should not be visible
|
||||||
.{ .label = "private", .kind = .Function, .detail = "fn private() !void" },
|
.{ .label = "private", .kind = .Function, .detail = "fn private() !void" },
|
||||||
});
|
});
|
||||||
|
try testCompletion(
|
||||||
|
\\const S1 = struct {
|
||||||
|
\\ usingnamespace struct {
|
||||||
|
\\ pub fn inner() void {}
|
||||||
|
\\ };
|
||||||
|
\\};
|
||||||
|
\\const foo = S1.<cursor>
|
||||||
|
, &.{
|
||||||
|
.{ .label = "inner", .kind = .Function, .detail = "fn inner() void" },
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
test "completion - block" {
|
test "completion - block" {
|
||||||
|
Loading…
Reference in New Issue
Block a user