diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/StackFrameDescriptorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/StackFrameDescriptorImpl.java index ba3fbd4cb78d..70717822e8c0 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/StackFrameDescriptorImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/StackFrameDescriptorImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -68,7 +68,15 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac try { myUiIndex = frame.getFrameIndex(); myLocation = frame.location(); - myThisObject = frame.thisObject(); + try { + myThisObject = frame.thisObject(); + } catch (EvaluateException e) { + // catch internal exceptions here + if (!(e.getCause() instanceof InternalException)) { + throw e; + } + LOG.info(e); + } myMethodOccurrence = tracker.getMethodOccurrence(myUiIndex, myLocation.method()); myIsSynthetic = DebuggerUtils.isSynthetic(myMethodOccurrence.getMethod()); ApplicationManager.getApplication().runReadAction(new Runnable() { diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java index 68b97f73fdd5..83ec3affc36b 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java @@ -347,8 +347,13 @@ public class HighlightMethodUtil { TextRange fixRange = getFixRange(methodCall); highlightInfo = HighlightUtil.checkUnhandledExceptions(methodCall, fixRange); if (highlightInfo == null) { - if (!LambdaUtil.isValidQualifier4InterfaceStaticMethodCall((PsiMethod)resolved, methodCall.getMethodExpression(), resolveResult.getCurrentFileResolveScope(), languageLevel)) { - highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).descriptionAndTooltip("Static method may be invoked on containing interface class only").range(fixRange).create(); + final String invalidCallMessage = + LambdaUtil.getInvalidQualifier4StaticInterfaceMethodMessage((PsiMethod)resolved, methodCall.getMethodExpression(), resolveResult.getCurrentFileResolveScope(), languageLevel); + if (invalidCallMessage != null) { + highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).descriptionAndTooltip(invalidCallMessage).range(fixRange).create(); + if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) { + QuickFixAction.registerQuickFixAction(highlightInfo, new IncreaseLanguageLevelFix(LanguageLevel.JDK_1_8)); + } } else { highlightInfo = GenericsHighlightUtil.checkInferredIntersections(substitutor, fixRange); } diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/ExtractIfConditionAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/ExtractIfConditionAction.java index a0f09b3c269d..46c97f62621d 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/ExtractIfConditionAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/ExtractIfConditionAction.java @@ -186,7 +186,7 @@ public class ExtractIfConditionAction extends PsiElementBaseIntentionAction { private static String createIfString(@NotNull PsiExpression condition, @NotNull PsiStatement thenBranch, @Nullable PsiStatement elseBranch) { - return createIfString(condition.getText(), toThenBranchString(thenBranch), toElseBranchString(elseBranch)); + return createIfString(condition.getText(), toThenBranchString(thenBranch), toElseBranchString(elseBranch, false)); } @NotNull @@ -200,7 +200,7 @@ public class ExtractIfConditionAction extends PsiElementBaseIntentionAction { private static String createIfString(@NotNull PsiExpression condition, @NotNull String thenBranch, @Nullable PsiStatement elseBranch) { - return createIfString(condition.getText(), thenBranch, toElseBranchString(elseBranch)); + return createIfString(condition.getText(), thenBranch, toElseBranchString(elseBranch, true)); } @NotNull @@ -221,12 +221,12 @@ public class ExtractIfConditionAction extends PsiElementBaseIntentionAction { } @Nullable - private static String toElseBranchString(@Nullable PsiStatement statement) { + private static String toElseBranchString(@Nullable PsiStatement statement, boolean skipElse) { if (statement == null) { return null; } - if (statement instanceof PsiBlockStatement || statement instanceof PsiIfStatement) { + if (statement instanceof PsiBlockStatement || skipElse && statement instanceof PsiIfStatement) { return statement.getText(); } diff --git a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java index 31fb45a139de..8f072b7853e9 100644 --- a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java @@ -457,15 +457,28 @@ public class LambdaUtil { public static boolean isValidQualifier4InterfaceStaticMethodCall(@NotNull PsiMethod method, @NotNull PsiReferenceExpression methodReferenceExpression, @Nullable PsiElement scope, @NotNull LanguageLevel languageLevel) { - if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) { - final PsiExpression qualifierExpression = methodReferenceExpression.getQualifierExpression(); - final PsiClass containingClass = method.getContainingClass(); - if (containingClass != null && containingClass.isInterface() && method.hasModifierProperty(PsiModifier.STATIC)) { - return qualifierExpression == null && (scope instanceof PsiImportStaticStatement || PsiTreeUtil.isAncestor(containingClass, methodReferenceExpression, true))|| - qualifierExpression instanceof PsiReferenceExpression && ((PsiReferenceExpression)qualifierExpression).resolve() == containingClass; + return getInvalidQualifier4StaticInterfaceMethodMessage(method, methodReferenceExpression, scope, languageLevel) == null; + } + + @Nullable + public static String getInvalidQualifier4StaticInterfaceMethodMessage(@NotNull PsiMethod method, + @NotNull PsiReferenceExpression methodReferenceExpression, + @Nullable PsiElement scope, @NotNull LanguageLevel languageLevel) { + final PsiExpression qualifierExpression = methodReferenceExpression.getQualifierExpression(); + final PsiClass containingClass = method.getContainingClass(); + if (containingClass != null && containingClass.isInterface() && method.hasModifierProperty(PsiModifier.STATIC)) { + if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) { + return "Static interface method invocations are not supported at this language level"; } + + if (qualifierExpression == null && + (scope instanceof PsiImportStaticStatement || PsiTreeUtil.isAncestor(containingClass, methodReferenceExpression, true)) || + qualifierExpression instanceof PsiReferenceExpression && ((PsiReferenceExpression)qualifierExpression).resolve() == containingClass) { + return null; + } + return "Static method may be invoked on containing interface class only"; } - return true; + return null; } //JLS 14.8 Expression Statements diff --git a/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java b/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java index 712fd868ab94..422f65adae0d 100644 --- a/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java @@ -726,9 +726,15 @@ public class ControlFlowUtil { if (nextOffset > flow.getSize()) nextOffset = flow.getSize(); if (offset > endOffset) return; int throwToOffset = instruction.offset; - boolean isNormal; + boolean isNormal = false; if (throwToOffset == nextOffset) { - isNormal = nextOffset == endOffset || throwToOffset <= endOffset && !isLeaf(nextOffset) && canCompleteNormally[nextOffset]; + + if (nextOffset == endOffset) { + final Instruction lastInstruction = flow.getInstructions().get(endOffset - 1); + isNormal = !(lastInstruction instanceof GoToInstruction && ((GoToInstruction)lastInstruction).isReturn); + } + + isNormal |= throwToOffset <= endOffset && !isLeaf(nextOffset) && canCompleteNormally[nextOffset]; } else { isNormal = canCompleteNormally[nextOffset]; diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/SymbolCollectingProcessor.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/SymbolCollectingProcessor.java index fbf16015414d..b5933ed64e68 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/SymbolCollectingProcessor.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/SymbolCollectingProcessor.java @@ -53,7 +53,7 @@ public class SymbolCollectingProcessor extends BaseScopeProcessor implements Ele @Override public boolean execute(@NotNull PsiElement element, @NotNull ResolveState state) { - if (element instanceof PsiNamedElement) { + if (element instanceof PsiNamedElement && element.isValid()) { PsiNamedElement named = (PsiNamedElement)element; String name = named.getName(); if (name != null) { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/CheckedExceptionCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/CheckedExceptionCompatibilityConstraint.java index 4520f8d6d2ed..23460fbda4fc 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/CheckedExceptionCompatibilityConstraint.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/CheckedExceptionCompatibilityConstraint.java @@ -107,7 +107,7 @@ public class CheckedExceptionCompatibilityConstraint extends InputOutputConstrai final List exceptions = ExceptionUtil.ourThrowsGuard.doPreventingRecursion(myExpression, false, new Computable>() { @Override public List compute() { - return ExceptionUtil.getUnhandledExceptions(body); + return ExceptionUtil.getUnhandledExceptions(new PsiElement[] {body}); } }); if (exceptions != null) { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/AccessToStaticMethodsFromInterfaces.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/AccessToStaticMethodsFromInterfaces.java new file mode 100644 index 000000000000..b2b0bb1feb9e --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/AccessToStaticMethodsFromInterfaces.java @@ -0,0 +1,14 @@ +class Test { + interface I { + static void foo() {} + } + + abstract class IImpl implements I {} + interface I2 extends I {} + + { + I.foo(); + IImpl.foo(); + I2.foo(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/exceptions/ExceptionsThrownByCallArguments.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/exceptions/ExceptionsThrownByCallArguments.java new file mode 100644 index 000000000000..18cbec819bcf --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/exceptions/ExceptionsThrownByCallArguments.java @@ -0,0 +1,49 @@ +import java.io.File; + +class Test { + public interface A { + Object call() throws E; + } + + public interface B { + void call() throws E; + } + + static T method(A lambda) { + try { + lambda.call(); + } catch (Throwable e) { + e.printStackTrace(); + } + return null; + } + + static void method(B lambda) { + try { + lambda.call(); + } catch (Throwable e) { + e.printStackTrace(); + } + } + + static String returns(String s) throws Exception { + System.out.println(s); return null; + } + + static void voids(String s) throws Exception { + System.out.println(s); + } + + static { + + method(() -> { + voids("B"); + }); + method(() -> voids("B")); + + method(() -> { + return new File(returns("A")); + }); + method(() -> new File(returns("A"))); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/VoidValueCompatibilityCantCompleteNormallyWithCallWithExceptionAsLastReturnStatement.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/VoidValueCompatibilityCantCompleteNormallyWithCallWithExceptionAsLastReturnStatement.java new file mode 100644 index 000000000000..fdec0c7cce47 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/VoidValueCompatibilityCantCompleteNormallyWithCallWithExceptionAsLastReturnStatement.java @@ -0,0 +1,58 @@ +class Test { + public interface A { + Object call() throws E; + } + + public interface B { + void call() throws E; + } + + static Object method(A lambda) { + System.out.println("A::"); + try { + lambda.call(); + } catch (Throwable throwable) { + throwable.printStackTrace(); + } + return null; + } + + static void method(B lambda) { + System.out.println("B::"); + try { + lambda.call(); + } catch (Throwable throwable) { + throwable.printStackTrace(); + } + } + + static Object returns(String s) throws Exception { + System.out.println(s); return null; + } + + static void voids(String s) throws Exception { + System.out.println(s); + } + + public static void main(String[] args) { + + method(() -> { + voids("-> B"); + }); + + + method(() -> voids("-> B")); + + method(() -> { + return returns("-> A"); + }); + + method(() -> returns("-> A") ); + + method(() -> { + returns("-> B"); + }); + } + + +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extractIfCondition/afterMissedBrackets.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extractIfCondition/afterMissedBrackets.java new file mode 100644 index 000000000000..4ffce63057e7 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extractIfCondition/afterMissedBrackets.java @@ -0,0 +1,16 @@ +// "Extract if (a)" "true" +class TestThreadInspection { + void f(boolean a, boolean b, boolean c){ + if (a) + if (b) { + System.out.println("a&b"); + } else { + if (c) { + System.out.println("c"); + } + } + else if (c) { + System.out.println("c"); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extractIfCondition/afterNoElse.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extractIfCondition/afterNoElse.java new file mode 100644 index 000000000000..04d5e5a81acd --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extractIfCondition/afterNoElse.java @@ -0,0 +1,9 @@ +// "Extract if (a)" "true" +class TestThreadInspection { + void f(boolean a, boolean b, boolean c){ + if (a) + if (b) { + System.out.println("a&b"); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extractIfCondition/afterOrMissedBrackets.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extractIfCondition/afterOrMissedBrackets.java new file mode 100644 index 000000000000..0a4ac53ddf5b --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extractIfCondition/afterOrMissedBrackets.java @@ -0,0 +1,14 @@ +// "Extract if (a)" "true" +class TestThreadInspection { + void f(boolean a, boolean b, boolean c){ + if (a) { + System.out.println("a&b"); + } else if (b) { + System.out.println("a&b"); + } else { + if (c) { + System.out.println("c"); + } + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extractIfCondition/afterOrSimpleElse.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extractIfCondition/afterOrSimpleElse.java new file mode 100644 index 000000000000..811bffcb2e5b --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extractIfCondition/afterOrSimpleElse.java @@ -0,0 +1,12 @@ +// "Extract if (a)" "true" +class TestThreadInspection { + void f(boolean a, boolean b, boolean c){ + if (a) { + System.out.println("a&b"); + } else if (b) { + System.out.println("a&b"); + } else { + System.out.println("c"); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extractIfCondition/afterSimpleElse.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extractIfCondition/afterSimpleElse.java new file mode 100644 index 000000000000..db4a3fe20eb8 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extractIfCondition/afterSimpleElse.java @@ -0,0 +1,14 @@ +// "Extract if (a)" "true" +class TestThreadInspection { + void f(boolean a, boolean b, boolean c){ + if (a) + if (b) { + System.out.println("a&b"); + } else { + System.out.println("c"); + } + else { + System.out.println("c"); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extractIfCondition/beforeMissedBrackets.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extractIfCondition/beforeMissedBrackets.java new file mode 100644 index 000000000000..82eb001446dc --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extractIfCondition/beforeMissedBrackets.java @@ -0,0 +1,10 @@ +// "Extract if (a)" "true" +class TestThreadInspection { + void f(boolean a, boolean b, boolean c){ + if (a && b) { + System.out.println("a&b"); + } else if (c) { + System.out.println("c"); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extractIfCondition/beforeNoElse.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extractIfCondition/beforeNoElse.java new file mode 100644 index 000000000000..8200a27bf900 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extractIfCondition/beforeNoElse.java @@ -0,0 +1,8 @@ +// "Extract if (a)" "true" +class TestThreadInspection { + void f(boolean a, boolean b, boolean c){ + if (a && b) { + System.out.println("a&b"); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extractIfCondition/beforeOrMissedBrackets.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extractIfCondition/beforeOrMissedBrackets.java new file mode 100644 index 000000000000..076d920bbdaf --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extractIfCondition/beforeOrMissedBrackets.java @@ -0,0 +1,10 @@ +// "Extract if (a)" "true" +class TestThreadInspection { + void f(boolean a, boolean b, boolean c){ + if (a || b) { + System.out.println("a&b"); + } else if (c) { + System.out.println("c"); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extractIfCondition/beforeOrSimpleElse.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extractIfCondition/beforeOrSimpleElse.java new file mode 100644 index 000000000000..6099057312df --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extractIfCondition/beforeOrSimpleElse.java @@ -0,0 +1,10 @@ +// "Extract if (a)" "true" +class TestThreadInspection { + void f(boolean a, boolean b, boolean c){ + if (a || b) { + System.out.println("a&b"); + } else { + System.out.println("c"); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extractIfCondition/beforeSimpleElse.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extractIfCondition/beforeSimpleElse.java new file mode 100644 index 000000000000..49433287d742 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/extractIfCondition/beforeSimpleElse.java @@ -0,0 +1,10 @@ +// "Extract if (a)" "true" +class TestThreadInspection { + void f(boolean a, boolean b, boolean c){ + if (a && b) { + System.out.println("a&b"); + } else { + System.out.println("c"); + } + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java index 36861062d1a0..1c41cd93ea5d 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java @@ -187,4 +187,5 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase { public void testIDEA111420() { doTest(false, false); } public void testIDEA111450() { doTest(true, false); } public void testExternalizable() { doTest(true, false); } + public void testAccessToStaticMethodsFromInterfaces() { doTest(true, false); } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/ExceptionVariablesInferenceTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/ExceptionVariablesInferenceTest.java index c55c6ae2e775..542620a57df7 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/ExceptionVariablesInferenceTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/ExceptionVariablesInferenceTest.java @@ -49,6 +49,10 @@ public class ExceptionVariablesInferenceTest extends LightDaemonAnalyzerTestCase doTest(); } + public void testExceptionsThrownByCallArguments() throws Exception { + doTest(); + } + private void doTest() throws Exception { doTest(false); } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/OverloadResolutionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/OverloadResolutionTest.java index 1b27e3539a9a..7306c4ef47e5 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/OverloadResolutionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/OverloadResolutionTest.java @@ -47,6 +47,10 @@ public class OverloadResolutionTest extends LightDaemonAnalyzerTestCase { doTest(); } + public void testVoidValueCompatibilityCantCompleteNormallyWithCallWithExceptionAsLastReturnStatement() throws Exception { + doTest(); + } + public void testIDEA102800() throws Exception { doTest(); } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ExtractIfConditionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ExtractIfConditionTest.java new file mode 100644 index 000000000000..4876ba5b6b0e --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ExtractIfConditionTest.java @@ -0,0 +1,30 @@ +/* + * Copyright 2000-2014 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. + */ +package com.intellij.codeInsight.daemon.quickFix; + + + +public class ExtractIfConditionTest extends LightQuickFixParameterizedTestCase { + + public void test() throws Exception { doAllTests(); } + + @Override + protected String getBasePath() { + return "/codeInsight/daemonCodeAnalyzer/quickFix/extractIfCondition"; + } + +} + diff --git a/platform/lang-api/src/com/intellij/lang/folding/CustomFoldingSurroundDescriptor.java b/platform/lang-api/src/com/intellij/lang/folding/CustomFoldingSurroundDescriptor.java index 433289c8685d..e5b60142d370 100644 --- a/platform/lang-api/src/com/intellij/lang/folding/CustomFoldingSurroundDescriptor.java +++ b/platform/lang-api/src/com/intellij/lang/folding/CustomFoldingSurroundDescriptor.java @@ -31,8 +31,6 @@ import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.psi.codeStyle.CommonCodeStyleSettings; import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.util.PsiUtilCore; -import com.intellij.testFramework.LightVirtualFile; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IdentifierHighlighterPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IdentifierHighlighterPass.java index 6dc614983563..02e1bc9d8cfa 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IdentifierHighlighterPass.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/IdentifierHighlighterPass.java @@ -33,6 +33,7 @@ import com.intellij.openapi.editor.impl.DocumentMarkupModel; import com.intellij.openapi.editor.markup.MarkupModel; import com.intellij.openapi.editor.markup.RangeHighlighter; import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Couple; import com.intellij.openapi.util.Pair; @@ -85,7 +86,13 @@ public class IdentifierHighlighterPass extends TextEditorHighlightingPass { } int flags = TargetElementUtilBase.ELEMENT_NAME_ACCEPTED | TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED; - PsiElement myTarget = TargetElementUtilBase.getInstance().findTargetElement(myEditor, flags, myCaretOffset); + PsiElement myTarget; + try { + myTarget = TargetElementUtilBase.getInstance().findTargetElement(myEditor, flags, myCaretOffset); + } + catch (IndexNotReadyException e) { + return; + } if (myTarget == null) { if (!PsiDocumentManager.getInstance(myProject).isUncommited(myEditor.getDocument())) { diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java b/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java index 8ed569bae70f..66e951cb1a2f 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java @@ -25,6 +25,7 @@ import com.intellij.openapi.application.ex.ApplicationInfoEx; import com.intellij.openapi.extensions.PluginId; import com.intellij.openapi.options.ShowSettingsUtil; import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.updateSettings.impl.UpdateSettings; import com.intellij.ui.DoubleClickListener; import com.intellij.ui.ScrollPaneFactory; @@ -237,7 +238,7 @@ public class AvailablePluginsManagerMain extends PluginManagerMain { } private AnAction createFilterByCategoryAction(final String availableCategory) { - return new AnAction(availableCategory) { + return new DumbAwareAction(availableCategory) { @Override public void actionPerformed(AnActionEvent e) { final String filter = myFilter.getFilter().toLowerCase(Locale.ENGLISH); @@ -280,7 +281,7 @@ public class AvailablePluginsManagerMain extends PluginManagerMain { } private AnAction createFilterByRepositoryAction(final String host) { - return new AnAction(host) { + return new DumbAwareAction(host) { @Override public void actionPerformed(AnActionEvent e) { final String filter = myFilter.getFilter().toLowerCase(Locale.ENGLISH); diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/sorters/AbstractSortByAction.java b/platform/platform-impl/src/com/intellij/ide/plugins/sorters/AbstractSortByAction.java index e817f6ad823b..a77222bdc3ff 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/sorters/AbstractSortByAction.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/sorters/AbstractSortByAction.java @@ -20,11 +20,12 @@ import com.intellij.ide.plugins.PluginTable; import com.intellij.ide.plugins.PluginTableModel; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.ToggleAction; +import com.intellij.openapi.project.DumbAware; /** * @author Konstantin Bulenkov */ -public abstract class AbstractSortByAction extends ToggleAction { +public abstract class AbstractSortByAction extends ToggleAction implements DumbAware { protected final PluginTable myTable; protected final PluginTableModel myModel; diff --git a/platform/testRunner/src/com/intellij/execution/testframework/actions/ViewAssertEqualsDiffAction.java b/platform/testRunner/src/com/intellij/execution/testframework/actions/ViewAssertEqualsDiffAction.java index a5615647ab6e..18c077535d46 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/actions/ViewAssertEqualsDiffAction.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/actions/ViewAssertEqualsDiffAction.java @@ -24,7 +24,6 @@ import com.intellij.execution.testframework.stacktrace.DiffHyperlink; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.util.Comparing; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; @@ -118,7 +117,7 @@ public class ViewAssertEqualsDiffAction extends AnAction implements TestTreeView myProviders = providers; if (hyperlink != null) { for (DiffHyperlink viewProvider : providers) { - if (Comparing.equal(hyperlink, viewProvider)) { + if (hyperlink.equals(viewProvider)) { provider = viewProvider; break; } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java index cd6d6455e9dd..3f9f6ca0f2df 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java @@ -55,7 +55,7 @@ import java.util.ArrayList; import java.util.List; public class XDebugSessionTab extends DebuggerSessionTabBase { - private static final DataKey TAB_KEY = DataKey.create("XDebugSessionTab"); + public static final DataKey TAB_KEY = DataKey.create("XDebugSessionTab"); private XWatchesViewImpl myWatchesView; private final List myViews = new ArrayList(); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/SetValueInplaceEditor.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/SetValueInplaceEditor.java index 4f1d43865a52..96acb2134b4d 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/SetValueInplaceEditor.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/SetValueInplaceEditor.java @@ -16,6 +16,7 @@ package com.intellij.xdebugger.impl.ui.tree; import com.intellij.codeInsight.hint.HintManager; +import com.intellij.ide.DataManager; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.ui.Messages; import com.intellij.ui.AppUIUtil; @@ -24,6 +25,7 @@ import com.intellij.xdebugger.frame.XValueModifier; import com.intellij.xdebugger.frame.presentation.XValuePresentation; import com.intellij.xdebugger.impl.XDebuggerUtilImpl; import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl; +import com.intellij.xdebugger.impl.ui.XDebugSessionTab; import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants; import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl; import com.intellij.xdebugger.impl.ui.tree.nodes.XValuePresentationUtil; @@ -104,12 +106,14 @@ public class SetValueInplaceEditor extends XDebuggerTreeInplaceEditor { myModifier.setValue(myExpressionEditor.getExpression().getExpression(), new XValueModifier.XModificationCallback() { @Override public void valueModified() { - AppUIUtil.invokeOnEdt(new Runnable() { - @Override - public void run() { - myTree.rebuildAndRestore(treeState); - } - }); + if (isDetachedTree(myTree)) { + AppUIUtil.invokeOnEdt(new Runnable() { + @Override + public void run() { + myTree.rebuildAndRestore(treeState); + } + }); + } XDebuggerUtilImpl.rebuildAllSessionsViews(getProject()); } @@ -131,6 +135,10 @@ public class SetValueInplaceEditor extends XDebuggerTreeInplaceEditor { }); XDebuggerUtilImpl.rebuildAllSessionsViews(getProject()); } + + boolean isDetachedTree(XDebuggerTree tree) { + return XDebugSessionTab.TAB_KEY.getData(DataManager.getInstance().getDataContext(tree)) == null; + } }); super.doOKAction(); } diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/AbstractMethodWithMissingImplementationsInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/AbstractMethodWithMissingImplementationsInspection.java index bada670da023..702ae218a97a 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/AbstractMethodWithMissingImplementationsInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/AbstractMethodWithMissingImplementationsInspection.java @@ -84,11 +84,8 @@ public class AbstractMethodWithMissingImplementationsInspection } } - private static boolean hasMatchingImplementation( - @NotNull PsiClass aClass, - @NotNull PsiMethod method) { - final PsiMethod overridingMethod = - findOverridingMethod(aClass, method); + private static boolean hasMatchingImplementation(@NotNull PsiClass aClass, @NotNull PsiMethod method) { + final PsiMethod overridingMethod = findOverridingMethod(aClass, method); if (overridingMethod == null || overridingMethod.hasModifierProperty(PsiModifier.STATIC)) { return false; @@ -98,8 +95,7 @@ public class AbstractMethodWithMissingImplementationsInspection } final PsiClass superClass = method.getContainingClass(); final PsiManager manager = overridingMethod.getManager(); - final JavaPsiFacade facade = - JavaPsiFacade.getInstance(manager.getProject()); + final JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject()); return facade.arePackagesTheSame(superClass, aClass); } @@ -109,27 +105,23 @@ public class AbstractMethodWithMissingImplementationsInspection * @return the overriding method. */ @Nullable - private static PsiMethod findOverridingMethod( - PsiClass aClass, @NotNull PsiMethod method) { + private static PsiMethod findOverridingMethod(PsiClass aClass, @NotNull PsiMethod method) { final PsiClass superClass = method.getContainingClass(); if (aClass.equals(superClass)) { return null; } final PsiSubstitutor substitutor = - TypeConversionUtil.getSuperClassSubstitutor(superClass, - aClass, PsiSubstitutor.EMPTY); + TypeConversionUtil.getSuperClassSubstitutor(superClass, aClass, PsiSubstitutor.EMPTY); final MethodSignature signature = method.getSignature(substitutor); final List> pairs = - aClass.findMethodsAndTheirSubstitutorsByName( - signature.getName(), true); + aClass.findMethodsAndTheirSubstitutorsByName(signature.getName(), true); for (Pair pair : pairs) { final PsiMethod overridingMethod = pair.first; if (overridingMethod.hasModifierProperty(PsiModifier.ABSTRACT)) { continue; } - final PsiClass containingClass = - overridingMethod.getContainingClass(); - if (containingClass.isInterface()) { + final PsiClass containingClass = overridingMethod.getContainingClass(); + if (containingClass != null && containingClass.isInterface() && !overridingMethod.hasModifierProperty(PsiModifier.DEFAULT)) { continue; } final PsiSubstitutor overridingSubstitutor = pair.second; diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/TypeUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/TypeUtils.java index fd4570090de9..1a160637df6b 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/TypeUtils.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/TypeUtils.java @@ -104,10 +104,8 @@ public class TypeUtils { if (expression == null) { return null; } - PsiType type = expression.getType(); - if (type instanceof PsiLambdaExpressionType) { - type = ((PsiLambdaExpressionType)type).getExpression().getFunctionalInterfaceType(); - } + PsiType type = expression instanceof PsiFunctionalExpression ? ((PsiFunctionalExpression)expression).getFunctionalInterfaceType() + : expression.getType(); if (type == null) { return null; } diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/ParameterHidingMemberVariableInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/ParameterHidingMemberVariableInspectionBase.java index 0df3a6bc5416..8c1252d6b0ee 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/ParameterHidingMemberVariableInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/ParameterHidingMemberVariableInspectionBase.java @@ -18,6 +18,7 @@ package com.siyeh.ig.visibility; import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel; import com.intellij.psi.*; import com.intellij.psi.util.PropertyUtil; +import com.siyeh.HardcodedMethodConstants; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; @@ -117,8 +118,15 @@ public class ParameterHidingMemberVariableInspectionBase extends BaseInspection return; } } - if (m_ignoreForPropertySetters && PropertyUtil.isSimplePropertySetter(method)) { - return; + if (m_ignoreForPropertySetters) { + final String methodName = method.getName(); + if (methodName.startsWith(HardcodedMethodConstants.SET) && PsiType.VOID.equals(method.getReturnType())) { + return; + } + + if (PropertyUtil.isSimplePropertySetter(method)) { + return; + } } final PsiClass aClass = checkFieldName(variable, method); if (aClass == null) { diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/inheritance/abstract_method_with_missing_implementations/AbstractMethodWithMissingImplementations.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/inheritance/abstract_method_with_missing_implementations/AbstractMethodWithMissingImplementations.java index f6743260c5ea..ddbdc2a1822c 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/inheritance/abstract_method_with_missing_implementations/AbstractMethodWithMissingImplementations.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/inheritance/abstract_method_with_missing_implementations/AbstractMethodWithMissingImplementations.java @@ -6,4 +6,12 @@ class WithDefaultMethods { } class B implements A {} + + interface C { + void foo(); + } + interface D extends C { + default void foo(){} + } + class E implements C, D {} } \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/threading/defaultRun/MethodRef.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/threading/defaultRun/MethodRef.java new file mode 100644 index 000000000000..2f3875198e58 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/threading/defaultRun/MethodRef.java @@ -0,0 +1,10 @@ +package com.siyeh.igtest.threading.defaultRun; +class TestMethodRef { + { + new Thread(this::method2); + } + + public void method2() { + System.out.println("I am in thread"); + } +} \ No newline at end of file