fr.inria.prophet4j.feature.extended.ExtendedRepairGenerator Maven / Gradle / Ivy
The newest version!
package fr.inria.prophet4j.feature.extended;
import java.lang.reflect.Type;
import java.util.*;
import fr.inria.prophet4j.utility.Structure.RepairKind;
import fr.inria.prophet4j.utility.Structure.Repair;
import fr.inria.prophet4j.utility.Structure.DiffEntry;
import fr.inria.prophet4j.feature.RepairGenerator;
import fr.inria.prophet4j.feature.extended.util.ExtendedRepairAnalyzer;
import spoon.Launcher;
import spoon.reflect.code.CtIf;
import spoon.reflect.code.CtStatement;
import spoon.reflect.code.CtStatementList;
import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtElement;
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.visitor.filter.TypeFilter;
import spoon.reflect.code.*;
import spoon.reflect.factory.CoreFactory;
import spoon.reflect.path.CtRole;
import spoon.reflect.visitor.CtScanner;
// based on RepairGenerator.cpp
public class ExtendedRepairGenerator implements RepairGenerator {
private Set area; // loc_map
private DiffEntry diffEntry;
private CoreFactory factory;
private List repairs = new ArrayList<>();
private Map compound_counter = new HashMap<>();
private ExtendedRepairAnalyzer repairAnalyzer = new ExtendedRepairAnalyzer();
public ExtendedRepairGenerator(DiffEntry diffEntry) {
this.area = fuzzyLocator(diffEntry.srcNode);
this.diffEntry = diffEntry;
this.factory = new Launcher().getFactory().Core();
this.repairs.clear();
this.compound_counter.clear();
}
private boolean isTainted(CtStatement S) {
if (S == null) return false;
if (area.contains(S))
return true;
// why Prophet does not need the second condition ?
if (S instanceof CtStatementList && compound_counter.containsKey(S)) {
CtStatementList CS = (CtStatementList) S;
return compound_counter.get(CS) >= 2 || (compound_counter.get(CS) == 1 && CS.getStatements().size() == 1);
} else {
return false;
}
}
private void genTightCondition(CtIf n) {
CtExpression oldCondition = n.getCondition();
CtLiteral placeholder = factory.createLiteral();
placeholder.setValue(true); // consider the placeholder, should this be more concrete?
CtUnaryOperator tmpCondition = factory.createUnaryOperator();
tmpCondition.setKind(UnaryOperatorKind.NOT);
tmpCondition.setOperand(placeholder);
CtBinaryOperator newCondition = factory.createBinaryOperator();
newCondition.setKind(BinaryOperatorKind.AND);
newCondition.setLeftHandOperand(oldCondition);
newCondition.setRightHandOperand(placeholder);
CtIf S = n.clone();
S.setParent(n.getParent());
S.setCondition(newCondition);
Repair repair = new Repair();
repair.kind = RepairKind.TightenConditionKind;
repair.isReplace = true;
repair.srcElem = n;
repair.dstElem = S;
repair.atoms.addAll(repairAnalyzer.getCondCandidateVars(n));
repairs.add(repair);
// we do not consider the case of short-circuit evaluation at all
}
private void genLooseCondition(CtIf n) {
CtExpression oldCondition = n.getCondition();
CtLiteral placeholder = factory.createLiteral();
placeholder.setValue(true); // consider the placeholder, should this be more concrete?
CtBinaryOperator newCondition = factory.createBinaryOperator();
newCondition.setKind(BinaryOperatorKind.OR);
newCondition.setLeftHandOperand(oldCondition);
newCondition.setRightHandOperand(placeholder);
CtIf S = n.clone();
S.setParent(n.getParent());
S.setCondition(newCondition);
Repair repair = new Repair();
repair.kind = RepairKind.LoosenConditionKind;
repair.isReplace = true;
repair.srcElem = n;
repair.dstElem = S;
repair.atoms.addAll(repairAnalyzer.getCondCandidateVars(n));
repairs.add(repair);
// we do not consider the case of short-circuit evaluation at all
}
private void genAddIfGuard(CtStatement n) {
CtLiteral placeholder = factory.createLiteral();
placeholder.setValue(true); // consider the placeholder, should this be more concrete?
CtUnaryOperator guardCondition = factory.createUnaryOperator();
guardCondition.setKind(UnaryOperatorKind.NOT);
guardCondition.setOperand(placeholder);
CtIf guardIf = factory.createIf();
guardIf.setParent(n.getParent());
guardIf.setCondition(guardCondition);
guardIf.setThenStatement(n.clone());
Repair repair = new Repair();
repair.kind = RepairKind.GuardKind;
repair.isReplace = true;
repair.srcElem = n;
repair.dstElem = guardIf;
repair.atoms.addAll(repairAnalyzer.getCondCandidateVars(n));
repairs.add(repair);
// we do not consider the case of if statement as special at all
}
private void genAddIfExit(CtStatement n) {
CtLiteral placeholder = factory.createLiteral();
placeholder.setValue(true); // consider the placeholder, should this be more concrete?
Type returnType = void.class;
CtMethod curFD = repairAnalyzer.getCurrentFunction(n);
if (curFD != null) {
CtStatement lastStatement = curFD.getBody().getLastStatement();
// CtReturn ctReturn = curFD.getBody().getLastStatement();
// Type returnType = ctReturn.getClass().getGenericSuperclass();
List ctReturns = lastStatement.getElements(new TypeFilter<>(CtReturn.class));
if (ctReturns.size() > 0) {
returnType = ctReturns.get(0).getClass().getGenericSuperclass();
}
}
if (returnType == void.class) {
CtLiteral