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-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightNamesUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightNamesUtil.java index b6b136530032..5e8fb9d20af6 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightNamesUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightNamesUtil.java @@ -62,8 +62,13 @@ public class HighlightNamesUtil { if (!isDeclaration) { if (isCalledOnThis(elementToHighlight)) { - PsiClass enclosingClass = PsiTreeUtil.getParentOfType(elementToHighlight, PsiClass.class); - isInherited = enclosingClass != null && enclosingClass.isInheritor(method.getContainingClass(), true); + final PsiClass containingClass = method.getContainingClass(); + PsiClass enclosingClass = containingClass == null ? null : PsiTreeUtil.getParentOfType(elementToHighlight, PsiClass.class); + while (enclosingClass != null) { + isInherited = enclosingClass.isInheritor(containingClass, true); + if (isInherited) break; + enclosingClass = PsiTreeUtil.getParentOfType(enclosingClass, PsiClass.class, true); + } } } 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-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveClassesOrPackagesHandler.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveClassesOrPackagesHandler.java index cc27b3298e60..d440c16501b9 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveClassesOrPackagesHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveClassesOrPackagesHandler.java @@ -470,8 +470,12 @@ public class JavaMoveClassesOrPackagesHandler extends MoveHandlerDelegate { return true; } } + if (target instanceof PsiPackage && source instanceof PsiClass) { + final GlobalSearchScope globalSearchScope = GlobalSearchScope.projectScope(source.getProject()); + return ((PsiPackage)target).findClassByShortName(((PsiClass)source).getName(), globalSearchScope).length > 0; + } if (target instanceof PsiDirectory && source instanceof PsiDirectory) { - final PsiPackage aPackage = JavaDirectoryServiceImpl.getInstance().getPackage((PsiDirectory)source); + final PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage((PsiDirectory)source); if (aPackage != null && !MoveClassesOrPackagesImpl.checkNesting(target.getProject(), aPackage, target, false)) return true; } return super.isMoveRedundant(source, target); diff --git a/java/java-impl/src/com/intellij/refactoring/typeCook/TypeCookHandler.java b/java/java-impl/src/com/intellij/refactoring/typeCook/TypeCookHandler.java index c36786a21268..2ebdcb850a55 100644 --- a/java/java-impl/src/com/intellij/refactoring/typeCook/TypeCookHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/typeCook/TypeCookHandler.java @@ -31,11 +31,7 @@ public class TypeCookHandler implements RefactoringActionHandler { } public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, DataContext dataContext) { - if (elements == null || elements.length == 0) return; - - for (PsiElement element : elements) { - if (!CommonRefactoringUtil.checkReadOnlyStatus(project, element)) return; - } + if (elements.length == 0) return; new TypeCookDialog(project, elements).show(); } 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/advHighlighting/NamesHighlighting.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/NamesHighlighting.java index a92aefa049be..e25fa4ac277e 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/NamesHighlighting.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/NamesHighlighting.java @@ -59,4 +59,38 @@ class NoCtrClass { class Generic<TT extends Runnable> { TT field; +} + +class InheritedSymbolNames { + + private static class A { + public String getName() { + return "classA"; + } + } + + private static class B extends A { + { + new java.lang.Runnable() { + public void run() { + getName(); + } + }; + getName(); + } + } + + private static class C extends A { + { + new java.lang.Runnable() { + public void run() { + getName(); + } + }; + getName(); + } + public String getName() { + return "classC"; + } + } } \ No newline at end of file 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/core-api/src/com/intellij/openapi/components/ServiceManager.java b/platform/core-api/src/com/intellij/openapi/components/ServiceManager.java index f269d1fff5b2..3731b68d78d1 100644 --- a/platform/core-api/src/com/intellij/openapi/components/ServiceManager.java +++ b/platform/core-api/src/com/intellij/openapi/components/ServiceManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.intellij.openapi.components; import com.intellij.openapi.application.ApplicationManager; @@ -22,26 +21,25 @@ import com.intellij.openapi.util.NotNullLazyKey; import com.intellij.util.NotNullFunction; import org.jetbrains.annotations.NotNull; - /** * For old-style components, the contract specifies a lifecycle: the component gets created and notified during the project opening process. * For services, there's no such contract, so we don't even load the class implementing the service until someone requests it. */ -@SuppressWarnings({"unchecked"}) public class ServiceManager { - private ServiceManager() { - } + private ServiceManager() { } public static T getService(@NotNull Class serviceClass) { - return (T)ApplicationManager.getApplication().getPicoContainer().getComponentInstance(serviceClass.getName()); + @SuppressWarnings("unchecked") T instance = (T)ApplicationManager.getApplication().getPicoContainer().getComponentInstance(serviceClass.getName()); + return instance; } public static T getService(@NotNull Project project, @NotNull Class serviceClass) { - return (T)project.getPicoContainer().getComponentInstance(serviceClass.getName()); + @SuppressWarnings("unchecked") T instance = (T)project.getPicoContainer().getComponentInstance(serviceClass.getName()); + return instance; } /** - * Creates lazy caching key to store project-level service instance from {@link #getService(com.intellij.openapi.project.Project, Class)}. + * Creates lazy caching key to store project-level service instance from {@link #getService(Project, Class)}. * * @param serviceClass Service class to create key for. * @param Service class type. 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/InstalledPluginsState.java b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsState.java index dd300e5a3693..2c332e3e41a4 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsState.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/InstalledPluginsState.java @@ -15,12 +15,14 @@ */ package com.intellij.ide.plugins; +import com.intellij.idea.IdeaApplication; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.extensions.PluginId; import com.intellij.openapi.updateSettings.impl.PluginDownloader; import com.intellij.openapi.updateSettings.impl.UpdateSettings; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.Collections; @@ -30,6 +32,11 @@ import java.util.Map; * A service to hold a state of plugin changes in a current session (i.e. before the changes are applied on restart). */ public class InstalledPluginsState { + @Nullable + public static InstalledPluginsState getInstanceIfLoaded() { + return IdeaApplication.isLoaded() ? getInstance() : null; + } + public static InstalledPluginsState getInstance() { return ServiceManager.getService(InstalledPluginsState.class); } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginInstaller.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginInstaller.java index 58710c96607e..4f235f12a85b 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginInstaller.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginInstaller.java @@ -52,7 +52,6 @@ public class PluginInstaller { public static final String UNKNOWN_HOST_MARKER = "__unknown_repository__"; private static final Object ourLock = new Object(); - private static final InstalledPluginsState ourState = InstalledPluginsState.getInstance(); private PluginInstaller() { } @@ -149,7 +148,7 @@ public class PluginInstaller { for (int i = 0; i < pluginNode.getDepends().size(); i++) { PluginId depPluginId = pluginNode.getDepends().get(i); if (PluginManager.isPluginInstalled(depPluginId) || PluginManagerCore.isModuleDependency(depPluginId) || - ourState.wasInstalled(depPluginId) || + InstalledPluginsState.getInstance().wasInstalled(depPluginId) || (pluginIds != null && pluginIds.contains(depPluginId))) { // ignore installed or installing plugins continue; diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/RepositoryHelper.java b/platform/platform-impl/src/com/intellij/ide/plugins/RepositoryHelper.java index c1adafce70c9..7e09ada33600 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/RepositoryHelper.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/RepositoryHelper.java @@ -18,6 +18,7 @@ package com.intellij.ide.plugins; import com.google.common.hash.Hashing; import com.google.common.io.Files; import com.intellij.ide.IdeBundle; +import com.intellij.idea.IdeaApplication; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.application.impl.ApplicationInfoImpl; import com.intellij.openapi.diagnostic.Logger; @@ -68,7 +69,7 @@ public class RepositoryHelper { public static List loadPlugins(@Nullable String repositoryUrl, @Nullable BuildNumber buildnumber, @Nullable final ProgressIndicator indicator) throws IOException { - boolean forceHttps = repositoryUrl == null && UpdateSettings.getInstance().SECURE_CONNECTION; + boolean forceHttps = repositoryUrl == null && IdeaApplication.isLoaded() && UpdateSettings.getInstance().SECURE_CONNECTION; return loadPlugins(repositoryUrl, buildnumber, forceHttps, indicator); } 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/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java index b51b3d82e07b..4ceaba3fe4d6 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java @@ -56,28 +56,25 @@ public class PluginDownloader { private final String myPluginId; private final String myPluginUrl; + private final String myPluginName; private String myPluginVersion; - private String myFileName; - private String myPluginName; private BuildNumber myBuildNumber; - private boolean myForceHttps; private File myFile; private File myOldFile; private String myDescription; private List myDepends; private IdeaPluginDescriptor myDescriptor; + private boolean myForceHttps; private PluginDownloader(@NotNull String pluginId, @NotNull String pluginUrl, - @Nullable String pluginVersion, - @Nullable String fileName, @Nullable String pluginName, + @Nullable String pluginVersion, @Nullable BuildNumber buildNumber) { myPluginId = pluginId; myPluginUrl = pluginUrl; myPluginVersion = pluginVersion; - myFileName = fileName; myPluginName = pluginName; myBuildNumber = buildNumber; } @@ -90,18 +87,8 @@ public class PluginDownloader { return myPluginVersion; } - public String getFileName() { - if (myFileName == null) { - myFileName = myPluginUrl.substring(myPluginUrl.lastIndexOf('/') + 1); - } - return myFileName; - } - public String getPluginName() { - if (myPluginName == null) { - myPluginName = FileUtil.getNameWithoutExtension(getFileName()); - } - return myPluginName; + return myPluginName != null ? myPluginName : myPluginId; } public BuildNumber getBuildNumber() { @@ -179,7 +166,8 @@ public class PluginDownloader { IdeaPluginDescriptorImpl actualDescriptor = loadDescriptionFromJar(myFile); if (actualDescriptor != null) { - if (InstalledPluginsState.getInstance().wasUpdated(actualDescriptor.getPluginId())) { + InstalledPluginsState state = InstalledPluginsState.getInstanceIfLoaded(); + if (state != null && state.wasUpdated(actualDescriptor.getPluginId())) { return false; //already updated } @@ -237,7 +225,10 @@ public class PluginDownloader { StartupActionScriptManager.addActionCommand(deleteOld); } PluginInstaller.install(myFile, getPluginName(), true); - InstalledPluginsState.getInstance().onPluginInstall(myDescriptor); + InstalledPluginsState state = InstalledPluginsState.getInstanceIfLoaded(); + if (state != null) { + state.onPluginInstall(myDescriptor); + } } @NotNull @@ -256,11 +247,8 @@ public class PluginDownloader { public File process(@NotNull HttpRequests.Request request) throws IOException { request.saveToFile(file, indicator); - if (myFileName == null) { - myFileName = guessFileName(request.getConnection(), file); - } - - File newFile = new File(file.getParentFile(), myFileName); + String fileName = guessFileName(request.getConnection(), file); + File newFile = new File(file.getParentFile(), fileName); FileUtil.rename(file, newFile); return newFile; } @@ -312,9 +300,9 @@ public class PluginDownloader { @Nullable String host, @Nullable BuildNumber buildNumber) throws IOException { try { - PluginId id = descriptor.getPluginId(); - String url = getUrl(descriptor, host, buildNumber, id); - PluginDownloader downloader = new PluginDownloader(id.getIdString(), url, descriptor.getVersion(), null, descriptor.getName(), null); + String url = getUrl(descriptor, host, buildNumber); + String id = descriptor.getPluginId().getIdString(); + PluginDownloader downloader = new PluginDownloader(id, url, descriptor.getName(), descriptor.getVersion(), buildNumber); downloader.setDescriptor(descriptor); downloader.setDescription(descriptor.getDescription()); downloader.setDepends(((PluginNode)descriptor).getDepends()); @@ -328,8 +316,7 @@ public class PluginDownloader { @NotNull private static String getUrl(@NotNull IdeaPluginDescriptor descriptor, @Nullable String host, - @Nullable BuildNumber buildNumber, - PluginId id) throws URISyntaxException, MalformedURLException { + @Nullable BuildNumber buildNumber) throws URISyntaxException, MalformedURLException { if (host != null && descriptor instanceof PluginNode) { String url = ((PluginNode)descriptor).getDownloadUrl(); return new URI(url).isAbsolute() ? url : new URL(new URL(host), url).toExternalForm(); @@ -346,7 +333,7 @@ public class PluginDownloader { URIBuilder uriBuilder = new URIBuilder(appInfo.getPluginsDownloadUrl()); uriBuilder.addParameter("action", "download"); - uriBuilder.addParameter("id", id.getIdString()); + uriBuilder.addParameter("id", descriptor.getPluginId().getIdString()); uriBuilder.addParameter("build", buildNumberAsString); uriBuilder.addParameter("uuid", uuid); return uriBuilder.toString(); diff --git a/platform/platform-tests/testSrc/com/intellij/ide/plugins/RepositoryHelperTest.java b/platform/platform-tests/testSrc/com/intellij/ide/plugins/RepositoryHelperTest.java index 2276689ded88..8b5da122386a 100644 --- a/platform/platform-tests/testSrc/com/intellij/ide/plugins/RepositoryHelperTest.java +++ b/platform/platform-tests/testSrc/com/intellij/ide/plugins/RepositoryHelperTest.java @@ -68,6 +68,7 @@ public class RepositoryHelperTest { " ...\n" + " com.intellij.javaee\n" + " 3.5\n" + + " plugin.zip\n" + " \n" + " \n" + " tc Server Support\n" + @@ -79,6 +80,7 @@ public class RepositoryHelperTest { " ...\n" + " com.intellij.javaee\n" + " 00\n" + + " plugin.zip\n" + " " + " \n" + ""); 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 diff --git a/plugins/devkit/src/inspections/TitleCapitalizationInspection.java b/plugins/devkit/src/inspections/TitleCapitalizationInspection.java index 2de34c1856de..593cb176e7cc 100644 --- a/plugins/devkit/src/inspections/TitleCapitalizationInspection.java +++ b/plugins/devkit/src/inspections/TitleCapitalizationInspection.java @@ -159,6 +159,9 @@ public class TitleCapitalizationInspection extends BaseJavaLocalInspectionTool { if (arg instanceof PsiMethodCallExpression) { PsiMethod psiMethod = ((PsiMethodCallExpression)arg).resolveMethod(); PsiExpression returnValue = PropertyUtil.getGetterReturnExpression(psiMethod); + if (arg == returnValue) { + return null; + } if (returnValue != null) { return getTitleValue(returnValue); } diff --git a/plugins/devkit/testData/inspections/capitalization/RecursiveMethod.java b/plugins/devkit/testData/inspections/capitalization/RecursiveMethod.java new file mode 100644 index 000000000000..b852a3373328 --- /dev/null +++ b/plugins/devkit/testData/inspections/capitalization/RecursiveMethod.java @@ -0,0 +1,8 @@ +import org.jetbrains.annotations.Nls; + +class RecursiveMethod { + @Nls(capitalization = Nls.Capitalization.Title) + public String getName() { + return getName(); + } +} \ No newline at end of file diff --git a/plugins/devkit/testSources/inspections/CapitalizationInspectionTest.java b/plugins/devkit/testSources/inspections/CapitalizationInspectionTest.java index 51b181a7ae84..2177ebfc3ea1 100644 --- a/plugins/devkit/testSources/inspections/CapitalizationInspectionTest.java +++ b/plugins/devkit/testSources/inspections/CapitalizationInspectionTest.java @@ -37,6 +37,11 @@ public class CapitalizationInspectionTest extends LightCodeInsightFixtureTestCas doTest(); } + public void testRecursiveMethod() throws Exception { + myFixture.testHighlighting(getTestName(false) + ".java"); + assertEmpty(myFixture.filterAvailableIntentions("Properly capitalize")); + } + public void doTest() { myFixture.testHighlighting(getTestName(false) + ".java"); final IntentionAction action = myFixture.filterAvailableIntentions("Properly capitalize").get(0);