From 2415e7ca6d12b7f1941459dac29f3a298b61488f Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Tue, 30 Mar 2021 20:59:58 +0300 Subject: [PATCH] Removed all zig.ast.Tree methods that call lastToken with our own versions --- src/analysis.zig | 111 ++------------- src/ast.zig | 309 ++++++++++++++++++++++++++++++++++++++++ src/main.zig | 8 +- src/references.zig | 23 ++- src/semantic_tokens.zig | 26 ++-- 5 files changed, 342 insertions(+), 135 deletions(-) diff --git a/src/analysis.zig b/src/analysis.zig index 88a7451..16b3f5b 100644 --- a/src/analysis.zig +++ b/src/analysis.zig @@ -726,7 +726,13 @@ pub fn resolveTypeOfNodeInternal( }; } - if (try lookupSymbolGlobal(store, arena, handle, tree.getNodeSource(node), starts[main_tokens[node]])) |child| { + if (try lookupSymbolGlobal( + store, + arena, + handle, + tree.getNodeSource(node), + starts[main_tokens[node]], + )) |child| { switch (child.decl.*) { .ast_node => |n| { if (n == node) return null; @@ -1443,28 +1449,6 @@ fn nodeContainsSourceIndex(tree: ast.Tree, node: ast.Node.Index, source_index: u return source_index >= first_token and source_index <= last_token; } -fn isBuiltinCall(tree: ast.Tree, node: ast.Node.Index) bool { - return switch (tree.nodes.items(.tag)[node]) { - .builtin_call, - .builtin_call_comma, - .builtin_call_two, - .builtin_call_two_comma, - => true, - else => false, - }; -} - -pub fn fnProto(tree: ast.Tree, node: ast.Node.Index, buf: *[1]ast.Node.Index) ?ast.full.FnProto { - return switch (tree.nodes.items(.tag)[node]) { - .fn_proto => tree.fnProto(node), - .fn_proto_multi => tree.fnProtoMulti(node), - .fn_proto_one => tree.fnProtoOne(buf, node), - .fn_proto_simple => tree.fnProtoSimple(buf, node), - .fn_decl => fnProto(tree, tree.nodes.items(.data)[node].lhs, buf), - else => null, - }; -} - pub fn getImportStr(tree: ast.Tree, node: ast.Node.Index, source_index: usize) ?[]const u8 { const node_tags = tree.nodes.items(.tag); var buf: [2]ast.Node.Index = undefined; @@ -2058,25 +2042,6 @@ pub const DeclWithHandle = struct { } }; -pub fn containerField(tree: ast.Tree, node: ast.Node.Index) ?ast.full.ContainerField { - return switch (tree.nodes.items(.tag)[node]) { - .container_field => tree.containerField(node), - .container_field_init => tree.containerFieldInit(node), - .container_field_align => tree.containerFieldAlign(node), - else => null, - }; -} - -pub fn ptrType(tree: ast.Tree, node: ast.Node.Index) ?ast.full.PtrType { - return switch (tree.nodes.items(.tag)[node]) { - .ptr_type => tree.ptrType(node), - .ptr_type_aligned => tree.ptrTypeAligned(node), - .ptr_type_bit_range => tree.ptrTypeBitRange(node), - .ptr_type_sentinel => tree.ptrTypeSentinel(node), - else => null, - }; -} - fn findContainerScope(container_handle: NodeWithHandle) ?*Scope { const container = container_handle.node; const handle = container_handle.handle; @@ -2551,56 +2516,6 @@ fn nodeSourceRange(tree: ast.Tree, node: ast.Node.Index) SourceRange { }; } -pub fn isContainer(tree: ast.Tree, node: ast.Node.Index) bool { - return switch (tree.nodes.items(.tag)[node]) { - .container_decl, - .container_decl_trailing, - .container_decl_arg, - .container_decl_arg_trailing, - .container_decl_two, - .container_decl_two_trailing, - .tagged_union, - .tagged_union_trailing, - .tagged_union_two, - .tagged_union_two_trailing, - .tagged_union_enum_tag, - .tagged_union_enum_tag_trailing, - .root, - .error_set_decl, - => true, - else => false, - }; -} - -/// Returns the member indices of a given declaration container. -/// Asserts given `tag` is a container node -pub fn declMembers(tree: ast.Tree, node_idx: ast.Node.Index, buffer: *[2]ast.Node.Index) []const ast.Node.Index { - std.debug.assert(isContainer(tree, node_idx)); - return switch (tree.nodes.items(.tag)[node_idx]) { - .container_decl, .container_decl_trailing => tree.containerDecl(node_idx).ast.members, - .container_decl_arg, .container_decl_arg_trailing => tree.containerDeclArg(node_idx).ast.members, - .container_decl_two, .container_decl_two_trailing => tree.containerDeclTwo(buffer, node_idx).ast.members, - .tagged_union, .tagged_union_trailing => tree.taggedUnion(node_idx).ast.members, - .tagged_union_enum_tag, .tagged_union_enum_tag_trailing => tree.taggedUnionEnumTag(node_idx).ast.members, - .tagged_union_two, .tagged_union_two_trailing => tree.taggedUnionTwo(buffer, node_idx).ast.members, - .root => tree.rootDecls(), - .error_set_decl => &[_]ast.Node.Index{}, - else => unreachable, - }; -} - -/// Returns an `ast.full.VarDecl` for a given node index. -/// Returns null if the tag doesn't match -pub fn varDecl(tree: ast.Tree, node_idx: ast.Node.Index) ?ast.full.VarDecl { - return switch (tree.nodes.items(.tag)[node_idx]) { - .global_var_decl => tree.globalVarDecl(node_idx), - .local_var_decl => tree.localVarDecl(node_idx), - .aligned_var_decl => tree.alignedVarDecl(node_idx), - .simple_var_decl => tree.simpleVarDecl(node_idx), - else => null, - }; -} - // TODO Possibly collect all imports to diff them on changes // as well fn makeScopeInternal( @@ -2890,7 +2805,7 @@ fn makeScopeInternal( const if_node: ast.full.If = if (node_tag == .@"if") ifFull(tree, node_idx) else - tree.ifSimple(node_idx); + ifSimple(tree, node_idx); if (if_node.payload_token) |payload| { var scope = try scopes.addOne(allocator); @@ -2962,15 +2877,7 @@ fn makeScopeInternal( .@"for", .for_simple, => { - const while_node: ast.full.While = switch (node_tag) { - .@"while" => tree.whileFull(node_idx), - .while_simple => tree.whileSimple(node_idx), - .while_cont => tree.whileCont(node_idx), - .@"for" => tree.forFull(node_idx), - .for_simple => tree.forSimple(node_idx), - else => unreachable, - }; - + const while_node = whileAst(tree, node_idx).?; const is_for = node_tag == .@"for" or node_tag == .for_simple; if (while_node.label_token) |label| { diff --git a/src/ast.zig b/src/ast.zig index 80f387f..062d535 100644 --- a/src/ast.zig +++ b/src/ast.zig @@ -9,6 +9,109 @@ const Node = ast.Node; const full = ast.full; const assert = std.debug.assert; +fn fullPtrType(tree: Tree, info: full.PtrType.Ast) full.PtrType { + const token_tags = tree.tokens.items(.tag); + // TODO: looks like stage1 isn't quite smart enough to handle enum + // literals in some places here + const Size = std.builtin.TypeInfo.Pointer.Size; + const size: Size = switch (token_tags[info.main_token]) { + .asterisk, + .asterisk_asterisk, + => switch (token_tags[info.main_token + 1]) { + .r_bracket, .colon => .Many, + .identifier => if (token_tags[info.main_token - 1] == .l_bracket) Size.C else .One, + else => .One, + }, + .l_bracket => Size.Slice, + else => unreachable, + }; + var result: full.PtrType = .{ + .size = size, + .allowzero_token = null, + .const_token = null, + .volatile_token = null, + .ast = info, + }; + // We need to be careful that we don't iterate over any sub-expressions + // here while looking for modifiers as that could result in false + // positives. Therefore, start after a sentinel if there is one and + // skip over any align node and bit range nodes. + var i = if (info.sentinel != 0) lastToken(tree, info.sentinel) + 1 else info.main_token; + const end = tree.firstToken(info.child_type); + while (i < end) : (i += 1) { + switch (token_tags[i]) { + .keyword_allowzero => result.allowzero_token = i, + .keyword_const => result.const_token = i, + .keyword_volatile => result.volatile_token = i, + .keyword_align => { + assert(info.align_node != 0); + if (info.bit_range_end != 0) { + assert(info.bit_range_start != 0); + i = lastToken(tree, info.bit_range_end) + 1; + } else { + i = lastToken(tree, info.align_node) + 1; + } + }, + else => {}, + } + } + return result; +} + +pub fn ptrTypeSimple(tree: Tree, node: Node.Index) full.PtrType { + assert(tree.nodes.items(.tag)[node] == .ptr_type); + const data = tree.nodes.items(.data)[node]; + const extra = tree.extraData(data.lhs, Node.PtrType); + return fullPtrType(tree, .{ + .main_token = tree.nodes.items(.main_token)[node], + .align_node = extra.align_node, + .sentinel = extra.sentinel, + .bit_range_start = 0, + .bit_range_end = 0, + .child_type = data.rhs, + }); +} + +pub fn ptrTypeSentinel(tree: Tree, node: Node.Index) full.PtrType { + assert(tree.nodes.items(.tag)[node] == .ptr_type_sentinel); + const data = tree.nodes.items(.data)[node]; + return fullPtrType(tree, .{ + .main_token = tree.nodes.items(.main_token)[node], + .align_node = 0, + .sentinel = data.lhs, + .bit_range_start = 0, + .bit_range_end = 0, + .child_type = data.rhs, + }); +} + +pub fn ptrTypeAligned(tree: Tree, node: Node.Index) full.PtrType { + assert(tree.nodes.items(.tag)[node] == .ptr_type_aligned); + const data = tree.nodes.items(.data)[node]; + return fullPtrType(tree, .{ + .main_token = tree.nodes.items(.main_token)[node], + .align_node = data.lhs, + .sentinel = 0, + .bit_range_start = 0, + .bit_range_end = 0, + .child_type = data.rhs, + }); +} + +pub fn ptrTypeBitRange(tree: Tree, node: Node.Index) full.PtrType { + assert(tree.nodes.items(.tag)[node] == .ptr_type_bit_range); + const data = tree.nodes.items(.data)[node]; + const extra = tree.extraData(data.lhs, Node.PtrTypeBitRange); + return fullPtrType(tree, .{ + .main_token = tree.nodes.items(.main_token)[node], + .align_node = extra.align_node, + .sentinel = extra.sentinel, + .bit_range_start = extra.bit_range_start, + .bit_range_end = extra.bit_range_end, + .child_type = data.rhs, + }); +} + fn fullIf(tree: Tree, info: full.If.Ast) full.If { const token_tags = tree.tokens.items(.tag); var result: full.If = .{ @@ -46,6 +149,110 @@ pub fn ifFull(tree: Tree, node: Node.Index) full.If { }); } +pub fn ifSimple(tree: Tree, node: Node.Index) full.If { + assert(tree.nodes.items(.tag)[node] == .if_simple); + const data = tree.nodes.items(.data)[node]; + return fullIf(tree, .{ + .cond_expr = data.lhs, + .then_expr = data.rhs, + .else_expr = 0, + .if_token = tree.nodes.items(.main_token)[node], + }); +} + +fn fullWhile(tree: Tree, info: full.While.Ast) full.While { + const token_tags = tree.tokens.items(.tag); + var result: full.While = .{ + .ast = info, + .inline_token = null, + .label_token = null, + .payload_token = null, + .else_token = undefined, + .error_token = null, + }; + var tok_i = info.while_token - 1; + if (token_tags[tok_i] == .keyword_inline) { + result.inline_token = tok_i; + tok_i -= 1; + } + if (token_tags[tok_i] == .colon and + token_tags[tok_i - 1] == .identifier) + { + result.label_token = tok_i - 1; + } + const last_cond_token = lastToken(tree, info.cond_expr); + if (token_tags[last_cond_token + 2] == .pipe) { + result.payload_token = last_cond_token + 3; + } + if (info.else_expr != 0) { + // then_expr else |x| + // ^ ^ + result.else_token = lastToken(tree, info.then_expr) + 1; + if (token_tags[result.else_token + 1] == .pipe) { + result.error_token = result.else_token + 2; + } + } + return result; +} + +pub fn whileSimple(tree: Tree, node: Node.Index) full.While { + const data = tree.nodes.items(.data)[node]; + return fullWhile(tree, .{ + .while_token = tree.nodes.items(.main_token)[node], + .cond_expr = data.lhs, + .cont_expr = 0, + .then_expr = data.rhs, + .else_expr = 0, + }); +} + +pub fn whileCont(tree: Tree, node: Node.Index) full.While { + const data = tree.nodes.items(.data)[node]; + const extra = tree.extraData(data.rhs, Node.WhileCont); + return fullWhile(tree, .{ + .while_token = tree.nodes.items(.main_token)[node], + .cond_expr = data.lhs, + .cont_expr = extra.cont_expr, + .then_expr = extra.then_expr, + .else_expr = 0, + }); +} + +pub fn whileFull(tree: Tree, node: Node.Index) full.While { + const data = tree.nodes.items(.data)[node]; + const extra = tree.extraData(data.rhs, Node.While); + return fullWhile(tree, .{ + .while_token = tree.nodes.items(.main_token)[node], + .cond_expr = data.lhs, + .cont_expr = extra.cont_expr, + .then_expr = extra.then_expr, + .else_expr = extra.else_expr, + }); +} + +pub fn forSimple(tree: Tree, node: Node.Index) full.While { + const data = tree.nodes.items(.data)[node]; + return fullWhile(tree, .{ + .while_token = tree.nodes.items(.main_token)[node], + .cond_expr = data.lhs, + .cont_expr = 0, + .then_expr = data.rhs, + .else_expr = 0, + }); +} + +pub fn forFull(tree: Tree, node: Node.Index) full.While { + const data = tree.nodes.items(.data)[node]; + const extra = tree.extraData(data.rhs, Node.If); + return fullWhile(tree, .{ + .while_token = tree.nodes.items(.main_token)[node], + .cond_expr = data.lhs, + .cont_expr = 0, + .then_expr = extra.then_expr, + .else_expr = extra.else_expr, + }); +} + pub fn lastToken(tree: ast.Tree, node: ast.Node.Index) ast.TokenIndex { const TokenIndex = ast.TokenIndex; const tags = tree.nodes.items(.tag); @@ -558,3 +765,105 @@ pub fn lastToken(tree: ast.Tree, node: ast.Node.Index) ast.TokenIndex { }, }; } + +pub fn containerField(tree: ast.Tree, node: ast.Node.Index) ?ast.full.ContainerField { + return switch (tree.nodes.items(.tag)[node]) { + .container_field => tree.containerField(node), + .container_field_init => tree.containerFieldInit(node), + .container_field_align => tree.containerFieldAlign(node), + else => null, + }; +} + +pub fn ptrType(tree: ast.Tree, node: ast.Node.Index) ?ast.full.PtrType { + return switch (tree.nodes.items(.tag)[node]) { + .ptr_type => ptrTypeSimple(tree, node), + .ptr_type_aligned => ptrTypeAligned(tree, node), + .ptr_type_bit_range => ptrTypeBitRange(tree, node), + .ptr_type_sentinel => ptrTypeSentinel(tree, node), + else => null, + }; +} + +pub fn whileAst(tree: ast.Tree, node: ast.Node.Index) ?ast.full.While { + return switch (tree.nodes.items(.tag)[node]) { + .@"while" => whileFull(tree, node), + .while_simple => whileSimple(tree, node), + .while_cont => whileCont(tree, node), + .@"for" => forFull(tree, node), + .for_simple => forSimple(tree, node), + else => null, + }; +} + +pub fn isContainer(tree: ast.Tree, node: ast.Node.Index) bool { + return switch (tree.nodes.items(.tag)[node]) { + .container_decl, + .container_decl_trailing, + .container_decl_arg, + .container_decl_arg_trailing, + .container_decl_two, + .container_decl_two_trailing, + .tagged_union, + .tagged_union_trailing, + .tagged_union_two, + .tagged_union_two_trailing, + .tagged_union_enum_tag, + .tagged_union_enum_tag_trailing, + .root, + .error_set_decl, + => true, + else => false, + }; +} + +/// Returns the member indices of a given declaration container. +/// Asserts given `tag` is a container node +pub fn declMembers(tree: ast.Tree, node_idx: ast.Node.Index, buffer: *[2]ast.Node.Index) []const ast.Node.Index { + std.debug.assert(isContainer(tree, node_idx)); + return switch (tree.nodes.items(.tag)[node_idx]) { + .container_decl, .container_decl_trailing => tree.containerDecl(node_idx).ast.members, + .container_decl_arg, .container_decl_arg_trailing => tree.containerDeclArg(node_idx).ast.members, + .container_decl_two, .container_decl_two_trailing => tree.containerDeclTwo(buffer, node_idx).ast.members, + .tagged_union, .tagged_union_trailing => tree.taggedUnion(node_idx).ast.members, + .tagged_union_enum_tag, .tagged_union_enum_tag_trailing => tree.taggedUnionEnumTag(node_idx).ast.members, + .tagged_union_two, .tagged_union_two_trailing => tree.taggedUnionTwo(buffer, node_idx).ast.members, + .root => tree.rootDecls(), + .error_set_decl => &[_]ast.Node.Index{}, + else => unreachable, + }; +} + +/// Returns an `ast.full.VarDecl` for a given node index. +/// Returns null if the tag doesn't match +pub fn varDecl(tree: ast.Tree, node_idx: ast.Node.Index) ?ast.full.VarDecl { + return switch (tree.nodes.items(.tag)[node_idx]) { + .global_var_decl => tree.globalVarDecl(node_idx), + .local_var_decl => tree.localVarDecl(node_idx), + .aligned_var_decl => tree.alignedVarDecl(node_idx), + .simple_var_decl => tree.simpleVarDecl(node_idx), + else => null, + }; +} + +pub fn isBuiltinCall(tree: ast.Tree, node: ast.Node.Index) bool { + return switch (tree.nodes.items(.tag)[node]) { + .builtin_call, + .builtin_call_comma, + .builtin_call_two, + .builtin_call_two_comma, + => true, + else => false, + }; +} + +pub fn fnProto(tree: ast.Tree, node: ast.Node.Index, buf: *[1]ast.Node.Index) ?ast.full.FnProto { + return switch (tree.nodes.items(.tag)[node]) { + .fn_proto => tree.fnProto(node), + .fn_proto_multi => tree.fnProtoMulti(node), + .fn_proto_one => tree.fnProtoOne(buf, node), + .fn_proto_simple => tree.fnProtoSimple(buf, node), + .fn_decl => fnProto(tree, tree.nodes.items(.data)[node].lhs, buf), + else => null, + }; +} diff --git a/src/main.zig b/src/main.zig index 3806644..94e8656 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1106,7 +1106,13 @@ fn completeBuiltin(arena: *std.heap.ArenaAllocator, id: types.RequestId, config: }); } -fn completeGlobal(arena: *std.heap.ArenaAllocator, id: types.RequestId, pos_index: usize, handle: *DocumentStore.Handle, config: Config) !void { +fn completeGlobal( + arena: *std.heap.ArenaAllocator, + id: types.RequestId, + pos_index: usize, + handle: *DocumentStore.Handle, + config: Config, +) !void { var completions = std.ArrayList(types.CompletionItem).init(&arena.allocator); const context = DeclToCompletionContext{ diff --git a/src/references.zig b/src/references.zig index c91f407..a8bb920 100644 --- a/src/references.zig +++ b/src/references.zig @@ -120,7 +120,7 @@ fn symbolReferencesInternal( .error_set_decl, => { var buf: [2]ast.Node.Index = undefined; - for (analysis.declMembers(tree, node, &buf)) |member| + for (declMembers(tree, node, &buf)) |member| try symbolReferencesInternal(arena, store, .{ .node = member, .handle = handle }, decl, encoding, context, handler); }, .global_var_decl, @@ -128,7 +128,7 @@ fn symbolReferencesInternal( .simple_var_decl, .aligned_var_decl, => { - const var_decl = analysis.varDecl(tree, node).?; + const var_decl = varDecl(tree, node).?; if (var_decl.ast.type_node != 0) { try symbolReferencesInternal(arena, store, .{ .node = var_decl.ast.type_node, .handle = handle }, decl, encoding, context, handler); } @@ -143,7 +143,7 @@ fn symbolReferencesInternal( .container_field_align, .container_field_init, => { - const field = analysis.containerField(tree, node).?; + const field = containerField(tree, node).?; if (field.ast.type_expr != 0) { try symbolReferencesInternal(arena, store, .{ .node = field.ast.type_expr, .handle = handle }, decl, encoding, context, handler); } @@ -165,7 +165,7 @@ fn symbolReferencesInternal( .fn_decl, => { var buf: [1]ast.Node.Index = undefined; - const fn_proto = analysis.fnProto(tree, node, &buf).?; + const fn_proto = fnProto(tree, node, &buf).?; var it = fn_proto.iterate(tree); while (it.next()) |param| { if (param.type_expr != 0) @@ -231,14 +231,7 @@ fn symbolReferencesInternal( .for_simple, .@"for", => { - const loop: ast.full.While = switch (node_tags[node]) { - .@"while" => tree.whileFull(node), - .while_simple => tree.whileSimple(node), - .while_cont => tree.whileCont(node), - .for_simple => tree.forSimple(node), - .@"for" => tree.forFull(node), - else => unreachable, - }; + const loop = whileAst(tree, node).?; try symbolReferencesInternal(arena, store, .{ .node = loop.ast.cond_expr, .handle = handle }, decl, encoding, context, handler); if (loop.ast.cont_expr != 0) { try symbolReferencesInternal(arena, store, .{ .node = loop.ast.cont_expr, .handle = handle }, decl, encoding, context, handler); @@ -251,7 +244,7 @@ fn symbolReferencesInternal( .@"if", .if_simple, => { - const if_node: ast.full.If = if (node_tags[node] == .@"if") ifFull(tree, node) else tree.ifSimple(node); + const if_node: ast.full.If = if (node_tags[node] == .@"if") ifFull(tree, node) else ifSimple(tree, node); try symbolReferencesInternal(arena, store, .{ .node = if_node.ast.cond_expr, .handle = handle }, decl, encoding, context, handler); try symbolReferencesInternal(arena, store, .{ .node = if_node.ast.then_expr, .handle = handle }, decl, encoding, context, handler); @@ -270,7 +263,7 @@ fn symbolReferencesInternal( .ptr_type_bit_range, .ptr_type_sentinel, => { - const ptr_type = analysis.ptrType(tree, node).?; + const ptr_type = ptrType(tree, node).?; if (ptr_type.ast.align_node != 0) { try symbolReferencesInternal(arena, store, .{ .node = ptr_type.ast.align_node, .handle = handle }, decl, encoding, context, handler); @@ -582,7 +575,7 @@ pub fn symbolReferences( switch (scope.data) { .function => |proto| { var buf: [1]ast.Node.Index = undefined; - const fn_proto = analysis.fnProto(curr_handle.tree, proto, &buf).?; + const fn_proto = fnProto(curr_handle.tree, proto, &buf).?; var it = fn_proto.iterate(curr_handle.tree); while (it.next()) |candidate| { if (std.meta.eql(candidate, param)) { diff --git a/src/semantic_tokens.zig b/src/semantic_tokens.zig index 72cecd0..eab9747 100644 --- a/src/semantic_tokens.zig +++ b/src/semantic_tokens.zig @@ -329,7 +329,7 @@ fn writeContainerField( field_token_type: ?TokenType, child_frame: anytype, ) !void { - const container_field = analysis.containerField(builder.handle.tree, node).?; + const container_field = containerField(builder.handle.tree, node).?; if (analysis.getDocCommentTokenIndex(builder.handle.tree, node)) |docs| try writeDocComments(builder, builder.handle.tree, docs); @@ -443,7 +443,7 @@ fn writeNodeTokens( .simple_var_decl, .aligned_var_decl, => { - const var_decl = analysis.varDecl(tree, node).?; + const var_decl = varDecl(tree, node).?; if (analysis.getDocCommentTokenIndex(tree, node)) |comment_idx| try writeDocComments(builder, handle.tree, comment_idx); @@ -558,7 +558,7 @@ fn writeNodeTokens( .fn_decl, => { var buf: [1]ast.Node.Index = undefined; - const fn_proto: ast.full.FnProto = analysis.fnProto(tree, node, &buf).?; + const fn_proto: ast.full.FnProto = fnProto(tree, node, &buf).?; if (analysis.getDocCommentTokenIndex(tree, node)) |docs| try writeDocComments(builder, handle.tree, docs); @@ -657,15 +657,7 @@ fn writeNodeTokens( .for_simple, .@"for", => { - const while_node: ast.full.While = switch (tag) { - .@"while" => tree.whileFull(node), - .while_simple => tree.whileSimple(node), - .while_cont => tree.whileCont(node), - .@"for" => tree.forFull(node), - .for_simple => tree.forSimple(node), - else => unreachable, - }; - + const while_node = whileAst(tree, node).?; try writeToken(builder, while_node.label_token, .label); try writeToken(builder, while_node.inline_token, .keyword); try writeToken(builder, while_node.ast.while_token, .keyword); @@ -700,7 +692,7 @@ fn writeNodeTokens( .@"if", .if_simple, => { - const if_node: ast.full.If = if (tag == .@"if") ifFull(tree, node) else tree.ifSimple(node); + const if_node: ast.full.If = if (tag == .@"if") ifFull(tree, node) else ifSimple(tree, node); try writeToken(builder, if_node.ast.if_token, .keyword); try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, if_node.ast.cond_expr }); @@ -773,7 +765,7 @@ fn writeNodeTokens( .node = struct_init.ast.type_expr, .handle = handle, })) |struct_type| switch (struct_type.type.data) { - .other => |type_node| if (analysis.isContainer(struct_type.handle.tree, type_node)) + .other => |type_node| if (isContainer(struct_type.handle.tree, type_node)) fieldTokenType(type_node, struct_type.handle) else null, @@ -1039,7 +1031,7 @@ fn writeNodeTokens( switch (decl_type.decl.*) { .ast_node => |decl_node| { if (decl_type.handle.tree.nodes.items(.tag)[decl_node].isContainerField()) { - const tok_type: ?TokenType = if (analysis.isContainer(lhs_type.handle.tree, left_type_node)) + const tok_type: ?TokenType = if (isContainer(lhs_type.handle.tree, left_type_node)) fieldTokenType(decl_node, lhs_type.handle) else if (left_type_node == 0) TokenType.field @@ -1065,7 +1057,7 @@ fn writeNodeTokens( .ptr_type_bit_range, .ptr_type_sentinel, => { - const ptr_type = analysis.ptrType(tree, node).?; + const ptr_type = ptrType(tree, node).?; if (ptr_type.size == .One and token_tags[main_token] == .asterisk_asterisk and main_token == main_tokens[ptr_type.ast.child_type]) @@ -1150,7 +1142,7 @@ pub fn writeAllSemanticTokens(arena: *std.heap.ArenaAllocator, store: *DocumentS var gap_highlighter = GapHighlighter.init(&builder, 0); var buf: [2]ast.Node.Index = undefined; - for (analysis.declMembers(handle.tree, 0, &buf)) |child| { + for (declMembers(handle.tree, 0, &buf)) |child| { try gap_highlighter.next(child); try writeNodeTokens(&builder, arena, store, child); }