be optimistic, even complex CFG may result in fast DFA

This commit is contained in:
peter
2012-03-16 19:29:43 +04:00
parent a24c4a1c89
commit efab68f1ca
3 changed files with 85 additions and 8 deletions
@@ -32,6 +32,7 @@ import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
import gnu.trove.THashSet;
@@ -42,7 +43,8 @@ import java.util.*;
public class DataFlowRunner {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.dataFlow.DataFlowRunner");
private static final long ourTimeLimit = 10000;
private static final Key<Integer> TOO_EXPENSIVE_SIZE = Key.create("TOO_EXPENSIVE_SIZE");
private static final long ourTimeLimit = 1000;
private Instruction[] myInstructions;
private DfaVariableValue[] myFields;
@@ -107,13 +109,11 @@ public class DataFlowRunner {
}
}
int branchCount = 0;
for (Instruction instruction : myInstructions) {
if (instruction instanceof BranchingInstruction) branchCount++;
Integer tooExpensiveSize = psiBlock.getUserData(TOO_EXPENSIVE_SIZE);
if (tooExpensiveSize != null && tooExpensiveSize == psiBlock.getTextLength()) {
return RunnerResult.TOO_COMPLEX;
}
if (branchCount > 80) return RunnerResult.TOO_COMPLEX; // Do not even try. Definitely will out of time.
final ArrayList<DfaInstructionState> queue = new ArrayList<DfaInstructionState>();
for (final DfaMemoryState initialState : initialStates) {
queue.add(new DfaInstructionState(myInstructions[0], initialState));
@@ -124,7 +124,10 @@ public class DataFlowRunner {
final long before = System.currentTimeMillis();
int count = 0;
while (!queue.isEmpty()) {
if (count % 50 == 0 && !unitTestMode && System.currentTimeMillis() - before > timeLimit) return RunnerResult.TOO_COMPLEX;
if (count % 50 == 0 && !unitTestMode && System.currentTimeMillis() - before > timeLimit) {
psiBlock.putUserData(TOO_EXPENSIVE_SIZE, psiBlock.getTextLength());
return RunnerResult.TOO_COMPLEX;
}
ProgressManager.checkCanceled();
DfaInstructionState instructionState = queue.remove(0);
@@ -155,6 +158,7 @@ public class DataFlowRunner {
count++;
}
psiBlock.putUserData(TOO_EXPENSIVE_SIZE, null);
return RunnerResult.OK;
}
catch (ArrayIndexOutOfBoundsException e) {
@@ -0,0 +1,56 @@
public abstract class DDD {
abstract boolean condition();
abstract Object foo();
abstract Object bar();
void test(Object o, DDD another) {
try {
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
System.out.println(condition() && equals(o) ? another.foo() : another.bar());
}
catch (Exception e) {
System.out.println(e);
}
}
}
@@ -1,3 +1,18 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInspection;
import com.intellij.JavaTestUtil;
@@ -23,7 +38,7 @@ public class DataFlowInspectionFixtureTest extends JavaCodeInsightFixtureTestCas
final DataFlowInspection inspection = new DataFlowInspection();
inspection.SUGGEST_NULLABLE_ANNOTATIONS = true;
myFixture.enableInspections(inspection);
myFixture.testHighlighting(true, false, false, getTestName(false) + ".java");
myFixture.testHighlighting(true, false, true, getTestName(false) + ".java");
}
public void testTryInAnonymous() throws Throwable { doTest(); }
@@ -35,4 +50,6 @@ public class DataFlowInspectionFixtureTest extends JavaCodeInsightFixtureTestCas
public void testFieldInAnonymous() throws Throwable { doTest(); }
public void testNullableField() throws Throwable { doTest(); }
public void testCanBeNullDoesntImplyIsNull() throws Throwable { doTest(); }
public void testBigMethodNotComplex() throws Throwable { doTest(); }
}