mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-13 21:55:01 +07:00
StreamToLoopInspection: disable elements which type is PsiIntersection type or PsiImmediateClassType which is not resolvable in outer context (fixes EA-97901); better diagnostic for cases like EA-97901
This commit is contained in:
@@ -420,11 +420,14 @@ abstract class FunctionHelper {
|
||||
PsiTypeCastExpression castExpr = (PsiTypeCastExpression)lambdaExpression.getBody();
|
||||
LOG.assertTrue(castExpr != null);
|
||||
methodRef = (PsiMethodReferenceExpression)castExpr.getOperand();
|
||||
LOG.assertTrue(methodRef != null);
|
||||
}
|
||||
}
|
||||
}
|
||||
PsiLambdaExpression lambda = LambdaRefactoringUtil.convertMethodReferenceToLambda(methodRef, true, true);
|
||||
LOG.assertTrue(lambda != null);
|
||||
if(lambda == null) {
|
||||
throw new IllegalStateException("Unable to convert method reference to lambda: "+methodRef.getText());
|
||||
}
|
||||
PsiElement body = lambda.getBody();
|
||||
LOG.assertTrue(body instanceof PsiExpression);
|
||||
myExpression = (PsiExpression)body;
|
||||
|
||||
+18
-5
@@ -29,6 +29,7 @@ import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.impl.PsiDiamondTypeUtil;
|
||||
import com.intellij.psi.impl.source.PsiImmediateClassType;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
@@ -164,10 +165,7 @@ public class StreamToLoopInspection extends BaseJavaBatchLocalInspectionTool {
|
||||
PsiExpression qualifier = call.getMethodExpression().getQualifierExpression();
|
||||
if(qualifier != null) {
|
||||
PsiType elementType = StreamApiUtil.getStreamElementType(qualifier.getType());
|
||||
if(elementType == null || ((elementType instanceof PsiClassType) && ((PsiClassType)elementType).isRaw())) {
|
||||
// Raw type in any stream step is not supported
|
||||
return null;
|
||||
}
|
||||
if (!isValidElementType(elementType, call)) return null;
|
||||
Operation op = Operation.createIntermediate(name, args, outVar, elementType, supportUnknownSources);
|
||||
if (op != null) return op;
|
||||
op = TerminalOperation.createTerminal(name, args, elementType, callType, isVoidContext(call.getParent()));
|
||||
@@ -178,6 +176,21 @@ public class StreamToLoopInspection extends BaseJavaBatchLocalInspectionTool {
|
||||
return SourceOperation.createSource(call, supportUnknownSources);
|
||||
}
|
||||
|
||||
private static boolean isValidElementType(PsiType elementType, PsiElement context) {
|
||||
if(elementType == null || ((elementType instanceof PsiClassType) && ((PsiClassType)elementType).isRaw())) {
|
||||
// Raw type in any stream step is not supported
|
||||
return false;
|
||||
}
|
||||
if(elementType instanceof PsiImmediateClassType) {
|
||||
PsiType typeFromText =
|
||||
JavaPsiFacade.getElementFactory(context.getProject()).createTypeFromText(elementType.getCanonicalText(), context);
|
||||
if(!(typeFromText instanceof PsiClassType) || ((PsiClassType)typeFromText).resolve() == null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isVoidContext(PsiElement element) {
|
||||
return element instanceof PsiExpressionStatement ||
|
||||
(element instanceof PsiLambdaExpression &&
|
||||
@@ -198,7 +211,7 @@ public class StreamToLoopInspection extends BaseJavaBatchLocalInspectionTool {
|
||||
FunctionHelper fn = FunctionHelper.create(args[0], 1, true);
|
||||
if (fn == null) return null;
|
||||
PsiType elementType = PsiUtil.substituteTypeParameter(type, CommonClassNames.JAVA_LANG_ITERABLE, 0, false);
|
||||
if(elementType == null) return null;
|
||||
if(!isValidElementType(elementType, terminalCall)) return null;
|
||||
elementType = GenericsUtil.getVariableTypeByExpressionType(elementType);
|
||||
TerminalOperation terminal = new TerminalOperation.ForEachTerminalOperation(fn);
|
||||
SourceOperation source = new SourceOperation.ForEachSource(qualifier);
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// "Replace Stream API chain with loop" "false"
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class Test {
|
||||
interface A {void a();}
|
||||
interface B {void b();}
|
||||
|
||||
public void test(Object obj) {
|
||||
Stream.of((A & B) obj).fo<caret>rEach(B::b);
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// "Replace Stream API chain with loop" "false"
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Main {
|
||||
public void test2(List<? extends CharSequence> list) {
|
||||
list.stream().map(String::length).for<caret>Each(System.out::println);
|
||||
}
|
||||
}
|
||||
@@ -50,6 +50,9 @@ public class StreamApiUtil {
|
||||
}
|
||||
PsiType streamType = PsiUtil.substituteTypeParameter(type, CommonClassNames.JAVA_UTIL_STREAM_STREAM, 0, false);
|
||||
if (variableType) {
|
||||
if (streamType instanceof PsiIntersectionType) {
|
||||
return null;
|
||||
}
|
||||
streamType = GenericsUtil.getVariableTypeByExpressionType(streamType);
|
||||
}
|
||||
return streamType;
|
||||
|
||||
Reference in New Issue
Block a user