ids -> tags (part 1)

This commit is contained in:
SuperAuguste 2020-07-16 10:56:22 -04:00
parent 6eee43af2f
commit da4d2c2be1
2 changed files with 136 additions and 136 deletions

View File

@ -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);
} }

View File

@ -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);