From 49e9988a405c9766f65858daa299a8de19cb76a3 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Tue, 17 May 2011 18:34:18 +0400 Subject: [PATCH] [ann] Exceptions with interfaces in multi-catch: assignability and control flow fix --- .../psi/controlFlow/ControlFlowAnalyzer.java | 9 ++-- .../advHighlighting7/MultiCatch.java | 50 ++++++++++++++++--- .../com/intellij/psi/PsiDisjunctionType.java | 11 ++-- .../intellij/psi/util/TypeConversionUtil.java | 7 ++- 4 files changed, 56 insertions(+), 21 deletions(-) diff --git a/java/java-impl/src/com/intellij/psi/controlFlow/ControlFlowAnalyzer.java b/java/java-impl/src/com/intellij/psi/controlFlow/ControlFlowAnalyzer.java index 553515046fdf..502a9e49d761 100644 --- a/java/java-impl/src/com/intellij/psi/controlFlow/ControlFlowAnalyzer.java +++ b/java/java-impl/src/com/intellij/psi/controlFlow/ControlFlowAnalyzer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2011 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. @@ -26,7 +26,6 @@ import com.intellij.psi.jsp.JavaJspElementVisitor; import com.intellij.psi.jsp.JspFile; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.util.PsiUtil; import com.intellij.util.containers.Stack; import gnu.trove.THashMap; import gnu.trove.TIntArrayList; @@ -947,10 +946,8 @@ class ControlFlowAnalyzer extends JavaJspElementVisitor { for (int i = myCatchParameters.size() - 1; i >= 0; i--) { ProgressManager.checkCanceled(); PsiParameter parameter = myCatchParameters.get(i); - final PsiType type = parameter.getType(); - PsiClass caughtClass = PsiUtil.resolveClassInType(type); - if (caughtClass == null) continue; - if (type.isAssignableFrom(throwType) || throwType.isAssignableFrom(type)) { + PsiType catchType = parameter.getType(); + if (catchType.isAssignableFrom(throwType) || throwType.isAssignableFrom(catchType)) { blocks.add(myCatchBlocks.get(i)); } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/MultiCatch.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/MultiCatch.java index e3d1f29ec55f..d856731bead5 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/MultiCatch.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/MultiCatch.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2011 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ abstract class C { private static class NE { } private static class E extends Exception { public String s; } @@ -6,9 +21,9 @@ abstract class C { private static class E3 extends E { } private static class E4 extends E { } private static class RE extends RuntimeException { } - private interface I { } - private static class IE1 extends E implements I { } - private static class IE2 extends E implements I { } + private interface I { void i(); } + private static class IE1 extends E implements I { public void i() { } } + private static class IE2 extends E implements I { public void i() { } } private static class F { F(X x) { } } abstract void f() throws E1, E2; @@ -18,8 +33,7 @@ abstract class C { try { f(); } catch (E1 | E2 e) { } try { f(); } catch (E2 | E1 e) { e.printStackTrace(); System.out.println(e.s); } try { f(); } catch (E2 | E1 e) { } catch (E e) { } catch (RE e) { } - try { f(); } catch (E1 | E2 e) { E ee = e; } - try { g(); } catch (IE1 | IE2 e) { E ee = e; I ii = e; } + try { g(); } catch (IE1 | IE2 e) { E ee = e; I ii = e; e.i(); } try { g(); } catch (IE1 | IE2 e) { F f = new F<>(e); } try { g(); } catch (IE1 | IE2 e) { new F>(e); } @@ -33,12 +47,32 @@ abstract class C { try { f(); } catch (E | E ignore) { } try { f(); } catch (E1 | E2 | E3 e) { } - try { f(); } catch (E3 | E4 | RE e) { } + try { f(); } catch (E3 | E4 | RE e) { } catch (E e) { } + try { f(); } catch (E3 | E4 | RE e) { } try { f(); } catch (E e) { } catch (E1 | E3 e) { } try { f(); } catch (E1 | E2 e) { } catch (E2 e) { } - try { f(); } catch (E1 | E2 e) { } catch (E e) { E1 ee = e; } - try { f(); } catch (E | RE e) { e = null; } + try { f(); } catch (E1 | E2 e) { E2 ee = e; } + try { f(); } catch (E1 | E2 e) { e = new E1(); } + try { f(); } catch (E1 | E2 e) { e = new E(); } + } +} + +class D { + static class E extends Exception { } + static interface I { void i(); } + static class E1 extends E implements I { public void i() { } } + static class E2 extends E implements I { public void i() { } } + + void m(boolean f) { + try { + if (f) + throw new E1(); + else + throw new E2(); + } catch (E1|E2 e) { + System.out.println(e); + } } } \ No newline at end of file diff --git a/java/openapi/src/com/intellij/psi/PsiDisjunctionType.java b/java/openapi/src/com/intellij/psi/PsiDisjunctionType.java index 13aba61f6651..d41683ac7ecf 100644 --- a/java/openapi/src/com/intellij/psi/PsiDisjunctionType.java +++ b/java/openapi/src/com/intellij/psi/PsiDisjunctionType.java @@ -116,10 +116,11 @@ public class PsiDisjunctionType extends PsiType { @Override public PsiType[] getSuperTypes() { final PsiType lub = getLeastUpperBound(); - final PsiType[] superTypes = lub.getSuperTypes(); - final PsiType[] result = new PsiType[superTypes.length + 1]; - result[0] = lub; - System.arraycopy(superTypes, 0, result, 1, superTypes.length); - return result; + if (lub instanceof PsiIntersectionType) { + return ((PsiIntersectionType)lub).getConjuncts(); + } + else { + return new PsiType[]{lub}; + } } } diff --git a/java/openapi/src/com/intellij/psi/util/TypeConversionUtil.java b/java/openapi/src/com/intellij/psi/util/TypeConversionUtil.java index 47cb4c99a4f7..62b5f319e51e 100644 --- a/java/openapi/src/com/intellij/psi/util/TypeConversionUtil.java +++ b/java/openapi/src/com/intellij/psi/util/TypeConversionUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2011 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. @@ -672,7 +672,10 @@ public class TypeConversionUtil { } if (left instanceof PsiDisjunctionType) { - return isAssignable(((PsiDisjunctionType)left).getLeastUpperBound(), right, allowUncheckedConversion); + for (PsiType type : ((PsiDisjunctionType)left).getDisjunctions()) { + if (isAssignable(type, right, allowUncheckedConversion)) return true; + } + return false; } if (right instanceof PsiDisjunctionType) { return isAssignable(left, ((PsiDisjunctionType)right).getLeastUpperBound(), allowUncheckedConversion);