ids -> tags (part 1)
This commit is contained in:
parent
6eee43af2f
commit
da4d2c2be1
264
src/analysis.zig
264
src/analysis.zig
@ -6,13 +6,13 @@ const offsets = @import("offsets.zig");
|
|||||||
|
|
||||||
/// Get a declaration's doc comment node
|
/// Get a declaration's doc comment node
|
||||||
fn getDocCommentNode(tree: *ast.Tree, node: *ast.Node) ?*ast.Node.DocComment {
|
fn getDocCommentNode(tree: *ast.Tree, node: *ast.Node) ?*ast.Node.DocComment {
|
||||||
if (node.cast(ast.Node.FnProto)) |func| {
|
if (node.castTag(.FnProto)) |func| {
|
||||||
return func.doc_comments;
|
return func.doc_comments;
|
||||||
} else if (node.cast(ast.Node.VarDecl)) |var_decl| {
|
} else if (node.castTag(.VarDecl)) |var_decl| {
|
||||||
return var_decl.doc_comments;
|
return var_decl.doc_comments;
|
||||||
} else if (node.cast(ast.Node.ContainerField)) |field| {
|
} else if (node.castTag(.ContainerField)) |field| {
|
||||||
return field.doc_comments;
|
return field.doc_comments;
|
||||||
} else if (node.cast(ast.Node.ErrorTag)) |tag| {
|
} else if (node.castTag(.ErrorTag)) |tag| {
|
||||||
return tag.doc_comments;
|
return tag.doc_comments;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -141,7 +141,7 @@ pub fn getContainerFieldSignature(tree: *ast.Tree, field: *ast.Node.ContainerFie
|
|||||||
|
|
||||||
/// The type node is "type"
|
/// The type node is "type"
|
||||||
fn typeIsType(tree: *ast.Tree, node: *ast.Node) bool {
|
fn typeIsType(tree: *ast.Tree, node: *ast.Node) bool {
|
||||||
if (node.cast(ast.Node.Identifier)) |ident| {
|
if (node.castTag(.Identifier)) |ident| {
|
||||||
return std.mem.eql(u8, tree.tokenSlice(ident.token), "type");
|
return std.mem.eql(u8, tree.tokenSlice(ident.token), "type");
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -175,32 +175,32 @@ pub fn isPascalCase(name: []const u8) bool {
|
|||||||
// ANALYSIS ENGINE
|
// ANALYSIS ENGINE
|
||||||
|
|
||||||
pub fn getDeclNameToken(tree: *ast.Tree, node: *ast.Node) ?ast.TokenIndex {
|
pub fn getDeclNameToken(tree: *ast.Tree, node: *ast.Node) ?ast.TokenIndex {
|
||||||
switch (node.id) {
|
switch (node.tag) {
|
||||||
.VarDecl => {
|
.VarDecl => {
|
||||||
const vari = node.cast(ast.Node.VarDecl).?;
|
const vari = node.castTag(.VarDecl).?;
|
||||||
return vari.name_token;
|
return vari.name_token;
|
||||||
},
|
},
|
||||||
.FnProto => {
|
.FnProto => {
|
||||||
const func = node.cast(ast.Node.FnProto).?;
|
const func = node.castTag(.FnProto).?;
|
||||||
if (func.name_token == null) return null;
|
if (func.name_token == null) return null;
|
||||||
return func.name_token.?;
|
return func.name_token.?;
|
||||||
},
|
},
|
||||||
.ContainerField => {
|
.ContainerField => {
|
||||||
const field = node.cast(ast.Node.ContainerField).?;
|
const field = node.castTag(.ContainerField).?;
|
||||||
return field.name_token;
|
return field.name_token;
|
||||||
},
|
},
|
||||||
.ErrorTag => {
|
.ErrorTag => {
|
||||||
const tag = node.cast(ast.Node.ErrorTag).?;
|
const tag = node.castTag(.ErrorTag).?;
|
||||||
return tag.name_token;
|
return tag.name_token;
|
||||||
},
|
},
|
||||||
// We need identifier for captures and error set tags
|
// We need identifier for captures and error set tags
|
||||||
.Identifier => {
|
.Identifier => {
|
||||||
const ident = node.cast(ast.Node.Identifier).?;
|
const ident = node.castTag(.Identifier).?;
|
||||||
return ident.token;
|
return ident.token;
|
||||||
},
|
},
|
||||||
.TestDecl => {
|
.TestDecl => {
|
||||||
const decl = node.cast(ast.Node.TestDecl).?;
|
const decl = node.castTag(.TestDecl).?;
|
||||||
return (decl.name.cast(ast.Node.StringLiteral) orelse return null).token;
|
return (decl.name.castTag(.StringLiteral) orelse return null).token;
|
||||||
},
|
},
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
@ -210,7 +210,7 @@ pub fn getDeclNameToken(tree: *ast.Tree, node: *ast.Node) ?ast.TokenIndex {
|
|||||||
|
|
||||||
fn getDeclName(tree: *ast.Tree, node: *ast.Node) ?[]const u8 {
|
fn getDeclName(tree: *ast.Tree, node: *ast.Node) ?[]const u8 {
|
||||||
const name = tree.tokenSlice(getDeclNameToken(tree, node) orelse return null);
|
const name = tree.tokenSlice(getDeclNameToken(tree, node) orelse return null);
|
||||||
return switch (node.id) {
|
return switch (node.tag) {
|
||||||
.TestDecl => name[1 .. name.len - 1],
|
.TestDecl => name[1 .. name.len - 1],
|
||||||
else => name,
|
else => name,
|
||||||
};
|
};
|
||||||
@ -218,7 +218,7 @@ fn getDeclName(tree: *ast.Tree, node: *ast.Node) ?[]const u8 {
|
|||||||
|
|
||||||
fn isContainerDecl(decl_handle: DeclWithHandle) bool {
|
fn isContainerDecl(decl_handle: DeclWithHandle) bool {
|
||||||
return switch (decl_handle.decl.*) {
|
return switch (decl_handle.decl.*) {
|
||||||
.ast_node => |inner_node| inner_node.id == .ContainerDecl or inner_node.id == .Root,
|
.ast_node => |inner_node| inner_node.tag == .ContainerDecl or inner_node.tag == .Root,
|
||||||
else => false,
|
else => false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -230,18 +230,18 @@ fn resolveVarDeclAliasInternal(
|
|||||||
root: bool,
|
root: bool,
|
||||||
) error{OutOfMemory}!?DeclWithHandle {
|
) error{OutOfMemory}!?DeclWithHandle {
|
||||||
const handle = node_handle.handle;
|
const handle = node_handle.handle;
|
||||||
if (node_handle.node.cast(ast.Node.Identifier)) |ident| {
|
if (node_handle.node.castTag(.Identifier)) |ident| {
|
||||||
return try lookupSymbolGlobal(store, arena, handle, handle.tree.tokenSlice(ident.token), handle.tree.token_locs[ident.token].start);
|
return try lookupSymbolGlobal(store, arena, handle, handle.tree.tokenSlice(ident.token), handle.tree.token_locs[ident.token].start);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node_handle.node.cast(ast.Node.InfixOp)) |infix_op| {
|
if (node_handle.node.castTag(.InfixOp)) |infix_op| {
|
||||||
if (infix_op.op != .Period) return null;
|
if (infix_op.op != .Period) return null;
|
||||||
|
|
||||||
const container_node = if (infix_op.lhs.cast(ast.Node.BuiltinCall)) |builtin_call| block: {
|
const container_node = if (infix_op.lhs.castTag(.BuiltinCall)) |builtin_call| block: {
|
||||||
if (!std.mem.eql(u8, handle.tree.tokenSlice(builtin_call.builtin_token), "@import"))
|
if (!std.mem.eql(u8, handle.tree.tokenSlice(builtin_call.builtin_token), "@import"))
|
||||||
return null;
|
return null;
|
||||||
const inner_node = (try resolveTypeOfNode(store, arena, .{ .node = infix_op.lhs, .handle = handle })) orelse return null;
|
const inner_node = (try resolveTypeOfNode(store, arena, .{ .node = infix_op.lhs, .handle = handle })) orelse return null;
|
||||||
std.debug.assert(inner_node.type.data.other.id == .Root);
|
std.debug.assert(inner_node.type.data.other.tag == .Root);
|
||||||
break :block NodeWithHandle{ .node = inner_node.type.data.other, .handle = inner_node.handle };
|
break :block NodeWithHandle{ .node = inner_node.type.data.other, .handle = inner_node.handle };
|
||||||
} else if (try resolveVarDeclAliasInternal(store, arena, .{ .node = infix_op.lhs, .handle = handle }, false)) |decl_handle| block: {
|
} else if (try resolveVarDeclAliasInternal(store, arena, .{ .node = infix_op.lhs, .handle = handle }, false)) |decl_handle| block: {
|
||||||
if (decl_handle.decl.* != .ast_node) return null;
|
if (decl_handle.decl.* != .ast_node) return null;
|
||||||
@ -251,7 +251,7 @@ fn resolveVarDeclAliasInternal(
|
|||||||
else => return null,
|
else => return null,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (resolved_node.id != .ContainerDecl and resolved_node.id != .Root) return null;
|
if (resolved_node.tag != .ContainerDecl and resolved_node.tag != .Root) return null;
|
||||||
break :block NodeWithHandle{ .node = resolved_node, .handle = resolved.handle };
|
break :block NodeWithHandle{ .node = resolved_node, .handle = resolved.handle };
|
||||||
} else return null;
|
} else return null;
|
||||||
|
|
||||||
@ -273,13 +273,13 @@ pub fn resolveVarDeclAlias(store: *DocumentStore, arena: *std.heap.ArenaAllocato
|
|||||||
const decl = decl_handle.node;
|
const decl = decl_handle.node;
|
||||||
const handle = decl_handle.handle;
|
const handle = decl_handle.handle;
|
||||||
|
|
||||||
if (decl.cast(ast.Node.VarDecl)) |var_decl| {
|
if (decl.castTag(.VarDecl)) |var_decl| {
|
||||||
if (var_decl.init_node == null) return null;
|
if (var_decl.init_node == null) return null;
|
||||||
if (handle.tree.token_ids[var_decl.mut_token] != .Keyword_const) return null;
|
if (handle.tree.token_ids[var_decl.mut_token] != .Keyword_const) return null;
|
||||||
if (var_decl.init_node == null) return null;
|
if (var_decl.init_node == null) return null;
|
||||||
|
|
||||||
const base_expr = var_decl.init_node.?;
|
const base_expr = var_decl.init_node.?;
|
||||||
if (base_expr.cast(ast.Node.InfixOp)) |infix_op| {
|
if (base_expr.castTag(.InfixOp)) |infix_op| {
|
||||||
if (infix_op.op != .Period) return null;
|
if (infix_op.op != .Period) return null;
|
||||||
const name = handle.tree.tokenSlice(infix_op.rhs.firstToken());
|
const name = handle.tree.tokenSlice(infix_op.rhs.firstToken());
|
||||||
if (!std.mem.eql(u8, handle.tree.tokenSlice(var_decl.name_token), name))
|
if (!std.mem.eql(u8, handle.tree.tokenSlice(var_decl.name_token), name))
|
||||||
@ -301,15 +301,15 @@ fn findReturnStatementInternal(
|
|||||||
var result: ?*ast.Node.ControlFlowExpression = null;
|
var result: ?*ast.Node.ControlFlowExpression = null;
|
||||||
var child_idx: usize = 0;
|
var child_idx: usize = 0;
|
||||||
while (base_node.iterate(child_idx)) |child_node| : (child_idx += 1) {
|
while (base_node.iterate(child_idx)) |child_node| : (child_idx += 1) {
|
||||||
switch (child_node.id) {
|
switch (child_node.tag) {
|
||||||
.ControlFlowExpression => blk: {
|
.ControlFlowExpression => blk: {
|
||||||
const cfe = child_node.cast(ast.Node.ControlFlowExpression).?;
|
const cfe = child_node.castTag(.ControlFlowExpression).?;
|
||||||
if (cfe.kind != .Return) break :blk;
|
if (cfe.kind != .Return) break :blk;
|
||||||
|
|
||||||
// If we are calling ourselves recursively, ignore this return.
|
// If we are calling ourselves recursively, ignore this return.
|
||||||
if (cfe.rhs) |rhs| {
|
if (cfe.rhs) |rhs| {
|
||||||
if (rhs.cast(ast.Node.Call)) |call_node| {
|
if (rhs.castTag(.Call)) |call_node| {
|
||||||
if (call_node.lhs.id == .Identifier) {
|
if (call_node.lhs.tag == .Identifier) {
|
||||||
if (std.mem.eql(u8, getDeclName(tree, call_node.lhs).?, getDeclName(tree, &fn_decl.base).?)) {
|
if (std.mem.eql(u8, getDeclName(tree, call_node.lhs).?, getDeclName(tree, &fn_decl.base).?)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -389,7 +389,7 @@ fn resolveUnwrapOptionalType(
|
|||||||
else => return null,
|
else => return null,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (opt_node.cast(ast.Node.PrefixOp)) |prefix_op| {
|
if (opt_node.castTag(.PrefixOp)) |prefix_op| {
|
||||||
if (prefix_op.op == .OptionalType) {
|
if (prefix_op.op == .OptionalType) {
|
||||||
return ((try resolveTypeOfNodeInternal(store, arena, .{
|
return ((try resolveTypeOfNodeInternal(store, arena, .{
|
||||||
.node = prefix_op.rhs,
|
.node = prefix_op.rhs,
|
||||||
@ -416,7 +416,7 @@ fn resolveUnwrapErrorType(
|
|||||||
.primitive, .slice => return null,
|
.primitive, .slice => return null,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (rhs_node.cast(ast.Node.InfixOp)) |infix_op| {
|
if (rhs_node.castTag(.InfixOp)) |infix_op| {
|
||||||
if (infix_op.op == .ErrorUnion) {
|
if (infix_op.op == .ErrorUnion) {
|
||||||
return ((try resolveTypeOfNodeInternal(store, arena, .{
|
return ((try resolveTypeOfNodeInternal(store, arena, .{
|
||||||
.node = infix_op.rhs,
|
.node = infix_op.rhs,
|
||||||
@ -440,7 +440,7 @@ fn resolveDerefType(
|
|||||||
else => return null,
|
else => return null,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (deref_node.cast(ast.Node.PrefixOp)) |pop| {
|
if (deref_node.castTag(.PrefixOp)) |pop| {
|
||||||
if (pop.op == .PtrType) {
|
if (pop.op == .PtrType) {
|
||||||
const op_token_id = deref.handle.tree.token_ids[pop.op_token];
|
const op_token_id = deref.handle.tree.token_ids[pop.op_token];
|
||||||
switch (op_token_id) {
|
switch (op_token_id) {
|
||||||
@ -471,7 +471,7 @@ fn resolveBracketAccessType(
|
|||||||
else => return null,
|
else => return null,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (lhs_node.cast(ast.Node.PrefixOp)) |pop| {
|
if (lhs_node.castTag(.PrefixOp)) |pop| {
|
||||||
switch (pop.op) {
|
switch (pop.op) {
|
||||||
.SliceType => {
|
.SliceType => {
|
||||||
if (rhs == .Single)
|
if (rhs == .Single)
|
||||||
@ -493,7 +493,7 @@ fn resolveBracketAccessType(
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
.PtrType => {
|
.PtrType => {
|
||||||
if (pop.rhs.cast(std.zig.ast.Node.PrefixOp)) |child_pop| {
|
if (pop.rhs.castTag(std.zig.ast.Node.PrefixOp)) |child_pop| {
|
||||||
switch (child_pop.op) {
|
switch (child_pop.op) {
|
||||||
.ArrayType => {
|
.ArrayType => {
|
||||||
if (rhs == .Single) {
|
if (rhs == .Single) {
|
||||||
@ -567,9 +567,9 @@ pub fn resolveTypeOfNodeInternal(
|
|||||||
const node = node_handle.node;
|
const node = node_handle.node;
|
||||||
const handle = node_handle.handle;
|
const handle = node_handle.handle;
|
||||||
|
|
||||||
switch (node.id) {
|
switch (node.tag) {
|
||||||
.VarDecl => {
|
.VarDecl => {
|
||||||
const vari = node.cast(ast.Node.VarDecl).?;
|
const vari = node.castTag(.VarDecl).?;
|
||||||
if (vari.type_node) |type_node| block: {
|
if (vari.type_node) |type_node| block: {
|
||||||
return ((try resolveTypeOfNodeInternal(
|
return ((try resolveTypeOfNodeInternal(
|
||||||
store,
|
store,
|
||||||
@ -600,7 +600,7 @@ pub fn resolveTypeOfNodeInternal(
|
|||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
.ContainerField => {
|
.ContainerField => {
|
||||||
const field = node.cast(ast.Node.ContainerField).?;
|
const field = node.castTag(.ContainerField).?;
|
||||||
return ((try resolveTypeOfNodeInternal(
|
return ((try resolveTypeOfNodeInternal(
|
||||||
store,
|
store,
|
||||||
arena,
|
arena,
|
||||||
@ -609,7 +609,7 @@ pub fn resolveTypeOfNodeInternal(
|
|||||||
)) orelse return null).instanceTypeVal();
|
)) orelse return null).instanceTypeVal();
|
||||||
},
|
},
|
||||||
.Call => {
|
.Call => {
|
||||||
const call = node.cast(ast.Node.Call).?;
|
const call = node.castTag(.Call).?;
|
||||||
const decl = (try resolveTypeOfNodeInternal(
|
const decl = (try resolveTypeOfNodeInternal(
|
||||||
store,
|
store,
|
||||||
arena,
|
arena,
|
||||||
@ -622,9 +622,9 @@ pub fn resolveTypeOfNodeInternal(
|
|||||||
.other => |n| n,
|
.other => |n| n,
|
||||||
else => return null,
|
else => return null,
|
||||||
};
|
};
|
||||||
if (decl_node.cast(ast.Node.FnProto)) |fn_decl| {
|
if (decl_node.castTag(.FnProto)) |fn_decl| {
|
||||||
var has_self_param: u8 = 0;
|
var has_self_param: u8 = 0;
|
||||||
if (call.lhs.cast(ast.Node.InfixOp)) |lhs_infix_op| {
|
if (call.lhs.castTag(.InfixOp)) |lhs_infix_op| {
|
||||||
if (lhs_infix_op.op == .Period) {
|
if (lhs_infix_op.op == .Period) {
|
||||||
has_self_param = 1;
|
has_self_param = 1;
|
||||||
}
|
}
|
||||||
@ -656,15 +656,15 @@ pub fn resolveTypeOfNodeInternal(
|
|||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
.Comptime => {
|
.Comptime => {
|
||||||
const ct = node.cast(ast.Node.Comptime).?;
|
const ct = node.castTag(.Comptime).?;
|
||||||
return try resolveTypeOfNodeInternal(store, arena, .{ .node = ct.expr, .handle = handle }, bound_type_params);
|
return try resolveTypeOfNodeInternal(store, arena, .{ .node = ct.expr, .handle = handle }, bound_type_params);
|
||||||
},
|
},
|
||||||
.GroupedExpression => {
|
.GroupedExpression => {
|
||||||
const grouped = node.cast(ast.Node.GroupedExpression).?;
|
const grouped = node.castTag(.GroupedExpression).?;
|
||||||
return try resolveTypeOfNodeInternal(store, arena, .{ .node = grouped.expr, .handle = handle }, bound_type_params);
|
return try resolveTypeOfNodeInternal(store, arena, .{ .node = grouped.expr, .handle = handle }, bound_type_params);
|
||||||
},
|
},
|
||||||
.StructInitializer => {
|
.StructInitializer => {
|
||||||
const struct_init = node.cast(ast.Node.StructInitializer).?;
|
const struct_init = node.castTag(.StructInitializer).?;
|
||||||
return ((try resolveTypeOfNodeInternal(
|
return ((try resolveTypeOfNodeInternal(
|
||||||
store,
|
store,
|
||||||
arena,
|
arena,
|
||||||
@ -676,7 +676,7 @@ pub fn resolveTypeOfNodeInternal(
|
|||||||
return TypeWithHandle.typeVal(node_handle);
|
return TypeWithHandle.typeVal(node_handle);
|
||||||
},
|
},
|
||||||
.SuffixOp => {
|
.SuffixOp => {
|
||||||
const suffix_op = node.cast(ast.Node.SuffixOp).?;
|
const suffix_op = node.castTag(.SuffixOp).?;
|
||||||
const left_type = (try resolveTypeOfNodeInternal(store, arena, .{
|
const left_type = (try resolveTypeOfNodeInternal(store, arena, .{
|
||||||
.node = suffix_op.lhs,
|
.node = suffix_op.lhs,
|
||||||
.handle = handle,
|
.handle = handle,
|
||||||
@ -690,7 +690,7 @@ pub fn resolveTypeOfNodeInternal(
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
.InfixOp => {
|
.InfixOp => {
|
||||||
const infix_op = node.cast(ast.Node.InfixOp).?;
|
const infix_op = node.castTag(.InfixOp).?;
|
||||||
switch (infix_op.op) {
|
switch (infix_op.op) {
|
||||||
.Period => {
|
.Period => {
|
||||||
const rhs_str = nodeToString(handle.tree, infix_op.rhs) orelse return null;
|
const rhs_str = nodeToString(handle.tree, infix_op.rhs) orelse return null;
|
||||||
@ -739,7 +739,7 @@ pub fn resolveTypeOfNodeInternal(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
.PrefixOp => {
|
.PrefixOp => {
|
||||||
const prefix_op = node.cast(ast.Node.PrefixOp).?;
|
const prefix_op = node.castTag(.PrefixOp).?;
|
||||||
switch (prefix_op.op) {
|
switch (prefix_op.op) {
|
||||||
.SliceType,
|
.SliceType,
|
||||||
.ArrayType,
|
.ArrayType,
|
||||||
@ -757,7 +757,7 @@ pub fn resolveTypeOfNodeInternal(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
.BuiltinCall => {
|
.BuiltinCall => {
|
||||||
const builtin_call = node.cast(ast.Node.BuiltinCall).?;
|
const builtin_call = node.castTag(.BuiltinCall).?;
|
||||||
const call_name = handle.tree.tokenSlice(builtin_call.builtin_token);
|
const call_name = handle.tree.tokenSlice(builtin_call.builtin_token);
|
||||||
if (std.mem.eql(u8, call_name, "@This")) {
|
if (std.mem.eql(u8, call_name, "@This")) {
|
||||||
if (builtin_call.params_len != 0) return null;
|
if (builtin_call.params_len != 0) return null;
|
||||||
@ -803,9 +803,9 @@ pub fn resolveTypeOfNodeInternal(
|
|||||||
if (builtin_call.params_len < 1) return null;
|
if (builtin_call.params_len < 1) return null;
|
||||||
|
|
||||||
const import_param = builtin_call.paramsConst()[0];
|
const import_param = builtin_call.paramsConst()[0];
|
||||||
if (import_param.id != .StringLiteral) return null;
|
if (import_param.tag != .StringLiteral) return null;
|
||||||
|
|
||||||
const import_str = handle.tree.tokenSlice(import_param.cast(ast.Node.StringLiteral).?.token);
|
const import_str = handle.tree.tokenSlice(import_param.castTag(.StringLiteral).?.token);
|
||||||
const new_handle = (store.resolveImport(handle, import_str[1 .. import_str.len - 1]) catch |err| block: {
|
const new_handle = (store.resolveImport(handle, import_str[1 .. import_str.len - 1]) catch |err| block: {
|
||||||
std.log.debug(.analysis, "Error {} while processing import {}\n", .{ err, import_str });
|
std.log.debug(.analysis, "Error {} while processing import {}\n", .{ err, import_str });
|
||||||
return null;
|
return null;
|
||||||
@ -814,13 +814,13 @@ pub fn resolveTypeOfNodeInternal(
|
|||||||
return TypeWithHandle.typeVal(.{ .node = &new_handle.tree.root_node.base, .handle = new_handle });
|
return TypeWithHandle.typeVal(.{ .node = &new_handle.tree.root_node.base, .handle = new_handle });
|
||||||
},
|
},
|
||||||
.ContainerDecl => {
|
.ContainerDecl => {
|
||||||
const container = node.cast(ast.Node.ContainerDecl).?;
|
const container = node.castTag(.ContainerDecl).?;
|
||||||
const kind = handle.tree.token_ids[container.kind_token];
|
const kind = handle.tree.token_ids[container.kind_token];
|
||||||
return TypeWithHandle.typeVal(node_handle);
|
return TypeWithHandle.typeVal(node_handle);
|
||||||
},
|
},
|
||||||
.FnProto => {
|
.FnProto => {
|
||||||
// This is a function type
|
// This is a function type
|
||||||
if (node.cast(ast.Node.FnProto).?.name_token == null) {
|
if (node.castTag(.FnProto).?.name_token == null) {
|
||||||
return TypeWithHandle.typeVal(node_handle);
|
return TypeWithHandle.typeVal(node_handle);
|
||||||
}
|
}
|
||||||
return TypeWithHandle{
|
return TypeWithHandle{
|
||||||
@ -874,7 +874,7 @@ pub const TypeWithHandle = struct {
|
|||||||
|
|
||||||
fn isRoot(self: TypeWithHandle) bool {
|
fn isRoot(self: TypeWithHandle) bool {
|
||||||
switch (self.type.data) {
|
switch (self.type.data) {
|
||||||
.other => |n| return n.id == .Root,
|
.other => |n| return n.tag == .Root,
|
||||||
else => return false,
|
else => return false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -882,7 +882,7 @@ pub const TypeWithHandle = struct {
|
|||||||
fn isContainer(self: TypeWithHandle, container_kind_tok: std.zig.Token.Id) bool {
|
fn isContainer(self: TypeWithHandle, container_kind_tok: std.zig.Token.Id) bool {
|
||||||
switch (self.type.data) {
|
switch (self.type.data) {
|
||||||
.other => |n| {
|
.other => |n| {
|
||||||
if (n.cast(ast.Node.ContainerDecl)) |cont| {
|
if (n.castTag(.ContainerDecl)) |cont| {
|
||||||
return self.handle.tree.token_ids[cont.kind_token] == container_kind_tok;
|
return self.handle.tree.token_ids[cont.kind_token] == container_kind_tok;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -899,7 +899,7 @@ pub const TypeWithHandle = struct {
|
|||||||
if (!self.isStructType()) return false;
|
if (!self.isStructType()) return false;
|
||||||
var idx: usize = 0;
|
var idx: usize = 0;
|
||||||
while (self.type.data.other.iterate(idx)) |child| : (idx += 1) {
|
while (self.type.data.other.iterate(idx)) |child| : (idx += 1) {
|
||||||
if (child.id == .ContainerField)
|
if (child.tag == .ContainerField)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -916,7 +916,7 @@ pub const TypeWithHandle = struct {
|
|||||||
pub fn isTypeFunc(self: TypeWithHandle) bool {
|
pub fn isTypeFunc(self: TypeWithHandle) bool {
|
||||||
switch (self.type.data) {
|
switch (self.type.data) {
|
||||||
.other => |n| {
|
.other => |n| {
|
||||||
if (n.cast(ast.Node.FnProto)) |fn_proto| {
|
if (n.castTag(.FnProto)) |fn_proto| {
|
||||||
return isTypeFunction(self.handle.tree, fn_proto);
|
return isTypeFunction(self.handle.tree, fn_proto);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -928,7 +928,7 @@ pub const TypeWithHandle = struct {
|
|||||||
pub fn isGenericFunc(self: TypeWithHandle) bool {
|
pub fn isGenericFunc(self: TypeWithHandle) bool {
|
||||||
switch (self.type.data) {
|
switch (self.type.data) {
|
||||||
.other => |n| {
|
.other => |n| {
|
||||||
if (n.cast(ast.Node.FnProto)) |fn_proto| {
|
if (n.castTag(.FnProto)) |fn_proto| {
|
||||||
return isGenericFunction(self.handle.tree, fn_proto);
|
return isGenericFunction(self.handle.tree, fn_proto);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -940,7 +940,7 @@ pub const TypeWithHandle = struct {
|
|||||||
pub fn isFunc(self: TypeWithHandle) bool {
|
pub fn isFunc(self: TypeWithHandle) bool {
|
||||||
switch (self.type.data) {
|
switch (self.type.data) {
|
||||||
.other => |n| {
|
.other => |n| {
|
||||||
return n.id == .FnProto;
|
return n.tag == .FnProto;
|
||||||
},
|
},
|
||||||
else => return false,
|
else => return false,
|
||||||
}
|
}
|
||||||
@ -957,9 +957,9 @@ fn maybeCollectImport(tree: *ast.Tree, builtin_call: *ast.Node.BuiltinCall, arr:
|
|||||||
if (builtin_call.params_len > 1) return;
|
if (builtin_call.params_len > 1) return;
|
||||||
|
|
||||||
const import_param = builtin_call.paramsConst()[0];
|
const import_param = builtin_call.paramsConst()[0];
|
||||||
if (import_param.id != .StringLiteral) return;
|
if (import_param.tag != .StringLiteral) return;
|
||||||
|
|
||||||
const import_str = tree.tokenSlice(import_param.cast(ast.Node.StringLiteral).?.token);
|
const import_str = tree.tokenSlice(import_param.castTag(.StringLiteral).?.token);
|
||||||
try arr.append(import_str[1 .. import_str.len - 1]);
|
try arr.append(import_str[1 .. import_str.len - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -968,24 +968,24 @@ fn maybeCollectImport(tree: *ast.Tree, builtin_call: *ast.Node.BuiltinCall, arr:
|
|||||||
pub fn collectImports(import_arr: *std.ArrayList([]const u8), tree: *ast.Tree) !void {
|
pub fn collectImports(import_arr: *std.ArrayList([]const u8), tree: *ast.Tree) !void {
|
||||||
// TODO: Currently only detects `const smth = @import("string literal")<.SomeThing>;`
|
// TODO: Currently only detects `const smth = @import("string literal")<.SomeThing>;`
|
||||||
for (tree.root_node.decls()) |decl| {
|
for (tree.root_node.decls()) |decl| {
|
||||||
if (decl.id != .VarDecl) continue;
|
if (decl.tag != .VarDecl) continue;
|
||||||
const var_decl = decl.cast(ast.Node.VarDecl).?;
|
const var_decl = decl.castTag(.VarDecl).?;
|
||||||
if (var_decl.init_node == null) continue;
|
if (var_decl.init_node == null) continue;
|
||||||
|
|
||||||
switch (var_decl.init_node.?.id) {
|
switch (var_decl.init_node.?.tag) {
|
||||||
.BuiltinCall => {
|
.BuiltinCall => {
|
||||||
const builtin_call = var_decl.init_node.?.cast(ast.Node.BuiltinCall).?;
|
const builtin_call = var_decl.init_node.?.castTag(.BuiltinCall).?;
|
||||||
try maybeCollectImport(tree, builtin_call, import_arr);
|
try maybeCollectImport(tree, builtin_call, import_arr);
|
||||||
},
|
},
|
||||||
.InfixOp => {
|
.InfixOp => {
|
||||||
const infix_op = var_decl.init_node.?.cast(ast.Node.InfixOp).?;
|
const infix_op = var_decl.init_node.?.castTag(.InfixOp).?;
|
||||||
|
|
||||||
switch (infix_op.op) {
|
switch (infix_op.op) {
|
||||||
.Period => {},
|
.Period => {},
|
||||||
else => continue,
|
else => continue,
|
||||||
}
|
}
|
||||||
if (infix_op.lhs.id != .BuiltinCall) continue;
|
if (infix_op.lhs.tag != .BuiltinCall) continue;
|
||||||
try maybeCollectImport(tree, infix_op.lhs.cast(ast.Node.BuiltinCall).?, import_arr);
|
try maybeCollectImport(tree, infix_op.lhs.castTag(.BuiltinCall).?, import_arr);
|
||||||
},
|
},
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
@ -1019,7 +1019,7 @@ pub fn getFieldAccessType(
|
|||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
const tok = tokenizer.next();
|
const tok = tokenizer.next();
|
||||||
switch (tok.id) {
|
switch (tok.tag) {
|
||||||
.Eof => return FieldAccessReturn{
|
.Eof => return FieldAccessReturn{
|
||||||
.original = current_type,
|
.original = current_type,
|
||||||
.unwrapped = try resolveDerefType(store, arena, current_type, &bound_type_params),
|
.unwrapped = try resolveDerefType(store, arena, current_type, &bound_type_params),
|
||||||
@ -1031,7 +1031,7 @@ pub fn getFieldAccessType(
|
|||||||
},
|
},
|
||||||
.Period => {
|
.Period => {
|
||||||
const after_period = tokenizer.next();
|
const after_period = tokenizer.next();
|
||||||
switch (after_period.id) {
|
switch (after_period.tag) {
|
||||||
.Eof => return FieldAccessReturn{
|
.Eof => return FieldAccessReturn{
|
||||||
.original = current_type,
|
.original = current_type,
|
||||||
.unwrapped = try resolveDerefType(store, arena, current_type, &bound_type_params),
|
.unwrapped = try resolveDerefType(store, arena, current_type, &bound_type_params),
|
||||||
@ -1080,7 +1080,7 @@ 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;
|
||||||
if (current_type_node.cast(ast.Node.FnProto)) |func| {
|
if (current_type_node.castTag(.FnProto)) |func| {
|
||||||
if (try resolveReturnType(store, arena, func, current_type.handle, &bound_type_params)) |ret| {
|
if (try resolveReturnType(store, arena, func, current_type.handle, &bound_type_params)) |ret| {
|
||||||
current_type = ret;
|
current_type = ret;
|
||||||
// Skip to the right paren
|
// Skip to the right paren
|
||||||
@ -1128,13 +1128,13 @@ pub fn getFieldAccessType(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn isNodePublic(tree: *ast.Tree, node: *ast.Node) bool {
|
pub fn isNodePublic(tree: *ast.Tree, node: *ast.Node) bool {
|
||||||
switch (node.id) {
|
switch (node.tag) {
|
||||||
.VarDecl => {
|
.VarDecl => {
|
||||||
const var_decl = node.cast(ast.Node.VarDecl).?;
|
const var_decl = node.castTag(.VarDecl).?;
|
||||||
return var_decl.visib_token != null;
|
return var_decl.visib_token != null;
|
||||||
},
|
},
|
||||||
.FnProto => {
|
.FnProto => {
|
||||||
const func = node.cast(ast.Node.FnProto).?;
|
const func = node.castTag(.FnProto).?;
|
||||||
return func.visib_token != null;
|
return func.visib_token != null;
|
||||||
},
|
},
|
||||||
else => return true,
|
else => return true,
|
||||||
@ -1142,27 +1142,27 @@ pub fn isNodePublic(tree: *ast.Tree, node: *ast.Node) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn nodeToString(tree: *ast.Tree, node: *ast.Node) ?[]const u8 {
|
pub fn nodeToString(tree: *ast.Tree, node: *ast.Node) ?[]const u8 {
|
||||||
switch (node.id) {
|
switch (node.tag) {
|
||||||
.ContainerField => {
|
.ContainerField => {
|
||||||
const field = node.cast(ast.Node.ContainerField).?;
|
const field = node.castTag(.ContainerField).?;
|
||||||
return tree.tokenSlice(field.name_token);
|
return tree.tokenSlice(field.name_token);
|
||||||
},
|
},
|
||||||
.ErrorTag => {
|
.ErrorTag => {
|
||||||
const tag = node.cast(ast.Node.ErrorTag).?;
|
const tag = node.castTag(.ErrorTag).?;
|
||||||
return tree.tokenSlice(tag.name_token);
|
return tree.tokenSlice(tag.name_token);
|
||||||
},
|
},
|
||||||
.Identifier => {
|
.Identifier => {
|
||||||
const field = node.cast(ast.Node.Identifier).?;
|
const field = node.castTag(.Identifier).?;
|
||||||
return tree.tokenSlice(field.token);
|
return tree.tokenSlice(field.token);
|
||||||
},
|
},
|
||||||
.FnProto => {
|
.FnProto => {
|
||||||
const func = node.cast(ast.Node.FnProto).?;
|
const func = node.castTag(.FnProto).?;
|
||||||
if (func.name_token) |name_token| {
|
if (func.name_token) |name_token| {
|
||||||
return tree.tokenSlice(name_token);
|
return tree.tokenSlice(name_token);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
std.log.debug(.analysis, "INVALID: {}\n", .{node.id});
|
std.log.debug(.analysis, "INVALID: {}\n", .{node.tag});
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1184,14 +1184,14 @@ pub fn getImportStr(tree: *ast.Tree, source_index: usize) ?[]const u8 {
|
|||||||
child_idx += 1;
|
child_idx += 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (child.cast(ast.Node.BuiltinCall)) |builtin_call| blk: {
|
if (child.castTag(.BuiltinCall)) |builtin_call| blk: {
|
||||||
const call_name = tree.tokenSlice(builtin_call.builtin_token);
|
const call_name = tree.tokenSlice(builtin_call.builtin_token);
|
||||||
|
|
||||||
if (!std.mem.eql(u8, call_name, "@import")) break :blk;
|
if (!std.mem.eql(u8, call_name, "@import")) break :blk;
|
||||||
if (builtin_call.params_len != 1) break :blk;
|
if (builtin_call.params_len != 1) break :blk;
|
||||||
|
|
||||||
const import_param = builtin_call.paramsConst()[0];
|
const import_param = builtin_call.paramsConst()[0];
|
||||||
const import_str_node = import_param.cast(ast.Node.StringLiteral) orelse break :blk;
|
const import_str_node = import_param.castTag(.StringLiteral) orelse break :blk;
|
||||||
const import_str = tree.tokenSlice(import_str_node.token);
|
const import_str = tree.tokenSlice(import_str_node.token);
|
||||||
return import_str[1 .. import_str.len - 1];
|
return import_str[1 .. import_str.len - 1];
|
||||||
}
|
}
|
||||||
@ -1350,11 +1350,11 @@ pub fn documentPositionContext(arena: *std.heap.ArenaAllocator, document: types.
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn addOutlineNodes(allocator: *std.mem.Allocator, tree: *ast.Tree, child: *ast.Node, context: *GetDocumentSymbolsContext) anyerror!void {
|
fn addOutlineNodes(allocator: *std.mem.Allocator, tree: *ast.Tree, child: *ast.Node, context: *GetDocumentSymbolsContext) anyerror!void {
|
||||||
switch (child.id) {
|
switch (child.tag) {
|
||||||
.StringLiteral, .IntegerLiteral, .BuiltinCall, .Call, .Identifier, .InfixOp, .PrefixOp, .SuffixOp, .ControlFlowExpression, .ArrayInitializerDot, .SwitchElse, .SwitchCase, .For, .EnumLiteral, .PointerIndexPayload, .StructInitializerDot, .PointerPayload, .While, .Switch, .Else, .BoolLiteral, .NullLiteral, .Defer, .StructInitializer, .FieldInitializer, .If, .MultilineStringLiteral, .UndefinedLiteral, .AnyType, .Block, .ErrorSetDecl => return,
|
.StringLiteral, .IntegerLiteral, .BuiltinCall, .Call, .Identifier, .InfixOp, .PrefixOp, .SuffixOp, .ControlFlowExpression, .ArrayInitializerDot, .SwitchElse, .SwitchCase, .For, .EnumLiteral, .PointerIndexPayload, .StructInitializerDot, .PointerPayload, .While, .Switch, .Else, .BoolLiteral, .NullLiteral, .Defer, .StructInitializer, .FieldInitializer, .If, .MultilineStringLiteral, .UndefinedLiteral, .AnyType, .Block, .ErrorSetDecl => return,
|
||||||
|
|
||||||
.ContainerDecl => {
|
.ContainerDecl => {
|
||||||
const decl = child.cast(ast.Node.ContainerDecl).?;
|
const decl = child.castTag(.ContainerDecl).?;
|
||||||
|
|
||||||
for (decl.fieldsAndDecls()) |cchild|
|
for (decl.fieldsAndDecls()) |cchild|
|
||||||
try addOutlineNodes(allocator, tree, cchild, context);
|
try addOutlineNodes(allocator, tree, cchild, context);
|
||||||
@ -1400,7 +1400,7 @@ fn getDocumentSymbolsInternal(allocator: *std.mem.Allocator, tree: *ast.Tree, no
|
|||||||
|
|
||||||
(try context.symbols.addOne()).* = .{
|
(try context.symbols.addOne()).* = .{
|
||||||
.name = name,
|
.name = name,
|
||||||
.kind = switch (node.id) {
|
.kind = switch (node.tag) {
|
||||||
.FnProto => .Function,
|
.FnProto => .Function,
|
||||||
.VarDecl => .Variable,
|
.VarDecl => .Variable,
|
||||||
.ContainerField => .Field,
|
.ContainerField => .Field,
|
||||||
@ -1501,7 +1501,7 @@ pub const DeclWithHandle = struct {
|
|||||||
if (entry.key == param_decl) return entry.value;
|
if (entry.key == param_decl) return entry.value;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
} else if (type_node.cast(ast.Node.Identifier)) |type_ident| {
|
} else if (type_node.castTag(.Identifier)) |type_ident| {
|
||||||
if (param_decl.name_token) |name_tok| {
|
if (param_decl.name_token) |name_tok| {
|
||||||
if (std.mem.eql(u8, self.handle.tree.tokenSlice(type_ident.firstToken()), self.handle.tree.tokenSlice(name_tok)))
|
if (std.mem.eql(u8, self.handle.tree.tokenSlice(type_ident.firstToken()), self.handle.tree.tokenSlice(name_tok)))
|
||||||
return null;
|
return null;
|
||||||
@ -1546,12 +1546,12 @@ pub const DeclWithHandle = struct {
|
|||||||
if (!switch_expr_type.isUnionType())
|
if (!switch_expr_type.isUnionType())
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (pay.items[0].cast(ast.Node.EnumLiteral)) |enum_lit| {
|
if (pay.items[0].castTag(.EnumLiteral)) |enum_lit| {
|
||||||
const scope = findContainerScope(.{ .node = switch_expr_type.type.data.other, .handle = switch_expr_type.handle }) orelse return null;
|
const scope = findContainerScope(.{ .node = switch_expr_type.type.data.other, .handle = switch_expr_type.handle }) orelse return null;
|
||||||
if (scope.decls.getEntry(self.handle.tree.tokenSlice(enum_lit.name))) |candidate| {
|
if (scope.decls.getEntry(self.handle.tree.tokenSlice(enum_lit.name))) |candidate| {
|
||||||
switch (candidate.value) {
|
switch (candidate.value) {
|
||||||
.ast_node => |node| {
|
.ast_node => |node| {
|
||||||
if (node.cast(ast.Node.ContainerField)) |container_field| {
|
if (node.castTag(.ContainerField)) |container_field| {
|
||||||
if (container_field.type_expr) |type_expr| {
|
if (container_field.type_expr) |type_expr| {
|
||||||
return ((try resolveTypeOfNodeInternal(
|
return ((try resolveTypeOfNodeInternal(
|
||||||
store,
|
store,
|
||||||
@ -1577,7 +1577,7 @@ fn findContainerScope(container_handle: NodeWithHandle) ?*Scope {
|
|||||||
const container = container_handle.node;
|
const container = container_handle.node;
|
||||||
const handle = container_handle.handle;
|
const handle = container_handle.handle;
|
||||||
|
|
||||||
if (container.id != .ContainerDecl and container.id != .Root and container.id != .ErrorSetDecl) {
|
if (container.tag != .ContainerDecl and container.tag != .Root and container.tag != .ErrorSetDecl) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1608,7 +1608,7 @@ fn iterateSymbolsContainerInternal(
|
|||||||
const container = container_handle.node;
|
const container = container_handle.node;
|
||||||
const handle = container_handle.handle;
|
const handle = container_handle.handle;
|
||||||
|
|
||||||
const is_enum = if (container.cast(ast.Node.ContainerDecl)) |cont_decl|
|
const is_enum = if (container.castTag(.ContainerDecl)) |cont_decl|
|
||||||
handle.tree.token_ids[cont_decl.kind_token] == .Keyword_enum
|
handle.tree.token_ids[cont_decl.kind_token] == .Keyword_enum
|
||||||
else
|
else
|
||||||
false;
|
false;
|
||||||
@ -1618,7 +1618,7 @@ fn iterateSymbolsContainerInternal(
|
|||||||
while (decl_it.next()) |entry| {
|
while (decl_it.next()) |entry| {
|
||||||
switch (entry.value) {
|
switch (entry.value) {
|
||||||
.ast_node => |node| {
|
.ast_node => |node| {
|
||||||
if (node.id == .ContainerField) {
|
if (node.tag == .ContainerField) {
|
||||||
if (!instance_access and !is_enum) continue;
|
if (!instance_access and !is_enum) continue;
|
||||||
if (instance_access and is_enum) continue;
|
if (instance_access and is_enum) continue;
|
||||||
}
|
}
|
||||||
@ -1693,7 +1693,7 @@ fn iterateSymbolsGlobalInternal(
|
|||||||
if (source_index >= scope.range.start and source_index < scope.range.end) {
|
if (source_index >= scope.range.start and source_index < scope.range.end) {
|
||||||
var decl_it = scope.decls.iterator();
|
var decl_it = scope.decls.iterator();
|
||||||
while (decl_it.next()) |entry| {
|
while (decl_it.next()) |entry| {
|
||||||
if (entry.value == .ast_node and entry.value.ast_node.id == .ContainerField) continue;
|
if (entry.value == .ast_node and entry.value.ast_node.tag == .ContainerField) continue;
|
||||||
if (entry.value == .label_decl) continue;
|
if (entry.value == .label_decl) continue;
|
||||||
try callback(context, DeclWithHandle{ .decl = &entry.value, .handle = handle });
|
try callback(context, DeclWithHandle{ .decl = &entry.value, .handle = handle });
|
||||||
}
|
}
|
||||||
@ -1850,7 +1850,7 @@ fn lookupSymbolContainerInternal(
|
|||||||
const container = container_handle.node;
|
const container = container_handle.node;
|
||||||
const handle = container_handle.handle;
|
const handle = container_handle.handle;
|
||||||
|
|
||||||
const is_enum = if (container.cast(ast.Node.ContainerDecl)) |cont_decl|
|
const is_enum = if (container.castTag(.ContainerDecl)) |cont_decl|
|
||||||
handle.tree.token_ids[cont_decl.kind_token] == .Keyword_enum
|
handle.tree.token_ids[cont_decl.kind_token] == .Keyword_enum
|
||||||
else
|
else
|
||||||
false;
|
false;
|
||||||
@ -1859,7 +1859,7 @@ fn lookupSymbolContainerInternal(
|
|||||||
if (container_scope.decls.getEntry(symbol)) |candidate| {
|
if (container_scope.decls.getEntry(symbol)) |candidate| {
|
||||||
switch (candidate.value) {
|
switch (candidate.value) {
|
||||||
.ast_node => |node| {
|
.ast_node => |node| {
|
||||||
if (node.id == .ContainerField) {
|
if (node.tag == .ContainerField) {
|
||||||
if (!instance_access and !is_enum) return null;
|
if (!instance_access and !is_enum) return null;
|
||||||
if (instance_access and is_enum) return null;
|
if (instance_access and is_enum) return null;
|
||||||
}
|
}
|
||||||
@ -1987,11 +1987,11 @@ fn makeScopeInternal(
|
|||||||
tree: *ast.Tree,
|
tree: *ast.Tree,
|
||||||
node: *ast.Node,
|
node: *ast.Node,
|
||||||
) error{OutOfMemory}!void {
|
) error{OutOfMemory}!void {
|
||||||
if (node.id == .Root or node.id == .ContainerDecl or node.id == .ErrorSetDecl) {
|
if (node.tag == .Root or node.tag == .ContainerDecl or node.tag == .ErrorSetDecl) {
|
||||||
const ast_decls = switch (node.id) {
|
const ast_decls = switch (node.tag) {
|
||||||
.ContainerDecl => node.cast(ast.Node.ContainerDecl).?.fieldsAndDeclsConst(),
|
.ContainerDecl => node.castTag(.ContainerDecl).?.fieldsAndDeclsConst(),
|
||||||
.Root => node.cast(ast.Node.Root).?.declsConst(),
|
.Root => node.castTag(.Root).?.declsConst(),
|
||||||
.ErrorSetDecl => node.cast(ast.Node.ErrorSetDecl).?.declsConst(),
|
.ErrorSetDecl => node.castTag(.ErrorSetDecl).?.declsConst(),
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2013,19 +2013,19 @@ fn makeScopeInternal(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (ast_decls) |decl| {
|
for (ast_decls) |decl| {
|
||||||
if (decl.cast(ast.Node.Use)) |use| {
|
if (decl.castTag(.Use)) |use| {
|
||||||
try uses.append(use);
|
try uses.append(use);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
try makeScopeInternal(allocator, scopes, error_completions, enum_completions, tree, decl);
|
try makeScopeInternal(allocator, scopes, error_completions, enum_completions, tree, decl);
|
||||||
const name = getDeclName(tree, decl) orelse continue;
|
const name = getDeclName(tree, decl) orelse continue;
|
||||||
if (decl.id == .TestDecl) {
|
if (decl.tag == .TestDecl) {
|
||||||
try tests.append(decl);
|
try tests.append(decl);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.id == .ErrorSetDecl) {
|
if (node.tag == .ErrorSetDecl) {
|
||||||
(try error_completions.addOne(allocator)).* = .{
|
(try error_completions.addOne(allocator)).* = .{
|
||||||
.label = name,
|
.label = name,
|
||||||
.kind = .Constant,
|
.kind = .Constant,
|
||||||
@ -2036,13 +2036,13 @@ fn makeScopeInternal(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decl.cast(ast.Node.ContainerField)) |field| {
|
if (decl.castTag(.ContainerField)) |field| {
|
||||||
const empty_field = field.type_expr == null and field.value_expr == null;
|
const empty_field = field.type_expr == null and field.value_expr == null;
|
||||||
if (empty_field and node.id == .Root) {
|
if (empty_field and node.tag == .Root) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.cast(ast.Node.ContainerDecl)) |container| {
|
if (node.castTag(.ContainerDecl)) |container| {
|
||||||
const kind = tree.token_ids[container.kind_token];
|
const kind = tree.token_ids[container.kind_token];
|
||||||
if (kind == .Keyword_struct or (kind == .Keyword_union and container.init_arg_expr == .None)) {
|
if (kind == .Keyword_struct or (kind == .Keyword_union and container.init_arg_expr == .None)) {
|
||||||
continue;
|
continue;
|
||||||
@ -2071,9 +2071,9 @@ fn makeScopeInternal(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (node.id) {
|
switch (node.tag) {
|
||||||
.FnProto => {
|
.FnProto => {
|
||||||
const func = node.cast(ast.Node.FnProto).?;
|
const func = node.castTag(.FnProto).?;
|
||||||
|
|
||||||
(try scopes.addOne(allocator)).* = .{
|
(try scopes.addOne(allocator)).* = .{
|
||||||
.range = nodeSourceRange(tree, node),
|
.range = nodeSourceRange(tree, node),
|
||||||
@ -2100,10 +2100,10 @@ fn makeScopeInternal(
|
|||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
.TestDecl => {
|
.TestDecl => {
|
||||||
return try makeScopeInternal(allocator, scopes, error_completions, enum_completions, tree, node.cast(ast.Node.TestDecl).?.body_node);
|
return try makeScopeInternal(allocator, scopes, error_completions, enum_completions, tree, node.castTag(.TestDecl).?.body_node);
|
||||||
},
|
},
|
||||||
.Block => {
|
.Block => {
|
||||||
const block = node.cast(ast.Node.Block).?;
|
const block = node.castTag(.Block).?;
|
||||||
if (block.label) |label| {
|
if (block.label) |label| {
|
||||||
std.debug.assert(tree.token_ids[label] == .Identifier);
|
std.debug.assert(tree.token_ids[label] == .Identifier);
|
||||||
var scope = try scopes.addOne(allocator);
|
var scope = try scopes.addOne(allocator);
|
||||||
@ -2141,13 +2141,13 @@ fn makeScopeInternal(
|
|||||||
|
|
||||||
var child_idx: usize = 0;
|
var child_idx: usize = 0;
|
||||||
while (node.iterate(child_idx)) |child_node| : (child_idx += 1) {
|
while (node.iterate(child_idx)) |child_node| : (child_idx += 1) {
|
||||||
if (child_node.cast(ast.Node.Use)) |use| {
|
if (child_node.castTag(.Use)) |use| {
|
||||||
try uses.append(use);
|
try uses.append(use);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
try makeScopeInternal(allocator, scopes, error_completions, enum_completions, tree, child_node);
|
try makeScopeInternal(allocator, scopes, error_completions, enum_completions, tree, child_node);
|
||||||
if (child_node.cast(ast.Node.VarDecl)) |var_decl| {
|
if (child_node.castTag(.VarDecl)) |var_decl| {
|
||||||
const name = tree.tokenSlice(var_decl.name_token);
|
const name = tree.tokenSlice(var_decl.name_token);
|
||||||
if (try scopes.items[scope_idx].decls.fetchPut(name, .{ .ast_node = child_node })) |existing| {
|
if (try scopes.items[scope_idx].decls.fetchPut(name, .{ .ast_node = child_node })) |existing| {
|
||||||
// TODO Record a redefinition error.
|
// TODO Record a redefinition error.
|
||||||
@ -2159,13 +2159,13 @@ fn makeScopeInternal(
|
|||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
.Comptime => {
|
.Comptime => {
|
||||||
return try makeScopeInternal(allocator, scopes, error_completions, enum_completions, tree, node.cast(ast.Node.Comptime).?.expr);
|
return try makeScopeInternal(allocator, scopes, error_completions, enum_completions, tree, node.castTag(.Comptime).?.expr);
|
||||||
},
|
},
|
||||||
.If => {
|
.If => {
|
||||||
const if_node = node.cast(ast.Node.If).?;
|
const if_node = node.castTag(.If).?;
|
||||||
|
|
||||||
if (if_node.payload) |payload| {
|
if (if_node.payload) |payload| {
|
||||||
std.debug.assert(payload.id == .PointerPayload);
|
std.debug.assert(payload.tag == .PointerPayload);
|
||||||
var scope = try scopes.addOne(allocator);
|
var scope = try scopes.addOne(allocator);
|
||||||
scope.* = .{
|
scope.* = .{
|
||||||
.range = .{
|
.range = .{
|
||||||
@ -2179,8 +2179,8 @@ fn makeScopeInternal(
|
|||||||
};
|
};
|
||||||
errdefer scope.decls.deinit();
|
errdefer scope.decls.deinit();
|
||||||
|
|
||||||
const ptr_payload = payload.cast(ast.Node.PointerPayload).?;
|
const ptr_payload = payload.castTag(.PointerPayload).?;
|
||||||
std.debug.assert(ptr_payload.value_symbol.id == .Identifier);
|
std.debug.assert(ptr_payload.value_symbol.tag == .Identifier);
|
||||||
const name = tree.tokenSlice(ptr_payload.value_symbol.firstToken());
|
const name = tree.tokenSlice(ptr_payload.value_symbol.firstToken());
|
||||||
try scope.decls.putNoClobber(name, .{
|
try scope.decls.putNoClobber(name, .{
|
||||||
.pointer_payload = .{
|
.pointer_payload = .{
|
||||||
@ -2193,7 +2193,7 @@ fn makeScopeInternal(
|
|||||||
|
|
||||||
if (if_node.@"else") |else_node| {
|
if (if_node.@"else") |else_node| {
|
||||||
if (else_node.payload) |payload| {
|
if (else_node.payload) |payload| {
|
||||||
std.debug.assert(payload.id == .Payload);
|
std.debug.assert(payload.tag == .Payload);
|
||||||
var scope = try scopes.addOne(allocator);
|
var scope = try scopes.addOne(allocator);
|
||||||
scope.* = .{
|
scope.* = .{
|
||||||
.range = .{
|
.range = .{
|
||||||
@ -2207,8 +2207,8 @@ fn makeScopeInternal(
|
|||||||
};
|
};
|
||||||
errdefer scope.decls.deinit();
|
errdefer scope.decls.deinit();
|
||||||
|
|
||||||
const err_payload = payload.cast(ast.Node.Payload).?;
|
const err_payload = payload.castTag(.Payload).?;
|
||||||
std.debug.assert(err_payload.error_symbol.id == .Identifier);
|
std.debug.assert(err_payload.error_symbol.tag == .Identifier);
|
||||||
const name = tree.tokenSlice(err_payload.error_symbol.firstToken());
|
const name = tree.tokenSlice(err_payload.error_symbol.firstToken());
|
||||||
try scope.decls.putNoClobber(name, .{ .ast_node = payload });
|
try scope.decls.putNoClobber(name, .{ .ast_node = payload });
|
||||||
}
|
}
|
||||||
@ -2216,7 +2216,7 @@ fn makeScopeInternal(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
.While => {
|
.While => {
|
||||||
const while_node = node.cast(ast.Node.While).?;
|
const while_node = node.castTag(.While).?;
|
||||||
if (while_node.label) |label| {
|
if (while_node.label) |label| {
|
||||||
std.debug.assert(tree.token_ids[label] == .Identifier);
|
std.debug.assert(tree.token_ids[label] == .Identifier);
|
||||||
var scope = try scopes.addOne(allocator);
|
var scope = try scopes.addOne(allocator);
|
||||||
@ -2238,7 +2238,7 @@ fn makeScopeInternal(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (while_node.payload) |payload| {
|
if (while_node.payload) |payload| {
|
||||||
std.debug.assert(payload.id == .PointerPayload);
|
std.debug.assert(payload.tag == .PointerPayload);
|
||||||
var scope = try scopes.addOne(allocator);
|
var scope = try scopes.addOne(allocator);
|
||||||
scope.* = .{
|
scope.* = .{
|
||||||
.range = .{
|
.range = .{
|
||||||
@ -2252,8 +2252,8 @@ fn makeScopeInternal(
|
|||||||
};
|
};
|
||||||
errdefer scope.decls.deinit();
|
errdefer scope.decls.deinit();
|
||||||
|
|
||||||
const ptr_payload = payload.cast(ast.Node.PointerPayload).?;
|
const ptr_payload = payload.castTag(.PointerPayload).?;
|
||||||
std.debug.assert(ptr_payload.value_symbol.id == .Identifier);
|
std.debug.assert(ptr_payload.value_symbol.tag == .Identifier);
|
||||||
const name = tree.tokenSlice(ptr_payload.value_symbol.firstToken());
|
const name = tree.tokenSlice(ptr_payload.value_symbol.firstToken());
|
||||||
try scope.decls.putNoClobber(name, .{
|
try scope.decls.putNoClobber(name, .{
|
||||||
.pointer_payload = .{
|
.pointer_payload = .{
|
||||||
@ -2266,7 +2266,7 @@ fn makeScopeInternal(
|
|||||||
|
|
||||||
if (while_node.@"else") |else_node| {
|
if (while_node.@"else") |else_node| {
|
||||||
if (else_node.payload) |payload| {
|
if (else_node.payload) |payload| {
|
||||||
std.debug.assert(payload.id == .Payload);
|
std.debug.assert(payload.tag == .Payload);
|
||||||
var scope = try scopes.addOne(allocator);
|
var scope = try scopes.addOne(allocator);
|
||||||
scope.* = .{
|
scope.* = .{
|
||||||
.range = .{
|
.range = .{
|
||||||
@ -2280,8 +2280,8 @@ fn makeScopeInternal(
|
|||||||
};
|
};
|
||||||
errdefer scope.decls.deinit();
|
errdefer scope.decls.deinit();
|
||||||
|
|
||||||
const err_payload = payload.cast(ast.Node.Payload).?;
|
const err_payload = payload.castTag(.Payload).?;
|
||||||
std.debug.assert(err_payload.error_symbol.id == .Identifier);
|
std.debug.assert(err_payload.error_symbol.tag == .Identifier);
|
||||||
const name = tree.tokenSlice(err_payload.error_symbol.firstToken());
|
const name = tree.tokenSlice(err_payload.error_symbol.firstToken());
|
||||||
try scope.decls.putNoClobber(name, .{ .ast_node = payload });
|
try scope.decls.putNoClobber(name, .{ .ast_node = payload });
|
||||||
}
|
}
|
||||||
@ -2289,7 +2289,7 @@ fn makeScopeInternal(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
.For => {
|
.For => {
|
||||||
const for_node = node.cast(ast.Node.For).?;
|
const for_node = node.castTag(.For).?;
|
||||||
if (for_node.label) |label| {
|
if (for_node.label) |label| {
|
||||||
std.debug.assert(tree.token_ids[label] == .Identifier);
|
std.debug.assert(tree.token_ids[label] == .Identifier);
|
||||||
var scope = try scopes.addOne(allocator);
|
var scope = try scopes.addOne(allocator);
|
||||||
@ -2310,9 +2310,9 @@ fn makeScopeInternal(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
std.debug.assert(for_node.payload.id == .PointerIndexPayload);
|
std.debug.assert(for_node.payload.tag == .PointerIndexPayload);
|
||||||
const ptr_idx_payload = for_node.payload.cast(ast.Node.PointerIndexPayload).?;
|
const ptr_idx_payload = for_node.payload.castTag(.PointerIndexPayload).?;
|
||||||
std.debug.assert(ptr_idx_payload.value_symbol.id == .Identifier);
|
std.debug.assert(ptr_idx_payload.value_symbol.tag == .Identifier);
|
||||||
|
|
||||||
var scope = try scopes.addOne(allocator);
|
var scope = try scopes.addOne(allocator);
|
||||||
scope.* = .{
|
scope.* = .{
|
||||||
@ -2336,7 +2336,7 @@ fn makeScopeInternal(
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (ptr_idx_payload.index_symbol) |index_symbol| {
|
if (ptr_idx_payload.index_symbol) |index_symbol| {
|
||||||
std.debug.assert(index_symbol.id == .Identifier);
|
std.debug.assert(index_symbol.tag == .Identifier);
|
||||||
const index_name = tree.tokenSlice(index_symbol.firstToken());
|
const index_name = tree.tokenSlice(index_symbol.firstToken());
|
||||||
if (try scope.decls.fetchPut(index_name, .{ .ast_node = index_symbol })) |existing| {
|
if (try scope.decls.fetchPut(index_name, .{ .ast_node = index_symbol })) |existing| {
|
||||||
// TODO Record a redefinition error
|
// TODO Record a redefinition error
|
||||||
@ -2350,11 +2350,11 @@ fn makeScopeInternal(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
.Switch => {
|
.Switch => {
|
||||||
const switch_node = node.cast(ast.Node.Switch).?;
|
const switch_node = node.castTag(.Switch).?;
|
||||||
for (switch_node.casesConst()) |case| {
|
for (switch_node.casesConst()) |case| {
|
||||||
if (case.*.cast(ast.Node.SwitchCase)) |case_node| {
|
if (case.*.castTag(.SwitchCase)) |case_node| {
|
||||||
if (case_node.payload) |payload| {
|
if (case_node.payload) |payload| {
|
||||||
std.debug.assert(payload.id == .PointerPayload);
|
std.debug.assert(payload.tag == .PointerPayload);
|
||||||
var scope = try scopes.addOne(allocator);
|
var scope = try scopes.addOne(allocator);
|
||||||
scope.* = .{
|
scope.* = .{
|
||||||
.range = .{
|
.range = .{
|
||||||
@ -2368,8 +2368,8 @@ fn makeScopeInternal(
|
|||||||
};
|
};
|
||||||
errdefer scope.decls.deinit();
|
errdefer scope.decls.deinit();
|
||||||
|
|
||||||
const ptr_payload = payload.cast(ast.Node.PointerPayload).?;
|
const ptr_payload = payload.castTag(.PointerPayload).?;
|
||||||
std.debug.assert(ptr_payload.value_symbol.id == .Identifier);
|
std.debug.assert(ptr_payload.value_symbol.tag == .Identifier);
|
||||||
const name = tree.tokenSlice(ptr_payload.value_symbol.firstToken());
|
const name = tree.tokenSlice(ptr_payload.value_symbol.firstToken());
|
||||||
try scope.decls.putNoClobber(name, .{
|
try scope.decls.putNoClobber(name, .{
|
||||||
.switch_payload = .{
|
.switch_payload = .{
|
||||||
@ -2384,7 +2384,7 @@ fn makeScopeInternal(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
.VarDecl => {
|
.VarDecl => {
|
||||||
const var_decl = node.cast(ast.Node.VarDecl).?;
|
const var_decl = node.castTag(.VarDecl).?;
|
||||||
if (var_decl.type_node) |type_node| {
|
if (var_decl.type_node) |type_node| {
|
||||||
try makeScopeInternal(allocator, scopes, error_completions, enum_completions, tree, type_node);
|
try makeScopeInternal(allocator, scopes, error_completions, enum_completions, tree, type_node);
|
||||||
}
|
}
|
||||||
|
@ -209,7 +209,7 @@ fn publishDiagnostics(arena: *std.heap.ArenaAllocator, handle: DocumentStore.Han
|
|||||||
|
|
||||||
if (tree.errors.len == 0) {
|
if (tree.errors.len == 0) {
|
||||||
for (tree.root_node.decls()) |decl| {
|
for (tree.root_node.decls()) |decl| {
|
||||||
switch (decl.id) {
|
switch (decl.tag) {
|
||||||
.FnProto => blk: {
|
.FnProto => blk: {
|
||||||
const func = decl.cast(std.zig.ast.Node.FnProto).?;
|
const func = decl.cast(std.zig.ast.Node.FnProto).?;
|
||||||
const is_extern = func.extern_export_inline_token != null;
|
const is_extern = func.extern_export_inline_token != null;
|
||||||
@ -320,7 +320,7 @@ fn nodeToCompletion(
|
|||||||
else
|
else
|
||||||
null;
|
null;
|
||||||
|
|
||||||
if (node.id == .ErrorSetDecl or node.id == .Root or node.id == .ContainerDecl) {
|
if (node.tag == .ErrorSetDecl or node.tag == .Root or node.tag == .ContainerDecl) {
|
||||||
const context = DeclToCompletionContext{
|
const context = DeclToCompletionContext{
|
||||||
.completions = list,
|
.completions = list,
|
||||||
.config = &config,
|
.config = &config,
|
||||||
@ -332,7 +332,7 @@ fn nodeToCompletion(
|
|||||||
|
|
||||||
if (is_type_val) return;
|
if (is_type_val) return;
|
||||||
|
|
||||||
switch (node.id) {
|
switch (node.tag) {
|
||||||
.FnProto => {
|
.FnProto => {
|
||||||
const func = node.cast(std.zig.ast.Node.FnProto).?;
|
const func = node.cast(std.zig.ast.Node.FnProto).?;
|
||||||
if (func.name_token) |name_token| {
|
if (func.name_token) |name_token| {
|
||||||
@ -557,7 +557,7 @@ fn hoverSymbol(id: types.RequestId, arena: *std.heap.ArenaAllocator, decl_handle
|
|||||||
else
|
else
|
||||||
"";
|
"";
|
||||||
|
|
||||||
const signature_str = switch (node.id) {
|
const signature_str = switch (node.tag) {
|
||||||
.VarDecl => blk: {
|
.VarDecl => blk: {
|
||||||
const var_decl = node.cast(std.zig.ast.Node.VarDecl).?;
|
const var_decl = node.cast(std.zig.ast.Node.VarDecl).?;
|
||||||
break :blk analysis.getVariableSignature(handle.tree, var_decl);
|
break :blk analysis.getVariableSignature(handle.tree, var_decl);
|
||||||
|
Loading…
Reference in New Issue
Block a user