mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-169542 'Analyze Dataflow to Here' misses assignment to variables passed to anonymous classes
This commit is contained in:
@@ -61,14 +61,11 @@ class SliceUsageCellRenderer extends SliceUsageCellRendererBase {
|
||||
}
|
||||
}
|
||||
|
||||
if (javaSliceUsage != null) {
|
||||
for (int i = 0; i < javaSliceUsage.indexNesting; i++) {
|
||||
append(
|
||||
" (Tracking container contents" +
|
||||
(javaSliceUsage.syntheticField.isEmpty() ? "" : " '" + javaSliceUsage.syntheticField + "'") +
|
||||
")",
|
||||
SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
|
||||
}
|
||||
if (javaSliceUsage != null && javaSliceUsage.indexNesting != 0) {
|
||||
append(
|
||||
" (Tracking container '" + getContainerName(javaSliceUsage) +
|
||||
(javaSliceUsage.syntheticField.isEmpty() ? "" : "." + javaSliceUsage.syntheticField) + "' contents)",
|
||||
SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
|
||||
}
|
||||
|
||||
PsiElement element = sliceUsage.getElement();
|
||||
@@ -101,5 +98,28 @@ class SliceUsageCellRenderer extends SliceUsageCellRendererBase {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getContainerName(@NotNull JavaSliceUsage usage) {
|
||||
String result = "";
|
||||
JavaSliceUsage prev = usage;
|
||||
String name = "";
|
||||
while (usage != null) {
|
||||
if (usage.indexNesting != prev.indexNesting) {
|
||||
result = name + (result.isEmpty() ? "" : ".") + result;
|
||||
if (usage.indexNesting == 0) break;
|
||||
}
|
||||
PsiElement element = usage.getElement();
|
||||
if (element instanceof PsiNamedElement) {
|
||||
name = ((PsiNamedElement)element).getName();
|
||||
}
|
||||
else if (element instanceof PsiReference) {
|
||||
name = ((PsiReference)element).getCanonicalText();
|
||||
}
|
||||
prev = usage;
|
||||
usage = (JavaSliceUsage)usage.getParent();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.slicer;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInspection.dataFlow.DfaPsiUtil;
|
||||
import com.intellij.codeInspection.dataFlow.DfaUtil;
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
@@ -42,10 +43,7 @@ import org.intellij.lang.annotations.Flow;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author cdr
|
||||
@@ -117,11 +115,20 @@ class SliceUtil {
|
||||
SliceUsage stopUsage = createTooComplexDFAUsage(expression, parent);
|
||||
return processor.process(stopUsage);
|
||||
}
|
||||
final Set<PsiExpression> expressions = new THashSet<>(values);
|
||||
PsiExpression initializer = variable.getInitializer();
|
||||
if (initializer != null && expressions.isEmpty()) expressions.add(initializer);
|
||||
if (values.isEmpty() && initializer != null) {
|
||||
values = Collections.singletonList(initializer);
|
||||
}
|
||||
boolean initializerReported = false;
|
||||
for (PsiExpression exp : expressions) {
|
||||
// no need to search and report assignments if we are going to report the variable anyway - it would create duplicate nodes if we did
|
||||
if (values.isEmpty() && !(variable instanceof PsiParameter) && !needToReportDeclaration) {
|
||||
values = DfaPsiUtil.getVariableAssignmentsInFile(variable, false, variable.getContainingFile().getLastChild());
|
||||
initializerReported = !values.isEmpty();
|
||||
}
|
||||
else if (!values.isEmpty() && !(variable instanceof PsiParameter)) {
|
||||
needToReportDeclaration = false; // already found all values
|
||||
}
|
||||
for (PsiExpression exp : values) {
|
||||
if (!handToProcessor(exp, processor, parent, parentSubstitutor, indexNesting, syntheticField)) return false;
|
||||
if (exp == initializer) initializerReported = true;
|
||||
}
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
import javax.swing.*;
|
||||
|
||||
class Foo {
|
||||
void foo(String <caret>s) {
|
||||
}
|
||||
|
||||
void bar() {
|
||||
final String <flown11>res;
|
||||
res = <flown111>"a";
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
foo(<flown1>res);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
class Foo1 {
|
||||
void foo() {
|
||||
String <caret>s = <flown1>bar();
|
||||
}
|
||||
|
||||
String bar() {
|
||||
String res;
|
||||
res = <flown111>"a";
|
||||
return <flown11>res;
|
||||
}
|
||||
}
|
||||
@@ -81,4 +81,6 @@ public class SliceBackwardTest extends SliceTestCase {
|
||||
|
||||
public void testListTrackToArray() throws Exception { doTest();}
|
||||
public void testTryCatchFinally() throws Exception { doTest();}
|
||||
public void testFinalVarAssignedBeforePassingToAnonymous() throws Exception { doTest();}
|
||||
public void testLocalVarDeclarationAndAssignment() throws Exception { doTest();}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user