Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

添加两个规则 #592

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.alibaba.p3c.pmd.lang.java.rule.oop;

/*
* Copyright 1999-2017 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import com.alibaba.p3c.pmd.I18nResources;
import com.alibaba.p3c.pmd.lang.AbstractXpathRule;
import com.alibaba.p3c.pmd.lang.java.util.ViolationUtils;
import net.sourceforge.pmd.lang.ast.Node;

/**
* [Mandatory]
*
* @author leonard99559
* @date 2019/10/16
*/
public class VarargsParameterRule extends AbstractXpathRule {
private static final String XPATH = "//FormalParameter[@Varargs = 'true' and ./Type[@TypeImage = 'Object']]";

public VarargsParameterRule() {
setXPath(XPATH);
}

@Override
public void addViolation(Object data, Node node, String arg) {
ViolationUtils.addViolationWithPrecisePosition(this, node, data,
I18nResources.getMessage("java.oop.VarargsParameterRule.rule.msg",
node.getImage()));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.alibaba.p3c.pmd.lang.java.rule.set;

/*
* Copyright 1999-2017 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import com.alibaba.p3c.pmd.lang.java.rule.AbstractAliRule;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
import org.jaxen.JaxenException;

import java.util.List;

/**
* [Mendatory] Equals method must be with hashCode() method.
*
* @author leonard99559
* @date 2019/10/16
*/
public class EqualsHashCodeRule extends AbstractAliRule {

@Override
public Object visit(ASTCompilationUnit rootNode, Object data) {

try {
List<Node> nodeList = rootNode.findChildNodesWithXPath(
"//ClassOrInterfaceBodyDeclaration[./Annotation[@AnnotationName = 'Override']]" +
"//MethodDeclaration[@MethodName = 'hashCode' or @MethodName = 'equals']");
if (nodeList.size() == 1) {
addViolationWithMessage(data, nodeList.get(0),
"java.set.EqualsHashCodeRule.rule.msg");
}
} catch (JaxenException e) {
e.printStackTrace();
}
return super.visit(rootNode, data);
}

}
12 changes: 12 additions & 0 deletions p3c-pmd/src/main/resources/messages.xml
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,15 @@
<entry key="java.set.UnsupportedExceptionWithModifyAsListRule.rule.msg">
<![CDATA[ 使用工具类Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,它的add/remove/clear方法会抛出UnsupportedOperationException异常。 ]]>
</entry>
<entry key="java.set.EqualsHashCodeRule.rule.msg">
<![CDATA[
关于hashCode和equals的处理,遵循如下规则:
1) 只要覆写equals,就必须覆写hashCode。
2) 因为Set存储的是不重复的对象,依据hashCode和equals进行判断,所以Set存储的对象必须覆写这两个方法。
3) 如果自定义对象作为Map的键,那么必须覆写hashCode和equals。
说明:String已覆写hashCode和equals方法,所以我们可以愉快地使用String对象作为key来使用。
]]>
</entry>
<!-- constant -->
<entry key="java.constant.UndefineMagicConstantRule.violation.msg">
<![CDATA[ 魔法值【%s】]]>
Expand Down Expand Up @@ -348,6 +357,9 @@
<![CDATA[说明:BigDecimal(double)存在精度损失风险,在精确计算或值比较的场景中可能会导致业务逻辑异常。]]>
</entry>

<entry key="java.oop.VarargsParameterRule.rule.msg">
<![CDATA[相同参数类型,相同业务含义,才可以使用Java的可变参数,避免使用Object。说明:可变参数必须放置在参数列表的最后。(提倡同学们尽量不用可变参数编程)]]>
</entry>
<!-- comment -->
<entry key="java.comment.CommentsMustBeJavadocFormatRule.rule.msg">
<![CDATA[类、类属性、类方法的注释必须使用javadoc规范,使用/**内容*/格式,不得使用//xxx方式和/*xxx*/方式。]]>
Expand Down
12 changes: 12 additions & 0 deletions p3c-pmd/src/main/resources/messages_en.xml
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,15 @@ Note: Below are the problems created by usage of Executors for thread pool creat
<entry key="java.set.UnsupportedExceptionWithModifyAsListRule.rule.msg">
<![CDATA[Do not use methods which will modify the list after using Arrays.asList to convert array to list, otherwise methods like add/remove/clear will throw UnsupportedOperationException. ]]>
</entry>
<entry key="java.set.EqualsHashCodeRule.rule.msg">
<![CDATA[
Regarding the processing of hashCode and equals, follow the rules below:
1) As long as you override 'equals', you must override 'hashCode'.
2) 'Set' stores unique objects, its uniqueness is judged by 'equals' and 'hashCode'. So the objects stored by 'Set' must override these two methods.
3) If the custom object is used as the map key, then 'hashCode' and 'equals' must be overridden.
Note: String has overridden the 'hashCode' and 'equals' methods, so we can happily use String objects as keys.
]]>
</entry>
<!-- constant -->
<entry key="java.constant.UndefineMagicConstantRule.violation.msg">
<![CDATA[Magic value [%s] ]]>
Expand Down Expand Up @@ -348,6 +357,9 @@ Note: Below are the problems created by usage of Executors for thread pool creat
<entry key="java.oop.BigDecimalAvoidDoubleConstructorRule.rule.msg.desc">
<![CDATA[Note:Use the constructor BigDecimal(String) or valueOf method of BigDecimal. Inside valueOf the toString of Double is executed, which truncate the mantissa according to the precision of double.]]>
</entry>
<entry key="java.oop.VarargsParameterRule.rule.msg">
<![CDATA[Only with the same parameter type and same business logic, you can use varargs and avoid using Object. Note: Varargs must be placed at the end of the parameter list. (Better to avoid programming with varargs)]]>
</entry>

<!-- comment -->
<entry key="java.comment.CommentsMustBeJavadocFormatRule.rule.msg">
Expand Down
16 changes: 16 additions & 0 deletions p3c-pmd/src/main/resources/rulesets/java/ali-oop.xml
Original file line number Diff line number Diff line change
Expand Up @@ -153,5 +153,21 @@ Positive example:
]]>
</example>
</rule>
<rule name="VarargsParameterRule" language="java"
message="java.oop.VarargsParameterRule.rule.msg"
class="com.alibaba.p3c.pmd.lang.java.rule.oop.VarargsParameterRule">
<priority>1</priority>
<example>
<![CDATA[
Positive example:
private void method(int a, int b, int... varargs) {

}
Negative example:
private void method(int a, int b, Object... varargs) {

}
]]>
</example>
</rule>
</ruleset>
39 changes: 39 additions & 0 deletions p3c-pmd/src/main/resources/rulesets/java/ali-set.xml
Original file line number Diff line number Diff line change
Expand Up @@ -129,5 +129,44 @@ Negative example:
]]>
</example>
</rule>
<rule name="EqualsHashCodeRule" language="java"
message="java.set.EqualsHashCodeRule.rule.msg"
class="com.alibaba.p3c.pmd.lang.java.rule.set.EqualsHashCodeRule">
<priority>1</priority>
<example>
<![CDATA[
Positive example:
public class Foo {

@Override
public boolean equals(Object o) {
// ...
}

@Override
public int hashCode() {
// ...
}
}

Negative example 1:
public class Foo {

@Override
public boolean equals(Object o) {
// ...
}
}

Negative example 2:
public class Foo {

@Override
public int hashCode() {
// ...
}
}
]]>
</example>
</rule>
</ruleset>
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,6 @@ public void setUp() {
addRule(RULESET, "PojoMustOverrideToStringRule");
addRule(RULESET, "StringConcatRule");
addRule(RULESET, "BigDecimalAvoidDoubleConstructorRule");
addRule(RULESET, "VarargsParameterRule");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,6 @@ public void setUp() {
addRule(RULESET, "ConcurrentExceptionWithModifyOriginSubListRule");
addRule(RULESET, "DontModifyInForeachCircleRule");
addRule(RULESET, "UnsupportedExceptionWithModifyAsListRule");
addRule(RULESET, "EqualsHashCodeRule");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<test-data xmlns="http://pmd.sourceforge.net/rule-tests"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests https://pmd.sourceforge.io/rule-tests_1_0_0.xsd">

<code-fragment id="varargs-with-object-type">
<![CDATA[
public class Foo {
public void bar(int a, int b, Object... varargs) { // BAD
return;
}
public void bar(int a, int b, int... varargs) {
return;
}
}
]]>
</code-fragment>
<test-code>
<description>varargs-with-object-type</description>
<expected-problems>1</expected-problems>
<expected-linenumbers>2</expected-linenumbers>
<code-ref id="varargs-with-object-type"/>
</test-code>


<!-- ====================================================================== -->
</test-data>
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<test-data xmlns="http://pmd.sourceforge.net/rule-tests"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests https://pmd.sourceforge.io/rule-tests_1_0_0.xsd">

<code-fragment id="sets-EqualsHashCodeRule-ok"><![CDATA[
public class Foo { // line 1
private Long id;

@Override
public boolean equals(Object o) { // line 5
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Foo foo = (Foo) o;
return Objects.equals(id, foo.id);
}

@Override
public int hashCode() { // line 17
return Objects.hash(id);
}
}
]]>
</code-fragment>

<test-code>
<description>sets-EqualsHashCodeRule-ok.</description>
<expected-problems>0</expected-problems>
<code-ref id="sets-EqualsHashCodeRule-ok"/>
</test-code>

<code-fragment id="sets-EqualsHashCodeRule-missHashCodeWarn"><![CDATA[
public class Foo { // line 1
private Long id;

@Override
public boolean equals(Object o) { // line 5
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Foo foo = (Foo) o;
return Objects.equals(id, foo.id);
}
}
]]>
</code-fragment>

<test-code>
<description>sets-EqualsHashCodeRule-missHashCodeWarn.</description>
<expected-problems>1</expected-problems>
<expected-linenumbers>5</expected-linenumbers>
<code-ref id="sets-EqualsHashCodeRule-missHashCodeWarn"/>
</test-code>

<code-fragment id="sets-EqualsHashCodeRule-missEqualsWarn"><![CDATA[
public class Foo { // line 1
private Long id;

@Override
public int hashCode() { // line 5
return Objects.hash(id);
}
}
]]>
</code-fragment>

<test-code>
<description>sets-EqualsHashCodeRule-missEqualsWarn.</description>
<expected-problems>1</expected-problems>
<expected-linenumbers>5</expected-linenumbers>
<code-ref id="sets-EqualsHashCodeRule-missEqualsWarn"/>
</test-code>
</test-data>