mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-58106 ("Infinite recursion" inspection breaks with tautological if's)
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2007 Dave Griffith, Bas Leijdekkers
|
||||
* Copyright 2003-2010 Dave Griffith, Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,22 +25,26 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class InfiniteRecursionInspection extends BaseInspection {
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getDisplayName() {
|
||||
return InspectionGadgetsBundle.message(
|
||||
"infinite.recursion.display.name");
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String buildErrorString(Object... infos) {
|
||||
return InspectionGadgetsBundle.message(
|
||||
"infinite.recursion.problem.descriptor");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabledByDefault(){
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseInspectionVisitor buildVisitor() {
|
||||
return new InfiniteRecursionVisitor();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2006 Dave Griffith, Bas Leijdekkers
|
||||
* Copyright 2003-2010 Dave Griffith, Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -353,13 +353,10 @@ public class RecursionUtils{
|
||||
|
||||
private static boolean referenceExpressionDefinitelyRecurses(
|
||||
PsiReferenceExpression expression, PsiMethod method){
|
||||
|
||||
final PsiExpression qualifierExpression =
|
||||
expression.getQualifierExpression();
|
||||
if(qualifierExpression != null){
|
||||
return expressionDefinitelyRecurses(qualifierExpression, method);
|
||||
}
|
||||
return false;
|
||||
return qualifierExpression != null &&
|
||||
expressionDefinitelyRecurses(qualifierExpression, method);
|
||||
}
|
||||
|
||||
private static boolean typeCastExpressionDefinitelyRecurses(
|
||||
@@ -573,9 +570,17 @@ public class RecursionUtils{
|
||||
}
|
||||
final PsiStatement thenBranch = ifStatement.getThenBranch();
|
||||
final PsiStatement elseBranch = ifStatement.getElseBranch();
|
||||
if(thenBranch == null || elseBranch == null){
|
||||
if(thenBranch == null){
|
||||
return false;
|
||||
}
|
||||
final Object value =
|
||||
ExpressionUtils.computeConstantExpression(condition);
|
||||
if (value == Boolean.TRUE) {
|
||||
return statementDefinitelyRecurses(thenBranch, method);
|
||||
} else if (value == Boolean.FALSE) {
|
||||
return elseBranch != null &&
|
||||
statementDefinitelyRecurses(elseBranch, method);
|
||||
}
|
||||
return statementDefinitelyRecurses(thenBranch, method) &&
|
||||
statementDefinitelyRecurses(elseBranch, method);
|
||||
}
|
||||
@@ -590,7 +595,9 @@ public class RecursionUtils{
|
||||
if(expressionDefinitelyRecurses(condition, method)){
|
||||
return true;
|
||||
}
|
||||
if(BoolUtils.isTrue(condition)){
|
||||
final Object value =
|
||||
ExpressionUtils.computeConstantExpression(condition);
|
||||
if(value == Boolean.TRUE) {
|
||||
final PsiStatement body = forStatement.getBody();
|
||||
return statementDefinitelyRecurses(body, method);
|
||||
}
|
||||
@@ -610,7 +617,9 @@ public class RecursionUtils{
|
||||
if(expressionDefinitelyRecurses(condition, method)){
|
||||
return true;
|
||||
}
|
||||
if(BoolUtils.isTrue(condition)){
|
||||
final Object value =
|
||||
ExpressionUtils.computeConstantExpression(condition);
|
||||
if(value == Boolean.TRUE){
|
||||
final PsiStatement body = whileStatement.getBody();
|
||||
return statementDefinitelyRecurses(body, method);
|
||||
}
|
||||
@@ -637,9 +646,7 @@ public class RecursionUtils{
|
||||
public static boolean methodDefinitelyRecurses(
|
||||
@NotNull PsiMethod method){
|
||||
final PsiCodeBlock body = method.getBody();
|
||||
if(body == null){
|
||||
return false;
|
||||
}
|
||||
return !codeBlockMayReturnBeforeRecursing(body, method, true);
|
||||
return body != null &&
|
||||
!codeBlockMayReturnBeforeRecursing(body, method, true);
|
||||
}
|
||||
}
|
||||
|
||||
+21
-3
@@ -1,4 +1,4 @@
|
||||
package com.siyeh.igtest.bugs;
|
||||
package com.siyeh.igtest.bugs.infinite_recursion;
|
||||
|
||||
import com.intellij.psi.PsiClass;
|
||||
|
||||
@@ -6,11 +6,11 @@ import java.util.List;
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
|
||||
public class InfiniteRecursionInspection
|
||||
public class InfiniteRecursion
|
||||
{
|
||||
public void foo()
|
||||
{
|
||||
new InfiniteRecursionInspection().foo();
|
||||
new InfiniteRecursion().foo();
|
||||
}
|
||||
|
||||
public void bar()
|
||||
@@ -122,4 +122,22 @@ public class InfiniteRecursionInspection
|
||||
rec(pc);
|
||||
}
|
||||
}
|
||||
|
||||
void foo1() {
|
||||
for (;true && true || false;) {
|
||||
foo1();
|
||||
}
|
||||
}
|
||||
|
||||
void foo2() {
|
||||
if (true || false) {
|
||||
foo2();
|
||||
}
|
||||
}
|
||||
|
||||
void bar1() {
|
||||
while (true || false) {
|
||||
bar1();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems>
|
||||
<problem>
|
||||
<file>InfiniteRecursion.java</file>
|
||||
<line>21</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Infinite recursion</problem_class>
|
||||
<description>Method <code>baz()</code> recurses infinitely, and can only end by throwing an exception #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>InfiniteRecursion.java</file>
|
||||
<line>52</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Infinite recursion</problem_class>
|
||||
<description>Method <code>barangoo()</code> recurses infinitely, and can only end by throwing an exception #loc
|
||||
</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>InfiniteRecursion.java</file>
|
||||
<line>61</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Infinite recursion</problem_class>
|
||||
<description>Method <code>bazoomer()</code> recurses infinitely, and can only end by throwing an exception #loc
|
||||
</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>InfiniteRecursion.java</file>
|
||||
<line>78</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Infinite recursion</problem_class>
|
||||
<description>Method <code>foobarangus()</code> recurses infinitely, and can only end by throwing an exception #loc
|
||||
</description>
|
||||
</problem>
|
||||
|
||||
|
||||
<problem>
|
||||
<file>InfiniteRecursion.java</file>
|
||||
<line>126</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Infinite recursion</problem_class>
|
||||
<description>Method <code>foo1()</code> recurses infinitely, and can only end by throwing an exception #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>InfiniteRecursion.java</file>
|
||||
<line>132</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Infinite recursion</problem_class>
|
||||
<description>Method <code>foo2()</code> recurses infinitely, and can only end by throwing an exception #loc</description>
|
||||
</problem>
|
||||
|
||||
|
||||
|
||||
|
||||
<problem>
|
||||
<file>InfiniteRecursion.java</file>
|
||||
<line>138</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Infinite recursion</problem_class>
|
||||
<description>Method <code>bar1()</code> recurses infinitely, and can only end by throwing an exception #loc</description>
|
||||
</problem>
|
||||
|
||||
|
||||
</problems>
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package com.siyeh.ig.bugs;
|
||||
|
||||
import com.IGInspectionTestCase;
|
||||
|
||||
public class InfiniteRecursionInspectionTest extends IGInspectionTestCase {
|
||||
|
||||
public void test() throws Exception {
|
||||
doTest("com/siyeh/igtest/bugs/infinite_recursion",
|
||||
new InfiniteRecursionInspection());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user