diff --git a/src/analysis.zig b/src/analysis.zig index 6a3b5e7..f4e697e 100644 --- a/src/analysis.zig +++ b/src/analysis.zig @@ -1202,7 +1202,7 @@ fn maybeCollectImport(tree: ast.Tree, builtin_call: ast.Node.Index, arr: *std.Ar &[_]ast.Node.Index{ data.lhs, data.rhs }, else => unreachable, }; - if (params.len > 1) return; + if (params.len != 1) return; if (tags[params[0]] != .string_literal) return; @@ -3171,6 +3171,29 @@ fn makeScopeInternal( if (slice.ast.sentinel != 0) try makeScopeInternal(allocator, scopes, error_completions, enum_completions, tree, slice.ast.sentinel); }, + .@"errdefer" => { + const expr = data[node_idx].rhs; + if (data[node_idx].lhs != 0) { + const payload_token = data[node_idx].lhs; + var scope = try scopes.addOne(allocator); + scope.* = .{ + .range = .{ + .start = offsets.tokenLocation(tree, payload_token).start, + .end = offsets.tokenLocation(tree, tree.lastToken(expr)).end, + }, + .decls = std.StringHashMap(Declaration).init(allocator), + .uses = &.{}, + .tests = &.{}, + .data = .other, + }; + errdefer scope.decls.deinit(); + + const name = tree.tokenSlice(payload_token); + try scope.decls.putNoClobber(name, .{ .ast_node = expr }); + } + + try makeScopeInternal(allocator, scopes, error_completions, enum_completions, tree, expr); + }, // no scope .@"asm", diff --git a/src/semantic_tokens.zig b/src/semantic_tokens.zig index 70bc475..58df675 100644 --- a/src/semantic_tokens.zig +++ b/src/semantic_tokens.zig @@ -328,8 +328,14 @@ fn writeNodeTokens( .container_field_init, => try writeContainerField(builder, arena, store, node, .field, child_frame), .@"errdefer" => { - if (datas[node].lhs != 0) - try writeToken(builder, datas[node].lhs, .variable); + try writeToken(builder, main_token, .keyword); + + if (datas[node].lhs != 0) { + const payload_tok = datas[node].lhs; + try writeToken(builder, payload_tok - 1, .operator); + try writeToken(builder, payload_tok, .variable); + try writeToken(builder, payload_tok + 1, .operator); + } try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, datas[node].rhs }); }, @@ -635,12 +641,22 @@ fn writeNodeTokens( try writeToken(builder, if_node.ast.if_token, .keyword); try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, if_node.ast.cond_expr }); - try writeToken(builder, if_node.payload_token, .variable); + if (if_node.payload_token) |payload| { + // if (?x) |x| + try writeToken(builder, payload - 1, .operator); // | + try writeToken(builder, payload, .variable); // x + try writeToken(builder, payload + 1, .operator); // | + } try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, if_node.ast.then_expr }); - try writeToken(builder, if_node.error_token, .variable); if (if_node.ast.else_expr != 0) { try writeToken(builder, if_node.else_token, .keyword); + if (if_node.error_token) |err_token| { + // else |err| + try writeToken(builder, err_token - 1, .operator); // | + try writeToken(builder, err_token, .variable); // err + try writeToken(builder, err_token + 1, .operator); // | + } try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, if_node.ast.else_expr }); } }, @@ -763,12 +779,14 @@ fn writeNodeTokens( try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, datas[node].lhs }); try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, datas[node].rhs }); }, - .deref, - .unwrap_optional, - => { + .deref => { try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, datas[node].lhs }); try writeToken(builder, main_token, .operator); }, + .unwrap_optional => { + try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, datas[node].lhs }); + try writeToken(builder, main_token + 1, .operator); + }, .grouped_expression => { try await @asyncCall(child_frame, {}, writeNodeTokens, .{ builder, arena, store, datas[node].lhs }); },