mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
be optimistic, even complex CFG may result in fast DFA
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+18
-1
@@ -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(); }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user