From 59af6284bdf470d6648f3438001c04e2abd04a01 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 25 Jun 2013 17:16:22 +0400 Subject: [PATCH] override from multiple interfaces with throws lists: intersect throws lists --- .../generation/GenerateMembersUtil.java | 26 ++++++++++++------- .../intellij/codeInsight/ExceptionUtil.java | 4 +-- .../afterMultipleInheritedThrows.java | 17 ++++++++++++ .../beforeMultipleInheritedThrows.java | 16 ++++++++++++ .../codeInsight/OverrideImplementTest.java | 1 + 5 files changed, 53 insertions(+), 11 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/overrideImplement/afterMultipleInheritedThrows.java create mode 100644 java/java-tests/testData/codeInsight/overrideImplement/beforeMultipleInheritedThrows.java diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java index 5a8eea42ae5f..6710f70ec7ae 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java @@ -15,6 +15,7 @@ */ package com.intellij.codeInsight.generation; +import com.intellij.codeInsight.ExceptionUtil; import com.intellij.codeInsight.daemon.impl.quickfix.CreateFromUsageUtils; import com.intellij.lang.ASTNode; import com.intellij.openapi.diagnostic.Logger; @@ -42,10 +43,7 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map; +import java.util.*; public class GenerateMembersUtil { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.generation.GenerateMembersUtil"); @@ -266,7 +264,17 @@ public class GenerateMembersUtil { substituteTypeParameters(factory, target, sourceMethod.getTypeParameterList(), resultMethod.getTypeParameterList(), substitutor, sourceMethod); substituteReturnType(PsiManager.getInstance(project), resultMethod, sourceMethod.getReturnType(), collisionResolvedSubstitutor); substituteParameters(factory, codeStyleManager, sourceMethod.getParameterList(), resultMethod.getParameterList(), collisionResolvedSubstitutor, target); - substituteThrows(factory, sourceMethod.getThrowsList(), resultMethod.getThrowsList(), collisionResolvedSubstitutor, sourceMethod); + final List thrownTypes = ExceptionUtil.collectSubstituted(collisionResolvedSubstitutor, sourceMethod.getThrowsList().getReferencedTypes()); + if (target instanceof PsiClass) { + final PsiClass[] supers = ((PsiClass)target).getSupers(); + for (PsiClass aSuper : supers) { + final PsiMethod psiMethod = aSuper.findMethodBySignature(sourceMethod, true); + if (psiMethod != null && psiMethod != sourceMethod) { + ExceptionUtil.retainExceptions(thrownTypes, ExceptionUtil.collectSubstituted(TypeConversionUtil.getSuperClassSubstitutor(aSuper, (PsiClass)target, PsiSubstitutor.EMPTY), psiMethod.getThrowsList().getReferencedTypes())); + } + } + } + substituteThrows(factory, resultMethod.getThrowsList(), collisionResolvedSubstitutor, sourceMethod, thrownTypes); return resultMethod; } catch (IncorrectOperationException e) { @@ -400,11 +408,11 @@ public class GenerateMembersUtil { } private static void substituteThrows(@NotNull JVMElementFactory factory, - @NotNull PsiReferenceList sourceThrowsList, @NotNull PsiReferenceList targetThrowsList, - @NotNull PsiSubstitutor substitutor, - @NotNull PsiMethod sourceMethod) { - for (PsiClassType thrownType : sourceThrowsList.getReferencedTypes()) { + @NotNull PsiSubstitutor substitutor, + @NotNull PsiMethod sourceMethod, + List thrownTypes) { + for (PsiClassType thrownType : thrownTypes) { targetThrowsList.add(factory.createReferenceElementByType((PsiClassType)substituteType(substitutor, thrownType, sourceMethod))); } } diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java b/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java index d96551cd3510..4b245a060297 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java @@ -439,7 +439,7 @@ public class ExceptionUtil { return getUnhandledExceptions(method, methodCall, topElement, substitutor); } - private static void retainExceptions(List ex, List thrownEx) { + public static void retainExceptions(List ex, List thrownEx) { final List replacement = new ArrayList(); for (Iterator iterator = ex.iterator(); iterator.hasNext(); ) { PsiClassType classType = iterator.next(); @@ -462,7 +462,7 @@ public class ExceptionUtil { ex.addAll(replacement); } - private static List collectSubstituted(PsiSubstitutor substitutor, PsiClassType[] thrownExceptions) { + public static List collectSubstituted(PsiSubstitutor substitutor, PsiClassType[] thrownExceptions) { final List ex = new ArrayList(); for (PsiClassType thrownException : thrownExceptions) { final PsiType psiType = substitutor.substitute(thrownException); diff --git a/java/java-tests/testData/codeInsight/overrideImplement/afterMultipleInheritedThrows.java b/java/java-tests/testData/codeInsight/overrideImplement/afterMultipleInheritedThrows.java new file mode 100644 index 000000000000..688387cd1826 --- /dev/null +++ b/java/java-tests/testData/codeInsight/overrideImplement/afterMultipleInheritedThrows.java @@ -0,0 +1,17 @@ +import java.io.*; +interface A { + void close() throws Exception; +} + +interface B { + void close() throws IOException; +} + +interface C { + void close() throws T; +} + +interface AB extends A, C, B { + @Override + void close() throws IOException; +} diff --git a/java/java-tests/testData/codeInsight/overrideImplement/beforeMultipleInheritedThrows.java b/java/java-tests/testData/codeInsight/overrideImplement/beforeMultipleInheritedThrows.java new file mode 100644 index 000000000000..8b66b898f9ac --- /dev/null +++ b/java/java-tests/testData/codeInsight/overrideImplement/beforeMultipleInheritedThrows.java @@ -0,0 +1,16 @@ +import java.io.*; +interface A { + void close() throws Exception; +} + +interface B { + void close() throws IOException; +} + +interface C { + void close() throws T; +} + +interface AB extends A, C, B { + +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/OverrideImplementTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/OverrideImplementTest.java index 458b3e7a21c1..a41edc32caee 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/OverrideImplementTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/OverrideImplementTest.java @@ -73,6 +73,7 @@ public class OverrideImplementTest extends LightCodeInsightTestCase { public void testOverrideInInterface() { doTest8(false, false); } + public void testMultipleInheritedThrows() {doTest8(false, false);} public void testLongFinalParameterList() { CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(getProject()).clone();