added 'getParent' to Pseudocode

fixed DataFlowInfoTest:
variable data shouldn't be built for locals as independent declarations
This commit is contained in:
Svetlana Isakova
2014-03-05 19:29:14 +04:00
parent 88f2c32724
commit 6857694d1a
4 changed files with 40 additions and 13 deletions
@@ -17,6 +17,7 @@
package org.jetbrains.jet.lang.cfg.pseudocode; package org.jetbrains.jet.lang.cfg.pseudocode;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.psi.JetElement; import org.jetbrains.jet.lang.psi.JetElement;
import java.util.List; import java.util.List;
@@ -26,6 +27,9 @@ public interface Pseudocode {
@NotNull @NotNull
JetElement getCorrespondingElement(); JetElement getCorrespondingElement();
@Nullable
Pseudocode getParent();
@NotNull @NotNull
Set<LocalFunctionDeclarationInstruction> getLocalDeclarations(); Set<LocalFunctionDeclarationInstruction> getLocalDeclarations();
@@ -78,6 +78,7 @@ public class PseudocodeImpl implements Pseudocode {
private final List<Instruction> mutableInstructionList = new ArrayList<Instruction>(); private final List<Instruction> mutableInstructionList = new ArrayList<Instruction>();
private final List<Instruction> instructions = new ArrayList<Instruction>(); private final List<Instruction> instructions = new ArrayList<Instruction>();
private Pseudocode parent = null;
private Set<LocalFunctionDeclarationInstruction> localDeclarations = null; private Set<LocalFunctionDeclarationInstruction> localDeclarations = null;
//todo getters //todo getters
private final Map<JetElement, Instruction> representativeInstructions = new HashMap<JetElement, Instruction>(); private final Map<JetElement, Instruction> representativeInstructions = new HashMap<JetElement, Instruction>();
@@ -122,6 +123,26 @@ public class PseudocodeImpl implements Pseudocode {
return localDeclarations; return localDeclarations;
} }
@Override
@Nullable
public Pseudocode getParent() {
return parent;
}
private void setParent(Pseudocode parent) {
this.parent = parent;
}
@NotNull
public Pseudocode getRootPseudocode() {
Pseudocode parent = getParent();
while (parent != null) {
if (parent.getParent() == null) return parent;
parent = parent.getParent();
}
return this;
}
/*package*/ PseudocodeLabel createLabel(String name) { /*package*/ PseudocodeLabel createLabel(String name) {
PseudocodeLabel label = new PseudocodeLabel(name); PseudocodeLabel label = new PseudocodeLabel(name);
labels.add(label); labels.add(label);
@@ -292,7 +313,9 @@ public class PseudocodeImpl implements Pseudocode {
@Override @Override
public void visitLocalFunctionDeclarationInstruction(LocalFunctionDeclarationInstruction instruction) { public void visitLocalFunctionDeclarationInstruction(LocalFunctionDeclarationInstruction instruction) {
((PseudocodeImpl)instruction.getBody()).postProcess(); PseudocodeImpl body = (PseudocodeImpl) instruction.getBody();
body.setParent(PseudocodeImpl.this);
body.postProcess();
instruction.setNext(getSinkInstruction()); instruction.setNext(getSinkInstruction());
} }
@@ -34,25 +34,25 @@ sink:
} }
--------------------- ---------------------
L3: L3:
<START> INIT: in: {} out: {} <START> INIT: in: {a=ID, f=D} out: {a=ID, f=D}
v(x: Int) INIT: in: {} out: {x=D} v(x: Int) INIT: in: {a=ID, f=D} out: {a=ID, f=D, x=D}
w(x) INIT: in: {x=D} out: {x=ID} w(x) INIT: in: {a=ID, f=D, x=D} out: {a=ID, f=D, x=ID}
mark(val y = x + a use(a)) INIT: in: {x=ID} out: {x=ID} mark(val y = x + a use(a)) INIT: in: {a=ID, f=D, x=ID} out: {a=ID, f=D, x=ID}
v(val y = x + a) INIT: in: {x=ID} out: {x=ID, y=D} v(val y = x + a) INIT: in: {a=ID, f=D, x=ID} out: {a=ID, f=D, x=ID, y=D}
mark(x + a) INIT: in: {x=ID, y=D} out: {x=ID, y=D} USE: in: {a=READ, x=READ} out: {a=READ, x=READ} mark(x + a) INIT: in: {a=ID, f=D, x=ID, y=D} out: {a=ID, f=D, x=ID, y=D} USE: in: {a=READ, x=READ} out: {a=READ, x=READ}
r(x) USE: in: {a=READ} out: {a=READ, x=READ} r(x) USE: in: {a=READ} out: {a=READ, x=READ}
r(a) r(a)
call(+, plus) call(+, plus)
w(y) INIT: in: {x=ID, y=D} out: {x=ID, y=ID} w(y) INIT: in: {a=ID, f=D, x=ID, y=D} out: {a=ID, f=D, x=ID, y=ID}
mark(use(a)) INIT: in: {x=ID, y=ID} out: {x=ID, y=ID} USE: in: {a=READ} out: {a=READ} mark(use(a)) INIT: in: {a=ID, f=D, x=ID, y=ID} out: {a=ID, f=D, x=ID, y=ID} USE: in: {a=READ} out: {a=READ}
r(a) USE: in: {} out: {a=READ} r(a) USE: in: {} out: {a=READ}
call(use, use) call(use, use)
L4: L4:
<END> <END>
error: error:
<ERROR> INIT: in: {} out: {} <ERROR> INIT: in: {} out: {}
sink: sink:
<SINK> INIT: in: {x=ID, y=ID} out: {x=ID, y=ID} USE: in: {} out: {} <SINK> INIT: in: {a=ID, f=D, x=ID, y=ID} out: {a=ID, f=D, x=ID, y=ID} USE: in: {} out: {}
===================== =====================
== use == == use ==
fun use(vararg a: Any?) = a fun use(vararg a: Any?) = a
@@ -42,7 +42,7 @@ public abstract class AbstractDataFlowTest extends AbstractPseudocodeTest {
@NotNull StringBuilder out, @NotNull StringBuilder out,
@NotNull BindingContext bindingContext @NotNull BindingContext bindingContext
) { ) {
PseudocodeVariablesData pseudocodeVariablesData = new PseudocodeVariablesData(pseudocode, bindingContext); PseudocodeVariablesData pseudocodeVariablesData = new PseudocodeVariablesData(pseudocode.getRootPseudocode(), bindingContext);
final Map<Instruction, Edges<Map<VariableDescriptor, VariableInitState>>> variableInitializers = final Map<Instruction, Edges<Map<VariableDescriptor, VariableInitState>>> variableInitializers =
pseudocodeVariablesData.getVariableInitializers(); pseudocodeVariablesData.getVariableInitializers();
final Map<Instruction, Edges<Map<VariableDescriptor, VariableUseState>>> useStatusData = final Map<Instruction, Edges<Map<VariableDescriptor, VariableUseState>>> useStatusData =