Skip to content

Commit

Permalink
fix(patch): Improve patches generation (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
surli authored and tdurieux committed Aug 3, 2018
1 parent 0d47b5e commit a551cdd
Show file tree
Hide file tree
Showing 11 changed files with 90 additions and 64 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ buildNumber.properties

bin
target

*.iml
.idea
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,11 @@ protected NPEOutput runProject(String name, String source, String test, String[]
if (positions.containsKey(name)) {
CtElement element = getElementFromPosition(spoon.getFactory().Type().get(positions.get(name).getClassname()), positions.get(name));
if (element != null) {
output.addAll(strategy1(spoon, (CtExpression) element));
output.addAll(strategy2(spoon, (CtExpression) element));
output.addAll(strategy3(spoon, (CtExpression) element));
output.addAll(strategy4(spoon, (CtExpression) element));
output.addAll(strategy1(spoon, (CtExpression) element, new String[] {source}));
output.addAll(strategy2(spoon, (CtExpression) element, new String[] {source}));
output.addAll(strategy3(spoon, (CtExpression) element, new String[] {source}));
output.addAll(strategy4(spoon, (CtExpression) element, new String[] {source}));
output.addAll(strategy4(spoon, (CtExpression) element, new String[] {source}));
} else {
Assert.fail("element not found");
}
Expand Down Expand Up @@ -188,7 +189,7 @@ private List<CtExpression> getVariableAccesses(CtElement elementToReplace, CtTyp
/**
* Replace null element by existing element
*/
private NPEOutput strategy1(Launcher launcher, CtExpression element) {
private NPEOutput strategy1(Launcher launcher, CtExpression element, final String[] inputSources) {
NPEOutput output = new NPEOutput();

Location location = getLocation(element);
Expand All @@ -201,7 +202,7 @@ private NPEOutput strategy1(Launcher launcher, CtExpression element) {
Decision decision = new Decision<>(new Strat1A(),
location,
InstanceFactory.fromCtExpression(ctVariableAccess));
output.addAll(applyAndRunPatch(launcher, new ReplaceLocal(ctVariableAccess), element, decision));
output.addAll(applyAndRunPatch(launcher, new ReplaceLocal(ctVariableAccess), element, decision, inputSources));
}
// in global mode the new element as to be the same type
variables = getVariableAccesses(element, element.getType());
Expand All @@ -211,15 +212,15 @@ private NPEOutput strategy1(Launcher launcher, CtExpression element) {
location,
InstanceFactory.fromCtExpression(ctVariableAccess));
output.addAll(applyAndRunPatch(launcher, new ReplaceGlobal(ctVariableAccess), element,
decision));
decision, inputSources));
}
return output;
}

/**
* Replace null element by new instance
*/
private NPEOutput strategy2(Launcher launcher, CtExpression element) {
private NPEOutput strategy2(Launcher launcher, CtExpression element, final String[] inputSources) {
NPEOutput output = new NPEOutput();

Location location = getLocation(element);
Expand All @@ -233,7 +234,7 @@ private NPEOutput strategy2(Launcher launcher, CtExpression element) {
Decision decision = new Decision<>(new Strat2A(), location,
InstanceFactory.fromCtExpression(newInstance));
output.addAll(applyAndRunPatch(launcher, new ReplaceLocal(newInstance), element,
decision));
decision, inputSources));
}

// in global mode the new element as to be the same type
Expand All @@ -245,23 +246,23 @@ private NPEOutput strategy2(Launcher launcher, CtExpression element) {
location,
InstanceFactory.fromCtExpression(newInstance));
output.addAll(applyAndRunPatch(launcher, new ReplaceGlobal(newInstance), element,
decision));
decision, inputSources));
}
return output;
}

/**
* Add check not null around null element
*/
private NPEOutput strategy3(Launcher launcher, CtExpression element) {
private NPEOutput strategy3(Launcher launcher, CtExpression element, final String[] inputSources) {
NPEOutput output = new NPEOutput();

Location location = getLocation(element);

Decision decision = new Decision<>(new Strat3(), location, new PrimitiveInstance(false));

output.addAll(applyAndRunPatch(launcher, new SkipLine(), element,
decision));
decision, inputSources));
return output;
}

Expand All @@ -275,7 +276,7 @@ private Location getLocation(CtExpression element) {
/**
* Skip method
*/
private NPEOutput strategy4(Launcher launcher, CtExpression element) {
private NPEOutput strategy4(Launcher launcher, CtExpression element, final String[] inputSources) {
NPEOutput output = new NPEOutput();
CtMethod method = element.getParent(CtMethod.class);

Expand Down Expand Up @@ -307,15 +308,15 @@ private NPEOutput strategy4(Launcher launcher, CtExpression element) {
}

Decision decision = new Decision<>(new Strat4(type), location, instance);
output.addAll(applyAndRunPatch(launcher, new SkipMethodReturn(ctVariable), element, decision));
output.addAll(applyAndRunPatch(launcher, new SkipMethodReturn(ctVariable), element, decision, inputSources));
}
}
return output;
}

private List<Lapse> applyAndRunPatch(Launcher launcher,
PatchTemplate patchTemplate,
CtExpression expression, Decision decision) {
CtExpression expression, Decision decision, final String[] inputSources) {
// clone the parent of the expression
CtType originalType = expression.getParent(CtType.class);
CtType cloneType = originalType.clone();
Expand All @@ -330,7 +331,7 @@ private List<Lapse> applyAndRunPatch(Launcher launcher,
// change the model with the new class
originalType.replace(cloneType);

List<Lapse> lapses = executeTest(launcher, decision);
List<Lapse> lapses = executeTest(launcher, decision, inputSources);

// restore the original class
cloneType.replace(originalType);
Expand All @@ -343,7 +344,7 @@ private List<Lapse> applyAndRunPatch(Launcher launcher,
return Collections.emptyList();
}

private List<Lapse> executeTest(final Launcher launcher, final Decision decision) {
private List<Lapse> executeTest(final Launcher launcher, final Decision decision, final String[] inputSources) {
Path tempBinFolder = null;
try {
tempBinFolder = Files.createTempDirectory("npefix_");
Expand Down Expand Up @@ -393,7 +394,7 @@ private List<Lapse> executeTest(final Launcher launcher, final Decision decision
continue;
}

Lapse lapse = new Lapse(null);
Lapse lapse = new Lapse(null, inputSources);
lapse.setTestClassName(testClassName);
lapse.setTestName(method);
lapse.addDecision(decision);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
public class ExecutionClient {

public static void main(String[] args) {
ExecutionClient executionClient = new ExecutionClient(args[0], args[1]);
ExecutionClient executionClient = new ExecutionClient(args[0], args[1], new String[0]);
Config.CONFIG.setRandomSeed(Integer.parseInt(args[2]));
executionClient.run();
}
Expand All @@ -33,10 +33,12 @@ public static void main(String[] args) {
private String testName;
private int port = Config.CONFIG.getServerPort();
private String host = Config.CONFIG.getServerHost();
private String[] inputSources;

public ExecutionClient(String classTestName, String testName) {
public ExecutionClient(String classTestName, String testName, String[] inputSources) {
this.classTestName = classTestName;
this.testName = testName;
this.inputSources = inputSources;
}

/**
Expand All @@ -55,7 +57,7 @@ private Selector getSelector() {

private void run() {
Selector selector = getSelector();
Lapse lapse = new Lapse(selector);
Lapse lapse = new Lapse(selector, inputSources);
lapse.setTestClassName(classTestName);
lapse.setTestName(testName);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@
*/
public class DefaultRepairStrategy implements RepairStrategy {

private String[] inputSources;
protected List<AbstractProcessor> processors;

public DefaultRepairStrategy() {
public DefaultRepairStrategy(String[] inputSources) {
processors = new ArrayList<>();
processors.add(new TernarySplitter());//
//processors.add(new IfSplitter());
Expand All @@ -53,6 +54,7 @@ public DefaultRepairStrategy() {
processors.add(new ConstructorEncapsulation());
processors.add(new VariableFor());//
//p.addProcessor(new ArrayRead());
this.inputSources = inputSources;
}

@Override
Expand All @@ -62,7 +64,7 @@ public NPEOutput run(Selector selector, List<String> methodTests) {

NPEOutput output = new NPEOutput();

Lapse lapse = new Lapse(selector);
Lapse lapse = new Lapse(selector, inputSources);

final TestRunner testRunner = new TestRunner();
for (int i = 0; i < methodTests.size(); i++) {
Expand Down Expand Up @@ -101,7 +103,7 @@ public NPEOutput run(Selector selector, List<String> methodTests) {
throw new RuntimeException(e);
}
}
lapse = new Lapse(selector);
lapse = new Lapse(selector, inputSources);
CallChecker.enable();
CallChecker.cache.clear();
CallChecker.getDecisions().clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public class Launcher {
private final Logger logger = LoggerFactory.getLogger(Launcher.class);

public Launcher(String[] sourcePath, String sourceOutput, String binOutput, String classpath) {
this(sourcePath, sourceOutput, binOutput, classpath, 7, new DefaultRepairStrategy());
this(sourcePath, sourceOutput, binOutput, classpath, 7, new DefaultRepairStrategy(sourcePath));
}

public Launcher(String[] sourcePath, String sourceOutput, String binOutput, String classpath, RepairStrategy repairStrategy) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
public class TryCatchRepairStrategy extends DefaultRepairStrategy {
private static Selector selector;

public TryCatchRepairStrategy() {
public TryCatchRepairStrategy(String[] inputSources) {
super(inputSources);
processors = new ArrayList<>();
processors.add(new CheckNotNull());//
processors.add(new ForceNullInit());//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ private static void sortPatchProject(String project, String projectSourcePath, S
decisions.add(decision);
}

PatchesGenerator patchesGenerator = new PatchesGenerator(decisions, spoon);
PatchesGenerator patchesGenerator = new PatchesGenerator(decisions, spoon, new String[] {projectSourcePath});
String diff = patchesGenerator.getDiff();
System.out.println(diff);
((JSONObject) execution).put("diff", diff);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@
public class PatchesGenerator {
private List<Decision> decisions;
private Launcher spoon;
private String[] inputSources;

public PatchesGenerator(List<Decision> decisions, Launcher spoon) {
public PatchesGenerator(List<Decision> decisions, Launcher spoon, String[] inputSources) {
this.decisions = new ArrayList<>();
for (int i = 0; i < decisions.size(); i++) {
Decision decision = decisions.get(i);
Expand All @@ -35,6 +36,7 @@ public PatchesGenerator(List<Decision> decisions, Launcher spoon) {
}
}
this.spoon = spoon;
this.inputSources = inputSources;
}

public String getDiff() {
Expand Down Expand Up @@ -148,8 +150,8 @@ private String createPatchDiff(String className, List<Decision> decisions) {
try {
String path = getClassPath(type);
diff = Diff.diff(r1, r2, false)
.toUnifiedDiff(path,
path,
.toUnifiedDiff("a" + path,
"b" + path,
new StringReader(originalClassContent),
new StringReader(classContent), 1);
} catch (IOException e) {
Expand All @@ -162,16 +164,28 @@ private String createPatchDiff(String className, List<Decision> decisions) {
private String getClassPath(CtType type) {
String path = type.getPosition().getFile().getPath();
String intersection = null;
Set<File> inputSources = spoon.getModelBuilder().getInputSources();
for (File inputSource : inputSources) {
for (String inputSource : inputSources) {
if (inputSource.startsWith("./")) {
inputSource = inputSource.substring(2);
}
if (intersection == null) {
intersection = inputSource.getPath();
intersection = inputSource;
} else {
intersection = intersection(intersection, inputSource);
}
}
int indexOfIntersection = path.indexOf(intersection);

if (indexOfIntersection != -1) {
path = path.substring(indexOfIntersection);
if (!path.startsWith("/")) {
return "/" + path;
} else {
intersection = intersection(intersection, inputSource.getPath());
return path;
}
} else {
return null;
}
path = path.replace(intersection, "");
return path;
}

/**
Expand Down
6 changes: 4 additions & 2 deletions src/main/java/fr/inria/spirals/npefix/resi/context/Lapse.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ public class Lapse implements Comparable<Lapse>, Serializable {
private Date startDate;
private Date endDate;
private boolean isFinished = false;
private String[] inputSources;

public Lapse(Selector strategySelector) {
public Lapse(Selector strategySelector, String[] inputSources) {
this.uniqueId = currentUniqueId++;
this.locations = new HashSet<>();
nbApplication = new HashMap<>();
Expand All @@ -45,6 +46,7 @@ public Lapse(Selector strategySelector) {
startDate = new Date();
this.strategySelector = strategySelector;
metadata.put("seed", Config.CONFIG.getRandomSeed());
this.inputSources = inputSources;
}

public void increaseNbApplication(Decision decision) {
Expand Down Expand Up @@ -141,7 +143,7 @@ public Object getMetadata(String key) {

public String toDiff(Launcher spoon) {
try {
PatchesGenerator patchesGenerator = new PatchesGenerator(decisions, spoon);
PatchesGenerator patchesGenerator = new PatchesGenerator(decisions, spoon, inputSources);
return patchesGenerator.getDiff();
} catch (Exception e) {
return null;
Expand Down
Loading

0 comments on commit a551cdd

Please sign in to comment.