Skip to content

Commit

Permalink
Fix P4J features + more feature work (#262)
Browse files Browse the repository at this point in the history
  • Loading branch information
monperrus authored Mar 25, 2024
1 parent dfc0ca7 commit 2805ed7
Show file tree
Hide file tree
Showing 22 changed files with 297 additions and 608 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,14 @@ public FineGrainDifftAnalyzer() {
@SuppressWarnings("rawtypes")
public AnalysisResult analyze(IRevision revision) {

List<IRevisionPair> javaFiles = revision.getChildren();

Map<String, Diff> diffOfFiles = new HashMap<>();

List<DiffRow> rows = null;

log.info("\n*****\nCommit: " + revision.getName());

for (IRevisionPair<String> fileFromRevision : javaFiles) {
for (IRevisionPair<String> fileFromRevision : revision.getChildren()) {

String left = fileFromRevision.getPreviousVersion();
String right = fileFromRevision.getNextVersion();
Expand Down
118 changes: 48 additions & 70 deletions src/main/java/fr/inria/coming/codefeatures/FeatureAnalyzer.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,31 @@

import java.io.File;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import add.entities.RepairPatterns;
import add.features.detector.repairpatterns.AbstractPatternDetector;
import add.features.detector.repairpatterns.CodeMovingDetector;
import add.features.detector.repairpatterns.ConditionalBlockDetector;
import add.features.detector.repairpatterns.ConstantChangeDetector;
import add.features.detector.repairpatterns.CopyPasteDetector;
import add.features.detector.repairpatterns.ExpressionFixDetector;
import add.features.detector.repairpatterns.MissingNullCheckDetector;
import add.features.detector.repairpatterns.RepairPatternDetector;
import add.features.detector.repairpatterns.SingleLineDetector;
import add.features.detector.repairpatterns.WrapsWithDetector;
import add.features.detector.repairpatterns.WrongReferenceDetector;
import add.main.Config;
import com.github.difflib.DiffUtils;
import com.github.difflib.UnifiedDiffUtils;
import com.github.gumtreediff.actions.EditScript;
import com.google.gson.Gson;
import fr.inria.coming.core.engine.files.FileDiff;
import fr.inria.coming.core.entities.interfaces.IRevisionPair;
import org.apache.log4j.Logger;

Expand Down Expand Up @@ -69,6 +83,7 @@ public AnalysisResult analyze(IRevision revision, RevisionResult previousResults


for (Object nameFile : diffResut.getDiffOfFiles().keySet()) {
System.out.println("Analyzing file: " + nameFile);
Diff diff = (Diff) diffResut.getDiffOfFiles().get(nameFile);

List<Operation> ops = diff.getRootOperations();
Expand Down Expand Up @@ -100,7 +115,7 @@ public AnalysisResult analyze(IRevision revision, RevisionResult previousResults

}

FeaturesResult p4jfeatures = (FeaturesResult) new P4JFeatureAnalyzer().analyze(revision, nameFile.toString());
FeaturesResult p4jfeatures = (FeaturesResult) new P4JFeatureAnalyzer().analyze(revision, previousResults);
if(p4jfeatures!=null) {
changesArray.add(p4jfeatures.getFeatures());
}
Expand All @@ -121,15 +136,17 @@ public AnalysisResult analyze(IRevision revision, RevisionResult previousResults
Config config = new Config();
config.setDiffPath(tempFile.getAbsolutePath());
config.setBuggySourceDirectoryPath(revision.getFolder());
RepairPatternDetector patternDetector = new RepairPatternDetector(config, diff);
RepairPatterns analyze = patternDetector.analyze();
RepairPatterns analyze =analyze(diff, config);

changesArray.add(new Gson().fromJson(analyze.toJson().toString(), JsonObject.class));
tempFile.delete();

//add more features
JsonObject patternJson = RepairPatternFeatureAnalyzer.analyze(revision.getFolder(), diff, nameFile.toString());
changesArray.add(patternJson);

if (revision instanceof FileDiff) {
// TODO: generalize the implementation of RepairPatternFeatureAnalyzer and P4JFeatureAnalyzer with IRevision.getChildren instead of hard coding FileDiff
//add more features
JsonObject patternJson = RepairPatternFeatureAnalyzer.analyze(revision, diff, nameFile.toString());
changesArray.add(patternJson);
}

} catch (Exception e) {
new RuntimeException("Unable to compute ADD analysis", e);
Expand All @@ -145,6 +162,30 @@ public AnalysisResult analyze(IRevision revision, RevisionResult previousResults

}

public RepairPatterns analyze(Diff editScript, Config config) {
RepairPatterns repairPatterns = new RepairPatterns();
List<Operation> operations = editScript.getRootOperations();
List<AbstractPatternDetector> detectors = new ArrayList();
detectors.add(new MissingNullCheckDetector(operations));
//detectors.add(new SingleLineDetector(config, operations));
detectors.add(new ConditionalBlockDetector(operations));
detectors.add(new WrapsWithDetector(operations));
detectors.add(new CopyPasteDetector(operations));
detectors.add(new ConstantChangeDetector(operations));
detectors.add(new CodeMovingDetector(operations));
detectors.add(new ExpressionFixDetector(operations));
detectors.add(new WrongReferenceDetector(operations));
Iterator var3 = detectors.iterator();

while(var3.hasNext()) {
AbstractPatternDetector detector = (AbstractPatternDetector)var3.next();
detector.detect(repairPatterns);
}

return repairPatterns;
}


public void putCodeFromHunk(RevisionResult previousResults, Object nameFile, JsonObject file) {
AnalysisResult resultsHunk = previousResults.get(HunkDifftAnalyzer.class.getSimpleName());
if (resultsHunk != null) {
Expand All @@ -170,69 +211,6 @@ public void putCodeFromHunk(RevisionResult previousResults, Object nameFile, Jso
}

@SuppressWarnings("unchecked")
public JsonArray processFilesPair(File pairFolder) {
Map<String, Diff> diffOfcommit = new HashMap();

JsonArray filesArray = new JsonArray();
for (File fileModif : pairFolder.listFiles()) {
int i_hunk = 0;

if (".DS_Store".equals(fileModif.getName()))
continue;

String pathname = fileModif.getAbsolutePath() + File.separator + pairFolder.getName() + "_"
+ fileModif.getName();

File previousVersion = new File(pathname + "_s.java");
if (!previousVersion.exists()) {
pathname = pathname + "_" + i_hunk;
previousVersion = new File(pathname + "_s.java");
if (!previousVersion.exists())
continue;
}

File postVersion = new File(pathname + "_t.java");
i_hunk++;

JsonObject file = new JsonObject();
try {
filesArray.add(file);
file.addProperty("file_name", fileModif.getName());
JsonArray changesArray = new JsonArray();
file.add("features", changesArray);

AstComparator comparator = new AstComparator();

Diff diff = comparator.compare(previousVersion, postVersion);
if (diff == null) {
file.addProperty("status", "differror");
continue;
}

log.info("--diff: " + diff);

List<Operation> ops = diff.getRootOperations();
String key = fileModif.getParentFile().getName() + "_" + fileModif.getName();
diffOfcommit.put(key, diff);

for (Operation operation : ops) {
CtElement affectedCtElement = getLeftElement(operation);

if (affectedCtElement != null) {
Cntx iContext = cresolver.analyzeFeatures(affectedCtElement);
changesArray.add(iContext.toJSON());
}
}

} catch (Throwable e) {
log.error("error with " + previousVersion);
log.error(e);
file.addProperty("status", "exception");
}

}
return filesArray;
}

/**
* Get the element that is modified
Expand Down
117 changes: 39 additions & 78 deletions src/main/java/fr/inria/coming/codefeatures/P4JFeatureAnalyzer.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,9 @@
import java.util.List;
import java.util.Map;

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import fr.inria.coming.core.entities.interfaces.IRevisionPair;
import org.apache.log4j.Logger;
import org.json.simple.JSONObject;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import fr.inria.coming.changeminer.analyzer.commitAnalyzer.FineGrainDifftAnalyzer;
import fr.inria.coming.changeminer.entity.IRevision;
Expand All @@ -29,20 +26,16 @@
import fr.inria.coming.main.ComingProperties;
import fr.inria.prophet4j.feature.Feature;
import fr.inria.prophet4j.feature.FeatureCross;
import fr.inria.prophet4j.feature.extended.ExtendedFeatureCross;
import fr.inria.prophet4j.feature.original.OriginalFeatureCross;
import fr.inria.prophet4j.learner.RepairEvaluator;
import fr.inria.prophet4j.utility.CodeDiffer;
import fr.inria.prophet4j.utility.Option;
import fr.inria.prophet4j.utility.Support;
import fr.inria.prophet4j.utility.Option.FeatureOption;
import fr.inria.prophet4j.utility.Option.RankingOption;
import fr.inria.prophet4j.utility.Structure.FeatureMatrix;
import fr.inria.prophet4j.utility.Structure.FeatureVector;
import fr.inria.prophet4j.utility.Structure.ParameterVector;

/**
*
* Computes the P4J features for a given file pair (does not work with repo)
* @author He Ye
*
*/
Expand All @@ -57,52 +50,55 @@ public AnalysisResult analyze(IRevision revision, RevisionResult previousResults

AnalysisResult resultFromDiffAnalysis = previousResults.getResultFromClass(FineGrainDifftAnalyzer.class);
DiffResult diffResut = (DiffResult) resultFromDiffAnalysis;
String filename = "";
if (diffResut.getDiffOfFiles().size()!=0) {
filename = diffResut.getDiffOfFiles().keySet().iterator().next().toString();
}else {
filename = diffResut.getAnalyzed().toString();
}
String filename = revision.getName();
// if (diffResut.getDiffOfFiles().size()!=0) {
// filename = diffResut.getDiffOfFiles().keySet().iterator().next().toString();
// }else {
// filename = diffResut.getAnalyzed().toString();
// }

if (resultFromDiffAnalysis == null) {
System.err.println("Error Diff must be executed before");
throw new IllegalArgumentException("Error: missing diff");
}

// determine source and target file path
String path = revision.getFolder();
Map<String, File> filePaths = null;
if(path!=null) {
filePaths = processFilesPair(new File(path),"");
} else {
return null;
JsonObject jsonfile = new JsonObject();
for (IRevisionPair pair: revision.getChildren()) {
// determine source and target file path
JsonObject jsonpair = extractFeatures(fileSrcTgtPaths(pair));
jsonfile.add(pair.getPreviousName(), jsonpair);
}
JsonObject jsonfile = extractFeatures(filePaths);
return (new FeaturesResult(revision,jsonfile));
}


public AnalysisResult analyze(IRevision revision, String targetFile) {
String path = revision.getFolder();
Map<String, File> filePaths = null;
if(path!=null) {
filePaths = processFilesPair(new File(path),targetFile);
} else {
return null;
}
JsonObject jsonfile = extractFeatures(filePaths);

if(jsonfile==null) {
return null;

public Map<String, File> fileSrcTgtPaths(IRevisionPair s) {

Map<String, File> filePaths = new HashMap<>();
final File src = new File(s.getPreviousName());
if (!src.exists()) {
throw new IllegalArgumentException("The source file not exist!");
}

return (new FeaturesResult(revision,jsonfile));

filePaths.put("src", src);
final File tgt = new File(s.getNextName());
if (!tgt.exists()) {
throw new IllegalArgumentException("The source file not exist!");
}
filePaths.put("target", tgt);
return filePaths;
}




public JsonObject extractFeatures(Map<String, File> filePaths) {
File src = filePaths.get("src");
if (src==null) {
return null;
}
File target = filePaths.get("target");
if (src == null || target == null) {
log.error("The source or target file not exist!");
return null;
}
Option option = new Option();
option.featureOption = FeatureOption.ORIGINAL;
//We set the first parameter of CodeDiffer as False to not allow the code generation at buggy location
Expand All @@ -114,12 +110,8 @@ public JsonObject extractFeatures(Map<String, File> filePaths) {
List<FeatureMatrix> featureMatrix = codeDiffer.runByGenerator(src, target);
//Get feature vector
JsonObject jsonfile = null;
if(cross) {
jsonfile = genVectorsCSV(option,target,featureMatrix);
return null;
} else {
jsonfile = getSimleP4JJSON(option,target,featureMatrix,true);
}
// csvfile = genVectorsCSV(option,target,featureMatrix);
jsonfile = getSimleP4JJSON(option,target,featureMatrix,true);
return jsonfile;
}

Expand Down Expand Up @@ -149,38 +141,7 @@ public JsonObject getSimleP4JJSON(Option option, File target, List<FeatureMatrix

}

public Map processFilesPair(File pairFolder,String targetFile) {
Map<String, File> pathmap = new HashMap();

for (File fileModif : pairFolder.listFiles()) {

if (".DS_Store".equals(fileModif.getName()))
continue;

if(targetFile!="") {
if (!fileModif.getPath().contains(targetFile)) {
continue;
}
}

String pathname = fileModif.getAbsolutePath() + File.separator + pairFolder.getName() + "_"
+ fileModif.getName();

File previousVersion = new File(pathname + "_s.java");
if (!previousVersion.exists()) {
log.error("The source file " + previousVersion.getPath() + " not exist!");
} else {
pathmap.put("src", previousVersion);
File postVersion = new File(pathname + "_t.java");
pathmap.put("target", postVersion);

}

}
return pathmap;

}


public JsonObject genVectorsCSV(Option option, File patchedFile, List<FeatureMatrix> featureMatrices) {

Expand Down
Loading

0 comments on commit 2805ed7

Please sign in to comment.