mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-21 12:14:37 +07:00
IDEA-23612 Handle overriding builtin exceptions.
This commit is contained in:
@@ -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<PsiClassType> thrownTypes = ExceptionUtil.collectSubstituted(collisionResolvedSubstitutor, sourceMethod.getThrowsList().getReferencedTypes());
|
||||
GlobalSearchScope scope = sourceMethod.getResolveScope();
|
||||
final List<PsiClassType> 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<PsiClassType> getExceptionsByMethod(@NotNull PsiMethod method, @NotNull PsiSubstitutor substitutor) {
|
||||
List<PsiClassType> result = ContainerUtil.newArrayList();
|
||||
|
||||
private static List<PsiClassType> 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<PsiClassType> 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<PsiClassType> ex = collectSubstituted(substitutor, thrownExceptions);
|
||||
GlobalSearchScope scope = methodCall.getResolveScope();
|
||||
final List<PsiClassType> ex = collectSubstituted(substitutor, thrownExceptions, scope);
|
||||
for (Pair<PsiMethod, PsiSubstitutor> 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<PsiClassType> collectSubstituted(PsiSubstitutor substitutor, PsiClassType[] thrownExceptions) {
|
||||
public static List<PsiClassType> collectSubstituted(PsiSubstitutor substitutor, PsiClassType[] thrownExceptions, GlobalSearchScope scope) {
|
||||
final List<PsiClassType> ex = new ArrayList<PsiClassType>();
|
||||
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<PsiClassType> getCloserExceptions(@NotNull PsiResourceVariable resource) {
|
||||
PsiMethod method = PsiUtil.getResourceCloserMethod(resource);
|
||||
PsiSubstitutor substitutor = PsiUtil.resolveGenericsClassInType(resource.getType()).getSubstitutor();
|
||||
return method != null ? getExceptionsByMethod(method, substitutor) : Collections.<PsiClassType>emptyList();
|
||||
return method != null ? getExceptionsByMethod(method, substitutor, resource) : Collections.<PsiClassType>emptyList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -593,7 +600,7 @@ public class ExceptionUtil {
|
||||
List<PsiClassType> 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();
|
||||
|
||||
+53
-1
@@ -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<OrderEntry> 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() {
|
||||
<error descr="Unhandled exception: java.lang.IllegalArgumentException">foo.Foo.libraryMethod();</error>
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
''').virtualFile)
|
||||
myFixture.checkHighlighting()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user