Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
eyckwu
p3c
提交
670c4f4a
P
p3c
项目概览
eyckwu
/
p3c
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
p3c
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
670c4f4a
编写于
12月 05, 2019
作者:
曾
曾候
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix
https://github.com/alibaba/p3c/issues/209
上级
20889aba
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
185 addition
and
150 deletion
+185
-150
p3c-pmd/src/main/java/com/alibaba/p3c/pmd/lang/java/rule/oop/WrapperTypeEqualityRule.java
...a/p3c/pmd/lang/java/rule/oop/WrapperTypeEqualityRule.java
+13
-2
p3c-pmd/src/test/resources/com/alibaba/p3c/pmd/lang/java/rule/oop/xml/WrapperTypeEqualityRule.xml
...3c/pmd/lang/java/rule/oop/xml/WrapperTypeEqualityRule.xml
+172
-148
未找到文件。
p3c-pmd/src/main/java/com/alibaba/p3c/pmd/lang/java/rule/oop/WrapperTypeEqualityRule.java
浏览文件 @
670c4f4a
...
...
@@ -45,8 +45,14 @@ public class WrapperTypeEqualityRule extends AbstractAliRule {
// possible elements around "==" are PrimaryExpression or UnaryExpression(e.g. a == -2)
List
<
ASTPrimaryExpression
>
expressions
=
node
.
findChildrenOfType
(
ASTPrimaryExpression
.
class
);
if
(
expressions
.
size
()
==
NumberConstants
.
INTEGER_SIZE_OR_LENGTH_2
)
{
if
(
NodeUtils
.
isWrapperType
(
expressions
.
get
(
0
))
&&
NodeUtils
.
isWrapperType
(
expressions
.
get
(
1
)))
{
// PMD can not resolve array length type, but only the
ASTPrimaryExpression
left
=
expressions
.
get
(
0
);
ASTPrimaryExpression
right
=
expressions
.
get
(
1
);
boolean
bothArrayLength
=
isArrayLength
(
left
)
&&
isArrayLength
(
right
);
boolean
bothWrapperType
=
NodeUtils
.
isWrapperType
(
left
)
&&
NodeUtils
.
isWrapperType
(
right
);
if
(!
bothArrayLength
&&
bothWrapperType
)
{
addViolationWithMessage
(
data
,
node
,
"java.oop.WrapperTypeEqualityRule.violation.msg"
);
}
}
...
...
@@ -54,4 +60,9 @@ public class WrapperTypeEqualityRule extends AbstractAliRule {
return
super
.
visit
(
node
,
data
);
}
private
boolean
isArrayLength
(
ASTPrimaryExpression
expression
)
{
// assume expression like "x.length" is the length of array, field with name "length" may result in misrecognition
return
"length"
.
equals
(
expression
.
jjtGetLastToken
().
getImage
())
&&
"."
.
equals
(
expression
.
jjtGetFirstToken
().
getNext
().
getImage
());
}
}
p3c-pmd/src/test/resources/com/alibaba/p3c/pmd/lang/java/rule/oop/xml/WrapperTypeEqualityRule.xml
浏览文件 @
670c4f4a
...
...
@@ -3,151 +3,175 @@
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=
"wrap-type-not-use-equal"
>
<![CDATA[
public class Foo {
private static final int x = 3;
public void bar() {
Integer a = 2;
int b = 2;
Integer c = 3;
if (a == b) { // OK
// do nothing
}
if (a == c) { // BAD
// do nothing
}
if (a != null) { // OK
// do nothing
}
if (a == -6) { // OK
// do nothing
}
if (a == x) { // OK
// do nothing
}
if (a == Integer.MAX_VALUE) { // BAD
// do nothing
}
// PMD can not resolve type of Inner.FLAG
if (a == Inner.FLAG) {
// do nothing
}
// After upgrade pmd version, can resolve
if (a == Integer.valueOf("2")) { //BAD
// do nothing
}
if (a == new Integer("2")) { // BAD
// do nothing
}
}
private static class Inner {
public static final Integer FLAG = 3;
}
}
]]>
</code-fragment>
<test-code>
<description>
compare wrapper type objects without equals
</description>
<expected-problems>
4
</expected-problems>
<expected-linenumbers>
11,23,31,34
</expected-linenumbers>
<code-ref
id=
"wrap-type-not-use-equal"
/>
</test-code>
<!-- ====================================================================== -->
<code-fragment
id=
"wrong-result-fix"
>
<![CDATA[
package com.alibaba.p3c.pmd.lang.java.rule.concurrent;
import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTName;
import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression;
import net.sourceforge.pmd.lang.java.ast.Token;
import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Executors;
public class ThreadPoolCreationRule extends AbstractJavaRule {
private static final String DOT = ".";
private static final String COLON = ";";
private static final String NEW = "new";
private static final String EXECUTORS_NEW = Executors.class.getSimpleName() + DOT + NEW;
private static final String FULL_EXECUTORS_NEW = Executors.class.getName() + DOT + NEW;
private static final String BRACKETS = "()";
private boolean executorsUsed;
private Set<String>
importedExecutorsMethods = new HashSet
<
>();
@Override
public Object visit(ASTPrimaryExpression node, Object data) {
if (!executorsUsed
&&
importedExecutorsMethods.isEmpty()) {
return super.visit(node, data);
}
Token initToken = (Token) node.jjtGetFirstToken();
if (!checkInitStatement(initToken)) {
addViolation(data, node);
}
return super.visit(node, data);
}
private boolean checkInitStatement(Token token) {
String fullAssignStatement = getFullAssignStatement(token);
if (fullAssignStatement.startsWith(EXECUTORS_NEW)) {
return false;
}
if (!fullAssignStatement.startsWith(NEW)
&&
!fullAssignStatement.startsWith(FULL_EXECUTORS_NEW)) {
return true;
}
// in case of lambda
int index = fullAssignStatement.indexOf(BRACKETS);
if (index == -1) {
return true;
}
fullAssignStatement = fullAssignStatement.substring(0, index);
// avoid java.util.concurrent.Executors.newxxxx
if (importedExecutorsMethods.contains(fullAssignStatement)) {
return false;
}
// static import
return !importedExecutorsMethods.contains(Executors.class.getName() + DOT + fullAssignStatement);
}
private String getFullAssignStatement(final Token token) {
if (token == null) {
return "";
}
StringBuilder sb = new StringBuilder(48);
Token next = token;
while (next.next != null
&&
!COLON.equals(next.image)) {
sb.append(next.image);
next = next.next;
}
return sb.toString();
}
@Override
public Object visit(ASTImportDeclaration node, Object data) {
ASTName name = node.getFirstChildOfType(ASTName.class);
// in case of static import
executorsUsed = executorsUsed || name.getType() == Executors.class;
if (name.getImage().startsWith(Executors.class.getName() + DOT)) {
importedExecutorsMethods.add(name.getImage());
}
return super.visit(node, data);
}
}
]]>
</code-fragment>
<test-code>
<description>
bugfix
</description>
<expected-problems>
0
</expected-problems>
<code-ref
id=
"wrong-result-fix"
/>
</test-code>
</test-data>
<code-fragment
id=
"wrap-type-not-use-equal"
>
<![CDATA[
public class Foo {
private static final int x = 3;
public void bar() {
Integer a = 2;
int b = 2;
Integer c = 3;
if (a == b) { // OK
// do nothing
}
if (a == c) { // BAD
// do nothing
}
if (a != null) { // OK
// do nothing
}
if (a == -6) { // OK
// do nothing
}
if (a == x) { // OK
// do nothing
}
if (a == Integer.MAX_VALUE) { // BAD
// do nothing
}
// PMD can not resolve type of Inner.FLAG
if (a == Inner.FLAG) {
// do nothing
}
// After upgrade pmd version, can resolve
if (a == Integer.valueOf("2")) { //BAD
// do nothing
}
if (a == new Integer("2")) { // BAD
// do nothing
}
}
private static class Inner {
public static final Integer FLAG = 3;
}
}
]]>
</code-fragment>
<test-code>
<description>
compare wrapper type objects without equals
</description>
<expected-problems>
4
</expected-problems>
<expected-linenumbers>
11,23,31,34
</expected-linenumbers>
<code-ref
id=
"wrap-type-not-use-equal"
/>
</test-code>
<!-- ====================================================================== -->
<code-fragment
id=
"wrong-result-fix"
>
<![CDATA[
package com.alibaba.p3c.pmd.lang.java.rule.concurrent;
import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration;
import net.sourceforge.pmd.lang.java.ast.ASTName;
import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression;
import net.sourceforge.pmd.lang.java.ast.Token;
import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Executors;
public class ThreadPoolCreationRule extends AbstractJavaRule {
private static final String DOT = ".";
private static final String COLON = ";";
private static final String NEW = "new";
private static final String EXECUTORS_NEW = Executors.class.getSimpleName() + DOT + NEW;
private static final String FULL_EXECUTORS_NEW = Executors.class.getName() + DOT + NEW;
private static final String BRACKETS = "()";
private boolean executorsUsed;
private Set<String>
importedExecutorsMethods = new HashSet
<
>();
@Override
public Object visit(ASTPrimaryExpression node, Object data) {
if (!executorsUsed
&&
importedExecutorsMethods.isEmpty()) {
return super.visit(node, data);
}
Token initToken = (Token) node.jjtGetFirstToken();
if (!checkInitStatement(initToken)) {
addViolation(data, node);
}
return super.visit(node, data);
}
private boolean checkInitStatement(Token token) {
String fullAssignStatement = getFullAssignStatement(token);
if (fullAssignStatement.startsWith(EXECUTORS_NEW)) {
return false;
}
if (!fullAssignStatement.startsWith(NEW)
&&
!fullAssignStatement.startsWith(FULL_EXECUTORS_NEW)) {
return true;
}
// in case of lambda
int index = fullAssignStatement.indexOf(BRACKETS);
if (index == -1) {
return true;
}
fullAssignStatement = fullAssignStatement.substring(0, index);
// avoid java.util.concurrent.Executors.newxxxx
if (importedExecutorsMethods.contains(fullAssignStatement)) {
return false;
}
// static import
return !importedExecutorsMethods.contains(Executors.class.getName() + DOT + fullAssignStatement);
}
private String getFullAssignStatement(final Token token) {
if (token == null) {
return "";
}
StringBuilder sb = new StringBuilder(48);
Token next = token;
while (next.next != null
&&
!COLON.equals(next.image)) {
sb.append(next.image);
next = next.next;
}
return sb.toString();
}
@Override
public Object visit(ASTImportDeclaration node, Object data) {
ASTName name = node.getFirstChildOfType(ASTName.class);
// in case of static import
executorsUsed = executorsUsed || name.getType() == Executors.class;
if (name.getImage().startsWith(Executors.class.getName() + DOT)) {
importedExecutorsMethods.add(name.getImage());
}
return super.visit(node, data);
}
}
]]>
</code-fragment>
<test-code>
<description>
bugfix
</description>
<expected-problems>
0
</expected-problems>
<code-ref
id=
"wrong-result-fix"
/>
</test-code>
<!-- ====================================================================== -->
<code-fragment
id=
"array-length-equals"
>
<![CDATA[
public class Test {
public void foo(){
Integer[] a;
Integer[] b;
if (a.length == b.length) {
return;
};
}
}
]]>
</code-fragment>
<test-code>
<description>
array length equals
</description>
<expected-problems>
0
</expected-problems>
<code-ref
id=
"array-length-equals"
/>
</test-code>
<!-- ====================================================================== -->
</test-data>
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录