From 3ceee85ff918494308b9bc2a5ffd9cd323b02bfb Mon Sep 17 00:00:00 2001 From: slarse Date: Sun, 24 May 2020 17:09:45 +0200 Subject: [PATCH] [fix] Merge comments attached to the compilation unit --- src/main/java/se/kth/spork/cli/Cli.java | 7 +++++- src/main/java/se/kth/spork/spoon/Parser.java | 7 ++++++ .../se/kth/spork/spoon/Spoon3dmMerge.java | 25 ++++++++++++++++++- .../se/kth/spork/spoon/Spoon3dmMergeTest.java | 5 ++++ 4 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/main/java/se/kth/spork/cli/Cli.java b/src/main/java/se/kth/spork/cli/Cli.java index 194dfb11..d0b6e26d 100644 --- a/src/main/java/se/kth/spork/cli/Cli.java +++ b/src/main/java/se/kth/spork/cli/Cli.java @@ -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"); } diff --git a/src/main/java/se/kth/spork/spoon/Parser.java b/src/main/java/se/kth/spork/spoon/Parser.java index 4a854f51..26fea2b6 100644 --- a/src/main/java/se/kth/spork/spoon/Parser.java +++ b/src/main/java/se/kth/spork/spoon/Parser.java @@ -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; @@ -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); @@ -87,6 +89,11 @@ private static CtModule parse(Consumer addResource) { CtModule module = model.getUnnamedModule(); + // FIXME This is an ugly workaround for merging compliation unit comments + List 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 imports = new ArrayList<>(parseImportStatements(model)); imports.sort(Comparator.comparing(CtElement::prettyprint)); diff --git a/src/main/java/se/kth/spork/spoon/Spoon3dmMerge.java b/src/main/java/se/kth/spork/spoon/Spoon3dmMerge.java index b7d0f99a..320eabff 100644 --- a/src/main/java/se/kth/spork/spoon/Spoon3dmMerge.java +++ b/src/main/java/se/kth/spork/spoon/Spoon3dmMerge.java @@ -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.*; @@ -129,9 +130,31 @@ public static Pair merge(T base, T left, T rig List mergedImports = mergeImportStatements(base, left, right); mergeTree.putMetadata(Parser.IMPORT_STATEMENTS, mergedImports); + LOGGER.info(() -> "Merging compilation unit comments"); + Pair 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 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; } /** diff --git a/src/test/java/se/kth/spork/spoon/Spoon3dmMergeTest.java b/src/test/java/se/kth/spork/spoon/Spoon3dmMergeTest.java index e6d2975f..e869fc0a 100644 --- a/src/test/java/se/kth/spork/spoon/Spoon3dmMergeTest.java +++ b/src/test/java/se/kth/spork/spoon/Spoon3dmMergeTest.java @@ -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 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); } }