Skip to content

Commit ae21dc4

Browse files
committed
Fix FPs on wrapped type headers in VisibilityKeywordIndentation
1 parent dbc3a5c commit ae21dc4

File tree

3 files changed

+93
-15
lines changed

3 files changed

+93
-15
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212
- Exceptions from empty structures (e.g., `if`) in `LoopExecutingAtMostOnce` and `RedundantJump`.
1313
- False positives from case statements in `LoopExecutingAtMostOnce`.
1414
- False positives from nested finally-except blocks in `RedundantJump`.
15+
- False positives around wrapped type declarations in `VisibilityKeywordIndentation`.
1516

1617
## [1.14.1] - 2025-03-05
1718

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

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020

2121
import au.com.integradev.delphi.utils.IndentationUtils;
2222
import org.sonar.check.Rule;
23-
import org.sonar.plugins.communitydelphi.api.ast.DelphiNode;
23+
import org.sonar.plugins.communitydelphi.api.ast.NameDeclarationNode;
24+
import org.sonar.plugins.communitydelphi.api.ast.TypeDeclarationNode;
2425
import org.sonar.plugins.communitydelphi.api.ast.VisibilityNode;
2526
import org.sonar.plugins.communitydelphi.api.check.DelphiCheck;
2627
import org.sonar.plugins.communitydelphi.api.check.DelphiCheckContext;
@@ -32,19 +33,21 @@ public class VisibilityKeywordIndentationCheck extends DelphiCheck {
3233
private static final String MESSAGE =
3334
"Indent this visibility specifier to the indentation level of the containing type.";
3435

35-
private static String getExpectedIndentation(DelphiNode node) {
36-
var visibilityNode = (VisibilityNode) node;
37-
// Class/Record/etc. -> VisibilitySection -> Visibility
38-
var parent = visibilityNode.getParent().getParent();
39-
return IndentationUtils.getLineIndentation(parent);
40-
}
41-
4236
@Override
4337
public DelphiCheckContext visit(VisibilityNode visibilityNode, DelphiCheckContext context) {
44-
if (!IndentationUtils.getLineIndentation(visibilityNode)
45-
.equals(getExpectedIndentation(visibilityNode))) {
46-
reportIssue(context, visibilityNode, MESSAGE);
38+
var declaration = visibilityNode.getNthParent(3);
39+
40+
if (declaration instanceof TypeDeclarationNode) {
41+
NameDeclarationNode typeName = ((TypeDeclarationNode) declaration).getTypeNameNode();
42+
43+
String actual = IndentationUtils.getLineIndentation(visibilityNode);
44+
String expected = IndentationUtils.getLineIndentation(typeName);
45+
46+
if (!actual.equals(expected)) {
47+
reportIssue(context, visibilityNode, MESSAGE);
48+
}
4749
}
50+
4851
return super.visit(visibilityNode, context);
4952
}
5053
}

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

Lines changed: 78 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class VisibilityKeywordIndentationCheckTest {
3434
"class helper for TObject",
3535
"record helper for string"
3636
})
37-
void testTooIndentedVisibilitySpecifierShouldAddIssue(String structType) {
37+
void testVisibilityWithTooMuchIndentationShouldAddIssue(String structType) {
3838
CheckVerifier.newVerifier()
3939
.withCheck(new VisibilityKeywordIndentationCheck())
4040
.onFile(
@@ -56,7 +56,7 @@ void testTooIndentedVisibilitySpecifierShouldAddIssue(String structType) {
5656
"class helper for TObject",
5757
"record helper for string"
5858
})
59-
void testCorrectlyIndentedVisibilitySpecifierShouldNotAddIssue(String structType) {
59+
void testVisibilityAnchoredToTypeDeclarationShouldNotAddIssue(String structType) {
6060
CheckVerifier.newVerifier()
6161
.withCheck(new VisibilityKeywordIndentationCheck())
6262
.onFile(
@@ -70,7 +70,7 @@ void testCorrectlyIndentedVisibilitySpecifierShouldNotAddIssue(String structType
7070
}
7171

7272
@Test
73-
void testImplicitPublishedVisibilitySectionShouldNotAddIssue() {
73+
void testImplicitPublishedVisibilityShouldNotAddIssue() {
7474
CheckVerifier.newVerifier()
7575
.withCheck(new VisibilityKeywordIndentationCheck())
7676
.onFile(
@@ -84,7 +84,7 @@ void testImplicitPublishedVisibilitySectionShouldNotAddIssue() {
8484
}
8585

8686
@Test
87-
void testUnindentedVisibilitySpecifierShouldAddIssue() {
87+
void testVisibilityAtMarginShouldAddIssue() {
8888
CheckVerifier.newVerifier()
8989
.withCheck(new VisibilityKeywordIndentationCheck())
9090
.onFile(
@@ -96,4 +96,78 @@ void testUnindentedVisibilitySpecifierShouldAddIssue() {
9696
.appendDecl(" end;"))
9797
.verifyIssues();
9898
}
99+
100+
@Test
101+
void testWrappedClassDeclarationShouldNotAddIssue() {
102+
CheckVerifier.newVerifier()
103+
.withCheck(new VisibilityKeywordIndentationCheck())
104+
.onFile(
105+
new DelphiTestUnitBuilder()
106+
.appendDecl("type")
107+
.appendDecl(" TFoo =")
108+
.appendDecl(" class(TObject)")
109+
.appendDecl(" private")
110+
.appendDecl(" procedure Proc;")
111+
.appendDecl(" end;"))
112+
.verifyNoIssues();
113+
}
114+
115+
@Test
116+
void testMisalignedCustomAttributeShouldNotAddIssue() {
117+
CheckVerifier.newVerifier()
118+
.withCheck(new VisibilityKeywordIndentationCheck())
119+
.onFile(
120+
new DelphiTestUnitBuilder()
121+
.appendDecl("type")
122+
.appendDecl(" [Foo]")
123+
.appendDecl(" TBar = class(TObject)")
124+
.appendDecl(" private")
125+
.appendDecl(" procedure Baz;")
126+
.appendDecl(" end;"))
127+
.verifyNoIssues();
128+
}
129+
130+
@Test
131+
void testSameLineCustomAttributeShouldNotAddIssue() {
132+
CheckVerifier.newVerifier()
133+
.withCheck(new VisibilityKeywordIndentationCheck())
134+
.onFile(
135+
new DelphiTestUnitBuilder()
136+
.appendDecl("type")
137+
.appendDecl(" [Foo] TBar = class(TObject)")
138+
.appendDecl(" private")
139+
.appendDecl(" procedure Baz;")
140+
.appendDecl(" end;"))
141+
.verifyNoIssues();
142+
}
143+
144+
@Test
145+
void testVarAnonymousRecordShouldNotAddIssue() {
146+
CheckVerifier.newVerifier()
147+
.withCheck(new VisibilityKeywordIndentationCheck())
148+
.onFile(
149+
new DelphiTestUnitBuilder()
150+
.appendDecl("var")
151+
.appendDecl(" Foo: record")
152+
.appendDecl(" public")
153+
.appendDecl(" public")
154+
.appendDecl(" Bar: Integer;")
155+
.appendDecl(" end;"))
156+
.verifyNoIssues();
157+
}
158+
159+
@Test
160+
void testConstAnonymousRecordShouldNotAddIssue() {
161+
CheckVerifier.newVerifier()
162+
.withCheck(new VisibilityKeywordIndentationCheck())
163+
.onFile(
164+
new DelphiTestUnitBuilder()
165+
.appendDecl("const")
166+
.appendDecl(" Foo: record")
167+
.appendDecl(" public")
168+
.appendDecl(" public")
169+
.appendDecl(" Bar: Integer;")
170+
.appendDecl(" end = ();"))
171+
.verifyNoIssues();
172+
}
99173
}

0 commit comments

Comments
 (0)