Merge branch 'master' into pr/4038
This commit is contained in:
6 files changed
+118
-25
No files matched your search
@@ -6749,6 +6749,15 @@
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "341816041",
|
||||
"name": "茅延安",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/100549608?v=4",
|
||||
"profile": "https://github.com/341816041",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 7,
|
||||
|
||||
@@ -961,6 +961,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/magwas"><img src="https://avatars.githubusercontent.com/u/756838?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Árpád Magosányi</b></sub></a><br /><a href="https://github.com/pmd/pmd/issues?q=author%3Amagwas" title="Bug reports">🐛</a></td>
|
||||
<td align="center"><a href="https://github.com/clsaa"><img src="https://avatars.githubusercontent.com/u/32028545?v=4?s=100" width="100px;" alt=""/><br /><sub><b>任贵杰</b></sub></a><br /><a href="https://github.com/pmd/pmd/issues?q=author%3Aclsaa" title="Bug reports">🐛</a></td>
|
||||
<td align="center"><a href="https://github.com/341816041"><img src="https://avatars.githubusercontent.com/u/100549608?v=4?s=100" width="100px;" alt=""/><br /><sub><b>茅延安</b></sub></a><br /><a href="https://github.com/pmd/pmd/commits?author=341816041" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
@@ -45,6 +45,9 @@ Being based on a proper Antlr grammar, CPD can:
|
||||
* [#4015](https://github.com/pmd/pmd/issues/4015): \[java] Support JDK 19
|
||||
* java-bestpractices
|
||||
* [#3455](https://github.com/pmd/pmd/issues/3455): \[java] WhileLoopWithLiteralBoolean - false negative with complex expressions
|
||||
* java-design
|
||||
* [#3729](https://github.com/pmd/pmd/issues/3729): \[java] TooManyMethods ignores "real" methods which are named like getters or setters
|
||||
* [#3949](https://github.com/pmd/pmd/issues/3949): \[java] FinalFieldCouldBeStatic - false negative with unnecessary parenthesis
|
||||
* java-performance
|
||||
* [#3625](https://github.com/pmd/pmd/issues/3625): \[java] AddEmptyString - false negative with empty var
|
||||
|
||||
@@ -67,6 +70,8 @@ Being based on a proper Antlr grammar, CPD can:
|
||||
### External Contributions
|
||||
* [#3984](https://github.com/pmd/pmd/pull/3984): \[java] Fix AddEmptyString false-negative issue - [@LiGaOg](https://github.com/LiGaOg)
|
||||
* [#3988](https://github.com/pmd/pmd/pull/3988): \[java] Modify WhileLoopWithLiteralBoolean to meet the missing case #3455 - [@VoidxHoshi](https://github.com/VoidxHoshi)
|
||||
* [#3992](https://github.com/pmd/pmd/pull/3992): \[java] FinalFieldCouldBeStatic - fix false negative with unnecessary parenthesis - [@dalizi007](https://github.com/dalizi007)
|
||||
* [#3994](https://github.com/pmd/pmd/pull/3994): \[java] TooManyMethods - improve getter/setter detection (#3729) - [@341816041](https://github.com/341816041)
|
||||
* [#4017](https://github.com/pmd/pmd/pull/4017): Add Gherkin support to CPD - [@ASBrouwers](https://github.com/ASBrouwers)
|
||||
|
||||
{% endtocmaker %}
|
||||
|
||||
@@ -821,6 +821,18 @@ in each object at runtime.
|
||||
or
|
||||
(: another static field :)
|
||||
self::Name[@Image=//FieldDeclaration[@Static=true()]/VariableDeclarator/@Name]
|
||||
or
|
||||
(:unnecessary parenthesis :)
|
||||
self::Expression/PrimaryExpression/PrimaryPrefix/Literal
|
||||
or
|
||||
(:empty array allocation :)
|
||||
self::AllocationExpression[ArrayDimsAndInits/Expression/PrimaryExpression/PrimaryPrefix/*
|
||||
[
|
||||
self::Literal[@IntLiteral = true()][@Image="0"]
|
||||
or
|
||||
self::Expression/PrimaryExpression/PrimaryPrefix/Literal[@IntLiteral = true()][@Image="0"]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
/VariableDeclaratorId
|
||||
@@ -1678,36 +1690,14 @@ complexity and find a way to have more fine grained objects.
|
||||
<property name="version" value="2.0"/>
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<!-- FIXME: Refine XPath to discard 'get' and 'set' methods with Block no more than 3 lines,
|
||||
something like this:
|
||||
not (
|
||||
(
|
||||
starts-with(@Name,'get')
|
||||
or
|
||||
starts-with(@Name,'set')
|
||||
or
|
||||
starts-with(@Name,'is')
|
||||
)
|
||||
and (
|
||||
(
|
||||
(../Block/attribute::endLine)
|
||||
-
|
||||
(../Block/attribute::beginLine)
|
||||
) <= 3
|
||||
)
|
||||
)
|
||||
This will avoid discarding 'real' methods...
|
||||
-->
|
||||
<![CDATA[
|
||||
//ClassOrInterfaceDeclaration/ClassOrInterfaceBody
|
||||
[
|
||||
count(./ClassOrInterfaceBodyDeclaration/MethodDeclaration[
|
||||
not (
|
||||
starts-with(@Name,'get')
|
||||
or
|
||||
starts-with(@Name,'set')
|
||||
or
|
||||
starts-with(@Name,'is')
|
||||
(starts-with(@Name,'get') or starts-with(@Name,'set') or starts-with(@Name,'is'))
|
||||
and
|
||||
count(Block/BlockStatement) <= 1
|
||||
)
|
||||
]) > $maxmethods
|
||||
]
|
||||
|
||||
+39
@@ -189,6 +189,45 @@ public class Foo {
|
||||
//private static final int staticFinal = nonStatic; //noncompliant: Non-static field 'nonStatic' cannot be referenced from a static context
|
||||
private static int staticNonFinal = 1; //no violation cause non-final
|
||||
private final int nonStatic2 = staticNonFinal; //violation because it could be static
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>#3949 - FinalFieldCouldBeStatic false negative with unnecessary parenthesis</description>
|
||||
<expected-problems>3</expected-problems>
|
||||
<expected-linenumbers>5,8,9</expected-linenumbers>
|
||||
<code><![CDATA[
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Foo {
|
||||
public final int BAR = (42);
|
||||
|
||||
// these empty arrays could theoretically be shared and therefore be static
|
||||
private final Object[] argsObjs1 = new Object[0];
|
||||
private final Object[] argsObjs2 = new Object[(0)];
|
||||
|
||||
// not flagging anonymous class instantiation
|
||||
private final StringBuffer mFilter = new StringBuffer(new CharSequence() {
|
||||
@Override public char charAt(int index) { return 'A'; }
|
||||
@Override public int length() { return 1; }
|
||||
@Override public CharSequence subSequence(int start, int end) { return this; }
|
||||
@Override public String toString() { return "Foo"; }
|
||||
});
|
||||
|
||||
// not flagging any instantiation in order to avoid false positives
|
||||
// especially for lists one could still require a separate list for each instance...
|
||||
public final List<String> mList = new ArrayList<>();
|
||||
|
||||
// not flagging instantiation of boxed types - would be a different rule
|
||||
// this is to keep this rule simple
|
||||
public final Integer DefaultInit = new Integer(27);
|
||||
private final String mString = new String("Foo");
|
||||
|
||||
// not flagging array creation. Same reasoning as for lists:
|
||||
// one could still require a separate array for each instance...
|
||||
private final int[] p = new int[42];
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
+49
@@ -113,4 +113,53 @@ public class OuterClass {
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<code-fragment id="code_22_real_methods"><![CDATA[
|
||||
public class Foo {
|
||||
public void setMethod1(){int a = 1;a++;}
|
||||
public void setMethod2(){int a = 1;a++;}
|
||||
public void setMethod3(){int a = 1;a++;}
|
||||
public void setMethod4(){int a = 1;a++;}
|
||||
public void setMethod5(){int a = 1;a++;}
|
||||
|
||||
public void getMethod6(){int a = 1;a++;}
|
||||
public void getMethod7(){int a = 1;a++;}
|
||||
public void getMethod8(){int a = 1;a++;}
|
||||
public void getMethod9(){int a = 1;a++;}
|
||||
public void getMethod10(){int a = 1;a++;}
|
||||
|
||||
public boolean isMethod11(){int a = 1;a++;}
|
||||
public boolean isMethod12(){int a = 1;a++;}
|
||||
public boolean isMethod13(){int a = 1;a++;}
|
||||
public boolean isMethod14(){int a = 1;a++;}
|
||||
public boolean isMethod15(){int a = 1;a++;}
|
||||
public boolean isMethod16(){int a = 1;a++;}
|
||||
|
||||
public void method17(){}
|
||||
public void method18(){}
|
||||
public void method19(){}
|
||||
public void method20(){}
|
||||
public void method21(){}
|
||||
public void method22(){}
|
||||
|
||||
private String field;
|
||||
public String getField() { return field; } // real getter
|
||||
public void setField(String field) { this.field = field; } // real setter
|
||||
}
|
||||
]]>
|
||||
</code-fragment>
|
||||
|
||||
<test-code>
|
||||
<description>#3729 TooManyMethods ignores "real" methods which are named like getters or setters - default</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-linenumbers>1</expected-linenumbers>
|
||||
<code-ref id="code_22_real_methods"/>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>#3729 TooManyMethods ignores "real" methods which are named like getters or setters - max 22 methods</description>
|
||||
<rule-property name="maxmethods">22</rule-property>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code-ref id="code_22_real_methods"/>
|
||||
</test-code>
|
||||
</test-data>
|
||||
Reference in new issue
Block a user