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 3dca018ab61a..e41b55b61655 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java @@ -276,13 +276,15 @@ public class GenerateMembersUtil { substituteReturnType(PsiManager.getInstance(project), resultMethod, sourceMethod.getReturnType(), collisionResolvedSubstitutor); substituteParameters(factory, codeStyleManager, sourceMethod.getParameterList(), resultMethod.getParameterList(), collisionResolvedSubstitutor, target); copyDocComment(sourceMethod, resultMethod, factory); - final List thrownTypes = ExceptionUtil.collectSubstituted(collisionResolvedSubstitutor, sourceMethod.getThrowsList().getReferencedTypes()); + GlobalSearchScope scope = sourceMethod.getResolveScope(); + final List thrownTypes = ExceptionUtil.collectSubstituted(collisionResolvedSubstitutor, sourceMethod.getThrowsList().getReferencedTypes(), + scope); 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())); + ExceptionUtil.retainExceptions(thrownTypes, ExceptionUtil.collectSubstituted(TypeConversionUtil.getSuperClassSubstitutor(aSuper, (PsiClass)target, PsiSubstitutor.EMPTY), psiMethod.getThrowsList().getReferencedTypes(), scope)); } } } 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 cb6b93dd226d..e268bbdcd526 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java @@ -22,12 +22,14 @@ import com.intellij.openapi.util.RecursionGuard; import com.intellij.openapi.util.RecursionManager; import com.intellij.psi.*; import com.intellij.psi.controlFlow.*; +import com.intellij.psi.impl.PsiClassImplUtil; import com.intellij.psi.impl.PsiImplUtil; import com.intellij.psi.infos.CandidateInfo; import com.intellij.psi.infos.MethodCandidateInfo; import com.intellij.psi.scope.MethodProcessorSetupFailedException; import com.intellij.psi.scope.processor.MethodResolverProcessor; import com.intellij.psi.scope.util.PsiScopesUtil; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.*; import com.intellij.util.ArrayUtil; import com.intellij.util.Function; @@ -187,7 +189,7 @@ public class ExceptionUtil { PsiMethod method = (PsiMethod)resolveResult.getElement(); if (method != null) { - addExceptions(result, getExceptionsByMethod(method, resolveResult.getSubstitutor())); + addExceptions(result, getExceptionsByMethod(method, resolveResult.getSubstitutor(), element)); } addExceptions(result, getThrownExceptions(element.getChildren())); @@ -196,12 +198,16 @@ public class ExceptionUtil { } @NotNull - private static List getExceptionsByMethod(@NotNull PsiMethod method, @NotNull PsiSubstitutor substitutor) { - List result = ContainerUtil.newArrayList(); - + private static List getExceptionsByMethod(@NotNull PsiMethod method, @NotNull PsiSubstitutor substitutor, + @NotNull PsiElement place) { PsiClassType[] referenceTypes = method.getThrowsList().getReferencedTypes(); + if (referenceTypes.length == 0) return Collections.emptyList(); + + GlobalSearchScope scope = place.getResolveScope(); + + List result = ContainerUtil.newArrayList(); for (PsiType type : referenceTypes) { - type = substitutor.substitute(type); + type = PsiClassImplUtil.correctType(substitutor.substitute(type), scope); if (type instanceof PsiClassType) { result.add((PsiClassType)type); } @@ -449,13 +455,14 @@ public class ExceptionUtil { } }); if (candidates.size() > 1) { - final List ex = collectSubstituted(substitutor, thrownExceptions); + GlobalSearchScope scope = methodCall.getResolveScope(); + final List ex = collectSubstituted(substitutor, thrownExceptions, scope); for (Pair pair : candidates) { final PsiClassType[] exceptions = pair.first.getThrowsList().getReferencedTypes(); if (exceptions.length == 0) { return getUnhandledExceptions(methodCall, topElement, PsiSubstitutor.EMPTY, PsiClassType.EMPTY_ARRAY); } - retainExceptions(ex, collectSubstituted(pair.second, exceptions)); + retainExceptions(ex, collectSubstituted(pair.second, exceptions, scope)); } return getUnhandledExceptions(methodCall, topElement, PsiSubstitutor.EMPTY, ex.toArray(new PsiClassType[ex.size()])); } @@ -512,10 +519,10 @@ public class ExceptionUtil { ex.addAll(replacement); } - public static List collectSubstituted(PsiSubstitutor substitutor, PsiClassType[] thrownExceptions) { + public static List collectSubstituted(PsiSubstitutor substitutor, PsiClassType[] thrownExceptions, GlobalSearchScope scope) { final List ex = new ArrayList(); for (PsiClassType thrownException : thrownExceptions) { - final PsiType psiType = substitutor.substitute(thrownException); + final PsiType psiType = PsiClassImplUtil.correctType(substitutor.substitute(thrownException), scope); if (psiType instanceof PsiClassType) { ex.add((PsiClassType)psiType); } @@ -527,7 +534,7 @@ public class ExceptionUtil { public static List getCloserExceptions(@NotNull PsiResourceVariable resource) { PsiMethod method = PsiUtil.getResourceCloserMethod(resource); PsiSubstitutor substitutor = PsiUtil.resolveGenericsClassInType(resource.getType()).getSubstitutor(); - return method != null ? getExceptionsByMethod(method, substitutor) : Collections.emptyList(); + return method != null ? getExceptionsByMethod(method, substitutor, resource) : Collections.emptyList(); } @NotNull @@ -593,7 +600,7 @@ public class ExceptionUtil { List result = ContainerUtil.newArrayList(); for (PsiClassType referencedType : referencedTypes) { - final PsiType type = GenericsUtil.eliminateWildcards(substitutor.substitute(referencedType), false); + final PsiType type = PsiClassImplUtil.correctType(GenericsUtil.eliminateWildcards(substitutor.substitute(referencedType), false), element.getResolveScope()); if (!(type instanceof PsiClassType)) continue; PsiClassType classType = (PsiClassType)type; PsiClass exceptionClass = ((PsiClassType)type).resolve(); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/MultipleModuleHighlightingTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/MultipleModuleHighlightingTest.groovy index 379068e37eeb..a5b84c0c1559 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/MultipleModuleHighlightingTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/MultipleModuleHighlightingTest.groovy @@ -14,11 +14,16 @@ * limitations under the License. */ package com.intellij.codeInsight - import com.intellij.openapi.module.JavaModuleType +import com.intellij.openapi.roots.ModuleRootManager import com.intellij.openapi.roots.ModuleRootModificationUtil +import com.intellij.openapi.roots.ModuleSourceOrderEntry +import com.intellij.openapi.roots.OrderEntry import com.intellij.testFramework.PsiTestUtil import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase +import com.intellij.util.Consumer +import com.intellij.util.containers.ContainerUtil + /** * @author peter */ @@ -95,4 +100,51 @@ class Class3 { ModuleRootModificationUtil.addDependency(myModule, mod1) ModuleRootModificationUtil.addDependency(myModule, mod2) } + + public void testOverridingJdkExceptions() { + def dep = PsiTestUtil.addModule(project, JavaModuleType.moduleType, "dep", myFixture.tempDirFixture.findOrCreateDir("dep")) + ModuleRootModificationUtil.setModuleSdk(dep, ModuleRootManager.getInstance(myModule).sdk) + ModuleRootModificationUtil.updateModel(myModule, { model -> + model.addModuleOrderEntry(dep) + + List entries = model.orderEntries as List + def srcEntry = ContainerUtil.findInstance(entries, ModuleSourceOrderEntry) + assert srcEntry + + model.rearrangeOrderEntries(([srcEntry] + (entries - srcEntry)) as OrderEntry[]) + } as Consumer) + + myFixture.addFileToProject "java/lang/IllegalArgumentException.java", ''' +package java.lang; + +public class IllegalArgumentException extends Exception { } +''' + + myFixture.addFileToProject 'dep/foo/Foo.java', ''' +package foo; + +public class Foo { + public static void libraryMethod() throws IllegalArgumentException {} +} +''' + + myFixture.configureFromExistingVirtualFile(myFixture.addFileToProject('Bar.java', ''' +class Bar { + +void caught() { + try { + foo.Foo.libraryMethod(); + } catch (IllegalArgumentException e) {} +} + +void uncaught() { + foo.Foo.libraryMethod(); +} + +} + +''').virtualFile) + myFixture.checkHighlighting() + } + }