From be230d90bf09c09c20c753f37173fd4f3cdc713e Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Fri, 20 Jan 2017 11:52:14 +0300 Subject: [PATCH] guava type migration: fix stack overflow when lambda implements guava & java function EA-92353 --- .../rules/guava/GuavaLambda.java | 3 +++ .../inspections/GuavaInspectionTest.java | 4 ++++ .../guava/lambdaImplementsBothInterfaces.java | 23 ++++++++++++++++++ .../lambdaImplementsBothInterfaces_after.java | 24 +++++++++++++++++++ 4 files changed, 54 insertions(+) create mode 100644 java/typeMigration/testData/inspections/guava/lambdaImplementsBothInterfaces.java create mode 100644 java/typeMigration/testData/inspections/guava/lambdaImplementsBothInterfaces_after.java diff --git a/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaLambda.java b/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaLambda.java index 2bac1de41f23..0cd29927bd37 100644 --- a/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaLambda.java +++ b/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaLambda.java @@ -69,6 +69,9 @@ public enum GuavaLambda { if (aClass == null) return null; for (GuavaLambda lambda : values()) { if (InheritanceUtil.isInheritor(aClass, lambda.getClassQName())) { + if (PREDICATE != lambda && InheritanceUtil.isInheritor(aClass, lambda.getJavaAnalogueClassQName())) { + return null; + } return lambda; } } diff --git a/java/typeMigration/test/com/intellij/codeInsight/inspections/GuavaInspectionTest.java b/java/typeMigration/test/com/intellij/codeInsight/inspections/GuavaInspectionTest.java index e50479f9da49..2519e6aba5f2 100644 --- a/java/typeMigration/test/com/intellij/codeInsight/inspections/GuavaInspectionTest.java +++ b/java/typeMigration/test/com/intellij/codeInsight/inspections/GuavaInspectionTest.java @@ -293,6 +293,10 @@ public class GuavaInspectionTest extends JavaCodeInsightFixtureTestCase { doTest(); } + public void testLambdaImplementsBothInterfaces() { + doTest(); + } + private void doTestNoQuickFixes(Class... highlightedElements) { myFixture.configureByFile(getTestName(true) + ".java"); diff --git a/java/typeMigration/testData/inspections/guava/lambdaImplementsBothInterfaces.java b/java/typeMigration/testData/inspections/guava/lambdaImplementsBothInterfaces.java new file mode 100644 index 000000000000..157a47d506b6 --- /dev/null +++ b/java/typeMigration/testData/inspections/guava/lambdaImplementsBothInterfaces.java @@ -0,0 +1,23 @@ +import com.google.common.collect.FluentIterable; + +import java.util.Set; + +class Test { + public interface HasCode { + String getCode(); + } + + public enum GetCode implements com.google.common.base.Function, java.util.function.Function { + FUNC; + + @Override + public String apply(HasCode e) { + return e.getCode(); + } + + } + + public Set getRegionCodeList(Set regions) { + return FluentIterable.from(regions).transform(GetCode.FUNC::apply).toSet(); + } +} \ No newline at end of file diff --git a/java/typeMigration/testData/inspections/guava/lambdaImplementsBothInterfaces_after.java b/java/typeMigration/testData/inspections/guava/lambdaImplementsBothInterfaces_after.java new file mode 100644 index 000000000000..a9a3863fa622 --- /dev/null +++ b/java/typeMigration/testData/inspections/guava/lambdaImplementsBothInterfaces_after.java @@ -0,0 +1,24 @@ +import com.google.common.base.Function; + +import java.util.Set; +import java.util.stream.Collectors; + +class Test { + public interface HasCode { + String getCode(); + } + + public enum GetCode implements Function, java.util.function.Function { + FUNC; + + @Override + public String apply(HasCode e) { + return e.getCode(); + } + + } + + public Set getRegionCodeList(Set regions) { + return regions.stream().map(GetCode.FUNC).collect(Collectors.toSet()); + } +} \ No newline at end of file