Handle if, while, for, payloads
This commit is contained in:
parent
d4871914ea
commit
c3d2aa3434
@ -513,26 +513,97 @@ pub fn nodeToString(tree: *ast.Tree, node: *ast.Node) ?[]const u8 {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn declsFromIndexInternal(decls: *std.ArrayList(*ast.Node), tree: *ast.Tree, node: *ast.Node) error{OutOfMemory}!void {
|
pub fn declsFromIndexInternal(decls: *std.ArrayList(*ast.Node), tree: *ast.Tree, node: *ast.Node, source_index: usize) error{OutOfMemory}!void {
|
||||||
switch (node.id) {
|
switch (node.id) {
|
||||||
.FnProto => {
|
.FnProto => {
|
||||||
const func = node.cast(ast.Node.FnProto).?;
|
const func = node.cast(ast.Node.FnProto).?;
|
||||||
|
|
||||||
var param_index: usize = 0;
|
var param_index: usize = 0;
|
||||||
while (param_index < func.params.len) : (param_index += 1)
|
while (param_index < func.params.len) : (param_index += 1)
|
||||||
try declsFromIndexInternal(decls, tree, func.params.at(param_index).*);
|
try declsFromIndexInternal(decls, tree, func.params.at(param_index).*, source_index);
|
||||||
|
|
||||||
if (func.body_node) |body_node|
|
if (func.body_node) |body_node| {
|
||||||
try declsFromIndexInternal(decls, tree, body_node);
|
if (!nodeContainsSourceIndex(tree, body_node, source_index)) return;
|
||||||
|
try declsFromIndexInternal(decls, tree, body_node, source_index);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
.TestDecl => {
|
.TestDecl => {
|
||||||
const test_decl = node.cast(ast.Node.TestDecl).?;
|
const test_decl = node.cast(ast.Node.TestDecl).?;
|
||||||
try declsFromIndexInternal(decls, tree, test_decl.body_node);
|
if (!nodeContainsSourceIndex(tree, test_decl.body_node, source_index)) return;
|
||||||
|
try declsFromIndexInternal(decls, tree, test_decl.body_node, source_index);
|
||||||
},
|
},
|
||||||
.Block => {
|
.Block => {
|
||||||
var index: usize = 0;
|
var index: usize = 0;
|
||||||
while (node.iterate(index)) |inode| : (index += 1) {
|
while (node.iterate(index)) |inode| : (index += 1) {
|
||||||
try declsFromIndexInternal(decls, tree, inode);
|
if (nodeComesAfterSourceIndex(tree, inode, source_index)) return;
|
||||||
|
try declsFromIndexInternal(decls, tree, inode, source_index);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.Comptime => {
|
||||||
|
const comptime_stmt = node.cast(ast.Node.Comptime).?;
|
||||||
|
if (nodeComesAfterSourceIndex(tree, comptime_stmt.expr, source_index)) return;
|
||||||
|
try declsFromIndexInternal(decls, tree, comptime_stmt.expr, source_index);
|
||||||
|
},
|
||||||
|
.If => {
|
||||||
|
const if_node = node.cast(ast.Node.If).?;
|
||||||
|
if (nodeContainsSourceIndex(tree, if_node.body, source_index)) {
|
||||||
|
if (if_node.payload) |payload| {
|
||||||
|
try declsFromIndexInternal(decls, tree, payload, source_index);
|
||||||
|
}
|
||||||
|
return try declsFromIndexInternal(decls, tree, if_node.body, source_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (if_node.@"else") |else_node| {
|
||||||
|
if (nodeContainsSourceIndex(tree, else_node.body, source_index)) {
|
||||||
|
if (else_node.payload) |payload| {
|
||||||
|
try declsFromIndexInternal(decls, tree, payload, source_index);
|
||||||
|
}
|
||||||
|
return try declsFromIndexInternal(decls, tree, else_node.body, source_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.While => {
|
||||||
|
const while_node = node.cast(ast.Node.While).?;
|
||||||
|
if (nodeContainsSourceIndex(tree, while_node.body, source_index)) {
|
||||||
|
if (while_node.payload) |payload| {
|
||||||
|
try declsFromIndexInternal(decls, tree, payload, source_index);
|
||||||
|
}
|
||||||
|
return try declsFromIndexInternal(decls, tree, while_node.body, source_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (while_node.@"else") |else_node| {
|
||||||
|
if (nodeContainsSourceIndex(tree, else_node.body, source_index)) {
|
||||||
|
if (else_node.payload) |payload| {
|
||||||
|
try declsFromIndexInternal(decls, tree, payload, source_index);
|
||||||
|
}
|
||||||
|
return try declsFromIndexInternal(decls, tree, else_node.body, source_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.For => {
|
||||||
|
const for_node = node.cast(ast.Node.For).?;
|
||||||
|
if (nodeContainsSourceIndex(tree, for_node.body, source_index)) {
|
||||||
|
try declsFromIndexInternal(decls, tree, for_node.payload, source_index);
|
||||||
|
return try declsFromIndexInternal(decls, tree, for_node.body, source_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (for_node.@"else") |else_node| {
|
||||||
|
if (nodeContainsSourceIndex(tree, else_node.body, source_index)) {
|
||||||
|
if (else_node.payload) |payload| {
|
||||||
|
try declsFromIndexInternal(decls, tree, payload, source_index);
|
||||||
|
}
|
||||||
|
return try declsFromIndexInternal(decls, tree, else_node.body, source_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// TODO: These convey no type information...
|
||||||
|
.Payload => try decls.append(node.cast(ast.Node.Payload).?.error_symbol),
|
||||||
|
.PointerPayload => try decls.append(node.cast(ast.Node.PointerPayload).?.value_symbol),
|
||||||
|
.PointerIndexPayload => {
|
||||||
|
const payload = node.cast(ast.Node.PointerIndexPayload).?;
|
||||||
|
try decls.append(payload.value_symbol);
|
||||||
|
if (payload.index_symbol) |idx| {
|
||||||
|
try decls.append(idx);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.VarDecl, .ParamDecl => try decls.append(node),
|
.VarDecl, .ParamDecl => try decls.append(node),
|
||||||
@ -547,14 +618,14 @@ pub fn addChildrenNodes(decls: *std.ArrayList(*ast.Node), tree: *ast.Tree, node:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn declsFromIndex(decls: *std.ArrayList(*ast.Node), tree: *ast.Tree, index: usize) !void {
|
pub fn declsFromIndex(decls: *std.ArrayList(*ast.Node), tree: *ast.Tree, source_index: usize) !void {
|
||||||
var node = &tree.root_node.base;
|
var node = &tree.root_node.base;
|
||||||
|
|
||||||
try addChildrenNodes(decls, tree, node);
|
try addChildrenNodes(decls, tree, node);
|
||||||
var node_index: usize = 0;
|
var node_index: usize = 0;
|
||||||
while (node.iterate(node_index)) |inode| : (node_index += 1) {
|
while (node.iterate(node_index)) |inode| : (node_index += 1) {
|
||||||
if (nodeContainsSourceIndex(tree, inode, index)) {
|
if (nodeContainsSourceIndex(tree, inode, source_index)) {
|
||||||
try declsFromIndexInternal(decls, tree, inode);
|
try declsFromIndexInternal(decls, tree, inode, source_index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -565,6 +636,12 @@ fn nodeContainsSourceIndex(tree: *ast.Tree, node: *ast.Node, source_index: usize
|
|||||||
return source_index >= first_token.start and source_index <= last_token.end;
|
return source_index >= first_token.start and source_index <= last_token.end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn nodeComesAfterSourceIndex(tree: *ast.Tree, node: *ast.Node, source_index: usize) bool {
|
||||||
|
const first_token = tree.tokens.at(node.firstToken());
|
||||||
|
const last_token = tree.tokens.at(node.lastToken());
|
||||||
|
return source_index < first_token.start;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn getImportStr(tree: *ast.Tree, source_index: usize) ?[]const u8 {
|
pub fn getImportStr(tree: *ast.Tree, source_index: usize) ?[]const u8 {
|
||||||
var node = &tree.root_node.base;
|
var node = &tree.root_node.base;
|
||||||
var index: usize = 0;
|
var index: usize = 0;
|
||||||
|
@ -283,16 +283,18 @@ fn nodeToCompletion(list: *std.ArrayList(types.CompletionItem), analysis_ctx: *D
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn identifierFromPosition(pos_index: usize, handle: DocumentStore.Handle) []const u8 {
|
fn identifierFromPosition(pos_index: usize, handle: DocumentStore.Handle) []const u8 {
|
||||||
if (pos_index + 1 >= handle.document.text.len) return &[0]u8{};
|
const text = handle.document.text;
|
||||||
|
|
||||||
|
if (pos_index + 1 >= text.len) return &[0]u8{};
|
||||||
var start_idx = pos_index;
|
var start_idx = pos_index;
|
||||||
|
|
||||||
while (start_idx > 0 and
|
while (start_idx > 0 and
|
||||||
(std.ascii.isAlNum(handle.document.text[start_idx]) or handle.document.text[start_idx] == '_')) : (start_idx -= 1)
|
(std.ascii.isAlNum(text[start_idx]) or text[start_idx] == '_')) : (start_idx -= 1)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
var end_idx = pos_index;
|
var end_idx = pos_index;
|
||||||
while (end_idx < handle.document.text.len - 1 and
|
while (end_idx < handle.document.text.len - 1 and
|
||||||
(std.ascii.isAlNum(handle.document.text[end_idx]) or handle.document.text[end_idx] == '_')) : (end_idx += 1)
|
(std.ascii.isAlNum(text[end_idx]) or text[end_idx] == '_')) : (end_idx += 1)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
return handle.document.text[start_idx + 1 .. end_idx];
|
return handle.document.text[start_idx + 1 .. end_idx];
|
||||||
|
Loading…
Reference in New Issue
Block a user