Skip to content

Commit 6511432

Browse files
authored
Remove static list of names and URIs from require_errdefer_deinit #48 (#117)
It now checks whether the type has a `deinit` call. It still tries to limit noise by only looking at declarations to `.empty`, `.init`, `initCapacity(..)` or `init(..)` without parameters that look like arenas or fixed buffers. I'm unsure about this.
1 parent 912b650 commit 6511432

File tree

6 files changed

+173
-170
lines changed

6 files changed

+173
-170
lines changed

integration_tests/test_cases/require_errdefer_dealloc/require_errdefer_dealloc.input.zig

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,22 @@ pub fn hasErrorButWithArena(input: u32) error{NotOk}!void {
9292
has_arena_d.deinit(std.heap.page_allocator);
9393
}
9494

95+
pub fn cleanupInConditionBlock(allocator: std.mem.Allocator) !void {
96+
const deinit_wip = true;
97+
var wip = try std.ArrayList(u8).initCapacity(allocator, 10);
98+
defer if (deinit_wip) wip.deinit();
99+
}
100+
101+
pub fn cleanupInAssignment() !void {
102+
var debug_gpa_state: std.heap.DebugAllocator(.{}) = .init;
103+
defer _ = debug_gpa_state.deinit();
104+
}
105+
106+
pub fn cleanupInCondition() !void {
107+
var debug_gpa_state: std.heap.DebugAllocator(.{}) = .init;
108+
defer {
109+
if (debug_gpa_state.deinit() == .leak) {}
110+
}
111+
}
112+
95113
const std = @import("std");

src/lib/ast.zig

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,27 @@ pub fn fullStatement(tree: Ast, node: Ast.Node.Index) ?Statement {
437437
};
438438
}
439439

440+
/// Visibility of a node in the AST (e.g., a function or variable declaration).
441+
pub const Visibility = enum { public, private };
442+
443+
/// Returns the visibility of a given function proto.
444+
pub fn fnProtoVisibility(tree: Ast, fn_decl: Ast.full.FnProto) Visibility {
445+
const visibility_token = fn_decl.visib_token orelse return .private;
446+
return switch (tree.tokens.items(.tag)[visibility_token]) {
447+
.keyword_pub => .public,
448+
else => .private,
449+
};
450+
}
451+
452+
/// Returns the visibility of a given variable declaration.
453+
pub fn varDeclVisibility(tree: Ast, var_decl: Ast.full.VarDecl) Visibility {
454+
const visibility_token = var_decl.visib_token orelse return .private;
455+
return switch (tree.tokens.items(.tag)[visibility_token]) {
456+
.keyword_pub => .public,
457+
else => .private,
458+
};
459+
}
460+
440461
test "isFieldVarAccess" {
441462
inline for (&.{
442463
.{

src/rules/no_inferred_error_unions.zig

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ fn run(
6262
if (tag != .fn_decl) continue :nodes;
6363

6464
const fn_decl = tree.fullFnProto(&fn_decl_buffer, node.toNodeIndex()) orelse continue :nodes;
65-
if (config.allow_private and isFnPrivate(tree, fn_decl)) continue :nodes;
65+
if (config.allow_private and zlinter.ast.fnProtoVisibility(tree, fn_decl) == .private) continue :nodes;
6666

6767
const return_type = NodeIndexShim.initOptional(fn_decl.ast.return_type) orelse continue :nodes;
6868

@@ -97,14 +97,6 @@ fn run(
9797
null;
9898
}
9999

100-
fn isFnPrivate(tree: Ast, fn_decl: Ast.full.FnProto) bool {
101-
const visibility_token = fn_decl.visib_token orelse return true;
102-
return switch (tree.tokens.items(.tag)[visibility_token]) {
103-
.keyword_pub => false,
104-
else => true,
105-
};
106-
}
107-
108100
test {
109101
std.testing.refAllDecls(@This());
110102
}

src/rules/no_unused.zig

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,7 @@ fn run(
6464
for (tree.rootDecls()) |decl| {
6565
const problem: ?struct { first: Ast.TokenIndex, last: Ast.TokenIndex } = problem: {
6666
if (tree.fullVarDecl(decl)) |var_decl| {
67-
if (var_decl.visib_token) |visib_token|
68-
if (token_tags[visib_token] == .keyword_pub)
69-
break :problem null;
67+
if (zlinter.ast.varDeclVisibility(tree, var_decl) == .public) break :problem null;
7068

7169
if (var_decl.extern_export_token) |extern_export_token|
7270
if (token_tags[extern_export_token] == .keyword_export)
@@ -81,9 +79,7 @@ fn run(
8179
} else {
8280
var buffer: [1]Ast.Node.Index = undefined;
8381
if (namedFnDeclProto(tree, &buffer, decl)) |fn_proto| {
84-
if (fn_proto.visib_token) |token|
85-
if (token_tags[token] == .keyword_pub)
86-
break :problem null;
82+
if (zlinter.ast.fnProtoVisibility(tree, fn_proto) == .public) break :problem null;
8783

8884
if (fn_proto.extern_export_inline_token) |token|
8985
if (token_tags[token] == .keyword_export)

src/rules/require_doc_comment.zig

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,10 @@ fn run(
7575

7676
switch (tag) {
7777
.fn_decl => if (tree.fullFnProto(&fn_decl_buffer, node.toNodeIndex())) |fn_decl| {
78-
const severity, const label = if (isFnPrivate(tree, fn_decl))
79-
.{ config.private_severity, "Private" }
80-
else
81-
.{ config.public_severity, "Public" };
78+
const severity, const label = switch (zlinter.ast.fnProtoVisibility(tree, fn_decl)) {
79+
.private => .{ config.private_severity, "Private" },
80+
.public => .{ config.public_severity, "Public" },
81+
};
8282
if (severity == .off) continue :nodes;
8383

8484
if (try hasDocComments(arena, tree, node.toNodeIndex())) continue :nodes;
@@ -92,10 +92,10 @@ fn run(
9292
});
9393
},
9494
else => if (tree.fullVarDecl(node.toNodeIndex())) |var_decl| {
95-
const severity, const label = if (isVarPrivate(tree, var_decl))
96-
.{ config.private_severity, "Private" }
97-
else
98-
.{ config.public_severity, "Public" };
95+
const severity, const label = switch (zlinter.ast.varDeclVisibility(tree, var_decl)) {
96+
.private => .{ config.private_severity, "Private" },
97+
.public => .{ config.public_severity, "Public" },
98+
};
9999
if (severity == .off) continue :nodes;
100100

101101
if (try hasDocComments(arena, tree, node.toNodeIndex())) continue :nodes;
@@ -132,22 +132,6 @@ fn hasDocComments(arena: std.mem.Allocator, tree: Ast, node: Ast.Node.Index) !bo
132132
return comments.len > 0;
133133
}
134134

135-
fn isFnPrivate(tree: Ast, fn_decl: Ast.full.FnProto) bool {
136-
const visibility_token = fn_decl.visib_token orelse return true;
137-
return switch (tree.tokens.items(.tag)[visibility_token]) {
138-
.keyword_pub => false,
139-
else => true,
140-
};
141-
}
142-
143-
fn isVarPrivate(tree: Ast, var_decl: Ast.full.VarDecl) bool {
144-
const visibility_token = var_decl.visib_token orelse return true;
145-
return switch (tree.tokens.items(.tag)[visibility_token]) {
146-
.keyword_pub => false,
147-
else => true,
148-
};
149-
}
150-
151135
test "require_doc_comment - public" {
152136
const rule = buildRule(.{});
153137
const source: [:0]const u8 =

0 commit comments

Comments
 (0)