[java-inspections] IDEA-332629 Support Optional.stream() in DFA

- added inlining for Optional.stream, based n SpecialField.OPTIONAL_VALUE

GitOrigin-RevId: 50287ae63b11083c133f9af54373310bf1b818f8
This commit is contained in:
Mikhail Pyltsin
2023-09-18 23:01:32 +00:00
committed by intellij-monorepo-bot
parent 8463c0a81b
commit dced7d86d0
3 changed files with 66 additions and 0 deletions
@@ -924,6 +924,29 @@ public class StreamChainInliner implements CallInliner {
return;
}
}
if (OPTIONAL_STREAM.test(sourceCall)) {
PsiExpression qualifierExpression = sourceCall.getMethodExpression().getQualifierExpression();
if (qualifierExpression != null) {
PsiType optValueType = PsiUtil.substituteTypeParameter(qualifierExpression.getType(), JAVA_UTIL_OPTIONAL, 0, false);
if (optValueType != null) {
builder.pushExpression(qualifierExpression);
builder //optVar
.unwrap(SpecialField.OPTIONAL_VALUE) //optVar.value
.pushForWrite(builder.createTempVariable(qualifierExpression.getType()))//optVar.value optValueVar
.swap() //optValueVar optVar.value
.assign() //optValueVar
.dup() //optValueVar optValueVar
.chain(firstStep::before)
.ifNull() //optValueVar
// skip loop at all
.pop() //..
.elseBranch() //optValueVar
.chain(firstStep::iteration)
.end();
return;
}
}
}
startStreamUnknown(builder, firstStep, originalQualifier, originalQualifierAlreadyChecked, inType);
}
@@ -0,0 +1,41 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.function.*;
import java.util.stream.*;
public class OptionalStreamInlining {
public static void testOptionalStream(String s) {
Optional<List<String>> strings = Optional.ofNullable(s)
.map(OptionalStreamInlining::getLetters);
Optional<String> s1 = strings
.stream()
.flatMap(Collection::stream)
.min(Comparator.naturalOrder());
if (s1.isPresent()) {
System.out.println(s.length());
} else {
System.out.println();
System.out.println(s.<warning descr="Method invocation 'length' may produce 'NullPointerException'">length</warning>());
}
}
public static void testOptionalStream2(String s) {
Optional<String> s1 = Optional.ofNullable(s)
.map(OptionalStreamInlining::getLetters)
.stream()
.flatMap(Collection::stream)
.min(Comparator.naturalOrder());
if (s1.isPresent()) {
System.out.println(s.length());
} else {
System.out.println();
System.out.println(s.<warning descr="Method invocation 'length' may produce 'NullPointerException'">length</warning>());
}
}
private static List<String> getLetters(String t){
ArrayList<String> strings = new ArrayList<>();
strings.add("1");
return strings;
}
}
@@ -22,4 +22,6 @@ public class DataFlowInspection9Test extends DataFlowInspectionTestCase {
public void testMutabilityInferred() { doTest(); }
public void testObjectsRequireNonNullElse() { doTest(); }
public void testNewCollectionAliasing() { doTest(); }
public void testOptionalStreamInlining() { doTest(); }
}