diff --git a/.all-contributorsrc b/.all-contributorsrc
index 1c882017e1..10051359fc 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -6835,6 +6835,15 @@
"contributions": [
"financial"
]
+ },
+ {
+ "login": "OlegAndreych",
+ "name": "Oleg Andreych",
+ "avatar_url": "https://avatars.githubusercontent.com/u/2041351?v=4",
+ "profile": "https://github.com/OlegAndreych",
+ "contributions": [
+ "code"
+ ]
}
],
"contributorsPerLine": 7,
diff --git a/docs/pages/pmd/projectdocs/credits.md b/docs/pages/pmd/projectdocs/credits.md
index 33f61a966d..91201439cf 100644
--- a/docs/pages/pmd/projectdocs/credits.md
+++ b/docs/pages/pmd/projectdocs/credits.md
@@ -530,444 +530,445 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Noam Tamim π |
Noel Grandin π |
Olaf Haalstra π |
+ Oleg Andreych π» |
Oleg Pavlenko π |
Oleksii Dykov π» |
Oliver Eikemeier π |
- Oliver Siegmar π΅ |
+ Oliver Siegmar π΅ |
Olivier Parent π» π |
Ollie Abbey π» π |
OverDrone π |
Ozan Gulle π» π |
PUNEET JAIN π |
Parbati Bose π |
- Paul Berg π |
+ Paul Berg π |
Pavel Bludov π |
Pavel MiΔka π |
Pedro Nuno Santos π |
Pedro Rijo π |
Pelisse Romain π» π π |
Per Abich π» |
- Pete Davids π |
+ Pete Davids π |
Peter Bruin π |
Peter Chittum π» π |
Peter Cudmore π |
Peter Kasson π |
Peter Kofler π |
Peter Paul Bakker π» |
- Pham Hai Trung π |
+ Pham Hai Trung π |
Philip Graf π» π |
Philip Hachey π |
Philippe Ozil π |
Phinehas Artemix π |
Phokham Nonava π |
Piotr SzymaΕski π |
- Piotrek Ε»ygieΕo π» π π |
+ Piotrek Ε»ygieΕo π» π π |
Pranay Jaiswal π |
Prasad Kamath π |
Prasanna π |
Presh-AR π |
Puneet1726 π |
Rafael CortΓͺs π |
- RaheemShaik999 π |
+ RaheemShaik999 π |
RajeshR π» π |
Ramachandra Mohan π |
Ramel0921 π |
Raquel Pau π |
Ravikiran Janardhana π |
Reda Benhemmouche π |
- Renato Oliveira π» π |
+ Renato Oliveira π» π |
Rich DiCroce π |
Riot R1cket π |
Rishabh Jain π |
RishabhDeep Singh π |
Robbie Martinus π» π |
Robert Henry π |
- Robert Painsi π |
+ Robert Painsi π |
Robert Russell π |
Robert SΓΆsemann π» π π’ π |
Robert Whitebit π |
Robin Richtsfeld π |
Robin Stocker π» π |
Robin Wils π |
- RochusOest π |
+ RochusOest π |
Rodolfo Noviski π |
Rodrigo Casara π |
Rodrigo Fernandes π |
Roman Salvador π» π |
Ronald Blaschke π |
RΓ³bert Papp π |
- Saikat Sengupta π |
+ Saikat Sengupta π |
Saksham Handu π |
Saladoc π |
Salesforce Bob Lightning π |
Sam Carlberg π |
Satoshi Kubo π |
Scott Kennedy π |
- Scott Wells π π» |
+ Scott Wells π π» |
Scrsloota π» |
Sebastian BΓΆgl π |
Sebastian Schuberth π |
Sebastian Schwarz π |
Sergey Gorbaty π |
Sergey Kozlov π |
- Sergey Yanzin π» π |
+ Sergey Yanzin π» π |
Seth Wilcox π» |
Shubham π» π |
Simon Abykov π» |
Simon Xiao π |
Srinivasan Venkatachalam π |
Stanislav Gromov π |
- Stanislav Myachenkov π» |
+ Stanislav Myachenkov π» |
Stefan Birkner π |
Stefan Bohn π |
Stefan Endrullis π |
Stefan KlΓΆss-Schuster π |
Stefan Wolf π |
Stephan H. Wissel π |
- Stephen π |
+ Stephen π |
Stephen Friedrich π |
Steve Babula π» |
Stexxe π |
Stian LΓ₯gstad π |
StuartClayton5 π |
Supun Arunoda π |
- Suren Abrahamyan π |
+ Suren Abrahamyan π |
Suvashri π |
SwatiBGupta1110 π |
SyedThoufich π |
Szymon Sasin π |
T-chuangxin π |
TERAI Atsuhiro π |
- TIOBE Software π» π |
+ TIOBE Software π» π |
Taylor Smock π |
Techeira DamiΓ‘n π» π |
Ted Husted π |
TehBakker π |
The Gitter Badger π |
Theodoor π |
- Thiago Henrique HΓΌpner π |
+ Thiago Henrique HΓΌpner π |
Thibault Meyer π |
Thomas GΓΌttler π |
Thomas Jones-Low π |
Thomas Smith π» π |
ThrawnCA π |
Thunderforge π» π |
- Tim van der Lippe π |
+ Tim van der Lippe π |
Tobias Weimer π» π |
Tom Daly π |
Tomer Figenblat π |
Tomi De Lucca π» π |
Torsten Kleiber π |
TrackerSB π |
- Ullrich Hafner π |
+ Ullrich Hafner π |
Utku Cuhadaroglu π» π |
Valentin Brandl π |
Valeria π |
Vasily Anisimov π |
Vibhor Goyal π |
Vickenty Fesunov π |
- Victor NoΓ«l π |
+ Victor NoΓ«l π |
Vincent Galloy π» |
Vincent HUYNH π |
Vincent Maurin π |
Vincent Privat π |
Vishhwas π |
Vitaly π |
- Vitaly Polonetsky π |
+ Vitaly Polonetsky π |
Vojtech Polivka π |
Vsevolod Zholobov π |
Vyom Yadav π» |
Wang Shidong π |
Waqas Ahmed π |
Wayne J. Earl π |
- Wchenghui π |
+ Wchenghui π |
Will Winder π |
William Brockhus π» π |
Wilson Kurniawan π |
Wim Deblauwe π |
Woongsik Choi π |
XenoAmess π» π |
- Yang π» |
+ Yang π» |
YaroslavTER π |
Young Chan π» π |
YuJin Kim π |
Yuri Dolzhenko π |
Yurii Dubinka π |
Zoltan Farkas π |
- Zustin π |
+ Zustin π |
aaronhurst-google π π» |
alexmodis π |
andreoss π |
andrey81inmd π» π |
anicoara π |
arunprasathav π |
- asiercamara π |
+ asiercamara π |
astillich-igniti π» |
avesolovksyy π |
avishvat π |
avivmu π |
axelbarfod1 π |
b-3-n π |
- balbhadra9 π |
+ balbhadra9 π |
base23de π |
bergander π |
berkam π» π |
breizh31 π |
caesarkim π |
carolyujing π |
- cesares-basilico π |
+ cesares-basilico π |
chrite π |
cobratbq π |
coladict π |
cosmoJFH π |
cristalp π |
crunsk π |
- cwholmes π |
+ cwholmes π |
cyberjj999 π |
cyw3 π |
d1ss0nanz π |
dalizi007 π» |
danbrycefairsailcom π |
dariansanity π |
- darrenmiliband π |
+ darrenmiliband π |
davidburstrom π |
dbirkman-paloalto π |
deepak-patra π |
dependabot[bot] π» π |
dinesh150 π |
diziaq π |
- dreaminpast123 π |
+ dreaminpast123 π |
duanyanan π |
dutt-sanjay π |
dylanleung π |
dzeigler π |
ekkirala π |
emersonmoura π |
- fairy π |
+ fairy π |
filiprafalowicz π» |
foxmason π |
frankegabor π |
frankl π |
freafrea π |
fsapatin π |
- gracia19 π |
+ gracia19 π |
guo fei π |
gurmsc5 π |
gwilymatgearset π» π |
haigsn π |
hemanshu070 π |
henrik242 π |
- hongpuwu π |
+ hongpuwu π |
hvbtup π» π |
igniti GmbH π |
ilovezfs π |
itaigilo π |
jakivey32 π |
jbennett2091 π |
- jcamerin π |
+ jcamerin π |
jkeener1 π |
jmetertea π |
johnra2 π» |
josemanuelrolon π» π |
kabroxiko π» π |
karwer π |
- kaulonline π |
+ kaulonline π |
kdaemonv π |
kenji21 π» π |
kfranic π |
khalidkh π |
krzyk π |
lasselindqvist π |
- lgemeinhardt π |
+ lgemeinhardt π |
lihuaib π |
lonelyma1021 π |
lpeddy π |
lujiefsi π» |
lukelukes π» |
lyriccoder π |
- marcelmore π |
+ marcelmore π |
matchbox π |
matthiaskraaz π |
meandonlyme π |
mikesive π |
milossesic π |
mohan-chinnappan-n π» |
- mriddell95 π |
+ mriddell95 π |
mrlzh π |
msloan π |
mucharlaravalika π |
mvenneman π |
nareshl119 π |
nicolas-harraudeau-sonarsource π |
- noerremark π |
+ noerremark π |
novsirion π |
oggboy π |
oinume π |
orimarko π» π |
pacvz π» |
pallavi agarwal π |
- parksungrin π |
+ parksungrin π |
patpatpat123 π |
patriksevallius π |
pbrajesh1 π |
phoenix384 π |
piotrszymanski-sc π» |
plan3d π |
- poojasix π |
+ poojasix π |
prabhushrikant π |
pujitha8783 π |
r-r-a-j π |
raghujayjunk π |
rajeshveera π |
rajeswarreddy88 π |
- recdevs π |
+ recdevs π |
reudismam π» π |
rijkt π |
rillig-tk π |
rmohan20 π» π |
rxmicro π |
ryan-gustafson π» π |
- sabi0 π |
+ sabi0 π |
scais π |
sebbASF π |
sergeygorbaty π» |
shilko2013 π |
shiomiyan π |
simeonKondr π |
- snajberk π |
+ snajberk π |
sniperrifle2004 π |
snuyanzin π π» |
sratz π |
stonio π |
sturton π» π |
sudharmohan π |
- suruchidawar π |
+ suruchidawar π |
svenfinitiv π |
tashiscool π |
test-git-hook π |
testation21 π» π |
thanosa π |
tiandiyixian π |
- tobwoerk π |
+ tobwoerk π |
tprouvot π π» |
trentchilders π |
triandicAnt π |
trishul14 π |
tsui π |
winhkey π |
- witherspore π |
+ witherspore π |
wjljack π |
wuchiuwong π |
xingsong π |
xioayuge π |
xnYi9wRezm π» π |
xuanuy π |
- xyf0921 π |
+ xyf0921 π |
yalechen-cyw3 π |
yasuharu-sato π |
zenglian π |
zgrzyt93 π» π |
zh3ng π |
zt_soft π |
- ztt79 π |
+ ztt79 π |
zzzzfeng π |
ΓrpΓ‘d MagosΓ‘nyi π |
δ»»θ΄΅ζ° π |
diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md
index 929bc6e4cc..57478e11d7 100644
--- a/docs/pages/release_notes.md
+++ b/docs/pages/release_notes.md
@@ -27,6 +27,8 @@ from Lua. This means, that the Lua language in PMD can now parse both Lua and Lu
* doc
* [#4109](https://github.com/pmd/pmd/pull/4109): \[doc] Add page for 3rd party rulesets
* [#4124](https://github.com/pmd/pmd/pull/4124): \[doc] Fix typos in Java rule docs
+* java-codestyle
+ * [#4085](https://github.com/pmd/pmd/issues/4085): \[java] UnnecessaryFullyQualifiedName false positive when nested and non-nested classes with the same name and in the same package are used together
### API Changes
@@ -44,6 +46,7 @@ Many thanks to our sponsors:
* [#4066](https://github.com/pmd/pmd/pull/4066): \[lua] Add support for Luau syntax and skipping literal sequences in CPD - [Matt Hargett](https://github.com/matthargett) (@matthargett)
* [#4116](https://github.com/pmd/pmd/pull/4116): \[core] Fix missing --file arg in TreeExport CLI example - [mohan-chinnappan-n](https://github.com/mohan-chinnappan-n) (@mohan-chinnappan-n)
* [#4124](https://github.com/pmd/pmd/pull/4124) : \[doc] Fix typos in Java rule docs - [Piotrek Ε»ygieΕo](https://github.com/pzygielo) (@pzygielo)
+* [#4128](https://github.com/pmd/pmd/pull/4128): \[java] Fix False-positive UnnecessaryFullyQualifiedName when nested and non-nest⦠#4103 - [Oleg Andreych](https://github.com/OlegAndreych) (@OlegAndreych)
* [#4131](https://github.com/pmd/pmd/pull/4131): \[doc] TooFewBranchesForASwitchStatement - Use "if-else" instead of "if-then" - [Suvashri](https://github.com/Suvashri) (@Suvashri)
{% endtocmaker %}
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryFullyQualifiedNameRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryFullyQualifiedNameRule.java
index 32bf8fa21c..8091d944e3 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryFullyQualifiedNameRule.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryFullyQualifiedNameRule.java
@@ -17,7 +17,9 @@ import java.util.logging.Logger;
import org.apache.commons.lang3.StringUtils;
import net.sourceforge.pmd.RuleContext;
+import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType;
+import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTName;
import net.sourceforge.pmd.lang.java.ast.ASTNameList;
@@ -186,9 +188,12 @@ public class UnnecessaryFullyQualifiedNameRule extends AbstractJavaRule {
if (matches.isEmpty()) {
if (isJavaLangImplicit(node)) {
- addViolation(data, node, new Object[] { node.getImage(), "java.lang.*", "implicit "});
+ asCtx(data).addViolation(node,
+ node.getImage(), "java.lang.*", "implicit ");
} else if (isSamePackage(node, name)) {
- addViolation(data, node, new Object[] { node.getImage(), currentPackage + ".*", "same package "});
+ if (!hasSameSimpleNameInScope(node)) {
+ asCtx(data).addViolation(node, node.getImage(), currentPackage + ".*", "same package ");
+ }
}
} else {
ASTImportDeclaration firstMatch = findFirstMatch(matches);
@@ -199,11 +204,29 @@ public class UnnecessaryFullyQualifiedNameRule extends AbstractJavaRule {
String importStr = firstMatch.getImportedName() + (firstMatch.isImportOnDemand() ? ".*" : "");
String type = firstMatch.isStatic() ? "static " : "";
- addViolation(data, node, new Object[] { node.getImage(), importStr, type });
+ asCtx(data).addViolation(node, node.getImage(), importStr, type);
}
}
}
+ private boolean hasSameSimpleNameInScope(TypeNode node) {
+ final ASTCompilationUnit root = node.getRoot();
+ final List declarationDescendants = root.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class);
+ final Class> nodeType = node.getType();
+
+ if (nodeType == null) {
+ return false;
+ }
+
+ for (ASTClassOrInterfaceDeclaration declarationDescendant : declarationDescendants) {
+ if (nodeType.getSimpleName().equals(declarationDescendant.getSimpleName())
+ && !nodeType.getName().equals(declarationDescendant.getQualifiedName().toString())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private ASTImportDeclaration findFirstMatch(List imports) {
// first search only static imports
ASTImportDeclaration result = null;
@@ -404,7 +427,7 @@ public class UnnecessaryFullyQualifiedNameRule extends AbstractJavaRule {
// Is it a conflict with a class in the same file?
final Set qualifiedTypes = node.getScope().getEnclosingScope(SourceFileScope.class)
- .getQualifiedTypeNames().keySet();
+ .getQualifiedTypeNames().keySet();
for (final String qualified : qualifiedTypes) {
int fullLength = qualified.length();
if (qualified.endsWith(unqualifiedName)
diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryFullyQualifiedName.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryFullyQualifiedName.xml
index f95d7bc81e..097e096767 100644
--- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryFullyQualifiedName.xml
+++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/codestyle/xml/UnnecessaryFullyQualifiedName.xml
@@ -622,6 +622,40 @@ public class UnnecessaryFullyQualifiedName {
]]>
+
+ False positive when same package inner class is referenced (not enum) #4085
+ 0
+
+
+
+
+ Should report fully-qualified name usage of a class in itself #4085
+ 1
+ 4
+
+
+
#2098 false positive with annotated package
0