From f57da477cd21b0c82b890af167cb1772bf5efe69 Mon Sep 17 00:00:00 2001 From: Skalar <19677138+NuclearPhone@users.noreply.github.com> Date: Tue, 27 Sep 2022 16:53:47 -0400 Subject: [PATCH 1/9] adds reformatting to camelCase for function names --- src/code_actions.zig | 63 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/src/code_actions.zig b/src/code_actions.zig index bfa1c413f..feb2e4553 100644 --- a/src/code_actions.zig +++ b/src/code_actions.zig @@ -32,6 +32,7 @@ pub const Builder = struct { .@"loop index capture" => try handleUnusedIndexCapture(builder, actions, loc), .@"capture" => try handleUnusedCapture(builder, actions, loc), }, + .non_camelcase_fn => try handleNonCamelcaseFunction(builder, actions, loc), .pointless_discard => try handlePointlessDiscard(builder, actions, loc), .omit_discard => |id| switch (id) { .@"index capture" => try handleUnusedIndexCapture(builder, actions, loc), @@ -70,6 +71,34 @@ pub const Builder = struct { } }; +fn handleNonCamelcaseFunction(builder: *Builder, actions: *std.ArrayListUnmanaged(types.CodeAction), loc: offsets.Loc) !void { + const identifier_name = offsets.locToSlice(builder.text(), loc); + + const tree = builder.handle.tree; + + const decl = (try analysis.lookupSymbolGlobal( + builder.document_store, + builder.arena, + builder.handle, + identifier_name, + loc.start + )) orelse return; + + const name_token_idx = decl.nameToken(); + const name_loc = offsets.tokenToLoc(tree, name_token_idx); + + const new_text = try createCamelcaseText(builder.arena.allocator(), identifier_name); + + const action1 = types.CodeAction { + .title = "make function name camelCase", + .kind = .SourceFixAll, + .isPreferred = true, + .edit = try builder.createWorkspaceEdit(&.{builder.createTextEditLoc(name_loc, new_text)}), + }; + + try actions.append(builder.arena.allocator(), action1); +} + fn handleUnusedFunctionParameter(builder: *Builder, actions: *std.ArrayListUnmanaged(types.CodeAction), loc: offsets.Loc) !void { const identifier_name = offsets.locToSlice(builder.text(), loc); @@ -159,7 +188,7 @@ fn handleUnusedVariableOrConstant(builder: *Builder, actions: *std.ArrayListUnma try actions.append(builder.arena.allocator(), .{ .title = "discard value", - .kind = .SourceFixAll, + .kind = .QuickFix, .isPreferred = true, .edit = try builder.createWorkspaceEdit(&.{builder.createTextEditPos(index, new_text)}), }); @@ -233,6 +262,33 @@ fn handlePointlessDiscard(builder: *Builder, actions: *std.ArrayListUnmanaged(ty }); } +// attempts to converts a slice of text into camelcase 'FUNCTION_NAME' -> 'functionName' +fn createCamelcaseText(allocator: std.mem.Allocator, identifier: []const u8) ![]const u8 { + var num_separators: usize = 0; + + const new_text_len = 1 + identifier.len - num_separators; + var new_text = try std.ArrayListUnmanaged(u8).initCapacity(allocator, new_text_len); + errdefer new_text.deinit(allocator); + + var idx: usize = 0; + + // sloppy + while(idx < identifier.len) { + const c = identifier[idx]; + + if(c == '_') { + const c2 = identifier[idx + 1]; + new_text.appendAssumeCapacity(std.ascii.toUpper(c2)); + idx += 2; + } else { + new_text.appendAssumeCapacity(std.ascii.toLower(c)); + idx += 1; + } + } + + return new_text.toOwnedSlice(allocator); +} + // returns a discard string `\n{indent}_ = identifier_name;` fn createDiscardText(allocator: std.mem.Allocator, identifier_name: []const u8, indent: usize) ![]const u8 { const new_text_len = 1 + indent + "_ = ;".len + identifier_name.len; @@ -252,6 +308,7 @@ const DiagnosticKind = union(enum) { unused: IdCat, pointless_discard: IdCat, omit_discard: DiscardCat, + non_camelcase_fn: void, unreachable_code, const IdCat = enum { @@ -284,6 +341,10 @@ const DiagnosticKind = union(enum) { return DiagnosticKind{ .omit_discard = parseEnum(DiscardCat, msg["discard of ".len..]) orelse return null, }; + } else if (std.mem.startsWith(u8, msg, "Functions should")) { + return DiagnosticKind { + .non_camelcase_fn = {}, + }; } return null; } From a0b0bc0c0c8129ddb30ee68f20f9ee7b724f81fb Mon Sep 17 00:00:00 2001 From: Skalar <19677138+NuclearPhone@users.noreply.github.com> Date: Tue, 27 Sep 2022 17:23:50 -0400 Subject: [PATCH 2/9] removes useless +1 byte when allocating a string --- src/code_actions.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/code_actions.zig b/src/code_actions.zig index feb2e4553..25826c474 100644 --- a/src/code_actions.zig +++ b/src/code_actions.zig @@ -266,7 +266,7 @@ fn handlePointlessDiscard(builder: *Builder, actions: *std.ArrayListUnmanaged(ty fn createCamelcaseText(allocator: std.mem.Allocator, identifier: []const u8) ![]const u8 { var num_separators: usize = 0; - const new_text_len = 1 + identifier.len - num_separators; + const new_text_len = identifier.len - num_separators; var new_text = try std.ArrayListUnmanaged(u8).initCapacity(allocator, new_text_len); errdefer new_text.deinit(allocator); From c550880205595b996dd0bf6126219e25df02156c Mon Sep 17 00:00:00 2001 From: Skalar <19677138+NuclearPhone@users.noreply.github.com> Date: Tue, 27 Sep 2022 20:26:00 -0400 Subject: [PATCH 3/9] added some forgotten functionality --- src/code_actions.zig | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/src/code_actions.zig b/src/code_actions.zig index 25826c474..4a97d0617 100644 --- a/src/code_actions.zig +++ b/src/code_actions.zig @@ -73,29 +73,23 @@ pub const Builder = struct { fn handleNonCamelcaseFunction(builder: *Builder, actions: *std.ArrayListUnmanaged(types.CodeAction), loc: offsets.Loc) !void { const identifier_name = offsets.locToSlice(builder.text(), loc); - + const tree = builder.handle.tree; - const decl = (try analysis.lookupSymbolGlobal( - builder.document_store, - builder.arena, - builder.handle, - identifier_name, - loc.start - )) orelse return; - + const decl = (try analysis.lookupSymbolGlobal(builder.document_store, builder.arena, builder.handle, identifier_name, loc.start)) orelse return; + const name_token_idx = decl.nameToken(); - const name_loc = offsets.tokenToLoc(tree, name_token_idx); - + const name_loc = offsets.tokenToLoc(tree, name_token_idx); + const new_text = try createCamelcaseText(builder.arena.allocator(), identifier_name); - - const action1 = types.CodeAction { + + const action1 = types.CodeAction{ .title = "make function name camelCase", .kind = .SourceFixAll, .isPreferred = true, .edit = try builder.createWorkspaceEdit(&.{builder.createTextEditLoc(name_loc, new_text)}), }; - + try actions.append(builder.arena.allocator(), action1); } @@ -265,18 +259,22 @@ fn handlePointlessDiscard(builder: *Builder, actions: *std.ArrayListUnmanaged(ty // attempts to converts a slice of text into camelcase 'FUNCTION_NAME' -> 'functionName' fn createCamelcaseText(allocator: std.mem.Allocator, identifier: []const u8) ![]const u8 { var num_separators: usize = 0; - + + for (identifier) |c| { + if (c == '_') num_separators += 1; + } + const new_text_len = identifier.len - num_separators; var new_text = try std.ArrayListUnmanaged(u8).initCapacity(allocator, new_text_len); errdefer new_text.deinit(allocator); - + var idx: usize = 0; - + // sloppy - while(idx < identifier.len) { + while (idx < identifier.len) { const c = identifier[idx]; - if(c == '_') { + if (c == '_') { const c2 = identifier[idx + 1]; new_text.appendAssumeCapacity(std.ascii.toUpper(c2)); idx += 2; @@ -285,7 +283,7 @@ fn createCamelcaseText(allocator: std.mem.Allocator, identifier: []const u8) ![] idx += 1; } } - + return new_text.toOwnedSlice(allocator); } @@ -342,9 +340,9 @@ const DiagnosticKind = union(enum) { .omit_discard = parseEnum(DiscardCat, msg["discard of ".len..]) orelse return null, }; } else if (std.mem.startsWith(u8, msg, "Functions should")) { - return DiagnosticKind { + return DiagnosticKind{ .non_camelcase_fn = {}, - }; + }; } return null; } From 89a63f4bcf4f6b023230893e72ec7bcabd56219e Mon Sep 17 00:00:00 2001 From: Skalar <19677138+NuclearPhone@users.noreply.github.com> Date: Tue, 27 Sep 2022 20:30:55 -0400 Subject: [PATCH 4/9] fixes an issue caused by auto-fmt & changes action kind --- src/code_actions.zig | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/code_actions.zig b/src/code_actions.zig index 4a97d0617..49d2bfb36 100644 --- a/src/code_actions.zig +++ b/src/code_actions.zig @@ -76,7 +76,13 @@ fn handleNonCamelcaseFunction(builder: *Builder, actions: *std.ArrayListUnmanage const tree = builder.handle.tree; - const decl = (try analysis.lookupSymbolGlobal(builder.document_store, builder.arena, builder.handle, identifier_name, loc.start)) orelse return; + const decl = (try analysis.lookupSymbolGlobal( + builder.document_store, + builder.arena, + builder.handle, + identifier_name, + loc.start, + )) orelse return; const name_token_idx = decl.nameToken(); const name_loc = offsets.tokenToLoc(tree, name_token_idx); @@ -85,7 +91,7 @@ fn handleNonCamelcaseFunction(builder: *Builder, actions: *std.ArrayListUnmanage const action1 = types.CodeAction{ .title = "make function name camelCase", - .kind = .SourceFixAll, + .kind = .QuickFix, .isPreferred = true, .edit = try builder.createWorkspaceEdit(&.{builder.createTextEditLoc(name_loc, new_text)}), }; From 91c70248836562e1f5beec4db91fbcd5e6ca8e31 Mon Sep 17 00:00:00 2001 From: Skalar <19677138+NuclearPhone@users.noreply.github.com> Date: Tue, 27 Sep 2022 21:38:31 -0400 Subject: [PATCH 5/9] fixes several issues related to camelCase action --- src/code_actions.zig | 53 ++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/src/code_actions.zig b/src/code_actions.zig index 49d2bfb36..2fda0be67 100644 --- a/src/code_actions.zig +++ b/src/code_actions.zig @@ -74,26 +74,21 @@ pub const Builder = struct { fn handleNonCamelcaseFunction(builder: *Builder, actions: *std.ArrayListUnmanaged(types.CodeAction), loc: offsets.Loc) !void { const identifier_name = offsets.locToSlice(builder.text(), loc); - const tree = builder.handle.tree; - - const decl = (try analysis.lookupSymbolGlobal( - builder.document_store, - builder.arena, - builder.handle, - identifier_name, - loc.start, - )) orelse return; - - const name_token_idx = decl.nameToken(); - const name_loc = offsets.tokenToLoc(tree, name_token_idx); + // const decl = (try analysis.lookupSymbolGlobal( + // builder.document_store, + // builder.arena, + // builder.handle, + // identifier_name, + // loc.start, + // )) orelse return; const new_text = try createCamelcaseText(builder.arena.allocator(), identifier_name); const action1 = types.CodeAction{ .title = "make function name camelCase", - .kind = .QuickFix, + .kind = .SourceFixAll, .isPreferred = true, - .edit = try builder.createWorkspaceEdit(&.{builder.createTextEditLoc(name_loc, new_text)}), + .edit = try builder.createWorkspaceEdit(&.{builder.createTextEditLoc(loc, new_text)}), }; try actions.append(builder.arena.allocator(), action1); @@ -264,28 +259,28 @@ fn handlePointlessDiscard(builder: *Builder, actions: *std.ArrayListUnmanaged(ty // attempts to converts a slice of text into camelcase 'FUNCTION_NAME' -> 'functionName' fn createCamelcaseText(allocator: std.mem.Allocator, identifier: []const u8) ![]const u8 { - var num_separators: usize = 0; + // skip initial & ending underscores + const trimmed_identifier = std.mem.trim(u8, identifier, "_"); - for (identifier) |c| { - if (c == '_') num_separators += 1; - } + const num_separators = std.mem.count(u8, trimmed_identifier, "_"); - const new_text_len = identifier.len - num_separators; + const new_text_len = trimmed_identifier.len - num_separators; var new_text = try std.ArrayListUnmanaged(u8).initCapacity(allocator, new_text_len); errdefer new_text.deinit(allocator); var idx: usize = 0; + while (idx < trimmed_identifier.len) { + const ch = trimmed_identifier[idx]; + if (ch == '_') { + // the trimmed identifier is guaranteed to not have underscores at the end, + // so it can be assumed that ptr dereferences are safe until an alnum char is found + while (trimmed_identifier[idx] == '_') : (idx += 1) {} + const ch2 = trimmed_identifier[idx]; + new_text.appendAssumeCapacity(std.ascii.toUpper(ch2)); - // sloppy - while (idx < identifier.len) { - const c = identifier[idx]; - - if (c == '_') { - const c2 = identifier[idx + 1]; - new_text.appendAssumeCapacity(std.ascii.toUpper(c2)); - idx += 2; + idx += 1; } else { - new_text.appendAssumeCapacity(std.ascii.toLower(c)); + new_text.appendAssumeCapacity(std.ascii.toLower(ch)); idx += 1; } } @@ -345,7 +340,7 @@ const DiagnosticKind = union(enum) { return DiagnosticKind{ .omit_discard = parseEnum(DiscardCat, msg["discard of ".len..]) orelse return null, }; - } else if (std.mem.startsWith(u8, msg, "Functions should")) { + } else if (std.mem.startsWith(u8, msg, "Functions should be camelCase")) { return DiagnosticKind{ .non_camelcase_fn = {}, }; From 5904c9ec3a441119eff7fc388bc03328d8329e63 Mon Sep 17 00:00:00 2001 From: Skalar <19677138+NuclearPhone@users.noreply.github.com> Date: Wed, 28 Sep 2022 00:01:57 -0400 Subject: [PATCH 6/9] fixes a bug if a fn name is all underscores --- src/code_actions.zig | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/code_actions.zig b/src/code_actions.zig index 2fda0be67..1ad71b61b 100644 --- a/src/code_actions.zig +++ b/src/code_actions.zig @@ -74,13 +74,7 @@ pub const Builder = struct { fn handleNonCamelcaseFunction(builder: *Builder, actions: *std.ArrayListUnmanaged(types.CodeAction), loc: offsets.Loc) !void { const identifier_name = offsets.locToSlice(builder.text(), loc); - // const decl = (try analysis.lookupSymbolGlobal( - // builder.document_store, - // builder.arena, - // builder.handle, - // identifier_name, - // loc.start, - // )) orelse return; + if (std.mem.allEqual(u8, identifier_name, '_')) return; const new_text = try createCamelcaseText(builder.arena.allocator(), identifier_name); @@ -277,12 +271,11 @@ fn createCamelcaseText(allocator: std.mem.Allocator, identifier: []const u8) ![] while (trimmed_identifier[idx] == '_') : (idx += 1) {} const ch2 = trimmed_identifier[idx]; new_text.appendAssumeCapacity(std.ascii.toUpper(ch2)); - - idx += 1; } else { new_text.appendAssumeCapacity(std.ascii.toLower(ch)); - idx += 1; } + + idx += 1; } return new_text.toOwnedSlice(allocator); From 44503fedc21a18e222d92121a1816424b5b3691a Mon Sep 17 00:00:00 2001 From: Skalar <19677138+NuclearPhone@users.noreply.github.com> Date: Wed, 28 Sep 2022 16:26:30 -0400 Subject: [PATCH 7/9] sets camelCase action to quickfix --- src/code_actions.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/code_actions.zig b/src/code_actions.zig index b82b4bb94..048a9fa83 100644 --- a/src/code_actions.zig +++ b/src/code_actions.zig @@ -82,7 +82,7 @@ fn handleNonCamelcaseFunction(builder: *Builder, actions: *std.ArrayListUnmanage const action1 = types.CodeAction{ .title = "make function name camelCase", - .kind = .SourceFixAll, + .kind = .QuickFix, .isPreferred = true, .edit = try builder.createWorkspaceEdit(&.{builder.createTextEditLoc(loc, new_text)}), }; From 39ea5869a377eeec71fe333f2ee264fac7cf2bbb Mon Sep 17 00:00:00 2001 From: Skalar <19677138+NuclearPhone@users.noreply.github.com> Date: Wed, 28 Sep 2022 21:30:02 -0400 Subject: [PATCH 8/9] sets camelCase action to sourceFixAll --- src/code_actions.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/code_actions.zig b/src/code_actions.zig index 048a9fa83..b82b4bb94 100644 --- a/src/code_actions.zig +++ b/src/code_actions.zig @@ -82,7 +82,7 @@ fn handleNonCamelcaseFunction(builder: *Builder, actions: *std.ArrayListUnmanage const action1 = types.CodeAction{ .title = "make function name camelCase", - .kind = .QuickFix, + .kind = .SourceFixAll, .isPreferred = true, .edit = try builder.createWorkspaceEdit(&.{builder.createTextEditLoc(loc, new_text)}), }; From 5c4ccfb1d616ccb21f7ff583da97ad1d52a17325 Mon Sep 17 00:00:00 2001 From: Skalar <19677138+NuclearPhone@users.noreply.github.com> Date: Thu, 29 Sep 2022 00:42:33 -0400 Subject: [PATCH 9/9] fixes a mischanged line --- src/code_actions.zig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/code_actions.zig b/src/code_actions.zig index b82b4bb94..a4a9b16cc 100644 --- a/src/code_actions.zig +++ b/src/code_actions.zig @@ -82,7 +82,7 @@ fn handleNonCamelcaseFunction(builder: *Builder, actions: *std.ArrayListUnmanage const action1 = types.CodeAction{ .title = "make function name camelCase", - .kind = .SourceFixAll, + .kind = .QuickFix, .isPreferred = true, .edit = try builder.createWorkspaceEdit(&.{builder.createTextEditLoc(loc, new_text)}), }; @@ -173,7 +173,7 @@ fn handleUnusedVariableOrConstant(builder: *Builder, actions: *std.ArrayListUnma try actions.append(builder.arena.allocator(), .{ .title = "discard value", - .kind = .QuickFix, + .kind = .SourceFixAll, .isPreferred = true, .edit = try builder.createWorkspaceEdit(&.{builder.createTextEditPos(index, new_text)}), });