From 3833566790f1491a42028d9360f3f954cd8e11d4 Mon Sep 17 00:00:00 2001 From: Jonas Enlund Date: Sat, 8 Oct 2022 03:00:23 +0300 Subject: [PATCH 1/3] Add missing .switch_case_inline, .switch_case_inline_one cases (#699) * Add missing .switch_case_inline, .switch_case_inline_one cases * Include inline semantic token Co-authored-by: Auguste Rame <19855629+SuperAuguste@users.noreply.github.com> --- src/analysis.zig | 2 ++ src/ast.zig | 2 ++ src/inlay_hints.zig | 4 +++- src/references.zig | 8 ++++++-- src/semantic_tokens.zig | 5 ++++- 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/analysis.zig b/src/analysis.zig index 357e8ef..bb568fe 100644 --- a/src/analysis.zig +++ b/src/analysis.zig @@ -2828,7 +2828,9 @@ fn makeScopeInternal(allocator: std.mem.Allocator, context: ScopeContext, node_i } }, .switch_case, + .switch_case_inline, .switch_case_one, + .switch_case_inline_one, .switch_range, => { return; diff --git a/src/ast.zig b/src/ast.zig index 29d433a..5056a9c 100644 --- a/src/ast.zig +++ b/src/ast.zig @@ -437,6 +437,8 @@ pub fn lastToken(tree: Ast, node: Ast.Node.Index) Ast.TokenIndex { .array_type, .switch_case_one, .switch_case, + .switch_case_inline_one, + .switch_case_inline, .switch_range, => n = datas[n].rhs, diff --git a/src/inlay_hints.zig b/src/inlay_hints.zig index ad95c13..70f4fef 100644 --- a/src/inlay_hints.zig +++ b/src/inlay_hints.zig @@ -548,8 +548,10 @@ fn writeNodeInlayHint(builder: *Builder, arena: *std.heap.ArenaAllocator, store: .switch_case_one, .switch_case, + .switch_case_inline_one, + .switch_case_inline, => { - const switch_case = if (tag == .switch_case) tree.switchCase(node) else tree.switchCaseOne(node); + const switch_case = if (tag == .switch_case or tag == .switch_case_inline) tree.switchCase(node) else tree.switchCaseOne(node); try callWriteNodeInlayHint(allocator, .{ builder, arena, store, switch_case.ast.target_expr, range }); }, diff --git a/src/references.zig b/src/references.zig index 5905259..5176e52 100644 --- a/src/references.zig +++ b/src/references.zig @@ -176,13 +176,17 @@ fn symbolReferencesInternal( try symbolReferencesInternal(builder, case, handle); } }, - .switch_case_one => { + .switch_case_one, + .switch_case_inline_one, + => { const case_one = tree.switchCaseOne(node); try symbolReferencesInternal(builder, case_one.ast.target_expr, handle); for (case_one.ast.values) |val| try symbolReferencesInternal(builder, val, handle); }, - .switch_case => { + .switch_case, + .switch_case_inline, + => { const case = tree.switchCase(node); try symbolReferencesInternal(builder, case.ast.target_expr, handle); for (case.ast.values) |val| diff --git a/src/semantic_tokens.zig b/src/semantic_tokens.zig index ab0bf10..a1a49fe 100644 --- a/src/semantic_tokens.zig +++ b/src/semantic_tokens.zig @@ -518,8 +518,11 @@ fn writeNodeTokens(builder: *Builder, maybe_node: ?Ast.Node.Index) WriteTokensEr }, .switch_case_one, .switch_case, + .switch_case_inline_one, + .switch_case_inline, => { - const switch_case = if (tag == .switch_case) tree.switchCase(node) else tree.switchCaseOne(node); + const switch_case = if (tag == .switch_case or tag == .switch_case_inline) tree.switchCase(node) else tree.switchCaseOne(node); + try writeToken(builder, switch_case.inline_token, .keyword); for (switch_case.ast.values) |item_node| try callWriteNodeTokens(allocator, .{ builder, item_node }); // check it it's 'else' if (switch_case.ast.values.len == 0) try writeToken(builder, switch_case.ast.arrow_token - 1, .keyword); From f060d09f7e1bc9fd048152e6e32adf1c436040ce Mon Sep 17 00:00:00 2001 From: Techatrix <19954306+Techatrix@users.noreply.github.com> Date: Sat, 8 Oct 2022 22:04:34 +0200 Subject: [PATCH 2/3] correctly handle var decl without equal sign --- src/semantic_tokens.zig | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/semantic_tokens.zig b/src/semantic_tokens.zig index a1a49fe..5c33ddb 100644 --- a/src/semantic_tokens.zig +++ b/src/semantic_tokens.zig @@ -354,7 +354,9 @@ fn writeNodeTokens(builder: *Builder, maybe_node: ?Ast.Node.Index) WriteTokensEr } else { try writeTokenMod(builder, var_decl.ast.mut_token + 1, .variable, .{ .declaration = true }); } - try writeToken(builder, var_decl.ast.mut_token + 2, .operator); + if (token_tags[var_decl.ast.mut_token + 2] == .equal) { + try writeToken(builder, var_decl.ast.mut_token + 2, .operator); + } try callWriteNodeTokens(allocator, .{ builder, var_decl.ast.type_node }); try callWriteNodeTokens(allocator, .{ builder, var_decl.ast.align_node }); From 19fd17ff76d055606e2e9dde9e09dac7f9538430 Mon Sep 17 00:00:00 2001 From: nullptrdevs <16590917+nullptrdevs@users.noreply.github.com> Date: Sun, 9 Oct 2022 22:13:15 -0700 Subject: [PATCH 3/3] ability to highlight global variables (#655) anything declared with "var" at the root level --- README.md | 1 + schema.json | 5 +++++ src/Config.zig | 3 +++ src/Server.zig | 61 +++++++++++++++++++++++++++++++++++++------------- 4 files changed, 54 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index d2a557c..9773609 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,7 @@ The following options are currently available. |`include_at_in_builtins`|`bool`|`false`| Whether the @ sign should be part of the completion of builtins. |`max_detail_length`|`usize`|`1024 * 1024`| The detail field of completions is truncated to be no longer than this (in bytes). | `skip_std_references` | `bool` | `false` | When true, skips searching for references in std. Improves lookup speed for functions in user's code. Renaming and go-to-definition will continue to work as is. +| `highlight_global_var_declarations` | `bool` | `false` | Whether to highlight global var declarations. ### Per-build Configuration Options diff --git a/schema.json b/schema.json index 2673418..2d0fd0f 100644 --- a/schema.json +++ b/schema.json @@ -94,6 +94,11 @@ "description": "When true, skips searching for references in std. Improves lookup speed for functions in user's code. Renaming and go-to-definition will continue to work as is", "type": "boolean", "default": "false" + }, + "highlight_global_var_declarations": { + "description": "Whether to highlight global var declarations", + "type": "boolean", + "default": "false" } } } diff --git a/src/Config.zig b/src/Config.zig index 623ce88..642a096 100644 --- a/src/Config.zig +++ b/src/Config.zig @@ -76,6 +76,9 @@ skip_std_references: bool = false, /// Path to "builtin;" useful for debugging, automatically set if let null builtin_path: ?[]const u8 = null, +/// Whether to highlight global var declarations. +highlight_global_var_declarations: bool = false, + pub fn loadFromFile(allocator: std.mem.Allocator, file_path: []const u8) ?Config { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); diff --git a/src/Server.zig b/src/Server.zig index 3158d43..d1abe3b 100644 --- a/src/Server.zig +++ b/src/Server.zig @@ -175,6 +175,24 @@ fn publishDiagnostics(server: *Server, writer: anytype, handle: *DocumentStore.H }); } + for (handle.cimports) |cimport| { + if (cimport.result != .failure) continue; + const stderr = std.mem.trim(u8, cimport.result.failure, " "); + + var pos_and_diag_iterator = std.mem.split(u8, stderr, ":"); + _ = pos_and_diag_iterator.next(); // skip file path + _ = pos_and_diag_iterator.next(); // skip line + _ = pos_and_diag_iterator.next(); // skip character + + try diagnostics.append(allocator, .{ + .range = offsets.nodeToRange(handle.tree, cimport.node, server.offset_encoding), + .severity = .Error, + .code = "cImport", + .source = "zls", + .message = try allocator.dupe(u8, pos_and_diag_iterator.rest()), + }); + } + if (server.config.enable_ast_check_diagnostics and tree.errors.len == 0) { try getAstCheckDiagnostics(server, handle, &diagnostics); } @@ -251,23 +269,34 @@ fn publishDiagnostics(server: *Server, writer: anytype, handle: *DocumentStore.H } } } + + if (server.config.highlight_global_var_declarations) { + const main_tokens = tree.nodes.items(.main_token); + const tags = tree.tokens.items(.tag); + for (tree.rootDecls()) |decl| { + const decl_tag = tree.nodes.items(.tag)[decl]; + const decl_main_token = tree.nodes.items(.main_token)[decl]; - for (handle.cimports) |cimport| { - if (cimport.result != .failure) continue; - const stderr = std.mem.trim(u8, cimport.result.failure, " "); - - var pos_and_diag_iterator = std.mem.split(u8, stderr, ":"); - _ = pos_and_diag_iterator.next(); // skip file path - _ = pos_and_diag_iterator.next(); // skip line - _ = pos_and_diag_iterator.next(); // skip character - - try diagnostics.append(allocator, .{ - .range = offsets.nodeToRange(handle.tree, cimport.node, server.offset_encoding), - .severity = .Error, - .code = "cImport", - .source = "zls", - .message = try allocator.dupe(u8, pos_and_diag_iterator.rest()), - }); + switch (decl_tag) { + .simple_var_decl, + .aligned_var_decl, + .local_var_decl, + .global_var_decl, + => { + if (tags[main_tokens[decl]] != .keyword_var) continue; // skip anything immutable + // uncomment this to get a list :) + //log.debug("possible global variable \"{s}\"", .{tree.tokenSlice(decl_main_token + 1)}); + try diagnostics.append(allocator, .{ + .range = offsets.tokenToRange(tree, decl_main_token, server.offset_encoding), + .severity = .Hint, + .code = "highlight_global_var_declarations", + .source = "zls", + .message = "Global var declaration", + }); + }, + else => {}, + } + } } try send(writer, server.arena.allocator(), types.Notification{