mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
arrays and primitive collections
(annotations.xml was changed because the order of graph construction was changed - this particular case is a tricky one with loop, exception and synchronization)
This commit is contained in:
+2
-3
@@ -205,10 +205,9 @@ class ProceedState<Res> implements PendingAction<Res> {
|
||||
class MakeResult<Res> implements PendingAction<Res> {
|
||||
final State state;
|
||||
final Res subResult;
|
||||
final List<Integer> indices;
|
||||
final int[] indices;
|
||||
|
||||
// TODO - indices array
|
||||
MakeResult(State state, Res subResult, List<Integer> indices) {
|
||||
MakeResult(State state, Res subResult, int[] indices) {
|
||||
this.state = state;
|
||||
this.subResult = subResult;
|
||||
this.indices = indices;
|
||||
|
||||
+13
-11
@@ -144,7 +144,7 @@ class InOutAnalysis extends Analysis<Result<Key, Value>> {
|
||||
if (opcode == IFNONNULL && popValue(frame) instanceof ParamValue) {
|
||||
int nextInsnIndex = inValue == Value.Null ? insnIndex + 1 : methodNode.instructions.indexOf(((JumpInsnNode)insnNode).label);
|
||||
State nextState = new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, false);
|
||||
pending.push(new MakeResult<Result<Key, Value>>(state, myIdentity, Collections.singletonList(nextState.index)));
|
||||
pending.push(new MakeResult<Result<Key, Value>>(state, myIdentity, new int[]{nextState.index}));
|
||||
pending.push(new ProceedState<Result<Key, Value>>(nextState));
|
||||
return;
|
||||
}
|
||||
@@ -152,7 +152,7 @@ class InOutAnalysis extends Analysis<Result<Key, Value>> {
|
||||
if (opcode == IFNULL && popValue(frame) instanceof ParamValue) {
|
||||
int nextInsnIndex = inValue == Value.NotNull ? insnIndex + 1 : methodNode.instructions.indexOf(((JumpInsnNode)insnNode).label);
|
||||
State nextState = new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, false);
|
||||
pending.push(new MakeResult<Result<Key, Value>>(state, myIdentity, Collections.singletonList(nextState.index)));
|
||||
pending.push(new MakeResult<Result<Key, Value>>(state, myIdentity, new int[]{nextState.index}));
|
||||
pending.push(new ProceedState<Result<Key, Value>>(nextState));
|
||||
return;
|
||||
}
|
||||
@@ -160,7 +160,7 @@ class InOutAnalysis extends Analysis<Result<Key, Value>> {
|
||||
if (opcode == IFEQ && popValue(frame) == InstanceOfCheckValue && inValue == Value.Null) {
|
||||
int nextInsnIndex = methodNode.instructions.indexOf(((JumpInsnNode)insnNode).label);
|
||||
State nextState = new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, false);
|
||||
pending.push(new MakeResult<Result<Key, Value>>(state, myIdentity, Collections.singletonList(nextState.index)));
|
||||
pending.push(new MakeResult<Result<Key, Value>>(state, myIdentity, new int[]{nextState.index}));
|
||||
pending.push(new ProceedState<Result<Key, Value>>(nextState));
|
||||
return;
|
||||
}
|
||||
@@ -168,7 +168,7 @@ class InOutAnalysis extends Analysis<Result<Key, Value>> {
|
||||
if (opcode == IFNE && popValue(frame) == InstanceOfCheckValue && inValue == Value.Null) {
|
||||
int nextInsnIndex = insnIndex + 1;
|
||||
State nextState = new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, false);
|
||||
pending.push(new MakeResult<Result<Key, Value>>(state, myIdentity, Collections.singletonList(nextState.index)));
|
||||
pending.push(new MakeResult<Result<Key, Value>>(state, myIdentity, new int[]{nextState.index}));
|
||||
pending.push(new ProceedState<Result<Key, Value>>(nextState));
|
||||
return;
|
||||
}
|
||||
@@ -176,7 +176,7 @@ class InOutAnalysis extends Analysis<Result<Key, Value>> {
|
||||
if (opcode == IFEQ && popValue(frame) instanceof ParamValue) {
|
||||
int nextInsnIndex = inValue == Value.True ? insnIndex + 1 : methodNode.instructions.indexOf(((JumpInsnNode)insnNode).label);
|
||||
State nextState = new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, false);
|
||||
pending.push(new MakeResult<Result<Key, Value>>(state, myIdentity, Collections.singletonList(nextState.index)));
|
||||
pending.push(new MakeResult<Result<Key, Value>>(state, myIdentity, new int[]{nextState.index}));
|
||||
pending.push(new ProceedState<Result<Key, Value>>(nextState));
|
||||
return;
|
||||
}
|
||||
@@ -184,16 +184,18 @@ class InOutAnalysis extends Analysis<Result<Key, Value>> {
|
||||
if (opcode == IFNE && popValue(frame) instanceof ParamValue) {
|
||||
int nextInsnIndex = inValue == Value.False ? insnIndex + 1 : methodNode.instructions.indexOf(((JumpInsnNode)insnNode).label);
|
||||
State nextState = new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, false);
|
||||
pending.push(new MakeResult<Result<Key, Value>>(state, myIdentity, Collections.singletonList(nextState.index)));
|
||||
pending.push(new MakeResult<Result<Key, Value>>(state, myIdentity, new int[]{nextState.index}));
|
||||
pending.push(new ProceedState<Result<Key, Value>>(nextState));
|
||||
return;
|
||||
}
|
||||
|
||||
// general case
|
||||
List<Integer> nextInsnIndices = controlFlow.transitions[insnIndex];
|
||||
List<State> nextStates = new ArrayList<State>();
|
||||
List<Integer> subIndices = new ArrayList<Integer>();
|
||||
for (int nextInsnIndex : nextInsnIndices) {
|
||||
int[] nextInsnIndices = controlFlow.transitions[insnIndex];
|
||||
List<State> nextStates = new ArrayList<State>(nextInsnIndices.length);
|
||||
int[] subIndices = new int[nextInsnIndices.length];
|
||||
|
||||
for (int i = 0; i < nextInsnIndices.length; i++) {
|
||||
int nextInsnIndex = nextInsnIndices[i];
|
||||
Frame<BasicValue> nextFrame1 = nextFrame;
|
||||
if (controlFlow.errorTransitions.contains(new Edge(insnIndex, nextInsnIndex))) {
|
||||
nextFrame1 = new Frame<BasicValue>(frame);
|
||||
@@ -201,7 +203,7 @@ class InOutAnalysis extends Analysis<Result<Key, Value>> {
|
||||
nextFrame1.push(new BasicValue(Type.getType("java/lang/Throwable")));
|
||||
}
|
||||
nextStates.add(new State(++id, new Conf(nextInsnIndex, nextFrame1), nextHistory, taken, false));
|
||||
subIndices.add(id);
|
||||
subIndices[i] = id;
|
||||
}
|
||||
|
||||
pending.push(new MakeResult<Result<Key, Value>>(state, myIdentity, subIndices));
|
||||
|
||||
+19
-10
@@ -16,6 +16,7 @@
|
||||
package com.intellij.codeInspection.bytecodeAnalysis;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import gnu.trove.TIntArrayList;
|
||||
import gnu.trove.TIntHashSet;
|
||||
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode;
|
||||
import org.jetbrains.org.objectweb.asm.tree.InsnList;
|
||||
@@ -158,7 +159,7 @@ final class cfg {
|
||||
|
||||
// Graphs: Theory and Algorithms. by K. Thulasiraman , M. N. S. Swamy (1992)
|
||||
// 11.7.2 DFS of a directed graph
|
||||
static DFSTree buildDFSTree(List<Integer>[] transitions) {
|
||||
static DFSTree buildDFSTree(int[][] transitions) {
|
||||
Set<Edge> tree = new HashSet<Edge>();
|
||||
Set<Edge> forward = new HashSet<Edge>();
|
||||
Set<Edge> back = new HashSet<Edge>();
|
||||
@@ -307,10 +308,10 @@ final class Edge {
|
||||
final class ControlFlowGraph {
|
||||
final String className;
|
||||
final MethodNode methodNode;
|
||||
final List<Integer>[] transitions;
|
||||
final int[][] transitions;
|
||||
final Set<Edge> errorTransitions;
|
||||
|
||||
ControlFlowGraph(String className, MethodNode methodNode, List<Integer>[] transitions, Set<Edge> errorTransitions) {
|
||||
ControlFlowGraph(String className, MethodNode methodNode, int[][] transitions, Set<Edge> errorTransitions) {
|
||||
this.className = className;
|
||||
this.methodNode = methodNode;
|
||||
this.transitions = transitions;
|
||||
@@ -340,34 +341,42 @@ final class ControlFlowBuilder extends Analyzer<BasicValue> {
|
||||
static final BasicInterpreter INTERPRETER = new BasicInterpreter();
|
||||
final String className;
|
||||
final MethodNode methodNode;
|
||||
final LinkedList<Integer>[] transitions;
|
||||
final TIntArrayList[] transitions;
|
||||
final Set<Edge> errorTransitions;
|
||||
|
||||
ControlFlowBuilder(String className, MethodNode methodNode) {
|
||||
super(INTERPRETER);
|
||||
this.className = className;
|
||||
this.methodNode = methodNode;
|
||||
transitions = new LinkedList[methodNode.instructions.size()];
|
||||
transitions = new TIntArrayList[methodNode.instructions.size()];
|
||||
for (int i = 0; i < transitions.length; i++) {
|
||||
transitions[i] = new LinkedList<Integer>();
|
||||
transitions[i] = new TIntArrayList();
|
||||
}
|
||||
errorTransitions = new HashSet<Edge>();
|
||||
}
|
||||
|
||||
final ControlFlowGraph buildCFG() throws AnalyzerException {
|
||||
analyze(className, methodNode);
|
||||
return new ControlFlowGraph(className, methodNode, transitions, errorTransitions);
|
||||
int[][] resultTransitions = new int[transitions.length][];
|
||||
for (int i = 0; i < resultTransitions.length; i++) {
|
||||
resultTransitions[i] = transitions[i].toNativeArray();
|
||||
}
|
||||
return new ControlFlowGraph(className, methodNode, resultTransitions, errorTransitions);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void newControlFlowEdge(int insn, int successor) {
|
||||
transitions[insn].addFirst(successor);
|
||||
if (!transitions[insn].contains(successor)) {
|
||||
transitions[insn].add(successor);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final boolean newControlFlowExceptionEdge(int insn, int successor) {
|
||||
transitions[insn].addFirst(successor);
|
||||
errorTransitions.add(new Edge(insn, successor));
|
||||
if (!transitions[insn].contains(successor)) {
|
||||
transitions[insn].add(successor);
|
||||
errorTransitions.add(new Edge(insn, successor));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+11
-9
@@ -217,7 +217,7 @@ class NonNullInAnalysis extends Analysis<PResult> {
|
||||
if (opcode == IFNONNULL && popValue(frame) instanceof ParamValue) {
|
||||
int nextInsnIndex = insnIndex + 1;
|
||||
State nextState = new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, hasCompanions || notEmptySubResult);
|
||||
pending.push(new MakeResult<PResult>(state, subResult, Collections.singletonList(nextState.index)));
|
||||
pending.push(new MakeResult<PResult>(state, subResult, new int[]{nextState.index}));
|
||||
pending.push(new ProceedState<PResult>(nextState));
|
||||
return;
|
||||
}
|
||||
@@ -225,7 +225,7 @@ class NonNullInAnalysis extends Analysis<PResult> {
|
||||
if (opcode == IFNULL && popValue(frame) instanceof ParamValue) {
|
||||
int nextInsnIndex = methodNode.instructions.indexOf(((JumpInsnNode)insnNode).label);
|
||||
State nextState = new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, hasCompanions || notEmptySubResult);
|
||||
pending.push(new MakeResult<PResult>(state, subResult, Collections.singletonList(nextState.index)));
|
||||
pending.push(new MakeResult<PResult>(state, subResult, new int[]{nextState.index}));
|
||||
pending.push(new ProceedState<PResult>(nextState));
|
||||
return;
|
||||
}
|
||||
@@ -233,7 +233,7 @@ class NonNullInAnalysis extends Analysis<PResult> {
|
||||
if (opcode == IFEQ && popValue(frame) == InstanceOfCheckValue) {
|
||||
int nextInsnIndex = methodNode.instructions.indexOf(((JumpInsnNode)insnNode).label);
|
||||
State nextState = new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, hasCompanions || notEmptySubResult);
|
||||
pending.push(new MakeResult<PResult>(state, subResult, Collections.singletonList(nextState.index)));
|
||||
pending.push(new MakeResult<PResult>(state, subResult, new int[]{nextState.index}));
|
||||
pending.push(new ProceedState<PResult>(nextState));
|
||||
return;
|
||||
}
|
||||
@@ -241,16 +241,18 @@ class NonNullInAnalysis extends Analysis<PResult> {
|
||||
if (opcode == IFNE && popValue(frame) == InstanceOfCheckValue) {
|
||||
int nextInsnIndex = insnIndex + 1;
|
||||
State nextState = new State(++id, new Conf(nextInsnIndex, nextFrame), nextHistory, true, hasCompanions || notEmptySubResult);
|
||||
pending.push(new MakeResult<PResult>(state, subResult, Collections.singletonList(nextState.index)));
|
||||
pending.push(new MakeResult<PResult>(state, subResult, new int[]{nextState.index}));
|
||||
pending.push(new ProceedState<PResult>(nextState));
|
||||
return;
|
||||
}
|
||||
|
||||
// general case
|
||||
List<Integer> nextInsnIndices = controlFlow.transitions[insnIndex];
|
||||
List<State> nextStates = new ArrayList<State>();
|
||||
List<Integer> subIndices = new ArrayList<Integer>();
|
||||
for (int nextInsnIndex : nextInsnIndices) {
|
||||
int[] nextInsnIndices = controlFlow.transitions[insnIndex];
|
||||
List<State> nextStates = new ArrayList<State>(nextInsnIndices.length);
|
||||
int[] subIndices = new int[nextInsnIndices.length];
|
||||
|
||||
for (int i = 0; i < nextInsnIndices.length; i++) {
|
||||
int nextInsnIndex = nextInsnIndices[i];
|
||||
Frame<BasicValue> nextFrame1 = nextFrame;
|
||||
if (controlFlow.errorTransitions.contains(new Edge(insnIndex, nextInsnIndex))) {
|
||||
nextFrame1 = new Frame<BasicValue>(frame);
|
||||
@@ -258,7 +260,7 @@ class NonNullInAnalysis extends Analysis<PResult> {
|
||||
nextFrame1.push(new BasicValue(Type.getType("java/lang/Throwable")));
|
||||
}
|
||||
nextStates.add(new State(++id, new Conf(nextInsnIndex, nextFrame1), nextHistory, taken, hasCompanions || notEmptySubResult));
|
||||
subIndices.add(id);
|
||||
subIndices[i] = (id);
|
||||
}
|
||||
|
||||
pending.push(new MakeResult<PResult>(state, subResult, subIndices));
|
||||
|
||||
-5
@@ -61,11 +61,6 @@
|
||||
<item name="java.net.InetAddress int checkNumericZone(java.lang.String) 0">
|
||||
<annotation name="org.jetbrains.annotations.NotNull"/>
|
||||
</item>
|
||||
<item name="java.net.InetAddress java.lang.Object checkLookupTable(java.lang.String)">
|
||||
<annotation name="org.jetbrains.annotations.Contract">
|
||||
<val val=""null->null""/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item name="java.net.InetAddress java.lang.Object getCachedAddress(java.lang.String) 0">
|
||||
<annotation name="org.jetbrains.annotations.NotNull"/>
|
||||
</item>
|
||||
|
||||
Reference in New Issue
Block a user