mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-30 10:20:15 +07:00
use lambda to avoid context remapping (IDEA-185448)
for anonymous class this expressions have to be encoded to point to outer class, for lambda expressions there is no need for that. Leave unchanged (array initializer) for old java versions
This commit is contained in:
@@ -4,7 +4,6 @@
|
||||
package com.intellij.psi;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.RecursionGuard;
|
||||
import com.intellij.openapi.util.RecursionManager;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
@@ -17,7 +16,6 @@ import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.Producer;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import java.util.HashMap;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -980,18 +978,29 @@ public class LambdaUtil {
|
||||
}
|
||||
|
||||
public static PsiElement copyWithExpectedType(PsiElement expression, PsiType type) {
|
||||
final String objectWithMethod = "new Object() { " + type.getCanonicalText() + " get(){ return x;}}";
|
||||
final Project project = expression.getProject();
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory();
|
||||
PsiNewExpression newExpr = (PsiNewExpression)elementFactory.createExpressionFromText(objectWithMethod, expression);
|
||||
String canonicalText = type.getCanonicalText();
|
||||
if (!PsiUtil.isLanguageLevel8OrHigher(expression)) {
|
||||
final String arrayInitializer = "new " + canonicalText + "[]{0}";
|
||||
PsiNewExpression newExpr = (PsiNewExpression)createExpressionFromText(arrayInitializer, expression);
|
||||
final PsiArrayInitializerExpression initializer = newExpr.getArrayInitializer();
|
||||
LOG.assertTrue(initializer != null);
|
||||
return initializer.getInitializers()[0].replace(expression);
|
||||
}
|
||||
|
||||
final String callableWithExpectedType = "(java.util.concurrent.Callable<" + canonicalText + ">)() -> x";
|
||||
PsiTypeCastExpression typeCastExpr = (PsiTypeCastExpression)createExpressionFromText(callableWithExpectedType, expression);
|
||||
PsiLambdaExpression lambdaExpression = (PsiLambdaExpression)typeCastExpr.getOperand();
|
||||
LOG.assertTrue(lambdaExpression != null);
|
||||
PsiElement body = lambdaExpression.getBody();
|
||||
LOG.assertTrue(body instanceof PsiExpression);
|
||||
return body.replace(expression);
|
||||
}
|
||||
|
||||
private static PsiExpression createExpressionFromText(String exprText, PsiElement context) {
|
||||
PsiExpression expr = JavaPsiFacade.getInstance(context.getProject())
|
||||
.getElementFactory()
|
||||
.createExpressionFromText(exprText, context);
|
||||
//ensure refs to inner classes are collapsed to avoid raw types (container type would be raw in qualified text)
|
||||
newExpr = (PsiNewExpression)JavaCodeStyleManager.getInstance(project).shortenClassReferences(newExpr);
|
||||
PsiAnonymousClass anonymousClass = newExpr.getAnonymousClass();
|
||||
LOG.assertTrue(anonymousClass != null);
|
||||
PsiCodeBlock body = anonymousClass.getMethods()[0].getBody();
|
||||
LOG.assertTrue(body != null);
|
||||
PsiExpression returnValue = ((PsiReturnStatement)body.getStatements()[0]).getReturnValue();
|
||||
LOG.assertTrue(returnValue != null);
|
||||
return returnValue.replace(expression);
|
||||
return (PsiExpression)JavaCodeStyleManager.getInstance(context.getProject()).shortenClassReferences(expr);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
|
||||
import java.util.*;
|
||||
|
||||
class Test {
|
||||
private final Collection<Integer> collection = new ArrayList<>();
|
||||
|
||||
{
|
||||
List<Integer> l = Collections.unmodifiableList((List<Integer>)this.collection);
|
||||
System.out.println(l);
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,7 @@ public class LambdaRedundantCastTest extends LightDaemonAnalyzerTestCase {
|
||||
public void testSer() { doTest(); }
|
||||
public void testLambdaReturnExpressions() { doTest(); }
|
||||
public void testLambdaReturnExpressions1() { doTest(); }
|
||||
public void testPreserveThisContext() { doTest(); }
|
||||
public void testPreventBadReturnTypeInReturnExpression() { doTest(); }
|
||||
public void testExpectedTypeByNestedArrayInitializer() { doTest(); }
|
||||
public void testCastToPrimitive() {
|
||||
|
||||
Reference in New Issue
Block a user