Java: Don't collapse 'catch' sections containing no code but with different comments (IDEA-154035)

This commit is contained in:
Pavel Dolgov
2018-07-20 14:09:19 +03:00
parent 0309cdccf4
commit da6e2bcd3b
8 changed files with 163 additions and 1 deletions
@@ -17,11 +17,12 @@ package com.siyeh.ig.migration;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.JavaFeature;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.tree.IElementType;
import com.intellij.refactoring.extractMethod.InputVariables;
import com.intellij.refactoring.util.duplicates.DuplicatesFinder;
import com.intellij.refactoring.util.duplicates.Match;
@@ -233,6 +234,9 @@ public class TryWithIdenticalCatchesInspection extends BaseInspection {
}
boolean isDuplicate(@NotNull CatchSectionWrapper section) {
final Boolean sameComments = areSameComments(section);
if (sameComments != null) return sameComments;
final Match match = findDuplicate(section);
if (match == null) {
return false;
@@ -253,6 +257,42 @@ public class TryWithIdenticalCatchesInspection extends BaseInspection {
return myFinder.isDuplicate(section.myCodeBlock, true);
}
@Nullable
private Boolean areSameComments(@NotNull CatchSectionWrapper section) {
if (!myCodeBlock.isEmpty()) {
return null;
}
if (!section.myCodeBlock.isEmpty()) {
return false;
}
final List<String> comments = getCommentTexts(myCodeBlock);
final List<String> otherComments = getCommentTexts(section.myCodeBlock);
return comments.equals(otherComments);
}
@NotNull
private static List<String> getCommentTexts(@NotNull PsiElement element) {
final List<String> result = new ArrayList<>();
for (PsiElement child = element.getFirstChild(); child != null; child = child.getNextSibling()) {
if (child instanceof PsiComment) {
final IElementType type = ((PsiComment)child).getTokenType();
if (type == JavaTokenType.END_OF_LINE_COMMENT) {
final String text = StringUtil.trimStart(child.getText(), "//").trim();
if (!text.isEmpty()) {
result.add(text);
}
}
else if (type == JavaTokenType.C_STYLE_COMMENT) {
final String text = StringUtil.trimStart(StringUtil.trimEnd(child.getText(), "*/"), "/*").trim();
if (!text.isEmpty()) {
result.add(text);
}
}
}
}
return result;
}
boolean canSwapWith(@Nullable CatchSectionWrapper section) {
if (section == null) return false;
for (PsiClassType type : myTypes) {
@@ -0,0 +1,17 @@
class C {
void foo() {
try {
bar();
} catch (Ex1 e) {
// unique comment
} catch (Ex2 | Ex3 e) { /*same comment*/
// duplicate comment
}
}
void bar() throws Ex1, Ex2, Ex3 {}
static class Ex1 extends Exception {}
static class Ex2 extends Exception {}
static class Ex3 extends Exception {}
}
@@ -0,0 +1,19 @@
class C {
void foo() {
try {
bar();
} catch (Ex1 e) {
// unique comment
} catch (Ex2 e) { /*same comment*/
// duplicate comment
} <warning descr="'catch' branch identical to 'Ex2' branch">catch (Ex3 <caret>e)</warning> { // same comment
/*duplicate comment*/
}
}
void bar() throws Ex1, Ex2, Ex3 {}
static class Ex1 extends Exception {}
static class Ex2 extends Exception {}
static class Ex3 extends Exception {}
}
@@ -0,0 +1,18 @@
class C {
void foo() {
try {
bar();
} catch (Ex1 e) {
// unique comment
/*some more*/
} catch (Ex2 | Ex3 e) { /*same comment*/
// duplicate comment
}
}
void bar() throws Ex1, Ex2, Ex3 {}
static class Ex1 extends Exception {}
static class Ex2 extends Exception {}
static class Ex3 extends Exception {}
}
@@ -0,0 +1,20 @@
class C {
void foo() {
try {
bar();
} catch (Ex1 e) {
// unique comment
/*some more*/
} catch (Ex2 e) { /*same comment*/
// duplicate comment
} <warning descr="'catch' branch identical to 'Ex2' branch">catch (Ex3 <caret>e)</warning> { /* same comment */
//duplicate comment
}
}
void bar() throws Ex1, Ex2, Ex3 {}
static class Ex1 extends Exception {}
static class Ex2 extends Exception {}
static class Ex3 extends Exception {}
}
@@ -0,0 +1,16 @@
class C {
void foo() {
try {
bar();
} catch (Ex1 e) {
// unique comment
} catch (Ex2 | Ex3 e) {
}
}
void bar() throws Ex1, Ex2, Ex3 {}
static class Ex1 extends Exception {}
static class Ex2 extends Exception {}
static class Ex3 extends Exception {}
}
@@ -0,0 +1,20 @@
class C {
void foo() {
try {
bar();
} catch (Ex1 e) {
// unique comment
} catch (Ex2 e) {
} <warning descr="'catch' branch identical to 'Ex2' branch">catch (Ex3 <caret>e)</warning> {
//
/*
*/
}
}
void bar() throws Ex1, Ex2, Ex3 {}
static class Ex1 extends Exception {}
static class Ex2 extends Exception {}
static class Ex3 extends Exception {}
}
@@ -49,6 +49,18 @@ public class TryWithIdenticalCatchesTest extends LightCodeInsightFixtureTestCase
doTest(true);
}
public void testIdenticalCatchWithComments() {
doTest();
}
public void testIdenticalCatchWithEmptyComments() {
doTest();
}
public void testIdenticalCatchDifferentCommentStyle() {
doTest();
}
public void doTest() {
doTest(false);
}