From e62f352ab9bfd482c2cda254c3606747d864bb34 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Mon, 28 Oct 2013 16:43:47 +0100 Subject: [PATCH] IDEA-115468 (for loop variables, catch block parameters and resource variables not reported by "local variable or parameter can be final" inspection) --- .../localCanBeFinal/LocalCanBeFinal.java | 33 +++++++++++++++++++ .../CatchParameter/expected.xml | 9 +++++ .../CatchParameter/src/CatchParameter.java | 12 +++++++ .../localCanBeFinal/For/expected.xml | 9 +++++ .../localCanBeFinal/For/src/For.java | 7 ++++ .../localCanBeFinal/SCR7428/expected.xml | 5 +++ .../localCanBeFinal/SCR7428_1/expected.xml | 5 +++ .../codeInspection/LocalCanBeFinalTest.java | 14 +++++++- 8 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/inspection/localCanBeFinal/CatchParameter/expected.xml create mode 100644 java/java-tests/testData/inspection/localCanBeFinal/CatchParameter/src/CatchParameter.java create mode 100644 java/java-tests/testData/inspection/localCanBeFinal/For/expected.xml create mode 100644 java/java-tests/testData/inspection/localCanBeFinal/For/src/For.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/localCanBeFinal/LocalCanBeFinal.java b/java/java-analysis-impl/src/com/intellij/codeInspection/localCanBeFinal/LocalCanBeFinal.java index b684f46942cb..0c20acf17225 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/localCanBeFinal/LocalCanBeFinal.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/localCanBeFinal/LocalCanBeFinal.java @@ -145,6 +145,23 @@ public class LocalCanBeFinal extends BaseJavaBatchLocalInspectionTool { } } + @Override + public void visitCatchSection(PsiCatchSection section) { + super.visitCatchSection(section); + final PsiParameter parameter = section.getParameter(); + if (PsiTreeUtil.getParentOfType(parameter, PsiClass.class) != PsiTreeUtil.getParentOfType(body, PsiClass.class)) { + return; + } + final PsiCodeBlock catchBlock = section.getCatchBlock(); + if (catchBlock == null) return; + final int from = flow.getStartOffset(catchBlock); + final int end = flow.getEndOffset(catchBlock); + if (!ControlFlowUtil.getWrittenVariables(flow, from, end, false).contains(parameter)) { + writtenVariables.remove(parameter); + result.add(parameter); + } + } + @Override public void visitForeachStatement(PsiForeachStatement statement) { super.visitForeachStatement(statement); final PsiParameter param = statement.getIterationParameter(); @@ -176,6 +193,22 @@ public class LocalCanBeFinal extends BaseJavaBatchLocalInspectionTool { if (declaredElement instanceof PsiVariable) result.add(declaredElement); } } + + @Override + public void visitForStatement(PsiForStatement statement) { + super.visitForStatement(statement); + final PsiStatement initialization = statement.getInitialization(); + if (!(initialization instanceof PsiDeclarationStatement)) { + return; + } + final PsiDeclarationStatement declarationStatement = (PsiDeclarationStatement)initialization; + final PsiElement[] declaredElements = declarationStatement.getDeclaredElements(); + for (final PsiElement declaredElement : declaredElements) { + if (declaredElement instanceof PsiVariable) { + result.add(declaredElement); + } + } + } }); } diff --git a/java/java-tests/testData/inspection/localCanBeFinal/CatchParameter/expected.xml b/java/java-tests/testData/inspection/localCanBeFinal/CatchParameter/expected.xml new file mode 100644 index 000000000000..be39de52a78d --- /dev/null +++ b/java/java-tests/testData/inspection/localCanBeFinal/CatchParameter/expected.xml @@ -0,0 +1,9 @@ + + + + CatchParameter.java + 8 + Local variable or parameter can be final + Parameter <code>e</code> can have <code>final</code> modifier + + \ No newline at end of file diff --git a/java/java-tests/testData/inspection/localCanBeFinal/CatchParameter/src/CatchParameter.java b/java/java-tests/testData/inspection/localCanBeFinal/CatchParameter/src/CatchParameter.java new file mode 100644 index 000000000000..06185510844b --- /dev/null +++ b/java/java-tests/testData/inspection/localCanBeFinal/CatchParameter/src/CatchParameter.java @@ -0,0 +1,12 @@ +import java.io.*; + +class CatchParameter { + + void m() { + try (InputStream in = new FileInputStream("filename")) { // don't warn about 'in' because it is implicitly final + } catch (FileNotFoundException | RuntimeException e) { // don't warn about 'e' because it is implicitly final + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/localCanBeFinal/For/expected.xml b/java/java-tests/testData/inspection/localCanBeFinal/For/expected.xml new file mode 100644 index 000000000000..d1173640dc69 --- /dev/null +++ b/java/java-tests/testData/inspection/localCanBeFinal/For/expected.xml @@ -0,0 +1,9 @@ + + + + For.java + 3 + Local variable or parameter can be final + Variable <code>it</code> can have <code>final</code> modifier + + \ No newline at end of file diff --git a/java/java-tests/testData/inspection/localCanBeFinal/For/src/For.java b/java/java-tests/testData/inspection/localCanBeFinal/For/src/For.java new file mode 100644 index 000000000000..529844bc5326 --- /dev/null +++ b/java/java-tests/testData/inspection/localCanBeFinal/For/src/For.java @@ -0,0 +1,7 @@ +class For { + void f(List list) { + for (Iterator it = list.iterator(); it.hasNext();) { // 'it' can be final but not reported + } + for (int i = 0; i < 10; i++) {} + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/localCanBeFinal/SCR7428/expected.xml b/java/java-tests/testData/inspection/localCanBeFinal/SCR7428/expected.xml index f1378331ebcc..ef7e69d33a19 100644 --- a/java/java-tests/testData/inspection/localCanBeFinal/SCR7428/expected.xml +++ b/java/java-tests/testData/inspection/localCanBeFinal/SCR7428/expected.xml @@ -15,6 +15,11 @@ 9 foo final + + Junk.java + 13 + e final + Junk.java 15 diff --git a/java/java-tests/testData/inspection/localCanBeFinal/SCR7428_1/expected.xml b/java/java-tests/testData/inspection/localCanBeFinal/SCR7428_1/expected.xml index f1378331ebcc..ef7e69d33a19 100644 --- a/java/java-tests/testData/inspection/localCanBeFinal/SCR7428_1/expected.xml +++ b/java/java-tests/testData/inspection/localCanBeFinal/SCR7428_1/expected.xml @@ -15,6 +15,11 @@ 9 foo final + + Junk.java + 13 + e final + Junk.java 15 diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/LocalCanBeFinalTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/LocalCanBeFinalTest.java index fad802c7adb5..e29b65c31bcc 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/LocalCanBeFinalTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/LocalCanBeFinalTest.java @@ -131,8 +131,20 @@ public class LocalCanBeFinalTest extends InspectionTestCase { } public void testNestedForeach() throws Exception { - myTool.REPORT_VARIABLES = true; myTool.REPORT_PARAMETERS = false; + myTool.REPORT_VARIABLES = true; + doTest(); + } + + public void testFor() throws Exception { + myTool.REPORT_PARAMETERS = false; + myTool.REPORT_VARIABLES = true; + doTest(); + } + + public void testCatchParameter() throws Exception { + myTool.REPORT_PARAMETERS = false; + myTool.REPORT_VARIABLES = true; doTest(); } }