Skip to content

Commit 964d749

Browse files
committed
Ignore all blocks with comments in EmptyBlock
1 parent a3938fc commit 964d749

File tree

4 files changed

+72
-26
lines changed

4 files changed

+72
-26
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Changed
11+
12+
- `EmptyBlock` now ignores all empty blocks containing an explanatory comment.
13+
1014
## [1.17.2] - 2025-07-03
1115

1216
### Fixed

delphi-checks/src/main/java/au/com/integradev/delphi/checks/EmptyBlockCheck.java

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@
2020

2121
import org.sonar.check.Rule;
2222
import org.sonar.plugins.communitydelphi.api.ast.AnonymousMethodNode;
23-
import org.sonar.plugins.communitydelphi.api.ast.CaseItemStatementNode;
24-
import org.sonar.plugins.communitydelphi.api.ast.CaseStatementNode;
2523
import org.sonar.plugins.communitydelphi.api.ast.CompoundStatementNode;
2624
import org.sonar.plugins.communitydelphi.api.ast.DelphiNode;
2725
import org.sonar.plugins.communitydelphi.api.ast.ElseBlockNode;
@@ -50,37 +48,31 @@ public DelphiCheckContext visit(CompoundStatementNode block, DelphiCheckContext
5048
private static boolean shouldAddViolation(CompoundStatementNode block) {
5149
DelphiNode parent = block.getParent();
5250

53-
if (parent instanceof RoutineBodyNode || parent instanceof AnonymousMethodNode) {
54-
// Handled by EmptyRoutineRule
51+
if (!block.getComments().isEmpty()) {
52+
// An empty block is OK if it has an explanatory comment.
5553
return false;
5654
}
5755

58-
if (parent instanceof ExceptItemNode) {
59-
// Handled by SwallowedExceptionsRule
56+
if (parent instanceof RoutineBodyNode || parent instanceof AnonymousMethodNode) {
57+
// Handled by EmptyRoutine
6058
return false;
6159
}
6260

63-
if (parent instanceof CaseItemStatementNode) {
64-
// Handling all cases in a case statement is a reasonable thing to do.
65-
// With that being said, a comment is required.
66-
return block.getComments().isEmpty();
61+
if (parent instanceof ExceptItemNode) {
62+
// Handled by SwallowedException
63+
return false;
6764
}
6865

6966
if (parent instanceof StatementListNode) {
7067
StatementListNode statementList = (StatementListNode) parent;
71-
DelphiNode grandparent = parent.getParent();
68+
DelphiNode enclosing = statementList.getParent();
7269

7370
if (statementList.getStatements().size() == 1) {
74-
if (grandparent instanceof ElseBlockNode
75-
&& grandparent.getParent() instanceof CaseStatementNode) {
76-
// Handling all cases in a case statement is a reasonable thing to do.
77-
// With that being said, a comment is required.
78-
return block.getComments().isEmpty();
71+
if (enclosing instanceof ElseBlockNode) {
72+
enclosing = enclosing.getParent();
7973
}
80-
81-
// Handled by SwallowedExceptionsRule
82-
return !(grandparent instanceof ElseBlockNode)
83-
|| !(grandparent.getParent() instanceof ExceptBlockNode);
74+
// Handled by SwallowedException
75+
return !(enclosing instanceof ExceptBlockNode);
8476
}
8577
}
8678

delphi-checks/src/main/resources/org/sonar/l10n/delphi/rules/community-delphi/EmptyBlock.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ <h2>Why is this an issue?</h2>
55
</p>
66
<h3>Exceptions</h3>
77
<ul>
8+
<li>Empty blocks with an explanatory comment</li>
89
<li>Empty routine bodies (covered by the <code>EmptyRoutine</code> rule)</li>
910
<li>Empty except blocks (covered by the <code>SwallowedException</code> rule)</li>
10-
<li>Case blocks that are empty apart from a comment</li>
1111
</ul>

delphi-checks/src/test/java/au/com/integradev/delphi/checks/EmptyBlockCheckTest.java

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ void testEmptyBeginStatementsShouldAddIssue() {
8484
.appendImpl("end;")
8585
.appendImpl("procedure TEmptyProcs.Three;")
8686
.appendImpl("begin")
87-
.appendImpl(" if Foo then begin // Noncompliant")
88-
.appendImpl(" // Do nothing")
87+
.appendImpl(" if Foo then begin")
88+
.appendImpl(" // This exists for X reason")
8989
.appendImpl(" end;")
9090
.appendImpl("end;")
9191
.appendImpl("procedure GlobalProcedureFour;")
@@ -94,8 +94,11 @@ void testEmptyBeginStatementsShouldAddIssue() {
9494
.appendImpl("end;")
9595
.appendImpl("procedure GlobalProcedureFive;")
9696
.appendImpl("begin")
97-
.appendImpl(" if Foo then begin // Noncompliant")
98-
.appendImpl(" // Do nothing")
97+
.appendImpl(" // Noncompliant@+1")
98+
.appendImpl(" if Foo then begin")
99+
.appendImpl(" end")
100+
.appendImpl(" // Noncompliant@+1")
101+
.appendImpl(" else begin")
99102
.appendImpl(" end;")
100103
.appendImpl("end;"))
101104
.verifyIssues();
@@ -122,7 +125,7 @@ void testEmptyBlocksInCaseStatementShouldAddIssue() {
122125
}
123126

124127
@Test
125-
void testEmptyBlocksInCaseStatementShouldNotAddIssue() {
128+
void testNonEmptyBlocksInCaseStatementShouldNotAddIssue() {
126129
CheckVerifier.newVerifier()
127130
.withCheck(new EmptyBlockCheck())
128131
.onFile(
@@ -177,4 +180,51 @@ void testEmptyAnonymousMethodShouldNotAddIssue() {
177180
.appendImpl("end;"))
178181
.verifyNoIssues();
179182
}
183+
184+
@Test
185+
void testEmptyExceptShouldNotAddIssue() {
186+
CheckVerifier.newVerifier()
187+
.withCheck(new EmptyBlockCheck())
188+
.onFile(
189+
new DelphiTestUnitBuilder()
190+
.appendImpl("procedure Foo;")
191+
.appendImpl("begin")
192+
.appendImpl(" try")
193+
.appendImpl(" // Do risky stuff")
194+
.appendImpl(" except")
195+
.appendImpl(" end;")
196+
.appendImpl(" try")
197+
.appendImpl(" // Do risky stuff")
198+
.appendImpl(" except")
199+
.appendImpl(" on E: Exception do begin")
200+
.appendImpl(" end;")
201+
.appendImpl(" else begin")
202+
.appendImpl(" end;")
203+
.appendImpl(" end;")
204+
.appendImpl("end;"))
205+
.verifyNoIssues();
206+
}
207+
208+
@Test
209+
void testNestedEmptyElsesShouldAddIssue() {
210+
CheckVerifier.newVerifier()
211+
.withCheck(new EmptyBlockCheck())
212+
.onFile(
213+
new DelphiTestUnitBuilder()
214+
.appendImpl("procedure Foo;")
215+
.appendImpl("begin")
216+
.appendImpl(" // Noncompliant@+1")
217+
.appendImpl(" if Bar then begin")
218+
.appendImpl(" end")
219+
.appendImpl(" else begin")
220+
.appendImpl(" // Noncompliant@+1")
221+
.appendImpl(" if Baz then begin")
222+
.appendImpl(" end")
223+
.appendImpl(" // Noncompliant@+1")
224+
.appendImpl(" else begin")
225+
.appendImpl(" end;")
226+
.appendImpl(" end;")
227+
.appendImpl("end;"))
228+
.verifyIssues();
229+
}
180230
}

0 commit comments

Comments
 (0)