From f00d09c74675e0d472901d5aeb43e1eea0576665 Mon Sep 17 00:00:00 2001 From: SuperAuguste Date: Thu, 16 Jul 2020 15:02:30 -0400 Subject: [PATCH] fix almost everything - commented some things out, please don't file any issues yet! --- src/analysis.zig | 91 ++++++++------- src/main.zig | 9 +- src/references.zig | 152 ++++++++++++++----------- src/semantic_tokens.zig | 247 ++++++++++++++++++++-------------------- 4 files changed, 259 insertions(+), 240 deletions(-) diff --git a/src/analysis.zig b/src/analysis.zig index 9143cd1..721bb28 100644 --- a/src/analysis.zig +++ b/src/analysis.zig @@ -71,7 +71,7 @@ pub fn getFunctionSignature(tree: *ast.Tree, func: *ast.Node.FnProto) []const u8 /// Gets a function snippet insert text pub fn getFunctionSnippet(allocator: *std.mem.Allocator, tree: *ast.Tree, func: *ast.Node.FnProto, skip_self_param: bool) ![]const u8 { - const name_tok = func.name_token orelse unreachable; + const name_tok = func.getTrailer("name_token") orelse unreachable; var buffer = std.ArrayList(u8).init(allocator); try buffer.ensureCapacity(128); @@ -101,7 +101,6 @@ pub fn getFunctionSnippet(allocator: *std.mem.Allocator, tree: *ast.Tree, func: } switch (param.param_type) { - .var_args => try buffer.appendSlice("..."), .any_type => try buffer.appendSlice("anytype"), .type_expr => |type_expr| { var curr_tok = type_expr.firstToken(); @@ -234,8 +233,8 @@ fn resolveVarDeclAliasInternal( return try lookupSymbolGlobal(store, arena, handle, handle.tree.tokenSlice(ident.token), handle.tree.token_locs[ident.token].start); } - if (node_handle.node.castTag(.InfixOp)) |infix_op| { - if (infix_op.op != .Period) return null; + if (node_handle.node.cast(ast.Node.SimpleInfixOp)) |infix_op| { + if (node_handle.node.tag != .Period) return null; 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")) @@ -278,8 +277,8 @@ pub fn resolveVarDeclAlias(store: *DocumentStore, arena: *std.heap.ArenaAllocato if (handle.tree.token_ids[var_decl.mut_token] != .Keyword_const) return null; const base_expr = var_decl.getTrailer("init_node").?; - if (base_expr.castTag(.InfixOp)) |infix_op| { - if (infix_op.op != .Period) return null; + if (base_expr.cast(ast.Node.SimpleInfixOp)) |infix_op| { + if (base_expr.tag != .Period) return null; const name = handle.tree.tokenSlice(infix_op.rhs.firstToken()); if (!std.mem.eql(u8, handle.tree.tokenSlice(var_decl.name_token), name)) return null; @@ -331,7 +330,7 @@ fn findReturnStatementInternal( fn findReturnStatement(tree: *ast.Tree, fn_decl: *ast.Node.FnProto) ?*ast.Node.ControlFlowExpression { var already_found = false; - return findReturnStatementInternal(tree, fn_decl, fn_decl.body_node.?, &already_found); + return findReturnStatementInternal(tree, fn_decl, fn_decl.getTrailer("body_node").?, &already_found); } /// Resolves the return type of a function @@ -342,7 +341,7 @@ fn resolveReturnType( handle: *DocumentStore.Handle, bound_type_params: *BoundTypeParams, ) !?TypeWithHandle { - if (isTypeFunction(handle.tree, fn_decl) and fn_decl.body_node != null) { + if (isTypeFunction(handle.tree, fn_decl) and fn_decl.trailer_flags.has("body_node")) { // If this is a type function and it only contains a single return statement that returns // a container declaration, we will return that declaration. const ret = findReturnStatement(handle.tree, fn_decl) orelse return null; @@ -388,8 +387,8 @@ fn resolveUnwrapOptionalType( else => return null, }; - if (opt_node.castTag(.PrefixOp)) |prefix_op| { - if (prefix_op.op == .OptionalType) { + if (opt_node.cast(ast.Node.SimplePrefixOp)) |prefix_op| { + if (opt_node.tag == .OptionalType) { return ((try resolveTypeOfNodeInternal(store, arena, .{ .node = prefix_op.rhs, .handle = opt.handle, @@ -415,8 +414,8 @@ fn resolveUnwrapErrorType( .primitive, .slice => return null, }; - if (rhs_node.castTag(.InfixOp)) |infix_op| { - if (infix_op.op == .ErrorUnion) { + if (rhs_node.cast(ast.Node.SimpleInfixOp)) |infix_op| { + if (rhs_node.tag == .ErrorUnion) { return ((try resolveTypeOfNodeInternal(store, arena, .{ .node = infix_op.rhs, .handle = rhs.handle, @@ -427,7 +426,7 @@ fn resolveUnwrapErrorType( return null; } -/// Resolves the child type of a defer type +/// Resolves the child type of a deref type fn resolveDerefType( store: *DocumentStore, arena: *std.heap.ArenaAllocator, @@ -439,8 +438,8 @@ fn resolveDerefType( else => return null, }; - if (deref_node.castTag(.PrefixOp)) |pop| { - if (pop.op == .PtrType) { + if (deref_node.cast(ast.Node.SimplePrefixOp)) |pop| { + if (deref_node.tag == .PtrType) { const op_token_id = deref.handle.tree.token_ids[pop.op_token]; switch (op_token_id) { .Asterisk => { @@ -470,8 +469,8 @@ fn resolveBracketAccessType( else => return null, }; - if (lhs_node.castTag(.PrefixOp)) |pop| { - switch (pop.op) { + if (lhs_node.cast(ast.Node.SimplePrefixOp)) |pop| { + switch (lhs_node.tag) { .SliceType => { if (rhs == .Single) return ((try resolveTypeOfNodeInternal(store, arena, .{ @@ -492,8 +491,8 @@ fn resolveBracketAccessType( }; }, .PtrType => { - if (pop.rhs.castTag(std.zig.ast.Node.PrefixOp)) |child_pop| { - switch (child_pop.op) { + if (pop.rhs.cast(ast.Node.SimplePrefixOp)) |child_pop| { + switch (pop.rhs.tag) { .ArrayType => { if (rhs == .Single) { return ((try resolveTypeOfNodeInternal(store, arena, .{ @@ -569,17 +568,17 @@ pub fn resolveTypeOfNodeInternal( switch (node.tag) { .VarDecl => { const vari = node.castTag(.VarDecl).?; - if (vari.type_node) |type_node| block: { + if (vari.getTrailer("type_node")) |type_node| block: { return ((try resolveTypeOfNodeInternal( store, arena, - .{ .node = vari.type_node orelse break :block, .handle = handle }, + .{ .node = vari.getTrailer("type_node") orelse break :block, .handle = handle }, bound_type_params, )) orelse break :block).instanceTypeVal(); } - if (vari.init_node == null) return null; + if (vari.getTrailer("init_node") == null) return null; - return try resolveTypeOfNodeInternal(store, arena, .{ .node = vari.init_node.?, .handle = handle }, bound_type_params); + return try resolveTypeOfNodeInternal(store, arena, .{ .node = vari.getTrailer("init_node").?, .handle = handle }, bound_type_params); }, .Identifier => { if (isTypeIdent(handle.tree, node.firstToken())) { @@ -623,8 +622,8 @@ pub fn resolveTypeOfNodeInternal( }; if (decl_node.castTag(.FnProto)) |fn_decl| { var has_self_param: u8 = 0; - if (call.lhs.castTag(.InfixOp)) |lhs_infix_op| { - if (lhs_infix_op.op == .Period) { + if (call.lhs.cast(ast.Node.SimpleInfixOp)) |lhs_infix_op| { + if (call.lhs.tag == .Period) { has_self_param = 1; } } @@ -688,10 +687,11 @@ pub fn resolveTypeOfNodeInternal( else => null, }; }, - .InfixOp => { - const infix_op = node.castTag(.InfixOp).?; - switch (infix_op.op) { + // .InfixOp => { + // const infix_op = node.castTag(.InfixOp).?; + // switch (infix_op.op) { .Period => { + const infix_op = node.cast(ast.Node.SimpleInfixOp).?; const rhs_str = nodeToString(handle.tree, infix_op.rhs) orelse return null; // If we are accessing a pointer type, remove one pointerness level :) const left_type = try resolveFieldAccessLhsType( @@ -720,6 +720,7 @@ pub fn resolveTypeOfNodeInternal( } else return null; }, .UnwrapOptional => { + const infix_op = node.cast(ast.Node.SimpleInfixOp).?; const left_type = (try resolveTypeOfNodeInternal(store, arena, .{ .node = infix_op.lhs, .handle = handle, @@ -727,6 +728,7 @@ pub fn resolveTypeOfNodeInternal( return try resolveUnwrapOptionalType(store, arena, left_type, bound_type_params); }, .Catch => { + const infix_op = node.cast(ast.Node.SimpleInfixOp).?; const left_type = (try resolveTypeOfNodeInternal(store, arena, .{ .node = infix_op.lhs, .handle = handle, @@ -734,27 +736,28 @@ pub fn resolveTypeOfNodeInternal( return try resolveUnwrapErrorType(store, arena, left_type, bound_type_params); }, .ErrorUnion => return TypeWithHandle.typeVal(node_handle), - else => return null, - } - }, - .PrefixOp => { - const prefix_op = node.castTag(.PrefixOp).?; - switch (prefix_op.op) { + // else => return null, + // } + // }, + // .PrefixOp => { + // const prefix_op = node.castTag(.PrefixOp).?; + // switch (prefix_op.op) { .SliceType, .ArrayType, .OptionalType, .PtrType, => return TypeWithHandle.typeVal(node_handle), .Try => { + const prefix_op = node.cast(ast.Node.SimplePrefixOp).?; const rhs_type = (try resolveTypeOfNodeInternal(store, arena, .{ .node = prefix_op.rhs, .handle = handle, }, bound_type_params)) orelse return null; return try resolveUnwrapErrorType(store, arena, rhs_type, bound_type_params); }, - else => {}, - } - }, + // else => {}, + // } + // }, .BuiltinCall => { const builtin_call = node.castTag(.BuiltinCall).?; const call_name = handle.tree.tokenSlice(builtin_call.builtin_token); @@ -819,7 +822,7 @@ pub fn resolveTypeOfNodeInternal( }, .FnProto => { // This is a function type - if (node.castTag(.FnProto).?.name_token == null) { + if (node.castTag(.FnProto).?.trailer_flags.has("name_token")) { return TypeWithHandle.typeVal(node_handle); } return TypeWithHandle{ @@ -973,16 +976,12 @@ pub fn collectImports(import_arr: *std.ArrayList([]const u8), tree: *ast.Tree) ! switch (var_decl.getTrailer("init_node").?.tag) { .BuiltinCall => { - const builtin_call = var_decl.init_node.?.castTag(.BuiltinCall).?; + const builtin_call = var_decl.getTrailer("init_node").?.castTag(.BuiltinCall).?; try maybeCollectImport(tree, builtin_call, import_arr); }, - .InfixOp => { - const infix_op = var_decl.init_node.?.castTag(.InfixOp).?; + .Period => { + const infix_op = var_decl.getTrailer("init_node").?.cast(ast.Node.SimpleInfixOp).?; - switch (infix_op.op) { - .Period => {}, - else => continue, - } if (infix_op.lhs.tag != .BuiltinCall) continue; try maybeCollectImport(tree, infix_op.lhs.castTag(.BuiltinCall).?, import_arr); }, @@ -1030,7 +1029,7 @@ pub fn getFieldAccessType( }, .Period => { const after_period = tokenizer.next(); - switch (after_period.tag) { + switch (after_period.id) { .Eof => return FieldAccessReturn{ .original = current_type, .unwrapped = try resolveDerefType(store, arena, current_type, &bound_type_params), diff --git a/src/main.zig b/src/main.zig index 31087cc..bf54ae1 100644 --- a/src/main.zig +++ b/src/main.zig @@ -353,8 +353,8 @@ fn nodeToCompletion( break :param_check true; } - if (type_node.cast(std.zig.ast.Node.PrefixOp)) |prefix_op| { - if (prefix_op.op == .PtrType) { + if (type_node.cast(std.zig.ast.Node.SimplePrefixOp)) |prefix_op| { + if (type_node.tag == .PtrType) { if (try analysis.resolveTypeOfNode(&document_store, arena, .{ .node = prefix_op.rhs, .handle = handle, @@ -427,8 +427,9 @@ fn nodeToCompletion( }); } - if (prefix_op.rhs.cast(std.zig.ast.Node.PrefixOp)) |child_pop| { - switch (child_pop.op) { + const prefix_op = node.cast(std.zig.ast.Node.SimplePrefixOp).?; + if (prefix_op.rhs.cast(std.zig.ast.Node.SimplePrefixOp)) |child_pop| { + switch (prefix_op.rhs.tag) { .ArrayType => { try list.append(.{ .label = "len", diff --git a/src/references.zig b/src/references.zig index e0bc5e4..870a7d4 100644 --- a/src/references.zig +++ b/src/references.zig @@ -84,10 +84,10 @@ fn symbolReferencesInternal( }, .VarDecl => { const var_decl = node.cast(ast.Node.VarDecl).?; - if (var_decl.type_node) |type_node| { + if (var_decl.getTrailer("type_node")) |type_node| { try symbolReferencesInternal(arena, store, .{ .node = type_node, .handle = handle }, decl, encoding, context, handler); } - if (var_decl.init_node) |init_node| { + if (var_decl.getTrailer("init_node")) |init_node| { try symbolReferencesInternal(arena, store, .{ .node = init_node, .handle = handle }, decl, encoding, context, handler); } }, @@ -127,16 +127,16 @@ fn symbolReferencesInternal( }, else => {}, } - if (fn_proto.align_expr) |align_expr| { + if (fn_proto.getTrailer("align_expr")) |align_expr| { try symbolReferencesInternal(arena, store, .{ .node = align_expr, .handle = handle }, decl, encoding, context, handler); } - if (fn_proto.section_expr) |section_expr| { + if (fn_proto.getTrailer("section_expr")) |section_expr| { try symbolReferencesInternal(arena, store, .{ .node = section_expr, .handle = handle }, decl, encoding, context, handler); } - if (fn_proto.callconv_expr) |callconv_expr| { + if (fn_proto.getTrailer("callconv_expr")) |callconv_expr| { try symbolReferencesInternal(arena, store, .{ .node = callconv_expr, .handle = handle }, decl, encoding, context, handler); } - if (fn_proto.body_node) |body| { + if (fn_proto.getTrailer("body_node")) |body| { try symbolReferencesInternal(arena, store, .{ .node = body, .handle = handle }, decl, encoding, context, handler); } }, @@ -195,70 +195,43 @@ fn symbolReferencesInternal( try symbolReferencesInternal(arena, store, .{ .node = else_node.body, .handle = handle }, decl, encoding, context, handler); } }, - .InfixOp => { - const infix_op = node.cast(ast.Node.InfixOp).?; - switch (infix_op.op) { - .Period => { - try symbolReferencesInternal(arena, store, .{ .node = infix_op.lhs, .handle = handle }, decl, encoding, context, handler); + .ArrayType => { + const info = node.castTag(.ArrayType).?; + const prefix_op = node.cast(ast.Node.SimplePrefixOp).?; - const rhs_str = analysis.nodeToString(handle.tree, infix_op.rhs) orelse return; - var bound_type_params = analysis.BoundTypeParams.init(&arena.allocator); - const left_type = try analysis.resolveFieldAccessLhsType( - store, - arena, - (try analysis.resolveTypeOfNodeInternal(store, arena, .{ - .node = infix_op.lhs, - .handle = handle, - }, &bound_type_params)) orelse return, - &bound_type_params, - ); - - const left_type_node = switch (left_type.type.data) { - .other => |n| n, - else => return, - }; - - if (try analysis.lookupSymbolContainer( - store, - arena, - .{ .node = left_type_node, .handle = left_type.handle }, - rhs_str, - !left_type.type.is_type_val, - )) |child| { - if (std.meta.eql(child, decl)) { - try tokenReference(handle, infix_op.rhs.firstToken(), encoding, context, handler); - } - } - }, - else => { - try symbolReferencesInternal(arena, store, .{ .node = infix_op.lhs, .handle = handle }, decl, encoding, context, handler); - try symbolReferencesInternal(arena, store, .{ .node = infix_op.rhs, .handle = handle }, decl, encoding, context, handler); - }, - } + try symbolReferencesInternal(arena, store, .{ .node = info.len_expr, .handle = handle }, decl, encoding, context, handler); + try symbolReferencesInternal(arena, store, .{ .node = prefix_op.rhs, .handle = handle }, decl, encoding, context, handler); }, - .PrefixOp => { - const prefix_op = node.cast(ast.Node.PrefixOp).?; - switch (prefix_op.op) { - .ArrayType => |info| { - try symbolReferencesInternal(arena, store, .{ .node = info.len_expr, .handle = handle }, decl, encoding, context, handler); - if (info.sentinel) |sentinel| { - try symbolReferencesInternal(arena, store, .{ .node = sentinel, .handle = handle }, decl, encoding, context, handler); - } - }, - .PtrType, .SliceType => |info| { - if (info.align_info) |align_info| { - try symbolReferencesInternal(arena, store, .{ .node = align_info.node, .handle = handle }, decl, encoding, context, handler); - if (align_info.bit_range) |range| { - try symbolReferencesInternal(arena, store, .{ .node = range.start, .handle = handle }, decl, encoding, context, handler); - try symbolReferencesInternal(arena, store, .{ .node = range.end, .handle = handle }, decl, encoding, context, handler); - } - } - if (info.sentinel) |sentinel| { - try symbolReferencesInternal(arena, store, .{ .node = sentinel, .handle = handle }, decl, encoding, context, handler); - } - }, - else => {}, + .ArrayTypeSentinel => { + const info = node.castTag(.ArrayTypeSentinel).?; + const prefix_op = node.cast(ast.Node.SimplePrefixOp).?; + + try symbolReferencesInternal(arena, store, .{ .node = info.len_expr, .handle = handle }, decl, encoding, context, handler); + try symbolReferencesInternal(arena, store, .{ .node = info.sentinel, .handle = handle }, decl, encoding, context, handler); + try symbolReferencesInternal(arena, store, .{ .node = prefix_op.rhs, .handle = handle }, decl, encoding, context, handler); + }, + .PtrType, .SliceType => { + const info = switch (node.tag) { + .PtrType => node.castTag(.PtrType).?.ptr_info, + .SliceType => node.castTag(.SliceType).?.ptr_info, + else => return + }; + const prefix_op = node.cast(ast.Node.SimplePrefixOp).?; + + if (info.align_info) |align_info| { + try symbolReferencesInternal(arena, store, .{ .node = align_info.node, .handle = handle }, decl, encoding, context, handler); + if (align_info.bit_range) |range| { + try symbolReferencesInternal(arena, store, .{ .node = range.start, .handle = handle }, decl, encoding, context, handler); + try symbolReferencesInternal(arena, store, .{ .node = range.end, .handle = handle }, decl, encoding, context, handler); + } } + if (info.sentinel) |sentinel| { + try symbolReferencesInternal(arena, store, .{ .node = sentinel, .handle = handle }, decl, encoding, context, handler); + } + try symbolReferencesInternal(arena, store, .{ .node = prefix_op.rhs, .handle = handle }, decl, encoding, context, handler); + }, + .AddressOf, .Await, .BitNot, .BoolAnd, .OptionalType, .Negation, .NegationWrap => { + const prefix_op = node.cast(ast.Node.SimplePrefixOp).?; try symbolReferencesInternal(arena, store, .{ .node = prefix_op.rhs, .handle = handle }, decl, encoding, context, handler); }, .FieldInitializer => { @@ -344,7 +317,50 @@ fn symbolReferencesInternal( const test_decl = node.cast(ast.Node.TestDecl).?; try symbolReferencesInternal(arena, store, .{ .node = test_decl.body_node, .handle = handle }, decl, encoding, context, handler); }, - else => {}, + else => { + // switch (ast.Node.Tag.Type(node.tag)) { + // SimpleInfixOp => { + // switch (node.tag) { + // .Period => { + // try symbolReferencesInternal(arena, store, .{ .node = infix_op.lhs, .handle = handle }, decl, encoding, context, handler); + + // const rhs_str = analysis.nodeToString(handle.tree, infix_op.rhs) orelse return; + // var bound_type_params = analysis.BoundTypeParams.init(&arena.allocator); + // const left_type = try analysis.resolveFieldAccessLhsType( + // store, + // arena, + // (try analysis.resolveTypeOfNodeInternal(store, arena, .{ + // .node = infix_op.lhs, + // .handle = handle, + // }, &bound_type_params)) orelse return, + // &bound_type_params, + // ); + + // const left_type_node = switch (left_type.type.data) { + // .other => |n| n, + // else => return, + // }; + + // if (try analysis.lookupSymbolContainer( + // store, + // arena, + // .{ .node = left_type_node, .handle = left_type.handle }, + // rhs_str, + // !left_type.type.is_type_val, + // )) |child| { + // if (std.meta.eql(child, decl)) { + // try tokenReference(handle, infix_op.rhs.firstToken(), encoding, context, handler); + // } + // } + // }, + // else => { + // try symbolReferencesInternal(arena, store, .{ .node = infix_op.lhs, .handle = handle }, decl, encoding, context, handler); + // try symbolReferencesInternal(arena, store, .{ .node = infix_op.rhs, .handle = handle }, decl, encoding, context, handler); + // }, + // } + // } + // } + }, } } diff --git a/src/semantic_tokens.zig b/src/semantic_tokens.zig index 546f960..4ceb08c 100644 --- a/src/semantic_tokens.zig +++ b/src/semantic_tokens.zig @@ -253,22 +253,22 @@ fn writeNodeTokens(builder: *Builder, arena: *std.heap.ArenaAllocator, store: *D }, .VarDecl => { const var_decl = node.cast(ast.Node.VarDecl).?; - if (var_decl.doc_comments) |doc| try writeDocComments(builder, handle.tree, doc); - try writeToken(builder, var_decl.visib_token, .keyword); - try writeToken(builder, var_decl.extern_export_token, .keyword); - try writeToken(builder, var_decl.thread_local_token, .keyword); - try writeToken(builder, var_decl.comptime_token, .keyword); + if (var_decl.getTrailer("doc_comments")) |doc| try writeDocComments(builder, handle.tree, doc); + try writeToken(builder, var_decl.getTrailer("visib_token"), .keyword); + try writeToken(builder, var_decl.getTrailer("extern_export_token"), .keyword); + try writeToken(builder, var_decl.getTrailer("thread_local_token"), .keyword); + try writeToken(builder, var_decl.getTrailer("comptime_token"), .keyword); try writeToken(builder, var_decl.mut_token, .keyword); if (try analysis.resolveTypeOfNode(store, arena, .{ .node = node, .handle = handle })) |decl_type| { try colorIdentifierBasedOnType(builder, decl_type, var_decl.name_token, .{ .definition = true }); } else { try writeTokenMod(builder, var_decl.name_token, .variable, .{ .definition = true }); } - try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, var_decl.type_node }); - try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, var_decl.align_node }); - try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, var_decl.section_node }); - try writeToken(builder, var_decl.eq_token, .operator); - try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, var_decl.init_node }); + try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, var_decl.getTrailer("type_node") }); + try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, var_decl.getTrailer("align_node") }); + try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, var_decl.getTrailer("section_node") }); + try writeToken(builder, var_decl.getTrailer("eq_token"), .operator); + try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, var_decl.getTrailer("init_node") }); }, .Use => { const use = node.cast(ast.Node.Use).?; @@ -332,10 +332,10 @@ fn writeNodeTokens(builder: *Builder, arena: *std.heap.ArenaAllocator, store: *D }, .FnProto => { const fn_proto = node.cast(ast.Node.FnProto).?; - if (fn_proto.doc_comments) |docs| try writeDocComments(builder, handle.tree, docs); - try writeToken(builder, fn_proto.visib_token, .keyword); - try writeToken(builder, fn_proto.extern_export_inline_token, .keyword); - try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, fn_proto.lib_name }); + if (fn_proto.getTrailer("doc_comments")) |docs| try writeDocComments(builder, handle.tree, docs); + try writeToken(builder, fn_proto.getTrailer("visib_token"), .keyword); + try writeToken(builder, fn_proto.getTrailer("extern_export_inline_token"), .keyword); + try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, fn_proto.getTrailer("lib_name") }); try writeToken(builder, fn_proto.fn_token, .keyword); const func_name_tok_type: TokenType = if (analysis.isTypeFunction(handle.tree, fn_proto)) @@ -348,7 +348,7 @@ fn writeNodeTokens(builder: *Builder, arena: *std.heap.ArenaAllocator, store: *D else TokenModifiers{}; - try writeTokenMod(builder, fn_proto.name_token, func_name_tok_type, tok_mod); + try writeTokenMod(builder, fn_proto.getTrailer("name_token"), func_name_tok_type, tok_mod); for (fn_proto.paramsConst()) |param_decl| { if (param_decl.doc_comments) |docs| try writeDocComments(builder, handle.tree, docs); @@ -357,13 +357,12 @@ fn writeNodeTokens(builder: *Builder, arena: *std.heap.ArenaAllocator, store: *D try writeTokenMod(builder, param_decl.name_token, .parameter, .{ .definition = true }); switch (param_decl.param_type) { .any_type => |var_node| try writeToken(builder, var_node.firstToken(), .type), - .var_args => |var_args_tok| try writeToken(builder, var_args_tok, .operator), .type_expr => |type_expr| try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, type_expr }), } } - try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, fn_proto.align_expr }); - try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, fn_proto.section_expr }); - try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, fn_proto.callconv_expr }); + try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, fn_proto.getTrailer("align_expr") }); + try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, fn_proto.getTrailer("section_expr") }); + try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, fn_proto.getTrailer("callconv_expr") }); switch (fn_proto.return_type) { .Explicit => |type_expr| try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, type_expr }), @@ -373,7 +372,7 @@ fn writeNodeTokens(builder: *Builder, arena: *std.heap.ArenaAllocator, store: *D }, .Invalid => {}, } - try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, fn_proto.body_node }); + try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, fn_proto.getTrailer("body_node") }); }, .AnyFrameType => { const any_frame_type = node.cast(ast.Node.AnyFrameType).?; @@ -482,103 +481,6 @@ fn writeNodeTokens(builder: *Builder, arena: *std.heap.ArenaAllocator, store: *D if (if_node.@"else") |else_node| try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, &else_node.base }); }, - .InfixOp => { - const infix_op = node.cast(ast.Node.InfixOp).?; - try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, infix_op.lhs }); - if (infix_op.op != .Period and infix_op.op != .Catch) { - const token_type: TokenType = switch (infix_op.op) { - .BoolAnd, .BoolOr, .UnwrapOptional => .keyword, - else => .operator, - }; - - try writeToken(builder, infix_op.op_token, token_type); - try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, infix_op.rhs }); - } - switch (infix_op.op) { - .Catch => |n| { - try writeToken(builder, infix_op.op_token, .keyword); - try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, n }); - try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, infix_op.rhs }); - }, - .Period => { - const rhs_str = handle.tree.tokenSlice(infix_op.rhs.firstToken()); - - // TODO This is basically exactly the same as what is done in analysis.resolveTypeOfNode, with the added - // writeToken code. - // Maybe we can hook into it insead? Also applies to Identifier and VarDecl - var bound_type_params = analysis.BoundTypeParams.init(&arena.allocator); - const lhs_type = try analysis.resolveFieldAccessLhsType( - store, - arena, - (try analysis.resolveTypeOfNodeInternal(store, arena, .{ - .node = infix_op.lhs, - .handle = handle, - }, &bound_type_params)) orelse return, - &bound_type_params, - ); - const left_type_node = switch (lhs_type.type.data) { - .other => |n| n, - else => return, - }; - if (try analysis.lookupSymbolContainer(store, arena, .{ .node = left_type_node, .handle = lhs_type.handle }, rhs_str, !lhs_type.type.is_type_val)) |decl_type| { - switch (decl_type.decl.*) { - .ast_node => |decl_node| { - if (decl_node.id == .ContainerField) { - const tok_type: ?TokenType = if (left_type_node.cast(ast.Node.ContainerDecl)) |container_decl| - fieldTokenType(container_decl, lhs_type.handle) - else if (left_type_node.id == .Root) - TokenType.field - else - null; - - if (tok_type) |tt| try writeToken(builder, infix_op.rhs.firstToken(), tt); - return; - } else if (decl_node.id == .ErrorTag) { - try writeToken(builder, infix_op.rhs.firstToken(), .errorTag); - } - }, - else => {}, - } - - if (try decl_type.resolveType(store, arena, &bound_type_params)) |resolved_type| { - try colorIdentifierBasedOnType(builder, resolved_type, infix_op.rhs.firstToken(), .{}); - } - } - }, - else => {}, - } - }, - .PrefixOp => { - const prefix_op = node.cast(ast.Node.PrefixOp).?; - const tok_type: TokenType = switch (prefix_op.op) { - .Try, .Await, .Resume => .keyword, - else => .operator, - }; - - switch (prefix_op.op) { - .ArrayType => |info| { - try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, info.len_expr }); - }, - .SliceType, .PtrType => |info| { - if (prefix_op.op == .PtrType) try writeToken(builder, prefix_op.op_token, tok_type); - - if (info.align_info) |align_info| { - if (prefix_op.op == .PtrType) { - try writeToken(builder, prefix_op.op_token + 1, .keyword); - } else { - try writeToken(builder, prefix_op.op_token + 2, .keyword); - } - try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, align_info.node }); - } - try writeToken(builder, info.const_token, .keyword); - try writeToken(builder, info.volatile_token, .keyword); - try writeToken(builder, info.allowzero_token, .keyword); - }, - else => try writeToken(builder, prefix_op.op_token, tok_type), - } - - try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, prefix_op.rhs }); - }, .ArrayInitializer => { const array_initializer = node.cast(ast.Node.ArrayInitializer).?; try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, array_initializer.lhs }); @@ -602,7 +504,7 @@ fn writeNodeTokens(builder: *Builder, arena: *std.heap.ArenaAllocator, store: *D var gap_highlighter = GapHighlighter.init(builder, struct_initializer.lhs.lastToken() + 1); for (struct_initializer.listConst()) |field_init_node| { try gap_highlighter.next(field_init_node); - std.debug.assert(field_init_node.id == .FieldInitializer); + std.debug.assert(field_init_node.tag == .FieldInitializer); const field_init = field_init_node.cast(ast.Node.FieldInitializer).?; if (field_token_type) |tok_type| { try writeToken(builder, field_init.period_token, tok_type); @@ -614,13 +516,13 @@ fn writeNodeTokens(builder: *Builder, arena: *std.heap.ArenaAllocator, store: *D try gap_highlighter.end(struct_initializer.rtoken); }, .StructInitializerDot => { - const struct_initializer = node.cast(ast.Node.StructInitializerDot).?; + const struct_initializer = node.castTag(.StructInitializerDot).?; var gap_highlighter = GapHighlighter.init(builder, struct_initializer.dot + 1); for (struct_initializer.listConst()) |field_init_node| { try gap_highlighter.next(field_init_node); - std.debug.assert(field_init_node.id == .FieldInitializer); - const field_init = field_init_node.cast(ast.Node.FieldInitializer).?; + std.debug.assert(field_init_node.tag == .FieldInitializer); + const field_init = field_init_node.castTag(.FieldInitializer).?; try writeToken(builder, field_init.period_token, .field); try writeToken(builder, field_init.name_token, .field); try writeToken(builder, field_init.name_token + 1, .operator); @@ -718,7 +620,108 @@ fn writeNodeTokens(builder: *Builder, arena: *std.heap.ArenaAllocator, store: *D try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, test_decl.name }); try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, test_decl.body_node }); }, - else => {}, + else => { + // switch (ast.Node.Tag.Type(node.tag)) { + // SimpleInfixOp => { + // const infix_op = node.cast(ast.Node.InfixOp).?; + // try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, infix_op.lhs }); + // if (infix_op.op != .Period and infix_op.op != .Catch) { + // const token_type: TokenType = switch (infix_op.op) { + // .BoolAnd, .BoolOr, .UnwrapOptional => .keyword, + // else => .operator, + // }; + + // try writeToken(builder, infix_op.op_token, token_type); + // try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, infix_op.rhs }); + // } + // switch (infix_op.op) { + // .Catch => |n| { + // try writeToken(builder, infix_op.op_token, .keyword); + // try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, n }); + // try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, infix_op.rhs }); + // }, + // .Period => { + // const rhs_str = handle.tree.tokenSlice(infix_op.rhs.firstToken()); + + // // TODO This is basically exactly the same as what is done in analysis.resolveTypeOfNode, with the added + // // writeToken code. + // // Maybe we can hook into it insead? Also applies to Identifier and VarDecl + // var bound_type_params = analysis.BoundTypeParams.init(&arena.allocator); + // const lhs_type = try analysis.resolveFieldAccessLhsType( + // store, + // arena, + // (try analysis.resolveTypeOfNodeInternal(store, arena, .{ + // .node = infix_op.lhs, + // .handle = handle, + // }, &bound_type_params)) orelse return, + // &bound_type_params, + // ); + // const left_type_node = switch (lhs_type.type.data) { + // .other => |n| n, + // else => return, + // }; + // if (try analysis.lookupSymbolContainer(store, arena, .{ .node = left_type_node, .handle = lhs_type.handle }, rhs_str, !lhs_type.type.is_type_val)) |decl_type| { + // switch (decl_type.decl.*) { + // .ast_node => |decl_node| { + // if (decl_node.id == .ContainerField) { + // const tok_type: ?TokenType = if (left_type_node.cast(ast.Node.ContainerDecl)) |container_decl| + // fieldTokenType(container_decl, lhs_type.handle) + // else if (left_type_node.id == .Root) + // TokenType.field + // else + // null; + + // if (tok_type) |tt| try writeToken(builder, infix_op.rhs.firstToken(), tt); + // return; + // } else if (decl_node.id == .ErrorTag) { + // try writeToken(builder, infix_op.rhs.firstToken(), .errorTag); + // } + // }, + // else => {}, + // } + + // if (try decl_type.resolveType(store, arena, &bound_type_params)) |resolved_type| { + // try colorIdentifierBasedOnType(builder, resolved_type, infix_op.rhs.firstToken(), .{}); + // } + // } + // }, + // else => {}, + // } + // }, + // SimplePrefixOp => { + // const prefix_op = node.cast(ast.Node.PrefixOp).?; + // const tok_type: TokenType = switch (prefix_op.op) { + // .Try, .Await, .Resume => .keyword, + // else => .operator, + // }; + + // switch (prefix_op.op) { + // .ArrayType => |info| { + // try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, info.len_expr }); + // }, + // .SliceType, .PtrType => |info| { + // if (prefix_op.op == .PtrType) try writeToken(builder, prefix_op.op_token, tok_type); + + // if (info.align_info) |align_info| { + // if (prefix_op.op == .PtrType) { + // try writeToken(builder, prefix_op.op_token + 1, .keyword); + // } else { + // try writeToken(builder, prefix_op.op_token + 2, .keyword); + // } + // try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, align_info.node }); + // } + // try writeToken(builder, info.const_token, .keyword); + // try writeToken(builder, info.volatile_token, .keyword); + // try writeToken(builder, info.allowzero_token, .keyword); + // }, + // else => try writeToken(builder, prefix_op.op_token, tok_type), + // } + + // try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, prefix_op.rhs }); + // }, + // else => {} + // } + }, } }