mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
anonym -> lambda: decode context correctly
This commit is contained in:
+54
-23
@@ -15,18 +15,16 @@
|
||||
*/
|
||||
package com.intellij.codeInspection;
|
||||
|
||||
import com.intellij.codeInsight.ChangeContextUtil;
|
||||
import com.intellij.codeInsight.daemon.GroupNames;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.HighlightControlFlowUtil;
|
||||
import com.intellij.codeInsight.intention.HighPriorityAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.RedundantCastUtil;
|
||||
import com.intellij.util.Function;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -74,7 +72,7 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaLocalInspectionTool
|
||||
final String functionalInterfaceErrorMessage = LambdaUtil.checkInterfaceFunctional(baseClassType);
|
||||
if (functionalInterfaceErrorMessage == null) {
|
||||
final PsiMethod[] methods = aClass.getMethods();
|
||||
if (methods.length == 1) {
|
||||
if (methods.length == 1 && aClass.getFields().length == 0) {
|
||||
final PsiCodeBlock body = methods[0].getBody();
|
||||
if (body != null) {
|
||||
final boolean [] bodyContainsForbiddenRefs = new boolean[1];
|
||||
@@ -128,7 +126,7 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaLocalInspectionTool
|
||||
if (element != null) {
|
||||
final PsiAnonymousClass anonymousClass = PsiTreeUtil.getParentOfType(element, PsiAnonymousClass.class);
|
||||
LOG.assertTrue(anonymousClass != null);
|
||||
|
||||
ChangeContextUtil.encodeContextInfo(anonymousClass, true);
|
||||
boolean validContext = LambdaUtil.isValidLambdaContext(anonymousClass.getParent().getParent());
|
||||
final String canonicalText = anonymousClass.getBaseClassType().getCanonicalText();
|
||||
final PsiMethod method = anonymousClass.getMethods()[0];
|
||||
@@ -139,25 +137,69 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaLocalInspectionTool
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
|
||||
PsiLambdaExpression lambdaExpression =
|
||||
(PsiLambdaExpression)elementFactory.createExpressionFromText(withoutTypesDeclared, anonymousClass);
|
||||
|
||||
final PsiCodeBlock body = method.getBody();
|
||||
LOG.assertTrue(body != null);
|
||||
final PsiStatement[] statements = body.getStatements();
|
||||
PsiElement copy = body.copy();
|
||||
if (statements.length == 1 && statements[0] instanceof PsiReturnStatement) {
|
||||
PsiExpression value = ((PsiReturnStatement)statements[0]).getReturnValue();
|
||||
if (value != null) {
|
||||
copy = value.copy();
|
||||
}
|
||||
}
|
||||
|
||||
PsiElement lambdaBody = lambdaExpression.getBody();
|
||||
LOG.assertTrue(lambdaBody != null);
|
||||
lambdaBody.replace(copy);
|
||||
|
||||
final PsiNewExpression newExpression = (PsiNewExpression)anonymousClass.getParent();
|
||||
lambdaExpression = (PsiLambdaExpression)newExpression.replace(lambdaExpression);
|
||||
ChangeContextUtil.decodeContextInfo(lambdaExpression, null, null);
|
||||
if (!validContext) {
|
||||
lambdaExpression.replace(elementFactory.createExpressionFromText("((" + canonicalText + ")" + withoutTypesDeclared + ")", lambdaExpression));
|
||||
final PsiParenthesizedExpression typeCast =
|
||||
(PsiParenthesizedExpression)elementFactory.createExpressionFromText("((" + canonicalText + ")" + withoutTypesDeclared + ")", lambdaExpression);
|
||||
final PsiExpression typeCastExpr = typeCast.getExpression();
|
||||
LOG.assertTrue(typeCastExpr != null);
|
||||
final PsiExpression typeCastOperand = ((PsiTypeCastExpression)typeCastExpr).getOperand();
|
||||
LOG.assertTrue(typeCastOperand != null);
|
||||
final PsiElement fromText = ((PsiLambdaExpression)typeCastOperand).getBody();
|
||||
LOG.assertTrue(fromText != null);
|
||||
lambdaBody = lambdaExpression.getBody();
|
||||
LOG.assertTrue(lambdaBody != null);
|
||||
fromText.replace(lambdaBody);
|
||||
lambdaExpression.replace(typeCast);
|
||||
return;
|
||||
}
|
||||
|
||||
PsiType interfaceType = lambdaExpression.getFunctionalInterfaceType();
|
||||
if (isInferenced(lambdaExpression, interfaceType)) {
|
||||
lambdaExpression = (PsiLambdaExpression)lambdaExpression.replace(elementFactory.createExpressionFromText(lambdaWithTypesDeclared, lambdaExpression));
|
||||
if (isInferred(lambdaExpression, interfaceType)) {
|
||||
final PsiLambdaExpression withTypes =
|
||||
(PsiLambdaExpression)elementFactory.createExpressionFromText(lambdaWithTypesDeclared, lambdaExpression);
|
||||
final PsiElement withTypesBody = withTypes.getBody();
|
||||
LOG.assertTrue(withTypesBody != null);
|
||||
lambdaBody = lambdaExpression.getBody();
|
||||
LOG.assertTrue(lambdaBody != null);
|
||||
withTypesBody.replace(lambdaBody);
|
||||
lambdaExpression = (PsiLambdaExpression)lambdaExpression.replace(withTypes);
|
||||
|
||||
interfaceType = lambdaExpression.getFunctionalInterfaceType();
|
||||
if (isInferenced(lambdaExpression, interfaceType)) {
|
||||
lambdaExpression.replace(elementFactory.createExpressionFromText("(" + canonicalText + ")" + withoutTypesDeclared, lambdaExpression));
|
||||
if (isInferred(lambdaExpression, interfaceType)) {
|
||||
final PsiTypeCastExpression typeCast = (PsiTypeCastExpression)elementFactory.createExpressionFromText("(" + canonicalText + ")" + withoutTypesDeclared, lambdaExpression);
|
||||
final PsiExpression typeCastOperand = typeCast.getOperand();
|
||||
LOG.assertTrue(typeCastOperand instanceof PsiLambdaExpression);
|
||||
final PsiElement fromText = ((PsiLambdaExpression)typeCastOperand).getBody();
|
||||
LOG.assertTrue(fromText != null);
|
||||
lambdaBody = lambdaExpression.getBody();
|
||||
LOG.assertTrue(lambdaBody != null);
|
||||
fromText.replace(lambdaBody);
|
||||
lambdaExpression.replace(typeCast);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isInferenced(PsiLambdaExpression lambdaExpression, PsiType interfaceType) {
|
||||
private static boolean isInferred(PsiLambdaExpression lambdaExpression, PsiType interfaceType) {
|
||||
return interfaceType == null || !LambdaUtil.isLambdaFullyInferred(lambdaExpression, interfaceType) || LambdaUtil.checkInterfaceFunctional(interfaceType) != null;
|
||||
}
|
||||
|
||||
@@ -185,18 +227,7 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaLocalInspectionTool
|
||||
buf.append(")");
|
||||
}
|
||||
}
|
||||
buf.append("->");
|
||||
final PsiCodeBlock body = method.getBody();
|
||||
LOG.assertTrue(body != null);
|
||||
final PsiStatement[] statements = body.getStatements();
|
||||
if (statements.length == 1 && statements[0] instanceof PsiReturnStatement) {
|
||||
PsiExpression value = ((PsiReturnStatement)statements[0]).getReturnValue();
|
||||
if (value != null) {
|
||||
buf.append(value.getText());
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
buf.append(body.getText());
|
||||
buf.append("-> {}");
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
|
||||
+7
-7
@@ -2,13 +2,13 @@
|
||||
class Test {
|
||||
{
|
||||
Comparable<String> c = o -> {
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
System.out.println(o);
|
||||
}
|
||||
};
|
||||
return 0;
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
System.out.println(o);
|
||||
}
|
||||
};
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
class Test {
|
||||
{
|
||||
Comparable<String> c = o -> {
|
||||
System.out.println();
|
||||
return 0;
|
||||
System.out.println();
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// "Replace with lambda" "true"
|
||||
class Test {
|
||||
interface I {
|
||||
|
||||
}
|
||||
interface Bar extends I {
|
||||
int smth = 0;
|
||||
int compare(String o1, String o2);
|
||||
}
|
||||
{
|
||||
I bar2 = (Bar) (o1, o2) -> {
|
||||
System.out.println(Bar.smth);
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
class Test {
|
||||
{
|
||||
Runnable r = () -> {
|
||||
System.out.println("");
|
||||
System.out.println("");
|
||||
};
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
class Test {
|
||||
{
|
||||
Runnable[] r = new Runnable[] {() -> {
|
||||
System.out.println("");
|
||||
System.out.println("");
|
||||
}};
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// "Replace with lambda" "false"
|
||||
class Test {
|
||||
interface I {
|
||||
|
||||
}
|
||||
interface Bar extends I {
|
||||
int compare(String o1, String o2);
|
||||
}
|
||||
{
|
||||
I bar2 = new Ba<caret>r() {
|
||||
int k;
|
||||
@Override
|
||||
public int compare(String o1, String o2) {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
// "Replace with lambda" "true"
|
||||
class Test {
|
||||
interface I {
|
||||
|
||||
}
|
||||
interface Bar extends I {
|
||||
int smth = 0;
|
||||
int compare(String o1, String o2);
|
||||
}
|
||||
{
|
||||
I bar2 = new Ba<caret>r() {
|
||||
@Override
|
||||
public int compare(String o1, String o2) {
|
||||
System.out.println(smth);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user