-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create rule FullyQualifiedImportCheck
- Loading branch information
1 parent
bb975de
commit 0a252ea
Showing
6 changed files
with
202 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
59 changes: 59 additions & 0 deletions
59
delphi-checks/src/main/java/au/com/integradev/delphi/checks/FullyQualifiedImportCheck.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
/* | ||
* Sonar Delphi Plugin | ||
* Copyright (C) 2024 Integrated Application Development | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU Lesser General Public | ||
* License as published by the Free Software Foundation; either | ||
* version 3 of the License, or (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
* Lesser General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public | ||
* License along with this program; if not, write to the Free Software | ||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | ||
*/ | ||
package au.com.integradev.delphi.checks; | ||
|
||
import org.sonar.check.Rule; | ||
import org.sonar.plugins.communitydelphi.api.ast.UnitImportNode; | ||
import org.sonar.plugins.communitydelphi.api.check.DelphiCheck; | ||
import org.sonar.plugins.communitydelphi.api.check.DelphiCheckContext; | ||
import org.sonar.plugins.communitydelphi.api.reporting.QuickFix; | ||
import org.sonar.plugins.communitydelphi.api.reporting.QuickFixEdit; | ||
import org.sonar.plugins.communitydelphi.api.symbol.declaration.UnitImportNameDeclaration; | ||
|
||
@Rule(key = "FullyQualifiedImport") | ||
public class FullyQualifiedImportCheck extends DelphiCheck { | ||
|
||
@Override | ||
public DelphiCheckContext visit(UnitImportNode unitImportNode, DelphiCheckContext context) { | ||
if (!unitImportNode.isResolvedImport()) { | ||
return context; | ||
} | ||
|
||
UnitImportNameDeclaration unitImportNameDeclaration = unitImportNode.getImportNameDeclaration(); | ||
|
||
String unitFullyQualifiedName = unitImportNameDeclaration.getOriginalDeclaration().getImage(); | ||
String unitImportName = unitImportNameDeclaration.getImage(); | ||
|
||
if (unitImportName.length() != unitFullyQualifiedName.length()) { | ||
context | ||
.newIssue() | ||
.onNode(unitImportNode) | ||
.withMessage( | ||
"Fully qualify this unit name (found: \"%s\" expected: \"%s\").", | ||
unitImportName, unitFullyQualifiedName) | ||
.withQuickFixes( | ||
QuickFix.newFix("Fully qualify unit import") | ||
.withEdit( | ||
QuickFixEdit.replace(unitImportNode.getNameNode(), unitFullyQualifiedName))) | ||
.report(); | ||
} | ||
|
||
return context; | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
...src/main/resources/org/sonar/l10n/delphi/rules/community-delphi/FullyQualifiedImport.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<h2>Why is this an issue?</h2> | ||
<p> | ||
Imports should be done using the full name of the unit, as this facilitates code readability, avoids potential ambiguities about which unit is being imported, and ensures consistency throughout the codebase. | ||
</p> | ||
<p> | ||
Using the full name of the units not only improves code clarity and maintenance but also optimizes the compilation process. The compiler does not need to spend time searching implicit scopes to resolve which units are being referenced. By specifying the full unit name, the compiler can immediately locate the necessary files, resulting in faster and more efficient compilation. | ||
</p> | ||
<h2>How to fix it</h2> | ||
<p> | ||
Fully qualify the unit name. | ||
</p> | ||
<pre data-diff-id="1" data-diff-type="noncompliant"> | ||
uses | ||
Classes, | ||
SysUtils; | ||
</pre> | ||
<pre data-diff-id="1" data-diff-type="compliant"> | ||
uses | ||
System.Classes, | ||
System.SysUtils; | ||
</pre> |
18 changes: 18 additions & 0 deletions
18
...src/main/resources/org/sonar/l10n/delphi/rules/community-delphi/FullyQualifiedImport.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"title": "Imports should be fully qualified", | ||
"type": "CODE_SMELL", | ||
"status": "ready", | ||
"remediation": { | ||
"func": "Constant/Issue", | ||
"constantCost": "5min" | ||
}, | ||
"code": { | ||
"attribute": "CLEAR", | ||
"impacts": { | ||
"MAINTAINABILITY": "LOW" | ||
} | ||
}, | ||
"tags": ["convention"], | ||
"defaultSeverity": "Minor", | ||
"scope": "ALL" | ||
} |
102 changes: 102 additions & 0 deletions
102
...i-checks/src/test/java/au/com/integradev/delphi/checks/FullyQualifiedImportCheckTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
/* | ||
* Sonar Delphi Plugin | ||
* Copyright (C) 2024 Integrated Application Development | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU Lesser General Public | ||
* License as published by the Free Software Foundation; either | ||
* version 3 of the License, or (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
* Lesser General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public | ||
* License along with this program; if not, write to the Free Software | ||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | ||
*/ | ||
package au.com.integradev.delphi.checks; | ||
|
||
import au.com.integradev.delphi.builders.DelphiTestProgramBuilder; | ||
import au.com.integradev.delphi.builders.DelphiTestUnitBuilder; | ||
import au.com.integradev.delphi.checks.verifier.CheckVerifier; | ||
import org.junit.jupiter.api.Test; | ||
|
||
class FullyQualifiedImportCheckTest { | ||
|
||
@Test | ||
void testFullyQualifiedImportShouldNotAddIssue() { | ||
var importedUnit = new DelphiTestUnitBuilder().unitName("Scope.UnitU"); | ||
|
||
var testFile = new DelphiTestUnitBuilder().appendDecl("uses").appendDecl(" Scope.UnitU;"); | ||
|
||
CheckVerifier.newVerifier() | ||
.withCheck(new FullyQualifiedImportCheck()) | ||
.withSearchPathUnit(importedUnit) | ||
.onFile(testFile) | ||
.verifyNoIssues(); | ||
} | ||
|
||
@Test | ||
void testImportFullyQualifiedWithInKeywordShouldNotAddIssue() { | ||
var importedUnit = new DelphiTestUnitBuilder().unitName("Scope.UnitU"); | ||
|
||
var testFile = | ||
new DelphiTestProgramBuilder() | ||
.appendDecl("uses") | ||
.appendDecl(" Scope.UnitU in 'Test.UnitU.pas';"); | ||
|
||
CheckVerifier.newVerifier() | ||
.withCheck(new FullyQualifiedImportCheck()) | ||
.withSearchPathUnit(importedUnit) | ||
.onFile(testFile) | ||
.verifyNoIssues(); | ||
} | ||
|
||
@Test | ||
void testImportNotFullyQualifiedWithInKeywordShouldAddIssue() { | ||
var importedUnit = new DelphiTestUnitBuilder().unitName("Scope.UnitU"); | ||
|
||
var testFile = | ||
new DelphiTestProgramBuilder() | ||
.appendDecl("uses") | ||
.appendDecl(" // Fix qf1@[+1:2 to +1:7] <<Scope.UnitU>>") | ||
.appendDecl(" UnitU in 'Test.UnitU.pas'; // Noncompliant"); | ||
|
||
CheckVerifier.newVerifier() | ||
.withCheck(new FullyQualifiedImportCheck()) | ||
.withSearchPathUnit(importedUnit) | ||
.onFile(testFile) | ||
.withUnitScopeName("Scope") | ||
.verifyIssues(); | ||
} | ||
|
||
@Test | ||
void testUnresolvedImportShouldNotAddIssue() { | ||
var testFile = new DelphiTestUnitBuilder().appendDecl("uses").appendDecl(" RandomUnit;"); | ||
|
||
CheckVerifier.newVerifier() | ||
.withCheck(new FullyQualifiedImportCheck()) | ||
.onFile(testFile) | ||
.verifyNoIssues(); | ||
} | ||
|
||
@Test | ||
void testNotFullyQualifiedImportShouldAddIssue() { | ||
var importedUnit = new DelphiTestUnitBuilder().unitName("Scope.UnitU"); | ||
|
||
var testFile = | ||
new DelphiTestUnitBuilder() | ||
.appendDecl("uses") | ||
.appendDecl(" // Fix qf1@[+1:2 to +1:7] <<Scope.UnitU>>") | ||
.appendDecl(" UnitU; // Noncompliant"); | ||
|
||
CheckVerifier.newVerifier() | ||
.withCheck(new FullyQualifiedImportCheck()) | ||
.withSearchPathUnit(importedUnit) | ||
.onFile(testFile) | ||
.withUnitScopeName("Scope") | ||
.verifyIssues(); | ||
} | ||
} |