diff --git a/java/java-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java b/java/java-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java
new file mode 100644
index 000000000000..d4fddb4068d2
--- /dev/null
+++ b/java/java-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2000-2012 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.codeInspection;
+
+import com.intellij.codeInsight.daemon.GroupNames;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.JavaCodeStyleManager;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.RedundantCastUtil;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * User: anna
+ */
+public class AnonymousCanBeMethodReferenceInspection extends BaseJavaLocalInspectionTool {
+ public static final Logger LOG = Logger.getInstance("#" + AnonymousCanBeMethodReferenceInspection.class.getName());
+
+ @Nls
+ @NotNull
+ @Override
+ public String getGroupDisplayName() {
+ return GroupNames.LANGUAGE_LEVEL_SPECIFIC_GROUP_NAME;
+ }
+
+ @Nls
+ @NotNull
+ @Override
+ public String getDisplayName() {
+ return "Anonymous type can be replaced with method reference";
+ }
+
+ @Override
+ public boolean isEnabledByDefault() {
+ return true;
+ }
+
+ @NotNull
+ @Override
+ public String getShortName() {
+ return "Anonymous2MethodRef";
+ }
+
+ @NotNull
+ @Override
+ public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
+ return new JavaElementVisitor() {
+ @Override
+ public void visitAnonymousClass(PsiAnonymousClass aClass) {
+ super.visitAnonymousClass(aClass);
+ if (PsiUtil.getLanguageLevel(aClass).isAtLeast(LanguageLevel.JDK_1_8)) {
+ final PsiClassType baseClassType = aClass.getBaseClassType();
+ final String functionalInterfaceErrorMessage = LambdaUtil.checkInterfaceFunctional(baseClassType);
+ if (functionalInterfaceErrorMessage == null) {
+ final PsiMethod[] methods = aClass.getMethods();
+ if (methods.length == 1 && aClass.getFields().length == 0) {
+ final PsiCodeBlock body = methods[0].getBody();
+ final PsiCallExpression callExpression =
+ LambdaCanBeMethReferenceInspection.canBeMethodReferenceProblem(body, methods[0].getParameterList().getParameters());
+ if (callExpression != null && callExpression.resolveMethod() != methods[0]) {
+ final PsiElement parent = aClass.getParent();
+ if (parent instanceof PsiNewExpression) {
+ final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)parent).getClassOrAnonymousClassReference();
+ if (classReference != null) {
+ holder.registerProblem(classReference,
+ "Anonymous type can be replaced with method reference", new ReplaceWithMethodRefFix());
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ };
+ }
+
+ private static class ReplaceWithMethodRefFix implements LocalQuickFix {
+ @NotNull
+ @Override
+ public String getName() {
+ return "Replace with method reference";
+ }
+
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return getName();
+ }
+
+ @Override
+ public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
+ final PsiElement element = descriptor.getPsiElement();
+ final PsiAnonymousClass anonymousClass = PsiTreeUtil.getParentOfType(element, PsiAnonymousClass.class);
+ if (anonymousClass == null) return;
+ final PsiMethod[] methods = anonymousClass.getMethods();
+ if (methods.length != 1) return;
+
+ final PsiParameter[] parameters = methods[0].getParameterList().getParameters();
+ final PsiCallExpression callExpression = LambdaCanBeMethReferenceInspection.canBeMethodReferenceProblem(methods[0].getBody(), parameters);
+ if (callExpression == null) return;
+ final String methodRefText =
+ LambdaCanBeMethReferenceInspection.createMethodReferenceText(callExpression, parameters);
+
+ if (methodRefText != null) {
+ final String canonicalText = anonymousClass.getBaseClassType().getCanonicalText();
+ final PsiExpression psiExpression = JavaPsiFacade.getElementFactory(project).createExpressionFromText("(" + canonicalText + ")" + methodRefText, anonymousClass);
+
+ PsiElement castExpr = anonymousClass.getParent().replace(psiExpression);
+ if (RedundantCastUtil.isCastRedundant((PsiTypeCastExpression)castExpr)) {
+ final PsiExpression operand = ((PsiTypeCastExpression)castExpr).getOperand();
+ LOG.assertTrue(operand != null);
+ castExpr = castExpr.replace(operand);
+ }
+ JavaCodeStyleManager.getInstance(project).shortenClassReferences(castExpr);
+ }
+ }
+ }
+}
diff --git a/java/java-impl/src/com/intellij/codeInspection/LambdaCanBeMethReferenceInspection.java b/java/java-impl/src/com/intellij/codeInspection/LambdaCanBeMethReferenceInspection.java
index 056e6cbac9b7..fda1b3f8af09 100644
--- a/java/java-impl/src/com/intellij/codeInspection/LambdaCanBeMethReferenceInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/LambdaCanBeMethReferenceInspection.java
@@ -25,6 +25,7 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
/**
* User: anna
@@ -66,87 +67,148 @@ public class LambdaCanBeMethReferenceInspection extends BaseJavaLocalInspectionT
super.visitLambdaExpression(expression);
if (PsiUtil.getLanguageLevel(expression).isAtLeast(LanguageLevel.JDK_1_8)) {
final PsiElement body = expression.getBody();
- PsiCallExpression methodCall = null;
- if (body instanceof PsiCallExpression) {
- methodCall = (PsiCallExpression)body;
- } else if (body instanceof PsiCodeBlock) {
- final PsiStatement[] statements = ((PsiCodeBlock)body).getStatements();
- if (statements.length == 1) {
- if (statements[0] instanceof PsiReturnStatement) {
- final PsiExpression returnValue = ((PsiReturnStatement)statements[0]).getReturnValue();
- if (returnValue instanceof PsiCallExpression) {
- methodCall = (PsiCallExpression)returnValue;
- }
- } else if (statements[0] instanceof PsiExpressionStatement) {
- final PsiExpression expr = ((PsiExpressionStatement)statements[0]).getExpression();
- if (expr instanceof PsiCallExpression) {
- methodCall = (PsiCallExpression)expr;
- }
- }
- }
- }
-
- if (methodCall != null) {
- final PsiExpressionList argumentList = methodCall.getArgumentList();
- if (argumentList != null) {
- final PsiParameter[] parameters = expression.getParameterList().getParameters();
- final PsiExpression[] expressions = argumentList.getExpressions();
-
- final PsiMethod psiMethod = methodCall.resolveMethod();
- final PsiClass containingClass;
- boolean isConstructor;
- if (psiMethod == null) {
- isConstructor = true;
- if (!(methodCall instanceof PsiNewExpression)) return;
- final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)methodCall).getClassOrAnonymousClassReference();
- if (classReference == null) return;
- containingClass = (PsiClass)classReference.resolve();
- } else {
- containingClass = psiMethod.getContainingClass();
- isConstructor = psiMethod.isConstructor();
- }
- if (containingClass == null) return;
- boolean isReceiverType = parameters.length > 0 && LambdaUtil.isReceiverType(parameters[0].getType(), containingClass, PsiUtil.resolveGenericsClassInType(parameters[0].getType()).getSubstitutor());
- final boolean staticOrValidConstructorRef;
- if (isConstructor) {
- staticOrValidConstructorRef =
- (containingClass.getContainingClass() == null || containingClass.hasModifierProperty(PsiModifier.STATIC));
- } else {
- staticOrValidConstructorRef = psiMethod.hasModifierProperty(PsiModifier.STATIC);
- }
-
- final int offset = isReceiverType && !staticOrValidConstructorRef ? 1 : 0;
- if (parameters.length != expressions.length + offset) return;
-
- for (int i = 0; i < expressions.length; i++) {
- PsiExpression psiExpression = expressions[i];
- if (!(psiExpression instanceof PsiReferenceExpression)) return;
- final PsiElement resolve = ((PsiReferenceExpression)psiExpression).resolve();
- if (resolve == null) return;
- if (parameters[i + offset] != resolve) return;
- }
-
- if (offset > 0) {
- final PsiExpression qualifierExpression;
- if (methodCall instanceof PsiMethodCallExpression) {
- qualifierExpression = ((PsiMethodCallExpression)methodCall).getMethodExpression().getQualifierExpression();
- } else if (methodCall instanceof PsiNewExpression) {
- qualifierExpression = ((PsiNewExpression)methodCall).getQualifier();
- } else {
- qualifierExpression = null;
- }
- if (!(qualifierExpression instanceof PsiReferenceExpression) || ((PsiReferenceExpression)qualifierExpression).resolve() != parameters[0]) return;
- }
- holder.registerProblem(methodCall,
- "Can be replaced with method reference",
- ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new ReplaceWithMethodRefFix());
- }
+ final PsiCallExpression callExpression = canBeMethodReferenceProblem(body, expression.getParameterList().getParameters());
+ if (callExpression != null) {
+ holder.registerProblem(callExpression,
+ "Can be replaced with method reference",
+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new ReplaceWithMethodRefFix());
}
}
}
};
}
+ @Nullable
+ protected static PsiCallExpression canBeMethodReferenceProblem(@Nullable final PsiElement body, final PsiParameter[] parameters) {
+ PsiCallExpression methodCall = null;
+ if (body instanceof PsiCallExpression) {
+ methodCall = (PsiCallExpression)body;
+ }
+ else if (body instanceof PsiCodeBlock) {
+ final PsiStatement[] statements = ((PsiCodeBlock)body).getStatements();
+ if (statements.length == 1) {
+ if (statements[0] instanceof PsiReturnStatement) {
+ final PsiExpression returnValue = ((PsiReturnStatement)statements[0]).getReturnValue();
+ if (returnValue instanceof PsiCallExpression) {
+ methodCall = (PsiCallExpression)returnValue;
+ }
+ }
+ else if (statements[0] instanceof PsiExpressionStatement) {
+ final PsiExpression expr = ((PsiExpressionStatement)statements[0]).getExpression();
+ if (expr instanceof PsiCallExpression) {
+ methodCall = (PsiCallExpression)expr;
+ }
+ }
+ }
+ }
+
+ if (methodCall != null) {
+ final PsiExpressionList argumentList = methodCall.getArgumentList();
+ if (argumentList != null) {
+ final PsiExpression[] expressions = argumentList.getExpressions();
+
+ final PsiMethod psiMethod = methodCall.resolveMethod();
+ final PsiClass containingClass;
+ boolean isConstructor;
+ if (psiMethod == null) {
+ isConstructor = true;
+ if (!(methodCall instanceof PsiNewExpression)) return null;
+ final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)methodCall).getClassOrAnonymousClassReference();
+ if (classReference == null) return null;
+ containingClass = (PsiClass)classReference.resolve();
+ }
+ else {
+ containingClass = psiMethod.getContainingClass();
+ isConstructor = psiMethod.isConstructor();
+ }
+ if (containingClass == null) return null;
+ boolean isReceiverType = parameters.length > 0 && LambdaUtil.isReceiverType(parameters[0].getType(), containingClass, PsiUtil
+ .resolveGenericsClassInType(parameters[0].getType()).getSubstitutor());
+ final boolean staticOrValidConstructorRef;
+ if (isConstructor) {
+ staticOrValidConstructorRef =
+ (containingClass.getContainingClass() == null || containingClass.hasModifierProperty(PsiModifier.STATIC));
+ }
+ else {
+ staticOrValidConstructorRef = psiMethod.hasModifierProperty(PsiModifier.STATIC);
+ }
+
+ final int offset = isReceiverType && !staticOrValidConstructorRef ? 1 : 0;
+ if (parameters.length != expressions.length + offset) return null;
+
+ for (int i = 0; i < expressions.length; i++) {
+ PsiExpression psiExpression = expressions[i];
+ if (!(psiExpression instanceof PsiReferenceExpression)) return null;
+ final PsiElement resolve = ((PsiReferenceExpression)psiExpression).resolve();
+ if (resolve == null) return null;
+ if (parameters[i + offset] != resolve) return null;
+ }
+
+ if (offset > 0) {
+ final PsiExpression qualifierExpression;
+ if (methodCall instanceof PsiMethodCallExpression) {
+ qualifierExpression = ((PsiMethodCallExpression)methodCall).getMethodExpression().getQualifierExpression();
+ }
+ else if (methodCall instanceof PsiNewExpression) {
+ qualifierExpression = ((PsiNewExpression)methodCall).getQualifier();
+ }
+ else {
+ qualifierExpression = null;
+ }
+ if (!(qualifierExpression instanceof PsiReferenceExpression) ||
+ ((PsiReferenceExpression)qualifierExpression).resolve() != parameters[0]) {
+ return null;
+ }
+ }
+ return methodCall;
+ }
+ }
+ return null;
+ }
+
+ @Nullable
+ protected static String createMethodReferenceText(PsiElement element, final PsiParameter[] parameters) {
+ String methodRefText = null;
+ if (element instanceof PsiMethodCallExpression) {
+ final PsiMethodCallExpression methodCall = (PsiMethodCallExpression)element;
+ final PsiMethod psiMethod = methodCall.resolveMethod();
+ LOG.assertTrue(psiMethod != null);
+ final PsiClass containingClass = psiMethod.getContainingClass();
+ LOG.assertTrue(containingClass != null);
+ final PsiReferenceExpression methodExpression = methodCall.getMethodExpression();
+ final PsiExpression qualifierExpression = methodExpression.getQualifierExpression();
+ final String methodReferenceName = methodExpression.getReferenceName();
+ if (qualifierExpression != null) {
+ boolean isReceiverType = parameters.length > 0 && LambdaUtil.isReceiverType(parameters[0].getType(), containingClass, PsiUtil
+ .resolveGenericsClassInType(parameters[0].getType()).getSubstitutor());
+ methodRefText = (isReceiverType ? containingClass.getQualifiedName() : qualifierExpression.getText()) + "::" + methodReferenceName;
+ }
+ else {
+ methodRefText =
+ (psiMethod.hasModifierProperty(PsiModifier.STATIC) ? containingClass.getQualifiedName() : "this") + "::" + methodReferenceName;
+ }
+ }
+ else if (element instanceof PsiNewExpression) {
+ final PsiMethod constructor = ((PsiNewExpression)element).resolveConstructor();
+ if (constructor != null) {
+ final PsiClass containingClass = constructor.getContainingClass();
+ LOG.assertTrue(containingClass != null);
+ methodRefText = containingClass.getQualifiedName() + "::new";
+ }
+ else {
+ final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)element).getClassOrAnonymousClassReference();
+ if (classReference != null) {
+ final JavaResolveResult resolve = classReference.advancedResolve(false);
+ final PsiElement containingClass = resolve.getElement();
+ if (containingClass instanceof PsiClass) {
+ methodRefText = ((PsiClass)containingClass).getQualifiedName() + "::new";
+ }
+ }
+ }
+ }
+ return methodRefText;
+ }
+
private static class ReplaceWithMethodRefFix implements LocalQuickFix {
@NotNull
@Override
@@ -165,43 +227,11 @@ public class LambdaCanBeMethReferenceInspection extends BaseJavaLocalInspectionT
final PsiElement element = descriptor.getPsiElement();
final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(element, PsiLambdaExpression.class);
if (lambdaExpression == null) return;
- String methodRefText = null;
- if (element instanceof PsiMethodCallExpression) {
- final PsiMethodCallExpression methodCall = (PsiMethodCallExpression)element;
- final PsiMethod psiMethod = methodCall.resolveMethod();
- LOG.assertTrue(psiMethod != null);
- final PsiClass containingClass = psiMethod.getContainingClass();
- LOG.assertTrue(containingClass != null);
- final PsiReferenceExpression methodExpression = methodCall.getMethodExpression();
- final PsiExpression qualifierExpression = methodExpression.getQualifierExpression();
- final String methodReferenceName = methodExpression.getReferenceName();
- if (qualifierExpression != null) {
- final PsiParameter[] parameters = lambdaExpression.getParameterList().getParameters();
- boolean isReceiverType = parameters.length > 0 && LambdaUtil.isReceiverType(parameters[0].getType(), containingClass, PsiUtil.resolveGenericsClassInType(parameters[0].getType()).getSubstitutor());
- methodRefText = (isReceiverType ? containingClass.getQualifiedName() : qualifierExpression.getText()) + "::" + methodReferenceName;
- } else {
- methodRefText = (psiMethod.hasModifierProperty(PsiModifier.STATIC) ? containingClass.getQualifiedName() : "this") + "::" + methodReferenceName;
- }
- } else if (element instanceof PsiNewExpression) {
- final PsiMethod constructor = ((PsiNewExpression)element).resolveConstructor();
- if (constructor != null) {
- final PsiClass containingClass = constructor.getContainingClass();
- LOG.assertTrue(containingClass != null);
- methodRefText = containingClass.getQualifiedName() + "::new";
- } else {
- final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)element).getClassOrAnonymousClassReference();
- if (classReference != null) {
- final JavaResolveResult resolve = classReference.advancedResolve(false);
- final PsiElement containingClass = resolve.getElement();
- if (containingClass instanceof PsiClass) {
- methodRefText = ((PsiClass)containingClass).getQualifiedName() + "::new";
- }
- }
- }
- }
+ final String methodRefText = createMethodReferenceText(element, lambdaExpression.getParameterList().getParameters());
if (methodRefText != null) {
- final PsiExpression psiExpression = JavaPsiFacade.getElementFactory(project).createExpressionFromText(methodRefText, lambdaExpression);
+ final PsiExpression psiExpression =
+ JavaPsiFacade.getElementFactory(project).createExpressionFromText(methodRefText, lambdaExpression);
JavaCodeStyleManager.getInstance(project).shortenClassReferences(lambdaExpression.replace(psiExpression));
}
}
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassToInnerProcessor.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassToInnerProcessor.java
index 5fbfa3313d35..7aed2d8a03bc 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassToInnerProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassToInnerProcessor.java
@@ -144,7 +144,7 @@ public class MoveClassToInnerProcessor extends BaseRefactoringProcessor {
newClass = handler.moveClass(classToMove, myTargetClass);
if (newClass != null) break;
}
- LOG.assertTrue(newClass != null, "There is no appropriate MoveClassToInnerHandler!");
+ LOG.assertTrue(newClass != null, "There is no appropriate MoveClassToInnerHandler for " + myTargetClass + "; " + classToMove);
oldToNewElementsMapping.put(classToMove, newClass);
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
index 9c2e94b5c42b..5e9b995e3c9f 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
@@ -279,6 +279,7 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
}
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType);
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
+ final MethodSignature signature = interfaceMethod != null ? interfaceMethod.getSignature(resolveResult.getSubstitutor()) : null;
final PsiType interfaceMethodReturnType = LambdaUtil.getFunctionalInterfaceReturnType(functionalInterfaceType);
final LanguageLevel languageLevel = PsiUtil.getLanguageLevel(PsiMethodReferenceExpressionImpl.this);
if (isConstructor && interfaceMethod != null) {
@@ -293,11 +294,19 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
if (containingClass.getConstructors().length == 0 &&
!containingClass.isEnum() &&
!containingClass.hasModifierProperty(PsiModifier.ABSTRACT)) {
- return new JavaResolveResult[]{new ClassCandidateInfo(containingClass, substitutor)};
+ boolean hasReceiver = false;
+ final PsiType[] parameterTypes = signature.getParameterTypes();
+
+ if (parameterTypes.length == 1 && LambdaUtil.isReceiverType(parameterTypes[0], containingClass, substitutor)) {
+ hasReceiver = true;
+ }
+ if (parameterTypes.length == 0 || hasReceiver && !(containingClass.getContainingClass() == null || containingClass.hasModifierProperty(PsiModifier.STATIC))) {
+ return new JavaResolveResult[]{new ClassCandidateInfo(containingClass, substitutor)};
+ }
+ return JavaResolveResult.EMPTY_ARRAY;
}
}
- final MethodSignature signature = interfaceMethod != null ? interfaceMethod.getSignature(resolveResult.getSubstitutor()) : null;
final MethodReferenceConflictResolver conflictResolver =
new MethodReferenceConflictResolver(containingClass, substitutor, signature, beginsWithReferenceType);
final PsiConflictResolver[] resolvers;
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/DefaultConstructor.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/DefaultConstructor.java
index 84a3de3b8280..d216021ee7ca 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/DefaultConstructor.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/DefaultConstructor.java
@@ -44,3 +44,15 @@ class DefaultConstructor1 {
Runnable b1 = DefaultConstructor1 :: new;
}
}
+
+class DefaultConstructor2 {
+ interface I {
+ void foo(DefaultConstructor2 e);
+ }
+
+
+ void f() {
+ I i1 = DefaultConstructor2 :: new;
+ I i2 = this::new;
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2methodReference/after1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2methodReference/after1.java
new file mode 100644
index 000000000000..d5d6320a0e94
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2methodReference/after1.java
@@ -0,0 +1,13 @@
+// "Replace with method reference" "true"
+class Test {
+ interface Bar {
+ int compare(String o1, String o2);
+ }
+ static int c(String o1, String o2) {
+ return 0;
+ }
+
+ {
+ Bar bar2 = Test::c;
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2methodReference/afterInsertCast.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2methodReference/afterInsertCast.java
new file mode 100644
index 000000000000..f0dffef5fb5a
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2methodReference/afterInsertCast.java
@@ -0,0 +1,14 @@
+// "Replace with method reference" "true"
+class Test {
+ interface I {}
+ interface Bar extends I {
+ int compare(String o1, String o2);
+ }
+ static int c(String o1, String o2) {
+ return 0;
+ }
+
+ {
+ I bar2 = (Bar) Test::c;
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2methodReference/before1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2methodReference/before1.java
new file mode 100644
index 000000000000..7ca24f152943
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2methodReference/before1.java
@@ -0,0 +1,18 @@
+// "Replace with method reference" "true"
+class Test {
+ interface Bar {
+ int compare(String o1, String o2);
+ }
+ static int c(String o1, String o2) {
+ return 0;
+ }
+
+ {
+ Bar bar2 = new Bar() {
+ @Override
+ public int compare(final String o1, final String o2) {
+ return c(o1, o2);
+ }
+ };
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2methodReference/beforeInsertCast.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2methodReference/beforeInsertCast.java
new file mode 100644
index 000000000000..9a0caa2d6fc3
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2methodReference/beforeInsertCast.java
@@ -0,0 +1,19 @@
+// "Replace with method reference" "true"
+class Test {
+ interface I {}
+ interface Bar extends I {
+ int compare(String o1, String o2);
+ }
+ static int c(String o1, String o2) {
+ return 0;
+ }
+
+ {
+ I bar2 = new Bar() {
+ @Override
+ public int compare(final String o1, final String o2) {
+ return c(o1, o2);
+ }
+ };
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2methodReference/beforeRecursive.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2methodReference/beforeRecursive.java
new file mode 100644
index 000000000000..6b58d667789c
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2methodReference/beforeRecursive.java
@@ -0,0 +1,15 @@
+// "Replace with method reference" "false"
+class Test {
+ public interface I {
+ int m();
+ }
+ {
+ I i = new I() {
+ @Override
+ public int m() {
+ return m();
+ }
+ };
+
+ }
+}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Anonymous2MethodReferenceInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Anonymous2MethodReferenceInspectionTest.java
new file mode 100644
index 000000000000..e7fb3bedbf44
--- /dev/null
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Anonymous2MethodReferenceInspectionTest.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2000-2012 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;
+
+import com.intellij.codeInspection.AnonymousCanBeMethodReferenceInspection;
+import com.intellij.codeInspection.LocalInspectionTool;
+
+
+public class Anonymous2MethodReferenceInspectionTest extends LightQuickFixTestCase {
+ @Override
+ protected LocalInspectionTool[] configureLocalInspectionTools() {
+ return new LocalInspectionTool[]{
+ new AnonymousCanBeMethodReferenceInspection(),
+ };
+ }
+
+ public void test() throws Exception { doAllTests(); }
+
+ @Override
+ protected String getBasePath() {
+ return "/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2methodReference";
+ }
+
+}
\ No newline at end of file
diff --git a/platform/icons/src/general/help_small.png b/platform/icons/src/general/help_small.png
new file mode 100644
index 000000000000..6c04835138fa
Binary files /dev/null and b/platform/icons/src/general/help_small.png differ
diff --git a/platform/platform-impl/src/com/intellij/codeInsight/hint/HintUtil.java b/platform/platform-impl/src/com/intellij/codeInsight/hint/HintUtil.java
index 160202b9d053..e199dc37ca11 100644
--- a/platform/platform-impl/src/com/intellij/codeInsight/hint/HintUtil.java
+++ b/platform/platform-impl/src/com/intellij/codeInsight/hint/HintUtil.java
@@ -113,7 +113,7 @@ public class HintUtil {
HintLabel label = new HintLabel();
label.setText(text, hintHint);
- label.setIcon(AllIcons.Actions.Help);
+ label.setIcon(AllIcons.General.Help_small);
if (!hintHint.isAwtTooltip()) {
label.setBorder(createHintBorder());
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 ad6b174055e8..71d0cb4b8723 100644
--- a/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java
+++ b/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java
@@ -88,7 +88,7 @@ public class AvailablePluginsManagerMain extends PluginManagerMain {
pluginTable.getTableHeader().setReorderingAllowed(false);
pluginTable.setColumnWidth(PluginManagerColumnInfo.COLUMN_DOWNLOADS, 70);
pluginTable.setColumnWidth(PluginManagerColumnInfo.COLUMN_DATE, 50);
- pluginTable.setColumnWidth(PluginManagerColumnInfo.COLUMN_RATE, 60);
+ pluginTable.setColumnWidth(PluginManagerColumnInfo.COLUMN_RATE, 80);
return ScrollPaneFactory.createScrollPane(pluginTable);
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ActionsTreeUtil.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ActionsTreeUtil.java
index 6517c49b261f..4965ae040380 100644
--- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ActionsTreeUtil.java
+++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ActionsTreeUtil.java
@@ -160,6 +160,7 @@ public class ActionsTreeUtil {
? ((DefaultActionGroup)actionGroup).getChildActionsOrStubs()
: actionGroup.getChildren(null);
for (AnAction action : mainMenuTopGroups) {
+ if (!(action instanceof ActionGroup)) continue;
Group subGroup = createGroup((ActionGroup)action, false, filtered);
if (subGroup.getSize() > 0) {
group.addGroup(subGroup);
diff --git a/platform/platform-resources-en/src/messages/CommonBundle.properties b/platform/platform-resources-en/src/messages/CommonBundle.properties
index e17f4416c622..fb8dd67fc4ba 100644
--- a/platform/platform-resources-en/src/messages/CommonBundle.properties
+++ b/platform/platform-resources-en/src/messages/CommonBundle.properties
@@ -14,7 +14,7 @@ checkbox.remember.password=&Remember password
editbox.login=&Login:
checkbox.use.http.proxy=&Use HTTP proxy
checkbox.proxy.authentication=Proxy &authentication
-checkbox.use.http.proxy.pac=Auto-Detect Proxy Settings
+checkbox.use.http.proxy.pac=Auto-detect proxy settings
tooltip.http.proxy.pac=This will attempt to use your system settings and is useful if your system uses a proxy autoconfiguration file (.pac).
editbox.port.number= Port &number:
editbox.host.name= &Host name:
diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml
index 43099147515f..d1cb91fecc37 100644
--- a/platform/platform-resources/src/idea/PlatformActions.xml
+++ b/platform/platform-resources/src/idea/PlatformActions.xml
@@ -137,7 +137,7 @@