diff --git a/src/semantic_tokens.zig b/src/semantic_tokens.zig index 4ceb08c..4cddf38 100644 --- a/src/semantic_tokens.zig +++ b/src/semantic_tokens.zig @@ -620,108 +620,111 @@ 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 => { - // 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, - // }; + .Add, .AddWrap, .ArrayCat, .ArrayMult, .Assign, .AssignBitAnd, .AssignBitOr, .AssignBitShiftLeft, .AssignBitShiftRight, .AssignBitXor, .AssignDiv, .AssignSub, .AssignSubWrap, .AssignMod, .AssignAdd, .AssignAddWrap, .AssignMul, .AssignMulWrap, .BangEqual, .BitAnd, .BitOr, .BitShiftLeft, .BitShiftRight, .BitXor, .BoolAnd, .BoolOr, .Div, .EqualEqual, .ErrorUnion, .GreaterOrEqual, .GreaterThan, .LessOrEqual, .LessThan, .MergeErrorSets, .Mod, .Mul, .MulWrap, .Period, .Range, .Sub, .SubWrap, .UnwrapOptional => { + const infix_op = node.cast(ast.Node.SimpleInfixOp).?; + try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, infix_op.lhs }); + if (node.tag != .Period and node.tag != .Catch) { + const token_type: TokenType = switch (node.tag) { + .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()); + try writeToken(builder, infix_op.op_token, token_type); + try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, infix_op.rhs }); + } + switch (node.tag) { + .Catch => { + try writeToken(builder, infix_op.op_token, .keyword); + try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, infix_op.lhs }); + 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; + // 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.tag == .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.tag == .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 (tok_type) |tt| try writeToken(builder, infix_op.rhs.firstToken(), tt); + return; + } else if (decl_node.tag == .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 => {} - // } + if (try decl_type.resolveType(store, arena, &bound_type_params)) |resolved_type| { + try colorIdentifierBasedOnType(builder, resolved_type, infix_op.rhs.firstToken(), .{}); + } + } + }, + else => {}, + } }, + .AddressOf, .Await, .BitNot, .BoolNot, .OptionalType, .Negation, .NegationWrap, .Resume, .Try => { + const prefix_op = node.cast(ast.Node.SimplePrefixOp).?; + const tok_type: TokenType = switch (node.tag) { + .Try, .Await, .Resume => .keyword, + else => .operator, + }; + + switch (node.tag) { + .ArrayType => { + const info = node.castTag(.ArrayType).?; + try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, info.len_expr }); + }, + .SliceType, .PtrType => { + const info = switch (node.tag) { + .PtrType => node.castTag(.PtrType).?.ptr_info, + .SliceType => node.castTag(.SliceType).?.ptr_info, + else => return, + }; + + if (node.tag == .PtrType) try writeToken(builder, prefix_op.op_token, tok_type); + + if (info.align_info) |align_info| { + if (node.tag == .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 => {}, } }