Skip to content

Commit

Permalink
[fix] Merge comments attached to the compilation unit
Browse files Browse the repository at this point in the history
  • Loading branch information
slarse committed May 24, 2020
1 parent 48c8e78 commit 3ceee85
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 2 deletions.
7 changes: 6 additions & 1 deletion src/main/java/se/kth/spork/cli/Cli.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,13 @@ public static String prettyPrint(CtModule spoonRoot) {
.collect(Collectors.toList());
new PrinterPreprocessor(importNames, activePackage.getQualifiedName()).scan(spoonRoot);


StringBuilder sb = new StringBuilder();

String cuComment = (String) spoonRoot.getMetadata(Parser.COMPILATION_UNIT_COMMENT);
if (!cuComment.isEmpty()) {
sb.append(cuComment).append("\n");
}

if (!activePackage.isUnnamedPackage()) {
sb.append("package ").append(activePackage.getQualifiedName()).append(";").append("\n\n");
}
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/se/kth/spork/spoon/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import spoon.Launcher;
import spoon.compiler.Environment;
import spoon.reflect.CtModel;
import spoon.reflect.code.CtComment;
import spoon.reflect.declaration.*;
import spoon.support.compiler.FileSystemFile;
import spoon.support.compiler.VirtualFile;
Expand All @@ -24,6 +25,7 @@
*/
public class Parser {
public static final String IMPORT_STATEMENTS = "spork_import_statements";
public static final String COMPILATION_UNIT_COMMENT = "spork_cu_comment";

private static final LazyLogger LOGGER = new LazyLogger(Parser.class);

Expand Down Expand Up @@ -87,6 +89,11 @@ private static CtModule parse(Consumer<Launcher> addResource) {

CtModule module = model.getUnnamedModule();

// FIXME This is an ugly workaround for merging compliation unit comments
List<CtComment> cuComments = module.getFactory().CompilationUnit().getMap().values().iterator().next().getComments();
String cuComment = cuComments.isEmpty() ? "" : cuComments.get(0).getRawContent();
module.putMetadata(COMPILATION_UNIT_COMMENT, cuComment);

// TODO preserve order of import statements
List<CtImport> imports = new ArrayList<>(parseImportStatements(model));
imports.sort(Comparator.comparing(CtElement::prettyprint));
Expand Down
25 changes: 24 additions & 1 deletion src/main/java/se/kth/spork/spoon/Spoon3dmMerge.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import se.kth.spork.spoon.wrappers.RoledValues;
import se.kth.spork.spoon.wrappers.SpoonNode;
import se.kth.spork.util.LazyLogger;
import se.kth.spork.util.LineBasedMerge;
import se.kth.spork.util.Pair;
import spoon.reflect.declaration.*;

Expand Down Expand Up @@ -129,9 +130,31 @@ public static <T extends CtElement> Pair<T, Integer> merge(T base, T left, T rig
List<CtImport> mergedImports = mergeImportStatements(base, left, right);
mergeTree.putMetadata(Parser.IMPORT_STATEMENTS, mergedImports);

LOGGER.info(() -> "Merging compilation unit comments");
Pair<String, Integer> cuCommentMerge = mergeCuComments(base, left, right);
int cuCommentConflicts = cuCommentMerge.second;
mergeTree.putMetadata(Parser.COMPILATION_UNIT_COMMENT, cuCommentMerge.first);

LOGGER.info(() -> "Merged in " + (double) (System.nanoTime() - start) / 1e9 + " seconds");

return Pair.of(mergeTree, numConflicts);
return Pair.of(mergeTree, numConflicts + cuCommentConflicts);
}

/**
* Perform a line-based merge of the compilation unit comments.
*
* @return A pair with the merge and the amount of conflicts.
*/
private static Pair<String, Integer> mergeCuComments(CtElement base, CtElement left, CtElement right) {
String baseComment = getCuComment(base);
String leftComment = getCuComment(left);
String rightComment = getCuComment(right);
return LineBasedMerge.merge(baseComment, leftComment, rightComment);
}

private static String getCuComment(CtElement mod) {
String comment = (String) mod.getMetadata(Parser.COMPILATION_UNIT_COMMENT);
return comment == null ? "" : comment;
}

/**
Expand Down
5 changes: 5 additions & 0 deletions src/test/java/se/kth/spork/spoon/Spoon3dmMergeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,24 @@ void merge_shouldThrow_onUnhandledInconsistencies(Util.TestSources sources) {
private static void runTestMerge(Util.TestSources sources) {
CtModule expected = Parser.parse(sources.expected);
Object expectedImports = expected.getMetadata(Parser.IMPORT_STATEMENTS);
Object expectedCuComment = expected.getMetadata(Parser.COMPILATION_UNIT_COMMENT);
assert expectedImports != null;
assert expectedCuComment != null;

Pair<CtModule, Integer> merged = Spoon3dmMerge.merge(sources.base, sources.left, sources.right);
CtModule mergeTree = merged.first;
Object mergedImports = mergeTree.getMetadata(Parser.IMPORT_STATEMENTS);
Object mergedCuComment = mergeTree.getMetadata(Parser.COMPILATION_UNIT_COMMENT);

// this assert is just to give a better overview of obvious errors, but it relies on the pretty printer's
// correctness
// assertEquals(Cli.prettyPrint(expected), Cli.prettyPrint(mergeTree));
System.out.println(Cli.prettyPrint(mergeTree));

// these asserts are what actually matters
assertEquals(expected, mergeTree);
assertEquals(expectedImports, mergedImports);
assertEquals(expectedCuComment, mergedCuComment);
}
}

0 comments on commit 3ceee85

Please sign in to comment.