mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
[java-slice] Support Optional tracking (IDEA-189788)
GitOrigin-RevId: b2df50d27bc69c3d01059a0fc2dba6fb1926891a
This commit is contained in:
committed by
intellij-monorepo-bot
parent
25128f2ba9
commit
aa5d05cb34
@@ -118,6 +118,12 @@ class SliceUsageCellRenderer extends SliceUsageCellRendererBase {
|
||||
else if (element instanceof PsiReference) {
|
||||
name = ((PsiReference)element).getCanonicalText();
|
||||
}
|
||||
else if (element instanceof PsiExpression) {
|
||||
PsiType type = ((PsiExpression)element).getType();
|
||||
if (type != null) {
|
||||
name = type.getPresentableText();
|
||||
}
|
||||
}
|
||||
prev = usage;
|
||||
usage = (JavaSliceUsage)usage.getParent();
|
||||
}
|
||||
|
||||
@@ -151,19 +151,20 @@ final class SliceUtil {
|
||||
}
|
||||
}
|
||||
if (expression instanceof PsiMethodCallExpression) { // ctr call can't return value or be container get, so don't use PsiCall here
|
||||
PsiExpression returnedValue = JavaMethodContractUtil.findReturnedValue((PsiMethodCallExpression)expression);
|
||||
PsiMethodCallExpression call = (PsiMethodCallExpression)expression;
|
||||
PsiExpression returnedValue = JavaMethodContractUtil.findReturnedValue(call);
|
||||
if (returnedValue != null) {
|
||||
if (!builder.process(returnedValue, processor)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
PsiMethod method = ((PsiMethodCallExpression)expression).resolveMethod();
|
||||
PsiMethod method = call.resolveMethod();
|
||||
Flow anno = method == null ? null : isMethodFlowAnnotated(method);
|
||||
if (anno != null) {
|
||||
String target = anno.target();
|
||||
if (target.equals(Flow.DEFAULT_TARGET)) target = Flow.RETURN_METHOD_TARGET;
|
||||
if (target.equals(Flow.RETURN_METHOD_TARGET)) {
|
||||
PsiExpression qualifier = ((PsiMethodCallExpression)expression).getMethodExpression().getQualifierExpression();
|
||||
PsiExpression qualifier = call.getMethodExpression().getQualifierExpression();
|
||||
if (qualifier != null) {
|
||||
builder = builder.updateNesting(anno);
|
||||
String source = anno.source();
|
||||
@@ -173,7 +174,25 @@ final class SliceUtil {
|
||||
}
|
||||
}
|
||||
}
|
||||
return processMethodReturnValue((PsiMethodCallExpression)expression, processor, builder);
|
||||
if (method != null && builder.hasNesting()) {
|
||||
PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
boolean hasFlownParameter = false;
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
Flow paramAnno = isParamFlowAnnotated(method, i);
|
||||
if (paramAnno != null && !parameters[i].isVarArgs()) {
|
||||
PsiExpression[] args = call.getArgumentList().getExpressions();
|
||||
if (args.length > i) {
|
||||
JavaSliceBuilder argBuilder = builder.updateNesting(paramAnno);
|
||||
if (!argBuilder.process(args[i], processor)) {
|
||||
return false;
|
||||
}
|
||||
hasFlownParameter = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hasFlownParameter) return true;
|
||||
}
|
||||
return processMethodReturnValue(call, processor, builder);
|
||||
}
|
||||
if (expression instanceof PsiConditionalExpression) {
|
||||
PsiConditionalExpression conditional = (PsiConditionalExpression)expression;
|
||||
|
||||
+3
-2
@@ -1,5 +1,3 @@
|
||||
import javax.swing.*;
|
||||
|
||||
class Foo {
|
||||
void foo(String <caret>s) {
|
||||
}
|
||||
@@ -14,4 +12,7 @@ class Foo {
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
class SwingUtilities {
|
||||
static void invokeLater(Runnable runnable) {}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import java.util.Optional;
|
||||
|
||||
class MainTest {
|
||||
public static void main(String[] <flown1111>args) {
|
||||
Optional<String> optional;
|
||||
if (args.length > 0) {
|
||||
optional = <flown11>Optional.ofNullable(<flown111>args[0]);
|
||||
} else {
|
||||
optional = <flown12>Optional.of(<flown121>"foo");
|
||||
}
|
||||
String val = <flown1>optional.orElse(<flown13>"xyz");
|
||||
System.out.println(<caret>val);
|
||||
}
|
||||
}
|
||||
@@ -19,10 +19,13 @@ import com.intellij.analysis.AnalysisScope;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.execution.filters.ExceptionAnalysisProvider;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.slicer.*;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.intellij.testFramework.PsiTestUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -32,6 +35,11 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SliceBackwardTest extends SliceTestCase {
|
||||
@Override
|
||||
protected Sdk getTestProjectJdk() {
|
||||
return PsiTestUtil.addJdkAnnotations(IdeaTestUtil.getMockJdk11());
|
||||
}
|
||||
|
||||
private void doTest() throws Exception {
|
||||
doTest("");
|
||||
}
|
||||
@@ -110,7 +118,7 @@ public class SliceBackwardTest extends SliceTestCase {
|
||||
public void testAppend() throws Exception { doTest();}
|
||||
public void testRequireNonNull() throws Exception { doTest();}
|
||||
public void testBackAndForward() throws Exception { doTest();}
|
||||
|
||||
|
||||
public void testFilterIntRange() throws Exception { doTest(">=0");}
|
||||
public void testFilterIntRangeArray() throws Exception { doTest(">=0");}
|
||||
public void testFilterNull() throws Exception { doTest("null");}
|
||||
@@ -122,20 +130,21 @@ public class SliceBackwardTest extends SliceTestCase {
|
||||
public void testReturnParameter() throws Exception { doTest(); }
|
||||
public void testFilterLongByInt() throws Exception { doTest("<=0"); }
|
||||
public void testFilterDoubleByInt() throws Exception { doTest("0.0"); }
|
||||
|
||||
public void testStackFilterSimple() throws Exception {
|
||||
|
||||
public void testStackFilterSimple() throws Exception {
|
||||
doTest("null", "MainTest:test", "MainTest:foo", "MainTest:main");
|
||||
}
|
||||
|
||||
|
||||
public void testStackFilterBridgeMethod() throws Exception {
|
||||
doTest("null", "MainTest$Bar:get", "MainTest$Bar:get", "MainTest:bar", "MainTest:main");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void testStackFilterBridgeMethod2() throws Exception {
|
||||
doTest("null", "MainTest$Bar:get", "MainTest$Bar:get", "MainTest:bar", "MainTest:main");
|
||||
}
|
||||
|
||||
|
||||
public void testRecordComponent() throws Exception { doTest();}
|
||||
public void testRecordComponent2() throws Exception { doTest();}
|
||||
public void testRecordComponent3() throws Exception { doTest();}
|
||||
public void testOptionalAsContainer() throws Exception { doTest();}
|
||||
}
|
||||
|
||||
@@ -3311,17 +3311,38 @@
|
||||
<val name="pure" val="true"/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item name='java.util.Optional java.util.Optional<T> of(T) 0'>
|
||||
<annotation name='org.intellij.lang.annotations.Flow'>
|
||||
<val name="targetIsContainer" val="true"/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item name='java.util.Optional java.util.Optional<T> ofNullable(T) 0'>
|
||||
<annotation name='org.intellij.lang.annotations.Flow'>
|
||||
<val name="targetIsContainer" val="true"/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item name='java.util.Optional T get()'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
<annotation name='org.jetbrains.annotations.Contract'>
|
||||
<val name="pure" val="true"/>
|
||||
</annotation>
|
||||
<annotation name='org.intellij.lang.annotations.Flow'>
|
||||
<val name="sourceIsContainer" val="true"/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item name='java.util.Optional T orElse(T)'>
|
||||
<annotation name='org.jetbrains.annotations.Contract'>
|
||||
<val name="value" val=""!null -> !null""/>
|
||||
<val name="pure" val="true"/>
|
||||
</annotation>
|
||||
<annotation name='org.intellij.lang.annotations.Flow'>
|
||||
<val name="sourceIsContainer" val="true"/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item name='java.util.Optional T orElse(T) 0'>
|
||||
<annotation name='org.intellij.lang.annotations.Flow'>
|
||||
<val name="targetIsContainer" val="true"/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item name='java.util.Properties java.lang.String getProperty(java.lang.String) 0'>
|
||||
<annotation name='org.jetbrains.annotations.NonNls'/>
|
||||
|
||||
Reference in New Issue
Block a user