From 0dc1191c25c8e9004b087df1bfff8b308eb1773f Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 10 Oct 2012 10:35:51 +0200 Subject: [PATCH] IDEA-92588 (check for AutoCloseable on interface extraction) --- .../TurnRefsToSuperProcessorBase.java | 35 ++++++++++++++----- .../turnRefsToSuper/forEach1/after/Test.java | 15 ++++++++ .../turnRefsToSuper/forEach1/before/Test.java | 15 ++++++++ .../turnRefsToSuper/forEach2/after/Test.java | 15 ++++++++ .../turnRefsToSuper/forEach2/before/Test.java | 15 ++++++++ .../tryWithResources1/after/Test.java | 16 +++++++++ .../tryWithResources1/before/Test.java | 16 +++++++++ .../tryWithResources2/after/Test.java | 16 +++++++++ .../tryWithResources2/before/Test.java | 16 +++++++++ .../refactoring/TurnRefsToSuperTest.java | 4 +++ 10 files changed, 155 insertions(+), 8 deletions(-) create mode 100644 java/java-tests/testData/refactoring/turnRefsToSuper/forEach1/after/Test.java create mode 100644 java/java-tests/testData/refactoring/turnRefsToSuper/forEach1/before/Test.java create mode 100644 java/java-tests/testData/refactoring/turnRefsToSuper/forEach2/after/Test.java create mode 100644 java/java-tests/testData/refactoring/turnRefsToSuper/forEach2/before/Test.java create mode 100644 java/java-tests/testData/refactoring/turnRefsToSuper/tryWithResources1/after/Test.java create mode 100644 java/java-tests/testData/refactoring/turnRefsToSuper/tryWithResources1/before/Test.java create mode 100644 java/java-tests/testData/refactoring/turnRefsToSuper/tryWithResources2/after/Test.java create mode 100644 java/java-tests/testData/refactoring/turnRefsToSuper/tryWithResources2/before/Test.java diff --git a/java/java-impl/src/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperProcessorBase.java b/java/java-impl/src/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperProcessorBase.java index e4ac331c92b5..45b0b1ad5d1e 100644 --- a/java/java-impl/src/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperProcessorBase.java +++ b/java/java-impl/src/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperProcessorBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2012 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. @@ -46,6 +46,7 @@ import com.intellij.util.containers.HashMap; import com.intellij.util.containers.HashSet; import com.intellij.util.containers.Queue; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.LinkedList; @@ -501,32 +502,50 @@ public abstract class TurnRefsToSuperProcessorBase extends BaseRefactoringProces } } else { - LOG.assertTrue(false); + LOG.error("Unexpected scope: " + declScope); } } + else if (variable instanceof PsiResourceVariable) { + final PsiJavaParserFacade facade = JavaPsiFacade.getInstance(myProject).getParserFacade(); + checkConstrainingType(type, facade.createTypeFromText(CommonClassNames.JAVA_LANG_AUTO_CLOSEABLE, variable)); + } } private void analyzeVarUsage(final PsiElement element) { PsiType constrainingType = null; + final PsiElement parent = element.getParent(); if (parent instanceof PsiReturnStatement) { final PsiMethod method = PsiTreeUtil.getParentOfType(parent, PsiMethod.class); assert method != null; constrainingType = method.getReturnType(); - } else if (parent instanceof PsiAssignmentExpression) { + } + else if (parent instanceof PsiAssignmentExpression) { constrainingType = ((PsiAssignmentExpression)parent).getLExpression().getType(); - } else if (parent instanceof PsiLocalVariable) { + } + //todo[ann] this works for AImpl->A but fails on List (see testForEach1() and testIDEADEV23807()). + //else if (parent instanceof PsiForeachStatement) { + // final PsiType exprType = ((PsiExpression)element).getType(); + // if (!(exprType instanceof PsiArrayType)) { + // final PsiJavaParserFacade facade = JavaPsiFacade.getInstance(myProject).getParserFacade(); + // constrainingType = facade.createTypeFromText(CommonClassNames.JAVA_LANG_ITERABLE, parent); + // } + //} + else if (parent instanceof PsiLocalVariable) { constrainingType = ((PsiLocalVariable)parent).getType(); } - //TODO: I expect more cases here + checkConstrainingType(element, constrainingType); + } + + private void checkConstrainingType(PsiElement element, @Nullable PsiType constrainingType) { if (constrainingType instanceof PsiClassType) { final PsiClass resolved = ((PsiClassType)constrainingType).resolve(); if (!myClass.equals(resolved)) { - if (resolved == null || !isSuperInheritor(resolved)) { - markNode(element); - } + if (resolved == null || !isSuperInheritor(resolved)) { + markNode(element); } + } } } diff --git a/java/java-tests/testData/refactoring/turnRefsToSuper/forEach1/after/Test.java b/java/java-tests/testData/refactoring/turnRefsToSuper/forEach1/after/Test.java new file mode 100644 index 000000000000..158c1ada80d0 --- /dev/null +++ b/java/java-tests/testData/refactoring/turnRefsToSuper/forEach1/after/Test.java @@ -0,0 +1,15 @@ +class Test { + void test() throws Exception { + MyIterableImpl r = new MyIterableImpl(); + for (String s : r) { + r.length(); + } + } + + interface MyIterable { + } + + static class MyIterableImpl implements MyIterable, Iterable { + public Iterator iterator() { return null; } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/turnRefsToSuper/forEach1/before/Test.java b/java/java-tests/testData/refactoring/turnRefsToSuper/forEach1/before/Test.java new file mode 100644 index 000000000000..158c1ada80d0 --- /dev/null +++ b/java/java-tests/testData/refactoring/turnRefsToSuper/forEach1/before/Test.java @@ -0,0 +1,15 @@ +class Test { + void test() throws Exception { + MyIterableImpl r = new MyIterableImpl(); + for (String s : r) { + r.length(); + } + } + + interface MyIterable { + } + + static class MyIterableImpl implements MyIterable, Iterable { + public Iterator iterator() { return null; } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/turnRefsToSuper/forEach2/after/Test.java b/java/java-tests/testData/refactoring/turnRefsToSuper/forEach2/after/Test.java new file mode 100644 index 000000000000..1900c4022ae8 --- /dev/null +++ b/java/java-tests/testData/refactoring/turnRefsToSuper/forEach2/after/Test.java @@ -0,0 +1,15 @@ +class Test { + void test() throws Exception { + MyIterable r = new MyIterableImpl(); + for (String s : r) { + r.length(); + } + } + + interface MyIterable extends Iterable { + } + + static class MyIterableImpl implements MyIterable { + public Iterator iterator() { return null; } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/turnRefsToSuper/forEach2/before/Test.java b/java/java-tests/testData/refactoring/turnRefsToSuper/forEach2/before/Test.java new file mode 100644 index 000000000000..38a5c495d826 --- /dev/null +++ b/java/java-tests/testData/refactoring/turnRefsToSuper/forEach2/before/Test.java @@ -0,0 +1,15 @@ +class Test { + void test() throws Exception { + MyIterableImpl r = new MyIterableImpl(); + for (String s : r) { + r.length(); + } + } + + interface MyIterable extends Iterable { + } + + static class MyIterableImpl implements MyIterable { + public Iterator iterator() { return null; } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/turnRefsToSuper/tryWithResources1/after/Test.java b/java/java-tests/testData/refactoring/turnRefsToSuper/tryWithResources1/after/Test.java new file mode 100644 index 000000000000..2f00ea2d0a2b --- /dev/null +++ b/java/java-tests/testData/refactoring/turnRefsToSuper/tryWithResources1/after/Test.java @@ -0,0 +1,16 @@ +class Test { + void test() throws Exception { + try (MyResourceImpl r = new MyResourceImpl()) { + r.getName(); + } + } + + interface MyResource { + String getName(); + } + + static class MyResourceImpl implements MyResource, AutoCloseable { + public String getName() { return ""; } + public void close() throws Exception { } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/turnRefsToSuper/tryWithResources1/before/Test.java b/java/java-tests/testData/refactoring/turnRefsToSuper/tryWithResources1/before/Test.java new file mode 100644 index 000000000000..2f00ea2d0a2b --- /dev/null +++ b/java/java-tests/testData/refactoring/turnRefsToSuper/tryWithResources1/before/Test.java @@ -0,0 +1,16 @@ +class Test { + void test() throws Exception { + try (MyResourceImpl r = new MyResourceImpl()) { + r.getName(); + } + } + + interface MyResource { + String getName(); + } + + static class MyResourceImpl implements MyResource, AutoCloseable { + public String getName() { return ""; } + public void close() throws Exception { } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/turnRefsToSuper/tryWithResources2/after/Test.java b/java/java-tests/testData/refactoring/turnRefsToSuper/tryWithResources2/after/Test.java new file mode 100644 index 000000000000..082361297199 --- /dev/null +++ b/java/java-tests/testData/refactoring/turnRefsToSuper/tryWithResources2/after/Test.java @@ -0,0 +1,16 @@ +class Test { + void test() throws Exception { + try (MyResource r = new MyResourceImpl()) { + r.getName(); + } + } + + interface MyResource extends AutoCloseable { + String getName(); + } + + static class MyResourceImpl implements MyResource { + public String getName() { return ""; } + public void close() throws Exception { } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/turnRefsToSuper/tryWithResources2/before/Test.java b/java/java-tests/testData/refactoring/turnRefsToSuper/tryWithResources2/before/Test.java new file mode 100644 index 000000000000..0beff38cadcd --- /dev/null +++ b/java/java-tests/testData/refactoring/turnRefsToSuper/tryWithResources2/before/Test.java @@ -0,0 +1,16 @@ +class Test { + void test() throws Exception { + try (MyResourceImpl r = new MyResourceImpl()) { + r.getName(); + } + } + + interface MyResource extends AutoCloseable { + String getName(); + } + + static class MyResourceImpl implements MyResource { + public String getName() { return ""; } + public void close() throws Exception { } + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/TurnRefsToSuperTest.java b/java/java-tests/testSrc/com/intellij/refactoring/TurnRefsToSuperTest.java index 490c7c3f3634..44defbea3ef3 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/TurnRefsToSuperTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/TurnRefsToSuperTest.java @@ -53,12 +53,16 @@ public class TurnRefsToSuperTest extends MultiFileTestCase { public void testTypeArgumentsRH1() throws Exception { doTest("IImpl", "I", false); } public void testAnonymousWithTypeArguments() throws Exception { doTest("Clazz", "IntF", false); } public void testTypeArgumentsParam() throws Exception { doTest("Clazz", "IntF", false); } + public void testTryWithResources1() throws Exception { doTest("Test.MyResourceImpl", "Test.MyResource", false); } + public void testTryWithResources2() throws Exception { doTest("Test.MyResourceImpl", "Test.MyResource", false); } //todo[ann] fix and uncomment //public void testStaticCallArguments() throws Exception { doTest("Impl", "Int", false); } //public void testListArgs() throws Exception { doTest("Impl", "Int", false); } //public void testCovariantReturnTypes() throws Exception { doTest("Impl", "Int", false); } //public void testNewExpr() throws Exception { doTest("Impl", "Int", false); } + //public void testForEach1() throws Exception { doTest("Test.MyIterableImpl", "Test.MyIterable", false); } + //public void testForEach2() throws Exception { doTest("Test.MyIterableImpl", "Test.MyIterable", false); } private void doTest(@NonNls final String className, @NonNls final String superClassName, final boolean replaceInstanceOf) throws Exception { doTest(new PerformAction() {