package fr.inria.diversify.codeFragment;
import fr.inria.diversify.codeFragmentProcessor.SubStatementVisitor;
import spoon.reflect.code.*;
import spoon.reflect.declaration.CtElement;
import spoon.reflect.reference.CtTypeReference;
import spoon.support.reflect.code.*;
public class Statement extends CodeFragment {
public Statement(CtStatement stmt) {
init(stmt);
}
public Statement() {}
//validate if this can be replaced by other
public boolean isReplaceableBy(CodeFragment other, boolean varNameMatch, boolean subType) {
Class<?> cl = codeFragment.getClass();
Class<?> clOther = other.codeFragment.getClass();
if (clOther == CtBreakImpl.class || cl == CtBreakImpl.class)
return false;
if (clOther == CtContinueImpl.class || cl == CtContinueImpl.class)
return false;
if ((clOther == CtLocalVariableImpl.class || cl == CtLocalVariableImpl.class) && cl != clOther)
return false;
if ((clOther == CtCaseImpl.class || cl == CtCaseImpl.class))
return false;
if ((clOther == CtThrowImpl.class || cl == CtThrowImpl.class) && cl != clOther)
return false;
if(containsSuper(codeFragment) || containsSuper(other.codeFragment))
return false;
SubStatementVisitor sub = new SubStatementVisitor();
other.codeFragment.accept(sub);
if (sub.getStatements().contains(codeFragment)) {
return false;
}
if (!context.isReplaceableBy(other.context, varNameMatch, subType)) {
return false;
}
if((other.codeFragment instanceof CtReturn || other.codeFragment instanceof CtThrow)
&& !deadCode()) {
return false;
}
//validate for return
CtTypeReference t1 = this.hasReturn();
CtTypeReference t2 = other.hasReturn();
if (t1 == null && t2 == null)
return true;
if (t1 == null)
return false;
return t1.equals(t2);
}
public String codeFragmentString() {
String string = codeFragment.toString();
if(string.trim().endsWith("}"))
return string;
if(!string.endsWith(";"))
string = string+";";
if(!(codeFragment instanceof CtLocalVariableImpl
|| codeFragment instanceof CtReturnImpl))
return "{\n"+string+"\n}";
else
return string;
}
protected boolean deadCode() {
int position = 0;
CtBlock block = codeFragment.getParent(CtBlock.class);
if(block.getStatements() == null) {
return true;
}
for(Object stmt: block.getStatements()) {
position++;
if(codeFragment == stmt) {
break;
}
}
return position == block.getStatements().size();
}
protected boolean containsSuper(CtCodeElement cf) {
String string = cf.toString();
return string.contains("super(") || string.contains("super.");
}
public Statement clone() {
return new Statement((CtStatement) copyElem(codeFragment));
}
}