Skip to content

Commit

Permalink
Always returns a list of patch instead of an unique patch
Browse files Browse the repository at this point in the history
* refactor: synthetizer return now a List of patches

* utility method
  • Loading branch information
danglotb authored and tdurieux committed Sep 21, 2016
1 parent 1cb07c9 commit 6450cbb
Show file tree
Hide file tree
Showing 11 changed files with 367 additions and 360 deletions.
419 changes: 220 additions & 199 deletions nopol/src/main/java/fr/inria/lille/repair/common/config/Config.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,10 @@ public StatementType getType() {
public String toString() {
return String.format("%s:%d: %s %s", location.getContainingClassName(), getLineNumber(), type, expression.toString());
}

@Override
public SourceLocation getSourceLocation() {
return this.location;
}

}
53 changes: 4 additions & 49 deletions nopol/src/main/java/fr/inria/lille/repair/common/patch/Patch.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package fr.inria.lille.repair.common.patch;

import fr.inria.lille.repair.common.synth.StatementType;
import fr.inria.lille.repair.nopol.SourceLocation;

import java.io.File;

Expand All @@ -24,55 +25,6 @@
*/
public interface Patch {

/**
* Class that represents the inability to find a working patch.
*
* @author Favio D. DeMarco
*/
static final class NoPatch implements Patch {

private NoPatch() {
}

@Override
public String asString() {
throw new UnsupportedOperationException(toString());
}

@Override
public String getRootClassName() {
throw new UnsupportedOperationException(toString());
}

@Override
public File getFile(final File sourcePath) {
throw new UnsupportedOperationException(toString());
}

@Override
public int getLineNumber() {
throw new UnsupportedOperationException(toString());
}

@Override
public StatementType getType() {
throw new UnsupportedOperationException(toString());
}

/**
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "No viable patch found.";
}
}

/**
* Singleton that represents the inability to find a working patch.
*/
static final Patch NO_PATCH = new NoPatch();

String asString();

/**
Expand All @@ -85,4 +37,7 @@ public String toString() {
int getLineNumber();

StatementType getType();

SourceLocation getSourceLocation();

}
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ public StatementType getType() {
return type;
}

@Override
public SourceLocation getSourceLocation() {
return this.location;
}

/**
* @see java.lang.Object#toString()
*/
Expand Down
31 changes: 11 additions & 20 deletions nopol/src/main/java/fr/inria/lille/repair/nopol/NoPol.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
import java.util.*;
import java.util.concurrent.TimeUnit;

import static fr.inria.lille.repair.common.patch.Patch.NO_PATCH;

/**
* @author Favio D. DeMarco
Expand All @@ -59,7 +58,6 @@ public class NoPol {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private final SpoonedProject spooner;
private final File[] sourceFiles;
private static boolean singlePatch = true;
private String[] testClasses;
public long startTime;
private Config config;
Expand Down Expand Up @@ -180,15 +178,19 @@ private List<Patch> solveWithMultipleBuild(Collection<Statement> statements, Map
if (failingTest.isEmpty()) {
continue;
}
Patch patch = synth.buildPatch(classpath, tests, failingTest, config.getMaxTimeBuildPatch());
if (isOk(patch, gZoltar.getGzoltar().getTestResults(), synth.getProcessor())) {
patches.add(patch);
if (isSinglePatch()) {
break;
List<Patch> tmpPatches = synth.buildPatch(classpath, tests, failingTest, config.getMaxTimeBuildPatch());
for (int i = 0; i < tmpPatches.size(); i++) {
Patch patch = tmpPatches.get(i);
if (isOk(patch, gZoltar.getGzoltar().getTestResults(), synth.getProcessor())) {
patches.add(patch);
if (config.isOnlyOneSynthesisResult()) {
break;
}
} else {
logger.debug("Could not find a patch in {}", statement);
}
} else {
logger.debug("Could not find a patch in {}", statement);
}

} catch (RuntimeException re) {
re.printStackTrace();
}
Expand All @@ -201,21 +203,10 @@ private boolean isInTest(Statement statement) {
}

private boolean isOk(Patch newRepair, List<TestResult> testClasses, NopolProcessor processor) {
if (newRepair == NO_PATCH) {
return false;
}
logger.trace("Suggested patch: {}", newRepair);
return testPatch.passesAllTests(newRepair, testClasses, processor);
}

public static boolean isSinglePatch() {
return singlePatch;
}

public static boolean setSinglePatch(boolean singlePatch) {
return NoPol.singlePatch = singlePatch;
}

/**
* returns the list of failing tests
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,25 @@ public final class SourceLocation {

private final int lineNumber;

private int beginSource;
private int endSource;

public int getBeginSource() {
return beginSource;
}

public void setSourceStart(int beginSource) {
this.beginSource = beginSource;
}

public int getEndSource() {
return endSource;
}

public void setSourceEnd(int endSource) {
this.endSource = endSource;
}

/**
* @param containingClassName
* @param lineNumber
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public NopolProcessor(CtStatement target) {
@Override
public boolean isToBeProcessed(CtStatement statement) {
if (statement.getPosition() != null) {

return (statement.getPosition().getLine() == this.target
.getPosition().getLine())
&& (statement.getPosition().getColumn() == this.target
Expand Down Expand Up @@ -49,6 +50,10 @@ public void setType(Class<?> type) {
this.type = type;
}

public CtStatement getTarget() {
return target;
}

private Class<?> type;
private String defaultValue;
private String value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,106 +34,104 @@
import java.net.URL;
import java.util.*;

import static fr.inria.lille.repair.common.patch.Patch.NO_PATCH;

/**
* @author Favio D. DeMarco
*/
public final class DefaultSynthesizer<T> implements Synthesizer {

private final SourceLocation sourceLocation;
private final AngelicValue constraintModelBuilder;
private final StatementType type;
public static int nbStatementsWithAngelicValue = 0;
private static int dataSize = 0;
private static int nbVariables;
private final SpoonedProject spoonedProject;
private NopolProcessor conditionalProcessor;
private Config config;
private final SourceLocation sourceLocation;
private final AngelicValue constraintModelBuilder;
private final StatementType type;
public static int nbStatementsWithAngelicValue = 0;
private static int dataSize = 0;
private static int nbVariables;
private final SpoonedProject spoonedProject;
private NopolProcessor conditionalProcessor;
private Config config;

public DefaultSynthesizer(SpoonedProject spoonedProject, AngelicValue constraintModelBuilder, SourceLocation sourceLocation, StatementType type, NopolProcessor processor, Config config) {
this.constraintModelBuilder = constraintModelBuilder;
this.config = config;
this.sourceLocation = sourceLocation;
this.type = type;
this.spoonedProject = spoonedProject;
conditionalProcessor = processor;
}
public DefaultSynthesizer(SpoonedProject spoonedProject, AngelicValue constraintModelBuilder, SourceLocation sourceLocation, StatementType type, NopolProcessor processor, Config config) {
this.constraintModelBuilder = constraintModelBuilder;
this.config = config;
this.sourceLocation = sourceLocation;
this.type = type;
this.spoonedProject = spoonedProject;
conditionalProcessor = processor;
}

/*
* (non-Javadoc)
*
* @see fr.inria.lille.jefix.synth.Synthesizer#buildPatch(java.net.URL[], java.lang.String[])
*/
@Override
public Patch buildPatch(URL[] classpath, List<TestResult> testClasses, Collection<TestCase> failures, long maxTimeBuildPatch) {
Collection<Specification<T>> data = constraintModelBuilder.buildFor(classpath, testClasses, failures);
/*
* (non-Javadoc)
*
* @see fr.inria.lille.jefix.synth.Synthesizer#buildPatch(java.net.URL[], java.lang.String[])
*/
@Override
public List<Patch> buildPatch(URL[] classpath, List<TestResult> testClasses, Collection<TestCase> failures, long maxTimeBuildPatch) {
Collection<Specification<T>> data = constraintModelBuilder.buildFor(classpath, testClasses, failures);

// XXX FIXME TODO move this
// there should be at least two sets of values, otherwise the patch would be "true" or "false"
int dataSize = data.size();
if (dataSize < 2) {
LoggerFactory.getLogger(this.getClass()).info("{} input values set(s). There are not enough tests for {} otherwise the patch would be \"true\" or \"false\"",
dataSize, sourceLocation);
return NO_PATCH;
}
// the synthesizer do an infinite loop when all data does not have the same input size
int firstDataSize = data.iterator().next().inputs().size();
for (Iterator<Specification<T>> iterator = data.iterator(); iterator.hasNext(); ) {
Specification<T> next = iterator.next();
if (next.inputs().size() != firstDataSize) {
//return NO_PATCH;
}
}
// XXX FIXME TODO move this
// there should be at least two sets of values, otherwise the patch would be "true" or "false"
int dataSize = data.size();
if (dataSize < 2) {
LoggerFactory.getLogger(this.getClass()).info("{} input values set(s). There are not enough tests for {} otherwise the patch would be \"true\" or \"false\"",
dataSize, sourceLocation);
return Collections.EMPTY_LIST;
}
// the synthesizer do an infinite loop when all data does not have the same input size
int firstDataSize = data.iterator().next().inputs().size();
for (Iterator<Specification<T>> iterator = data.iterator(); iterator.hasNext(); ) {
Specification<T> next = iterator.next();
if (next.inputs().size() != firstDataSize) {
//return NO_PATCH;
}
}

// and it should be a viable patch, ie. fix the bug
if (!constraintModelBuilder.isAViablePatch()) {
LoggerFactory.getLogger(this.getClass()).info("Changing only this statement does not solve the bug. {}", sourceLocation);
return NO_PATCH;
}
nbStatementsWithAngelicValue++;
Candidates constantes = new Candidates();
ConstantCollector constantCollector = new ConstantCollector(constantes, null, config);
spoonedProject.forked(sourceLocation.getContainingClassName()).process(constantCollector);
Map<String, Integer> intConstants = new HashMap();
intConstants.put("-1", -1);
intConstants.put("0", 0);
intConstants.put("1", 1);
/*for (int i = 0; i < constantes.size(); i++) {
// and it should be a viable patch, ie. fix the bug
if (!constraintModelBuilder.isAViablePatch()) {
LoggerFactory.getLogger(this.getClass()).info("Changing only this statement does not solve the bug. {}", sourceLocation);
return Collections.EMPTY_LIST;
}
nbStatementsWithAngelicValue++;
Candidates constantes = new Candidates();
ConstantCollector constantCollector = new ConstantCollector(constantes, null, config);
spoonedProject.forked(sourceLocation.getContainingClassName()).process(constantCollector);
Map<String, Integer> intConstants = new HashMap();
intConstants.put("-1", -1);
intConstants.put("0", 0);
intConstants.put("1", 1);
/*for (int i = 0; i < constantes.size(); i++) {
Expression expression = constantes.get(i);
if(expression instanceof PrimitiveConstant) {
if(expression.getType() == Integer.class) {
intConstants.put(expression.getValue() + "", expression.getValue());
}
}
}*/
ConstraintBasedSynthesis synthesis = new ConstraintBasedSynthesis(intConstants);
CodeGenesis genesis = synthesis.codesSynthesisedFrom(
(Class<T>) (type.getType()), data);
if (!genesis.isSuccessful()) {
return NO_PATCH;
}
DefaultSynthesizer.dataSize = dataSize;
DefaultSynthesizer.nbVariables = data.iterator().next().inputs().keySet().size();
return new StringPatch(genesis.returnStatement(), sourceLocation, type);
}
ConstraintBasedSynthesis synthesis = new ConstraintBasedSynthesis(intConstants);
CodeGenesis genesis = synthesis.codesSynthesisedFrom(
(Class<T>) (type.getType()), data);
if (!genesis.isSuccessful()) {
return Collections.EMPTY_LIST;
}
DefaultSynthesizer.dataSize = dataSize;
DefaultSynthesizer.nbVariables = data.iterator().next().inputs().keySet().size();
return Collections.singletonList((Patch) new StringPatch(genesis.returnStatement(), sourceLocation, type));
}

public static int getNbStatementsWithAngelicValue() {
return nbStatementsWithAngelicValue;
}
public static int getNbStatementsWithAngelicValue() {
return nbStatementsWithAngelicValue;
}

public static int getDataSize() {
return dataSize;
}
public static int getDataSize() {
return dataSize;
}

public static int getNbVariables() {
return nbVariables;
}
public static int getNbVariables() {
return nbVariables;
}

@Override
public NopolProcessor getProcessor() {
return conditionalProcessor;
}
@Override
public NopolProcessor getProcessor() {
return conditionalProcessor;
}


}
Loading

0 comments on commit 6450cbb

Please sign in to comment.